diff options
Diffstat (limited to 'include')
90 files changed, 4256 insertions, 282 deletions
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index 4db89e98535..82ec6a3c050 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -47,7 +47,7 @@ /* Current ACPICA subsystem version in YYYYMMDD format */ -#define ACPI_CA_VERSION 0x20090320 +#define ACPI_CA_VERSION 0x20090521 #include "actypes.h" #include "actbl.h" @@ -201,6 +201,8 @@ acpi_evaluate_object_typed(acpi_handle object, acpi_status acpi_get_object_info(acpi_handle handle, struct acpi_buffer *return_buffer); +acpi_status acpi_install_method(u8 *buffer); + acpi_status acpi_get_next_object(acpi_object_type type, acpi_handle parent, @@ -375,7 +377,7 @@ acpi_status acpi_leave_sleep_state_prep(u8 sleep_state); acpi_status acpi_leave_sleep_state(u8 sleep_state); /* - * Debug output + * Error/Warning output */ void ACPI_INTERNAL_VAR_XFACE acpi_error(const char *module_name, @@ -394,6 +396,9 @@ void ACPI_INTERNAL_VAR_XFACE acpi_info(const char *module_name, u32 line_number, const char *format, ...) ACPI_PRINTF_LIKE(3); +/* + * Debug output + */ #ifdef ACPI_DEBUG_OUTPUT void ACPI_INTERNAL_VAR_XFACE diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index f555d927f7c..37ba576d06e 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h @@ -429,20 +429,12 @@ typedef unsigned long long acpi_integer; /* Data manipulation */ -#define ACPI_LOWORD(l) ((u16)(u32)(l)) -#define ACPI_HIWORD(l) ((u16)((((u32)(l)) >> 16) & 0xFFFF)) -#define ACPI_LOBYTE(l) ((u8)(u16)(l)) -#define ACPI_HIBYTE(l) ((u8)((((u16)(l)) >> 8) & 0xFF)) - -/* Full 64-bit integer must be available on both 32-bit and 64-bit platforms */ - -struct acpi_integer_overlay { - u32 lo_dword; - u32 hi_dword; -}; - -#define ACPI_LODWORD(integer) (ACPI_CAST_PTR (struct acpi_integer_overlay, &integer)->lo_dword) -#define ACPI_HIDWORD(integer) (ACPI_CAST_PTR (struct acpi_integer_overlay, &integer)->hi_dword) +#define ACPI_LOBYTE(integer) ((u8) (u16)(integer)) +#define ACPI_HIBYTE(integer) ((u8) (((u16)(integer)) >> 8)) +#define ACPI_LOWORD(integer) ((u16) (u32)(integer)) +#define ACPI_HIWORD(integer) ((u16)(((u32)(integer)) >> 16)) +#define ACPI_LODWORD(integer64) ((u32) (u64)(integer64)) +#define ACPI_HIDWORD(integer64) ((u32)(((u64)(integer64)) >> 32)) #define ACPI_SET_BIT(target,bit) ((target) |= (bit)) #define ACPI_CLEAR_BIT(target,bit) ((target) &= ~(bit)) diff --git a/include/acpi/platform/acgcc.h b/include/acpi/platform/acgcc.h index 8e2cdc57b19..935c5d7fc86 100644 --- a/include/acpi/platform/acgcc.h +++ b/include/acpi/platform/acgcc.h @@ -62,4 +62,8 @@ */ #define ACPI_UNUSED_VAR __attribute__ ((unused)) +#ifdef _ANSI +#define inline +#endif + #endif /* __ACGCC_H__ */ diff --git a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h index 6d49b2a498c..fcb8e4b159b 100644 --- a/include/acpi/platform/aclinux.h +++ b/include/acpi/platform/aclinux.h @@ -1,11 +1,11 @@ /****************************************************************************** * - * Name: aclinux.h - OS specific defines, etc. + * Name: aclinux.h - OS specific defines, etc. for Linux * *****************************************************************************/ /* - * Copyright (C) 2000 - 2008, Intel Corp. + * Copyright (C) 2000 - 2009, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -44,10 +44,13 @@ #ifndef __ACLINUX_H__ #define __ACLINUX_H__ +/* Common (in-kernel/user-space) ACPICA configuration */ + #define ACPI_USE_SYSTEM_CLIBRARY #define ACPI_USE_DO_WHILE_0 #define ACPI_MUTEX_TYPE ACPI_BINARY_SEMAPHORE + #ifdef __KERNEL__ #include <linux/string.h> @@ -63,15 +66,18 @@ #include <linux/spinlock_types.h> #include <asm/current.h> -/* Host-dependent types and defines */ +/* Host-dependent types and defines for in-kernel ACPICA */ #define ACPI_MACHINE_WIDTH BITS_PER_LONG -#define acpi_cache_t struct kmem_cache -#define acpi_spinlock spinlock_t * #define ACPI_EXPORT_SYMBOL(symbol) EXPORT_SYMBOL(symbol); #define strtoul simple_strtoul -#else /* !__KERNEL__ */ +#define acpi_cache_t struct kmem_cache +#define acpi_spinlock spinlock_t * +#define acpi_cpu_flags unsigned long +#define acpi_thread_id struct task_struct * + +#else /* !__KERNEL__ */ #include <stdarg.h> #include <string.h> @@ -79,6 +85,11 @@ #include <ctype.h> #include <unistd.h> +/* Host-dependent types and defines for user-space ACPICA */ + +#define ACPI_FLUSH_CPU_CACHE() +#define acpi_thread_id pthread_t + #if defined(__ia64__) || defined(__x86_64__) #define ACPI_MACHINE_WIDTH 64 #define COMPILER_DEPENDENT_INT64 long @@ -94,17 +105,17 @@ #define __cdecl #endif -#define ACPI_FLUSH_CPU_CACHE() -#endif /* __KERNEL__ */ +#endif /* __KERNEL__ */ /* Linux uses GCC */ #include "acgcc.h" -#define acpi_cpu_flags unsigned long - -#define acpi_thread_id struct task_struct * +#ifdef __KERNEL__ +/* + * Overrides for in-kernel ACPICA + */ static inline acpi_thread_id acpi_os_get_thread_id(void) { return current; @@ -119,30 +130,32 @@ static inline acpi_thread_id acpi_os_get_thread_id(void) #include <acpi/actypes.h> static inline void *acpi_os_allocate(acpi_size size) { - return kmalloc(size, irqs_disabled()? GFP_ATOMIC : GFP_KERNEL); + return kmalloc(size, irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL); } + static inline void *acpi_os_allocate_zeroed(acpi_size size) { - return kzalloc(size, irqs_disabled()? GFP_ATOMIC : GFP_KERNEL); + return kzalloc(size, irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL); } static inline void *acpi_os_acquire_object(acpi_cache_t * cache) { return kmem_cache_zalloc(cache, - irqs_disabled()? GFP_ATOMIC : GFP_KERNEL); + irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL); } -#define ACPI_ALLOCATE(a) acpi_os_allocate(a) -#define ACPI_ALLOCATE_ZEROED(a) acpi_os_allocate_zeroed(a) -#define ACPI_FREE(a) kfree(a) +#define ACPI_ALLOCATE(a) acpi_os_allocate(a) +#define ACPI_ALLOCATE_ZEROED(a) acpi_os_allocate_zeroed(a) +#define ACPI_FREE(a) kfree(a) -/* - * We need to show where it is safe to preempt execution of ACPICA - */ -#define ACPI_PREEMPTION_POINT() \ - do { \ - if (!irqs_disabled()) \ - cond_resched(); \ +/* Used within ACPICA to show where it is safe to preempt execution */ + +#define ACPI_PREEMPTION_POINT() \ + do { \ + if (!irqs_disabled()) \ + cond_resched(); \ } while (0) -#endif /* __ACLINUX_H__ */ +#endif /* __KERNEL__ */ + +#endif /* __ACLINUX_H__ */ diff --git a/include/asm-generic/atomic64.h b/include/asm-generic/atomic64.h new file mode 100644 index 00000000000..b18ce4f9ee3 --- /dev/null +++ b/include/asm-generic/atomic64.h @@ -0,0 +1,42 @@ +/* + * Generic implementation of 64-bit atomics using spinlocks, + * useful on processors that don't have 64-bit atomic instructions. + * + * Copyright © 2009 Paul Mackerras, IBM Corp. <paulus@au1.ibm.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. + */ +#ifndef _ASM_GENERIC_ATOMIC64_H +#define _ASM_GENERIC_ATOMIC64_H + +typedef struct { + long long counter; +} atomic64_t; + +#define ATOMIC64_INIT(i) { (i) } + +extern long long atomic64_read(const atomic64_t *v); +extern void atomic64_set(atomic64_t *v, long long i); +extern void atomic64_add(long long a, atomic64_t *v); +extern long long atomic64_add_return(long long a, atomic64_t *v); +extern void atomic64_sub(long long a, atomic64_t *v); +extern long long atomic64_sub_return(long long a, atomic64_t *v); +extern long long atomic64_dec_if_positive(atomic64_t *v); +extern long long atomic64_cmpxchg(atomic64_t *v, long long o, long long n); +extern long long atomic64_xchg(atomic64_t *v, long long new); +extern int atomic64_add_unless(atomic64_t *v, long long a, long long u); + +#define atomic64_add_negative(a, v) (atomic64_add_return((a), (v)) < 0) +#define atomic64_inc(v) atomic64_add(1LL, (v)) +#define atomic64_inc_return(v) atomic64_add_return(1LL, (v)) +#define atomic64_inc_and_test(v) (atomic64_inc_return(v) == 0) +#define atomic64_sub_and_test(a, v) (atomic64_sub_return((a), (v)) == 0) +#define atomic64_dec(v) atomic64_sub(1LL, (v)) +#define atomic64_dec_return(v) atomic64_sub_return(1LL, (v)) +#define atomic64_dec_and_test(v) (atomic64_dec_return((v)) == 0) +#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1LL, 0LL) + +#endif /* _ASM_GENERIC_ATOMIC64_H */ diff --git a/include/asm-generic/kmap_types.h b/include/asm-generic/kmap_types.h index 58c33055c30..54e8b3d956b 100644 --- a/include/asm-generic/kmap_types.h +++ b/include/asm-generic/kmap_types.h @@ -1,7 +1,7 @@ #ifndef _ASM_GENERIC_KMAP_TYPES_H #define _ASM_GENERIC_KMAP_TYPES_H -#ifdef CONFIG_DEBUG_HIGHMEM +#ifdef __WITH_KM_FENCE # define D(n) __KM_FENCE_##n , #else # define D(n) diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h index f8634ab53b8..45c18672b09 100644 --- a/include/drm/drm_pciids.h +++ b/include/drm/drm_pciids.h @@ -254,8 +254,8 @@ {0x1002, 0x940A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R600|RADEON_NEW_MEMMAP}, \ {0x1002, 0x940B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R600|RADEON_NEW_MEMMAP}, \ {0x1002, 0x940F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R600|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x94A0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV740|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x94A1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV740|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x94A0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV740|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x94A1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV740|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x94B1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV740|RADEON_NEW_MEMMAP}, \ {0x1002, 0x94B3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV740|RADEON_NEW_MEMMAP}, \ {0x1002, 0x94B5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV740|RADEON_NEW_MEMMAP}, \ @@ -273,8 +273,8 @@ {0x1002, 0x9456, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_NEW_MEMMAP}, \ {0x1002, 0x945A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x945B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x9460, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x9462, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9460, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9462, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_NEW_MEMMAP}, \ {0x1002, 0x946A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x946B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x947A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ diff --git a/include/drm/radeon_drm.h b/include/drm/radeon_drm.h index fe3e3a4b4ae..41862e9a4c2 100644 --- a/include/drm/radeon_drm.h +++ b/include/drm/radeon_drm.h @@ -496,6 +496,16 @@ typedef struct { #define DRM_RADEON_SETPARAM 0x19 #define DRM_RADEON_SURF_ALLOC 0x1a #define DRM_RADEON_SURF_FREE 0x1b +/* KMS ioctl */ +#define DRM_RADEON_GEM_INFO 0x1c +#define DRM_RADEON_GEM_CREATE 0x1d +#define DRM_RADEON_GEM_MMAP 0x1e +#define DRM_RADEON_GEM_PREAD 0x21 +#define DRM_RADEON_GEM_PWRITE 0x22 +#define DRM_RADEON_GEM_SET_DOMAIN 0x23 +#define DRM_RADEON_GEM_WAIT_IDLE 0x24 +#define DRM_RADEON_CS 0x26 +#define DRM_RADEON_INFO 0x27 #define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CP_INIT, drm_radeon_init_t) #define DRM_IOCTL_RADEON_CP_START DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_CP_START) @@ -524,6 +534,17 @@ typedef struct { #define DRM_IOCTL_RADEON_SETPARAM DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SETPARAM, drm_radeon_setparam_t) #define DRM_IOCTL_RADEON_SURF_ALLOC DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SURF_ALLOC, drm_radeon_surface_alloc_t) #define DRM_IOCTL_RADEON_SURF_FREE DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SURF_FREE, drm_radeon_surface_free_t) +/* KMS */ +#define DRM_IOCTL_RADEON_GEM_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_INFO, struct drm_radeon_gem_info) +#define DRM_IOCTL_RADEON_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_CREATE, struct drm_radeon_gem_create) +#define DRM_IOCTL_RADEON_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_MMAP, struct drm_radeon_gem_mmap) +#define DRM_IOCTL_RADEON_GEM_PREAD DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_PREAD, struct drm_radeon_gem_pread) +#define DRM_IOCTL_RADEON_GEM_PWRITE DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_PWRITE, struct drm_radeon_gem_pwrite) +#define DRM_IOCTL_RADEON_GEM_SET_DOMAIN DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_SET_DOMAIN, struct drm_radeon_gem_set_domain) +#define DRM_IOCTL_RADEON_GEM_WAIT_IDLE DRM_IOW(DRM_COMMAND_BASE + DRM_RADEON_GEM_WAIT_IDLE, struct drm_radeon_gem_wait_idle) +#define DRM_IOCTL_RADEON_CS DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_CS, struct drm_radeon_cs) +#define DRM_IOCTL_RADEON_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_INFO, struct drm_radeon_info) + typedef struct drm_radeon_init { enum { @@ -682,6 +703,7 @@ typedef struct drm_radeon_indirect { #define RADEON_PARAM_VBLANK_CRTC 13 /* VBLANK CRTC */ #define RADEON_PARAM_FB_LOCATION 14 /* FB location */ #define RADEON_PARAM_NUM_GB_PIPES 15 /* num GB pipes */ +#define RADEON_PARAM_DEVICE_ID 16 typedef struct drm_radeon_getparam { int param; @@ -751,4 +773,112 @@ typedef struct drm_radeon_surface_free { #define DRM_RADEON_VBLANK_CRTC1 1 #define DRM_RADEON_VBLANK_CRTC2 2 +/* + * Kernel modesetting world below. + */ +#define RADEON_GEM_DOMAIN_CPU 0x1 +#define RADEON_GEM_DOMAIN_GTT 0x2 +#define RADEON_GEM_DOMAIN_VRAM 0x4 + +struct drm_radeon_gem_info { + uint64_t gart_size; + uint64_t vram_size; + uint64_t vram_visible; +}; + +#define RADEON_GEM_NO_BACKING_STORE 1 + +struct drm_radeon_gem_create { + uint64_t size; + uint64_t alignment; + uint32_t handle; + uint32_t initial_domain; + uint32_t flags; +}; + +struct drm_radeon_gem_mmap { + uint32_t handle; + uint32_t pad; + uint64_t offset; + uint64_t size; + uint64_t addr_ptr; +}; + +struct drm_radeon_gem_set_domain { + uint32_t handle; + uint32_t read_domains; + uint32_t write_domain; +}; + +struct drm_radeon_gem_wait_idle { + uint32_t handle; + uint32_t pad; +}; + +struct drm_radeon_gem_busy { + uint32_t handle; + uint32_t busy; +}; + +struct drm_radeon_gem_pread { + /** Handle for the object being read. */ + uint32_t handle; + uint32_t pad; + /** Offset into the object to read from */ + uint64_t offset; + /** Length of data to read */ + uint64_t size; + /** Pointer to write the data into. */ + /* void *, but pointers are not 32/64 compatible */ + uint64_t data_ptr; +}; + +struct drm_radeon_gem_pwrite { + /** Handle for the object being written to. */ + uint32_t handle; + uint32_t pad; + /** Offset into the object to write to */ + uint64_t offset; + /** Length of data to write */ + uint64_t size; + /** Pointer to read the data from. */ + /* void *, but pointers are not 32/64 compatible */ + uint64_t data_ptr; +}; + +#define RADEON_CHUNK_ID_RELOCS 0x01 +#define RADEON_CHUNK_ID_IB 0x02 + +struct drm_radeon_cs_chunk { + uint32_t chunk_id; + uint32_t length_dw; + uint64_t chunk_data; +}; + +struct drm_radeon_cs_reloc { + uint32_t handle; + uint32_t read_domains; + uint32_t write_domain; + uint32_t flags; +}; + +struct drm_radeon_cs { + uint32_t num_chunks; + uint32_t cs_id; + /* this points to uint64_t * which point to cs chunks */ + uint64_t chunks; + /* updates to the limits after this CS ioctl */ + uint64_t gart_limit; + uint64_t vram_limit; +}; + +#define RADEON_INFO_DEVICE_ID 0x00 +#define RADEON_INFO_NUM_GB_PIPES 0x01 + +struct drm_radeon_info { + uint32_t request; + uint32_t pad; + uint64_t value; +}; + #endif diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h new file mode 100644 index 00000000000..cd22ab4b495 --- /dev/null +++ b/include/drm/ttm/ttm_bo_api.h @@ -0,0 +1,618 @@ +/************************************************************************** + * + * 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_BO_API_H_ +#define _TTM_BO_API_H_ + +#include "drm_hashtab.h" +#include <linux/kref.h> +#include <linux/list.h> +#include <linux/wait.h> +#include <linux/mutex.h> +#include <linux/mm.h> +#include <linux/rbtree.h> +#include <linux/bitmap.h> + +struct ttm_bo_device; + +struct drm_mm_node; + +/** + * struct ttm_mem_reg + * + * @mm_node: Memory manager node. + * @size: Requested size of memory region. + * @num_pages: Actual size of memory region in pages. + * @page_alignment: Page alignment. + * @placement: Placement flags. + * + * Structure indicating the placement and space resources used by a + * buffer object. + */ + +struct ttm_mem_reg { + struct drm_mm_node *mm_node; + unsigned long size; + unsigned long num_pages; + uint32_t page_alignment; + uint32_t mem_type; + uint32_t placement; +}; + +/** + * enum ttm_bo_type + * + * @ttm_bo_type_device: These are 'normal' buffers that can + * be mmapped by user space. Each of these bos occupy a slot in the + * device address space, that can be used for normal vm operations. + * + * @ttm_bo_type_user: These are user-space memory areas that are made + * available to the GPU by mapping the buffer pages into the GPU aperture + * space. These buffers cannot be mmaped from the device address space. + * + * @ttm_bo_type_kernel: These buffers are like ttm_bo_type_device buffers, + * but they cannot be accessed from user-space. For kernel-only use. + */ + +enum ttm_bo_type { + ttm_bo_type_device, + ttm_bo_type_user, + ttm_bo_type_kernel +}; + +struct ttm_tt; + +/** + * struct ttm_buffer_object + * + * @bdev: Pointer to the buffer object device structure. + * @buffer_start: The virtual user-space start address of ttm_bo_type_user + * buffers. + * @type: The bo type. + * @destroy: Destruction function. If NULL, kfree is used. + * @num_pages: Actual number of pages. + * @addr_space_offset: Address space offset. + * @acc_size: Accounted size for this object. + * @kref: Reference count of this buffer object. When this refcount reaches + * zero, the object is put on the delayed delete list. + * @list_kref: List reference count of this buffer object. This member is + * used to avoid destruction while the buffer object is still on a list. + * Lru lists may keep one refcount, the delayed delete list, and kref != 0 + * keeps one refcount. When this refcount reaches zero, + * 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 + * holds a pointer to a persistant shmem object. + * @ttm: TTM structure holding system pages. + * @evicted: Whether the object was evicted without user-space knowing. + * @cpu_writes: For synchronization. Number of cpu writers. + * @lru: List head for the lru list. + * @ddestroy: List head for the delayed destroy list. + * @swap: List head for swap LRU list. + * @val_seq: Sequence of the validation holding the @reserved lock. + * Used to avoid starvation when many processes compete to validate the + * buffer. This member is protected by the bo_device::lru_lock. + * @seq_valid: The value of @val_seq is valid. This value is protected by + * the bo_device::lru_lock. + * @reserved: Deadlock-free lock used for synchronization state transitions. + * @sync_obj_arg: Opaque argument to synchronization object function. + * @sync_obj: Pointer to a synchronization object. + * @priv_flags: Flags describing buffer object internal state. + * @vm_rb: Rb node for the vm rb tree. + * @vm_node: Address space manager node. + * @offset: The current GPU offset, which can have different meanings + * depending on the memory type. For SYSTEM type memory, it should be 0. + * @cur_placement: Hint of current placement. + * + * Base class for TTM buffer object, that deals with data placement and CPU + * mappings. GPU mappings are really up to the driver, but for simpler GPUs + * the driver can usually use the placement offset @offset directly as the + * GPU virtual address. For drivers implementing multiple + * GPU memory manager contexts, the driver should manage the address space + * in these contexts separately and use these objects to get the correct + * placement and caching for these GPU maps. This makes it possible to use + * these objects for even quite elaborate memory management schemes. + * The destroy member, the API visibility of this object makes it possible + * to derive driver specific types. + */ + +struct ttm_buffer_object { + /** + * Members constant at init. + */ + + struct ttm_bo_device *bdev; + unsigned long buffer_start; + enum ttm_bo_type type; + void (*destroy) (struct ttm_buffer_object *); + unsigned long num_pages; + uint64_t addr_space_offset; + size_t acc_size; + + /** + * Members not needing protection. + */ + + struct kref kref; + struct kref list_kref; + wait_queue_head_t event_queue; + spinlock_t lock; + + /** + * 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; + bool evicted; + + /** + * Members protected by the bo::reserved lock only when written to. + */ + + atomic_t cpu_writers; + + /** + * Members protected by the bdev::lru_lock. + */ + + struct list_head lru; + struct list_head ddestroy; + struct list_head swap; + uint32_t val_seq; + bool seq_valid; + + /** + * Members protected by the bdev::lru_lock + * only when written to. + */ + + atomic_t reserved; + + + /** + * Members protected by the bo::lock + */ + + void *sync_obj_arg; + void *sync_obj; + unsigned long priv_flags; + + /** + * Members protected by the bdev::vm_lock + */ + + struct rb_node vm_rb; + struct drm_mm_node *vm_node; + + + /** + * Special members that are protected by the reserve lock + * and the bo::lock when written to. Can be read with + * either of these locks held. + */ + + unsigned long offset; + uint32_t cur_placement; +}; + +/** + * struct ttm_bo_kmap_obj + * + * @virtual: The current kernel virtual address. + * @page: The page when kmap'ing a single page. + * @bo_kmap_type: Type of bo_kmap. + * + * Object describing a kernel mapping. Since a TTM bo may be located + * in various memory types with various caching policies, the + * mapping can either be an ioremap, a vmap, a kmap or part of a + * premapped region. + */ + +struct ttm_bo_kmap_obj { + void *virtual; + struct page *page; + enum { + ttm_bo_map_iomap, + ttm_bo_map_vmap, + ttm_bo_map_kmap, + ttm_bo_map_premapped, + } bo_kmap_type; +}; + +/** + * ttm_bo_reference - reference a struct ttm_buffer_object + * + * @bo: The buffer object. + * + * Returns a refcounted pointer to a buffer object. + */ + +static inline struct ttm_buffer_object * +ttm_bo_reference(struct ttm_buffer_object *bo) +{ + kref_get(&bo->kref); + return bo; +} + +/** + * ttm_bo_wait - wait for buffer idle. + * + * @bo: The buffer object. + * @interruptible: Use interruptible wait. + * @no_wait: Return immediately if buffer is busy. + * + * This function must be called with the bo::mutex held, and makes + * sure any previous rendering to the buffer is completed. + * 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. + */ +extern int ttm_bo_wait(struct ttm_buffer_object *bo, bool lazy, + bool interruptible, bool no_wait); +/** + * ttm_buffer_object_validate + * + * @bo: The buffer object. + * @proposed_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. + * Returns + * -EINVAL on invalid proposed_flags. + * -ENOMEM on out-of-memory condition. + * -EBUSY if no_wait is true and buffer busy. + * -ERESTART 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); +/** + * ttm_bo_unref + * + * @bo: The buffer object. + * + * Unreference and clear a pointer to a buffer object. + */ +extern void ttm_bo_unref(struct ttm_buffer_object **bo); + +/** + * ttm_bo_synccpu_write_grab + * + * @bo: The buffer object: + * @no_wait: Return immediately if buffer is busy. + * + * Synchronizes a buffer object for CPU RW access. This means + * blocking command submission that affects the buffer and + * 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. + */ + +extern int +ttm_bo_synccpu_write_grab(struct ttm_buffer_object *bo, bool no_wait); +/** + * ttm_bo_synccpu_write_release: + * + * @bo : The buffer object. + * + * Releases a synccpu lock. + */ +extern void ttm_bo_synccpu_write_release(struct ttm_buffer_object *bo); + +/** + * ttm_buffer_object_init + * + * @bdev: Pointer to a ttm_bo_device struct. + * @bo: Pointer to a ttm_buffer_object to be initialized. + * @size: Requested size of buffer object. + * @type: Requested type of buffer object. + * @flags: Initial placement flags. + * @page_alignment: Data alignment in pages. + * @buffer_start: Virtual address of user space data backing a + * user buffer object. + * @interruptible: If needing to sleep to wait for GPU resources, + * sleep interruptible. + * @persistant_swap_storage: Usually the swap storage is deleted for buffers + * pinned in physical memory. If this behaviour is not desired, this member + * holds a pointer to a persistant shmem object. Typically, this would + * point to the shmem object backing a GEM object if TTM is used to back a + * GEM user interface. + * @acc_size: Accounted size for this object. + * @destroy: Destroy function. Use NULL for kfree(). + * + * This function initializes a pre-allocated struct ttm_buffer_object. + * As this object may be part of a larger structure, this function, + * together with the @destroy function, + * enables driver-specific objects derived from a ttm_buffer_object. + * On successful return, the object kref and list_kref are set to 1. + * Returns + * -ENOMEM: Out of memory. + * -EINVAL: Invalid placement flags. + * -ERESTART: 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 *)); +/** + * ttm_bo_synccpu_object_init + * + * @bdev: Pointer to a ttm_bo_device struct. + * @bo: Pointer to a ttm_buffer_object to be initialized. + * @size: Requested size of buffer object. + * @type: Requested type of buffer object. + * @flags: Initial placement flags. + * @page_alignment: Data alignment in pages. + * @buffer_start: Virtual address of user space data backing a + * user buffer object. + * @interruptible: If needing to sleep while waiting for GPU resources, + * sleep interruptible. + * @persistant_swap_storage: Usually the swap storage is deleted for buffers + * pinned in physical memory. If this behaviour is not desired, this member + * holds a pointer to a persistant shmem object. Typically, this would + * point to the shmem object backing a GEM object if TTM is used to back a + * 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(). + * Returns + * -ENOMEM: Out of memory. + * -EINVAL: Invalid placement flags. + * -ERESTART: 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); + +/** + * ttm_bo_check_placement + * + * @bo: the buffer object. + * @set_flags: placement flags to set. + * @clr_flags: placement flags to clear. + * + * 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); + +/** + * 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. + * Note: if part of driver firstopen, it must be protected from a + * potentially racing lastclose. + * Returns: + * -EINVAL: invalid size or memory type. + * -ENOMEM: Not enough memory. + * May also return driver-specified errors. + */ + +extern int ttm_bo_init_mm(struct ttm_bo_device *bdev, unsigned type, + unsigned long p_offset, unsigned long p_size); +/** + * ttm_bo_clean_mm + * + * @bdev: Pointer to a ttm_bo_device struct. + * @mem_type: The memory type. + * + * Take down a manager for a given memory type after first walking + * the LRU list to evict any buffers left alive. + * + * Normally, this function is part of lastclose() or unload(), and at that + * point there shouldn't be any buffers left created by user-space, since + * there should've been removed by the file descriptor release() method. + * However, before this function is run, make sure to signal all sync objects, + * and verify that the delayed delete queue is empty. The driver must also + * make sure that there are no NO_EVICT buffers present in this memory type + * when the call is made. + * + * If this function is part of a VT switch, the caller must make sure that + * there are no appications currently validating buffers before this + * function is called. The caller can do that by first taking the + * struct ttm_bo_device::ttm_lock in write mode. + * + * Returns: + * -EINVAL: invalid or uninitialized memory type. + * -EBUSY: There are still buffers left in this memory type. + */ + +extern int ttm_bo_clean_mm(struct ttm_bo_device *bdev, unsigned mem_type); + +/** + * ttm_bo_evict_mm + * + * @bdev: Pointer to a ttm_bo_device struct. + * @mem_type: The memory type. + * + * Evicts all buffers on the lru list of the memory type. + * This is normally part of a VT switch or an + * out-of-memory-space-due-to-fragmentation handler. + * The caller must make sure that there are no other processes + * currently validating buffers, and can do that by taking the + * struct ttm_bo_device::ttm_lock in write mode. + * + * Returns: + * -EINVAL: Invalid or uninitialized memory type. + * -ERESTART: The call was interrupted by a signal while waiting to + * evict a buffer. + */ + +extern int ttm_bo_evict_mm(struct ttm_bo_device *bdev, unsigned mem_type); + +/** + * ttm_kmap_obj_virtual + * + * @map: A struct ttm_bo_kmap_obj returned from ttm_bo_kmap. + * @is_iomem: Pointer to an integer that on return indicates 1 if the + * virtual map is io memory, 0 if normal memory. + * + * Returns the virtual address of a buffer object area mapped by ttm_bo_kmap. + * If *is_iomem is 1 on return, the virtual address points to an io memory area, + * that should strictly be accessed by the iowriteXX() and similar functions. + */ + +static inline void *ttm_kmap_obj_virtual(struct ttm_bo_kmap_obj *map, + bool *is_iomem) +{ + *is_iomem = (map->bo_kmap_type == ttm_bo_map_iomap || + map->bo_kmap_type == ttm_bo_map_premapped); + return map->virtual; +} + +/** + * ttm_bo_kmap + * + * @bo: The buffer object. + * @start_page: The first page to map. + * @num_pages: Number of pages to map. + * @map: pointer to a struct ttm_bo_kmap_obj representing the map. + * + * Sets up a kernel virtual mapping, using ioremap, vmap or kmap to the + * data in the buffer object. The ttm_kmap_obj_virtual function can then be + * used to obtain a virtual address to the data. + * + * Returns + * -ENOMEM: Out of memory. + * -EINVAL: Invalid range. + */ + +extern int ttm_bo_kmap(struct ttm_buffer_object *bo, unsigned long start_page, + unsigned long num_pages, struct ttm_bo_kmap_obj *map); + +/** + * ttm_bo_kunmap + * + * @map: Object describing the map to unmap. + * + * Unmaps a kernel map set up by ttm_bo_kmap. + */ + +extern void ttm_bo_kunmap(struct ttm_bo_kmap_obj *map); + +#if 0 +#endif + +/** + * ttm_fbdev_mmap - mmap fbdev memory backed by a ttm buffer object. + * + * @vma: vma as input from the fbdev mmap method. + * @bo: The bo backing the address space. The address space will + * have the same size as the bo, and start at offset 0. + * + * This function is intended to be called by the fbdev mmap method + * if the fbdev address space is to be backed by a bo. + */ + +extern int ttm_fbdev_mmap(struct vm_area_struct *vma, + struct ttm_buffer_object *bo); + +/** + * ttm_bo_mmap - mmap out of the ttm device address space. + * + * @filp: filp as input from the mmap method. + * @vma: vma as input from the mmap method. + * @bdev: Pointer to the ttm_bo_device with the address space manager. + * + * This function is intended to be called by the device mmap method. + * if the device address space is to be backed by the bo manager. + */ + +extern int ttm_bo_mmap(struct file *filp, struct vm_area_struct *vma, + struct ttm_bo_device *bdev); + +/** + * ttm_bo_io + * + * @bdev: Pointer to the struct ttm_bo_device. + * @filp: Pointer to the struct file attempting to read / write. + * @wbuf: User-space pointer to address of buffer to write. NULL on read. + * @rbuf: User-space pointer to address of buffer to read into. + * Null on write. + * @count: Number of bytes to read / write. + * @f_pos: Pointer to current file position. + * @write: 1 for read, 0 for write. + * + * This function implements read / write into ttm buffer objects, and is + * intended to + * 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 + * interrupted by a signal. + */ + +extern ssize_t ttm_bo_io(struct ttm_bo_device *bdev, struct file *filp, + const char __user *wbuf, char __user *rbuf, + size_t count, loff_t *f_pos, bool write); + +extern void ttm_bo_swapout_all(struct ttm_bo_device *bdev); + +#endif diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h new file mode 100644 index 00000000000..62ed733c52a --- /dev/null +++ b/include/drm/ttm/ttm_bo_driver.h @@ -0,0 +1,867 @@ +/************************************************************************** + * + * 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_BO_DRIVER_H_ +#define _TTM_BO_DRIVER_H_ + +#include "ttm/ttm_bo_api.h" +#include "ttm/ttm_memory.h" +#include "drm_mm.h" +#include "linux/workqueue.h" +#include "linux/fs.h" +#include "linux/spinlock.h" + +struct ttm_backend; + +struct ttm_backend_func { + /** + * struct ttm_backend_func member populate + * + * @backend: Pointer to a struct ttm_backend. + * @num_pages: Number of pages to populate. + * @pages: Array of pointers to ttm pages. + * @dummy_read_page: Page to be used instead of NULL pages in the + * array @pages. + * + * Populate the backend with ttm pages. Depending on the backend, + * it may or may not copy the @pages array. + */ + int (*populate) (struct ttm_backend *backend, + unsigned long num_pages, struct page **pages, + struct page *dummy_read_page); + /** + * struct ttm_backend_func member clear + * + * @backend: Pointer to a struct ttm_backend. + * + * This is an "unpopulate" function. Release all resources + * allocated with populate. + */ + void (*clear) (struct ttm_backend *backend); + + /** + * struct ttm_backend_func member bind + * + * @backend: Pointer to a struct ttm_backend. + * @bo_mem: Pointer to a struct ttm_mem_reg describing the + * memory type and location for binding. + * + * Bind the backend pages into the aperture in the location + * indicated by @bo_mem. This function should be able to handle + * differences between aperture- and system page sizes. + */ + int (*bind) (struct ttm_backend *backend, struct ttm_mem_reg *bo_mem); + + /** + * struct ttm_backend_func member unbind + * + * @backend: Pointer to a struct ttm_backend. + * + * Unbind previously bound backend pages. This function should be + * able to handle differences between aperture- and system page sizes. + */ + int (*unbind) (struct ttm_backend *backend); + + /** + * struct ttm_backend_func member destroy + * + * @backend: Pointer to a struct ttm_backend. + * + * Destroy the backend. + */ + void (*destroy) (struct ttm_backend *backend); +}; + +/** + * struct ttm_backend + * + * @bdev: Pointer to a struct ttm_bo_device. + * @flags: For driver use. + * @func: Pointer to a struct ttm_backend_func that describes + * the backend methods. + * + */ + +struct ttm_backend { + struct ttm_bo_device *bdev; + uint32_t flags; + struct ttm_backend_func *func; +}; + +#define TTM_PAGE_FLAG_VMALLOC (1 << 0) +#define TTM_PAGE_FLAG_USER (1 << 1) +#define TTM_PAGE_FLAG_USER_DIRTY (1 << 2) +#define TTM_PAGE_FLAG_WRITE (1 << 3) +#define TTM_PAGE_FLAG_SWAPPED (1 << 4) +#define TTM_PAGE_FLAG_PERSISTANT_SWAP (1 << 5) +#define TTM_PAGE_FLAG_ZERO_ALLOC (1 << 6) + +enum ttm_caching_state { + tt_uncached, + tt_wc, + tt_cached +}; + +/** + * struct ttm_tt + * + * @dummy_read_page: Page to map where the ttm_tt page array contains a NULL + * pointer. + * @pages: Array of pages backing the data. + * @first_himem_page: Himem pages are put last in the page array, which + * enables us to run caching attribute changes on only the first part + * of the page array containing lomem pages. This is the index of the + * first himem page. + * @last_lomem_page: Index of the last lomem page in the page array. + * @num_pages: Number of pages in the page array. + * @bdev: Pointer to the current struct ttm_bo_device. + * @be: Pointer to the ttm backend. + * @tsk: The task for user ttm. + * @start: virtual address for user ttm. + * @swap_storage: Pointer to shmem struct file for swap storage. + * @caching_state: The current caching state of the pages. + * @state: The current binding state of the pages. + * + * This is a structure holding the pages, caching- and aperture binding + * status for a buffer object that isn't backed by fixed (VRAM / AGP) + * memory. + */ + +struct ttm_tt { + struct page *dummy_read_page; + struct page **pages; + long first_himem_page; + long last_lomem_page; + uint32_t page_flags; + unsigned long num_pages; + struct ttm_bo_device *bdev; + struct ttm_backend *be; + struct task_struct *tsk; + unsigned long start; + struct file *swap_storage; + enum ttm_caching_state caching_state; + enum { + tt_bound, + tt_unbound, + tt_unpopulated, + } state; +}; + +#define TTM_MEMTYPE_FLAG_FIXED (1 << 0) /* Fixed (on-card) PCI memory */ +#define TTM_MEMTYPE_FLAG_MAPPABLE (1 << 1) /* Memory mappable */ +#define TTM_MEMTYPE_FLAG_NEEDS_IOREMAP (1 << 2) /* Fixed memory needs ioremap + before kernel access. */ +#define TTM_MEMTYPE_FLAG_CMA (1 << 3) /* Can't map aperture */ + +/** + * struct ttm_mem_type_manager + * + * @has_type: The memory type has been initialized. + * @use_type: The memory type is enabled. + * @flags: TTM_MEMTYPE_XX flags identifying the traits of the memory + * managed by this memory type. + * @gpu_offset: If used, the GPU offset of the first managed page of + * fixed memory or the first managed location in an aperture. + * @io_offset: The io_offset of the first managed page of IO memory or + * the first managed location in an aperture. For TTM_MEMTYPE_FLAG_CMA + * memory, this should be set to NULL. + * @io_size: The size of a managed IO region (fixed memory or aperture). + * @io_addr: Virtual kernel address if the io region is pre-mapped. For + * TTM_MEMTYPE_FLAG_NEEDS_IOREMAP there is no pre-mapped io map and + * @io_addr should be set to NULL. + * @size: Size of the managed region. + * @available_caching: A mask of available caching types, TTM_PL_FLAG_XX, + * as defined in ttm_placement_common.h + * @default_caching: The default caching policy used for a buffer object + * placed in this memory type if the user doesn't provide one. + * @manager: The range manager used for this memory type. FIXME: If the aperture + * has a page size different from the underlying system, the granularity + * of this manager should take care of this. But the range allocating code + * in ttm_bo.c needs to be modified for this. + * @lru: The lru list for this memory type. + * + * This structure is used to identify and manage memory types for a device. + * It's set up by the ttm_bo_driver::init_mem_type method. + */ + +struct ttm_mem_type_manager { + + /* + * No protection. Constant from start. + */ + + bool has_type; + bool use_type; + uint32_t flags; + unsigned long gpu_offset; + unsigned long io_offset; + unsigned long io_size; + void *io_addr; + uint64_t size; + uint32_t available_caching; + uint32_t default_caching; + + /* + * Protected by the bdev->lru_lock. + * TODO: Consider one lru_lock per ttm_mem_type_manager. + * Plays ill with list removal, though. + */ + + struct drm_mm manager; + struct list_head lru; +}; + +/** + * 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. + * @init_mem_type: Callback to initialize a struct ttm_mem_type_manager + * structure. + * @evict_flags: Callback to obtain placement flags when a buffer is evicted. + * @move: Callback for a driver to hook in accelerated functions to + * move a buffer. + * If set to NULL, a potentially slow memcpy() move is used. + * @sync_obj_signaled: See ttm_fence_api.h + * @sync_obj_wait: See ttm_fence_api.h + * @sync_obj_flush: See ttm_fence_api.h + * @sync_obj_unref: See ttm_fence_api.h + * @sync_obj_ref: See ttm_fence_api.h + */ + +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 + * + * @bdev: The buffer object device. + * + * Create a driver specific struct ttm_backend. + */ + + struct ttm_backend *(*create_ttm_backend_entry) + (struct ttm_bo_device *bdev); + + /** + * struct ttm_bo_driver member invalidate_caches + * + * @bdev: the buffer object device. + * @flags: new placement of the rebound buffer object. + * + * A previosly evicted buffer has been rebound in a + * potentially new location. Tell the driver that it might + * consider invalidating read (texture) caches on the next command + * submission as a consequence. + */ + + int (*invalidate_caches) (struct ttm_bo_device *bdev, uint32_t flags); + int (*init_mem_type) (struct ttm_bo_device *bdev, uint32_t type, + struct ttm_mem_type_manager *man); + /** + * struct ttm_bo_driver member evict_flags: + * + * @bo: the buffer object to be evicted + * + * Return the bo flags for a buffer which is not mapped to the hardware. + * These will be placed in proposed_flags so that when the move is + * finished, they'll end up in bo->mem.flags + */ + + uint32_t(*evict_flags) (struct ttm_buffer_object *bo); + /** + * struct ttm_bo_driver member move: + * + * @bo: the buffer to move + * @evict: whether this motion is evicting the buffer from + * the graphics address space + * @interruptible: Use interruptible sleeps if possible when sleeping. + * @no_wait: whether this should give up and return -EBUSY + * if this move would require sleeping + * @new_mem: the new memory region receiving the buffer + * + * Move a buffer between two memory regions. + */ + int (*move) (struct ttm_buffer_object *bo, + bool evict, bool interruptible, + bool no_wait, struct ttm_mem_reg *new_mem); + + /** + * struct ttm_bo_driver_member verify_access + * + * @bo: Pointer to a buffer object. + * @filp: Pointer to a struct file trying to access the object. + * + * Called from the map / write / read methods to verify that the + * caller is permitted to access the buffer object. + * This member may be set to NULL, which will refuse this kind of + * access for all buffer objects. + * This function should return 0 if access is granted, -EPERM otherwise. + */ + int (*verify_access) (struct ttm_buffer_object *bo, + struct file *filp); + + /** + * In case a driver writer dislikes the TTM fence objects, + * the driver writer can replace those with sync objects of + * his / her own. If it turns out that no driver writer is + * using these. I suggest we remove these hooks and plug in + * fences directly. The bo driver needs the following functionality: + * See the corresponding functions in the fence object API + * documentation. + */ + + bool (*sync_obj_signaled) (void *sync_obj, void *sync_arg); + int (*sync_obj_wait) (void *sync_obj, void *sync_arg, + bool lazy, bool interruptible); + int (*sync_obj_flush) (void *sync_obj, void *sync_arg); + void (*sync_obj_unref) (void **sync_obj); + void *(*sync_obj_ref) (void *sync_obj); +}; + +#define TTM_NUM_MEM_TYPES 8 + +#define TTM_BO_PRIV_FLAG_MOVING 0 /* Buffer object is moving and needs + idling before CPU mapping */ +#define TTM_BO_PRIV_FLAG_MAX 1 +/** + * struct ttm_bo_device - Buffer object driver device-specific data. + * + * @mem_glob: Pointer to a struct ttm_mem_global object for accounting. + * @driver: Pointer to a struct ttm_bo_driver struct setup by the driver. + * @count: Current number of buffer object. + * @pages: Current number of pinned pages. + * @dummy_read_page: Pointer to a dummy page used for mapping requests + * of unpopulated pages. + * @shrink: A shrink callback object used for buffre object swap. + * @ttm_bo_extra_size: Extra size (sizeof(struct ttm_buffer_object) excluded) + * used by a buffer object. This is excluding page arrays and backing pages. + * @ttm_bo_size: This is @ttm_bo_extra_size + sizeof(struct ttm_buffer_object). + * @man: An array of mem_type_managers. + * @addr_space_mm: Range manager for the device address space. + * lru_lock: Spinlock that protects the buffer+device lru lists and + * ddestroy lists. + * @nice_mode: Try nicely to wait for buffer idle when cleaning a manager. + * If a GPU lockup has been detected, this is forced to 0. + * @dev_mapping: A pointer to the struct address_space representing the + * device address space. + * @wq: Work queue structure for the delayed delete workqueue. + * + */ + +struct ttm_bo_device { + + /* + * Constant after bo device init / atomic. + */ + + struct ttm_mem_global *mem_glob; + struct ttm_bo_driver *driver; + struct page *dummy_read_page; + struct ttm_mem_shrink shrink; + + size_t ttm_bo_extra_size; + size_t ttm_bo_size; + + rwlock_t vm_lock; + /* + * Protected by the vm lock. + */ + struct ttm_mem_type_manager man[TTM_NUM_MEM_TYPES]; + struct rb_root addr_space_rb; + struct drm_mm addr_space_mm; + + /* + * Might want to change this to one lock per manager. + */ + spinlock_t lru_lock; + /* + * Protected by the lru lock. + */ + struct list_head ddestroy; + struct list_head swap_lru; + + /* + * Protected by load / firstopen / lastclose /unload sync. + */ + + bool nice_mode; + struct address_space *dev_mapping; + + /* + * Internal protection. + */ + + struct delayed_work wq; +}; + +/** + * ttm_flag_masked + * + * @old: Pointer to the result and original value. + * @new: New value of bits. + * @mask: Mask of bits to change. + * + * Convenience function to change a number of bits identified by a mask. + */ + +static inline uint32_t +ttm_flag_masked(uint32_t *old, uint32_t new, uint32_t mask) +{ + *old ^= (*old ^ new) & mask; + return *old; +} + +/** + * ttm_tt_create + * + * @bdev: pointer to a struct ttm_bo_device: + * @size: Size of the data needed backing. + * @page_flags: Page flags as identified by TTM_PAGE_FLAG_XX flags. + * @dummy_read_page: See struct ttm_bo_device. + * + * Create a struct ttm_tt to back data with system memory pages. + * No pages are actually allocated. + * Returns: + * NULL: Out of memory. + */ +extern struct ttm_tt *ttm_tt_create(struct ttm_bo_device *bdev, + unsigned long size, + uint32_t page_flags, + struct page *dummy_read_page); + +/** + * ttm_tt_set_user: + * + * @ttm: The struct ttm_tt to populate. + * @tsk: A struct task_struct for which @start is a valid user-space address. + * @start: A valid user-space address. + * @num_pages: Size in pages of the user memory area. + * + * Populate a struct ttm_tt with a user-space memory area after first pinning + * the pages backing it. + * Returns: + * !0: Error. + */ + +extern int ttm_tt_set_user(struct ttm_tt *ttm, + struct task_struct *tsk, + unsigned long start, unsigned long num_pages); + +/** + * ttm_ttm_bind: + * + * @ttm: The struct ttm_tt containing backing pages. + * @bo_mem: The struct ttm_mem_reg identifying the binding location. + * + * Bind the pages of @ttm to an aperture location identified by @bo_mem + */ +extern int ttm_tt_bind(struct ttm_tt *ttm, struct ttm_mem_reg *bo_mem); + +/** + * ttm_ttm_destroy: + * + * @ttm: The struct ttm_tt. + * + * Unbind, unpopulate and destroy a struct ttm_tt. + */ +extern void ttm_tt_destroy(struct ttm_tt *ttm); + +/** + * ttm_ttm_unbind: + * + * @ttm: The struct ttm_tt. + * + * Unbind a struct ttm_tt. + */ +extern void ttm_tt_unbind(struct ttm_tt *ttm); + +/** + * ttm_ttm_destroy: + * + * @ttm: The struct ttm_tt. + * @index: Index of the desired page. + * + * Return a pointer to the struct page backing @ttm at page + * index @index. If the page is unpopulated, one will be allocated to + * populate that index. + * + * Returns: + * NULL on OOM. + */ +extern struct page *ttm_tt_get_page(struct ttm_tt *ttm, int index); + +/** + * ttm_tt_cache_flush: + * + * @pages: An array of pointers to struct page:s to flush. + * @num_pages: Number of pages to flush. + * + * Flush the data of the indicated pages from the cpu caches. + * This is used when changing caching attributes of the pages from + * cache-coherent. + */ +extern void ttm_tt_cache_flush(struct page *pages[], unsigned long num_pages); + +/** + * ttm_tt_set_placement_caching: + * + * @ttm A struct ttm_tt the backing pages of which will change caching policy. + * @placement: Flag indicating the desired caching policy. + * + * This function will change caching policy of any default kernel mappings of + * the pages backing @ttm. If changing from cached to uncached or + * write-combined, + * all CPU caches will first be flushed to make sure the data of the pages + * hit RAM. This function may be very costly as it involves global TLB + * and cache flushes and potential page splitting / combining. + */ +extern int ttm_tt_set_placement_caching(struct ttm_tt *ttm, uint32_t placement); +extern int ttm_tt_swapout(struct ttm_tt *ttm, + struct file *persistant_swap_storage); + +/* + * ttm_bo.c + */ + +/** + * ttm_mem_reg_is_pci + * + * @bdev: Pointer to a struct ttm_bo_device. + * @mem: A valid struct ttm_mem_reg. + * + * Returns true if the memory described by @mem is PCI memory, + * false otherwise. + */ +extern bool ttm_mem_reg_is_pci(struct ttm_bo_device *bdev, + struct ttm_mem_reg *mem); + +/** + * ttm_bo_mem_space + * + * @bo: Pointer to a struct ttm_buffer_object. the data of which + * we want to allocate space for. + * @proposed_placement: Proposed new placement for the buffer object. + * @mem: A struct ttm_mem_reg. + * @interruptible: Sleep interruptible when sliping. + * @no_wait: Don't sleep waiting for space to become available. + * + * Allocate memory space for the buffer object pointed to by @bo, using + * the placement flags in @mem, potentially evicting other idle buffer objects. + * This function may sleep while waiting for space to become available. + * Returns: + * -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. + */ +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); +/** + * ttm_bo_wait_for_cpu + * + * @bo: Pointer to a struct ttm_buffer_object. + * @no_wait: Don't sleep while waiting. + * + * 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. + */ + +extern int ttm_bo_wait_cpu(struct ttm_buffer_object *bo, bool no_wait); + +/** + * ttm_bo_pci_offset - Get the PCI offset for the buffer object memory. + * + * @bo Pointer to a struct ttm_buffer_object. + * @bus_base On return the base of the PCI region + * @bus_offset On return the byte offset into the PCI region + * @bus_size On return the byte size of the buffer object or zero if + * the buffer object memory is not accessible through a PCI region. + * + * Returns: + * -EINVAL if the buffer object is currently not mappable. + * 0 otherwise. + */ + +extern int ttm_bo_pci_offset(struct ttm_bo_device *bdev, + struct ttm_mem_reg *mem, + unsigned long *bus_base, + unsigned long *bus_offset, + unsigned long *bus_size); + +extern int ttm_bo_device_release(struct ttm_bo_device *bdev); + +/** + * ttm_bo_device_init + * + * @bdev: A pointer to a struct ttm_bo_device to initialize. + * @mem_global: A pointer to an initialized struct ttm_mem_global. + * @driver: A pointer to a struct ttm_bo_driver set up by the caller. + * @file_page_offset: Offset into the device address space that is available + * for buffer data. This ensures compatibility with other users of the + * address space. + * + * Initializes a struct ttm_bo_device: + * Returns: + * !0: Failure. + */ +extern int ttm_bo_device_init(struct ttm_bo_device *bdev, + struct ttm_mem_global *mem_glob, + struct ttm_bo_driver *driver, + uint64_t file_page_offset); + +/** + * ttm_bo_reserve: + * + * @bo: A pointer to a struct ttm_buffer_object. + * @interruptible: Sleep interruptible if waiting. + * @no_wait: Don't sleep while trying to reserve, rather return -EBUSY. + * @use_sequence: If @bo is already reserved, Only sleep waiting for + * it to become unreserved if @sequence < (@bo)->sequence. + * + * Locks a buffer object for validation. (Or prevents other processes from + * locking it for validation) and removes it from lru lists, while taking + * a number of measures to prevent deadlocks. + * + * Deadlocks may occur when two processes try to reserve multiple buffers in + * different order, either by will or as a result of a buffer being evicted + * to make room for a buffer already reserved. (Buffers are reserved before + * they are evicted). The following algorithm prevents such deadlocks from + * occuring: + * 1) Buffers are reserved with the lru spinlock held. Upon successful + * reservation they are removed from the lru list. This stops a reserved buffer + * from being evicted. However the lru spinlock is released between the time + * a buffer is selected for eviction and the time it is reserved. + * Therefore a check is made when a buffer is reserved for eviction, that it + * is still the first buffer in the lru list, before it is removed from the + * list. @check_lru == 1 forces this check. If it fails, the function returns + * -EINVAL, and the caller should then choose a new buffer to evict and repeat + * the procedure. + * 2) Processes attempting to reserve multiple buffers other than for eviction, + * (typically execbuf), should first obtain a unique 32-bit + * validation sequence number, + * and call this function with @use_sequence == 1 and @sequence == the unique + * sequence number. If upon call of this function, the buffer object is already + * reserved, the validation sequence is checked against the validation + * sequence of the process currently reserving the buffer, + * and if the current validation sequence is greater than that of the process + * holding the reservation, the function returns -EAGAIN. Otherwise it sleeps + * waiting for the buffer to become unreserved, after which it retries + * reserving. + * The caller should, when receiving an -EAGAIN error + * release all its buffer reservations, wait for @bo to become unreserved, and + * then rerun the validation with the same validation sequence. This procedure + * will always guarantee that the process with the lowest validation sequence + * will eventually succeed, preventing both deadlocks and starvation. + * + * Returns: + * -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 + * a signal. Release all buffer reservations and return to user-space. + */ +extern int ttm_bo_reserve(struct ttm_buffer_object *bo, + bool interruptible, + bool no_wait, bool use_sequence, uint32_t sequence); + +/** + * ttm_bo_unreserve + * + * @bo: A pointer to a struct ttm_buffer_object. + * + * Unreserve a previous reservation of @bo. + */ +extern void ttm_bo_unreserve(struct ttm_buffer_object *bo); + +/** + * ttm_bo_wait_unreserved + * + * @bo: A pointer to a struct ttm_buffer_object. + * + * Wait for a struct ttm_buffer_object to become unreserved. + * This is typically used in the execbuf code to relax cpu-usage when + * a potential deadlock condition backoff. + */ +extern int ttm_bo_wait_unreserved(struct ttm_buffer_object *bo, + bool interruptible); + +/** + * ttm_bo_block_reservation + * + * @bo: A pointer to a struct ttm_buffer_object. + * @interruptible: Use interruptible sleep when waiting. + * @no_wait: Don't sleep, but rather return -EBUSY. + * + * Block reservation for validation by simply reserving the buffer. + * This is intended for single buffer use only without eviction, + * and thus needs no deadlock protection. + * + * Returns: + * -EBUSY: If no_wait == 1 and the buffer is already reserved. + * -ERESTART: If interruptible == 1 and the process received a signal + * while sleeping. + */ +extern int ttm_bo_block_reservation(struct ttm_buffer_object *bo, + bool interruptible, bool no_wait); + +/** + * ttm_bo_unblock_reservation + * + * @bo: A pointer to a struct ttm_buffer_object. + * + * Unblocks reservation leaving lru lists untouched. + */ +extern void ttm_bo_unblock_reservation(struct ttm_buffer_object *bo); + +/* + * ttm_bo_util.c + */ + +/** + * ttm_bo_move_ttm + * + * @bo: A pointer to a struct ttm_buffer_object. + * @evict: 1: This is an eviction. Don't try to pipeline. + * @no_wait: Never sleep, but rather return with -EBUSY. + * @new_mem: struct ttm_mem_reg indicating where to move. + * + * Optimized move function for a buffer object with both old and + * new placement backed by a TTM. The function will, if successful, + * free any old aperture space, and set (@new_mem)->mm_node to NULL, + * and update the (@bo)->mem placement flags. If unsuccessful, the old + * data remains untouched, and it's up to the caller to free the + * memory space indicated by @new_mem. + * Returns: + * !0: Failure. + */ + +extern int ttm_bo_move_ttm(struct ttm_buffer_object *bo, + bool evict, bool no_wait, + struct ttm_mem_reg *new_mem); + +/** + * ttm_bo_move_memcpy + * + * @bo: A pointer to a struct ttm_buffer_object. + * @evict: 1: This is an eviction. Don't try to pipeline. + * @no_wait: Never sleep, but rather return with -EBUSY. + * @new_mem: struct ttm_mem_reg indicating where to move. + * + * Fallback move function for a mappable buffer object in mappable memory. + * The function will, if successful, + * free any old aperture space, and set (@new_mem)->mm_node to NULL, + * and update the (@bo)->mem placement flags. If unsuccessful, the old + * data remains untouched, and it's up to the caller to free the + * memory space indicated by @new_mem. + * Returns: + * !0: Failure. + */ + +extern int ttm_bo_move_memcpy(struct ttm_buffer_object *bo, + bool evict, + bool no_wait, struct ttm_mem_reg *new_mem); + +/** + * ttm_bo_free_old_node + * + * @bo: A pointer to a struct ttm_buffer_object. + * + * Utility function to free an old placement after a successful move. + */ +extern void ttm_bo_free_old_node(struct ttm_buffer_object *bo); + +/** + * ttm_bo_move_accel_cleanup. + * + * @bo: A pointer to a struct ttm_buffer_object. + * @sync_obj: A sync object that signals when moving is complete. + * @sync_obj_arg: An argument to pass to the sync object idle / wait + * functions. + * @evict: This is an evict move. Don't return until the buffer is idle. + * @no_wait: Never sleep, but rather return with -EBUSY. + * @new_mem: struct ttm_mem_reg indicating where to move. + * + * Accelerated move function to be called when an accelerated move + * has been scheduled. The function will create a new temporary buffer object + * representing the old placement, and put the sync object on both buffer + * objects. After that the newly created buffer object is unref'd to be + * destroyed when the move is complete. This will help pipeline + * buffer moves. + */ + +extern int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo, + void *sync_obj, + void *sync_obj_arg, + bool evict, bool no_wait, + struct ttm_mem_reg *new_mem); +/** + * ttm_io_prot + * + * @c_state: Caching state. + * @tmp: Page protection flag for a normal, cached mapping. + * + * Utility function that returns the pgprot_t that should be used for + * setting up a PTE with the caching model indicated by @c_state. + */ +extern pgprot_t ttm_io_prot(enum ttm_caching_state c_state, pgprot_t tmp); + +#if (defined(CONFIG_AGP) || (defined(CONFIG_AGP_MODULE) && defined(MODULE))) +#define TTM_HAS_AGP +#include <linux/agp_backend.h> + +/** + * ttm_agp_backend_init + * + * @bdev: Pointer to a struct ttm_bo_device. + * @bridge: The agp bridge this device is sitting on. + * + * Create a TTM backend that uses the indicated AGP bridge as an aperture + * for TT memory. This function uses the linux agpgart interface to + * bind and unbind memory backing a ttm_tt. + */ +extern struct ttm_backend *ttm_agp_backend_init(struct ttm_bo_device *bdev, + struct agp_bridge_data *bridge); +#endif + +#endif diff --git a/include/drm/ttm/ttm_memory.h b/include/drm/ttm/ttm_memory.h new file mode 100644 index 00000000000..d8b8f042c4f --- /dev/null +++ b/include/drm/ttm/ttm_memory.h @@ -0,0 +1,153 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + +#ifndef TTM_MEMORY_H +#define TTM_MEMORY_H + +#include <linux/workqueue.h> +#include <linux/spinlock.h> +#include <linux/wait.h> +#include <linux/errno.h> + +/** + * struct ttm_mem_shrink - callback to shrink TTM memory usage. + * + * @do_shrink: The callback function. + * + * Arguments to the do_shrink functions are intended to be passed using + * inheritance. That is, the argument class derives from struct ttm_mem_srink, + * and can be accessed using container_of(). + */ + +struct ttm_mem_shrink { + int (*do_shrink) (struct ttm_mem_shrink *); +}; + +/** + * struct ttm_mem_global - Global memory accounting structure. + * + * @shrink: A single callback to shrink TTM memory usage. Extend this + * to a linked list to be able to handle multiple callbacks when needed. + * @swap_queue: A workqueue to handle shrinking in low memory situations. We + * need a separate workqueue since it will spend a lot of time waiting + * for the GPU, and this will otherwise block other workqueue tasks(?) + * At this point we use only a single-threaded workqueue. + * @work: The workqueue callback for the shrink queue. + * @queue: Wait queue for processes suspended waiting for memory. + * @lock: Lock to protect the @shrink - and the memory accounting members, + * that is, essentially the whole structure with some exceptions. + * @emer_memory: Lowmem memory limit available for root. + * @max_memory: Lowmem memory limit available for non-root. + * @swap_limit: Lowmem memory limit where the shrink workqueue kicks in. + * @used_memory: Currently used lowmem memory. + * @used_total_memory: Currently used total (lowmem + highmem) memory. + * @total_memory_swap_limit: Total memory limit where the shrink workqueue + * kicks in. + * @max_total_memory: Total memory available to non-root processes. + * @emer_total_memory: Total memory available to root processes. + * + * Note that this structure is not per device. It should be global for all + * graphics devices. + */ + +struct ttm_mem_global { + struct ttm_mem_shrink *shrink; + struct workqueue_struct *swap_queue; + struct work_struct work; + wait_queue_head_t queue; + spinlock_t lock; + uint64_t emer_memory; + uint64_t max_memory; + uint64_t swap_limit; + uint64_t used_memory; + uint64_t used_total_memory; + uint64_t total_memory_swap_limit; + uint64_t max_total_memory; + uint64_t emer_total_memory; +}; + +/** + * ttm_mem_init_shrink - initialize a struct ttm_mem_shrink object + * + * @shrink: The object to initialize. + * @func: The callback function. + */ + +static inline void ttm_mem_init_shrink(struct ttm_mem_shrink *shrink, + int (*func) (struct ttm_mem_shrink *)) +{ + shrink->do_shrink = func; +} + +/** + * ttm_mem_register_shrink - register a struct ttm_mem_shrink object. + * + * @glob: The struct ttm_mem_global object to register with. + * @shrink: An initialized struct ttm_mem_shrink object to register. + * + * Returns: + * -EBUSY: There's already a callback registered. (May change). + */ + +static inline int ttm_mem_register_shrink(struct ttm_mem_global *glob, + struct ttm_mem_shrink *shrink) +{ + spin_lock(&glob->lock); + if (glob->shrink != NULL) { + spin_unlock(&glob->lock); + return -EBUSY; + } + glob->shrink = shrink; + spin_unlock(&glob->lock); + return 0; +} + +/** + * ttm_mem_unregister_shrink - unregister a struct ttm_mem_shrink object. + * + * @glob: The struct ttm_mem_global object to unregister from. + * @shrink: A previously registert struct ttm_mem_shrink object. + * + */ + +static inline void ttm_mem_unregister_shrink(struct ttm_mem_global *glob, + struct ttm_mem_shrink *shrink) +{ + spin_lock(&glob->lock); + BUG_ON(glob->shrink != shrink); + glob->shrink = NULL; + spin_unlock(&glob->lock); +} + +extern int ttm_mem_global_init(struct ttm_mem_global *glob); +extern void ttm_mem_global_release(struct ttm_mem_global *glob); +extern int ttm_mem_global_alloc(struct ttm_mem_global *glob, uint64_t memory, + bool no_wait, bool interruptible, bool himem); +extern void ttm_mem_global_free(struct ttm_mem_global *glob, + uint64_t amount, bool himem); +extern size_t ttm_round_pot(size_t size); +#endif diff --git a/include/drm/ttm/ttm_module.h b/include/drm/ttm/ttm_module.h new file mode 100644 index 00000000000..889a4c7958a --- /dev/null +++ b/include/drm/ttm/ttm_module.h @@ -0,0 +1,58 @@ +/************************************************************************** + * + * Copyright 2008-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_MODULE_H_ +#define _TTM_MODULE_H_ + +#include <linux/kernel.h> + +#define TTM_PFX "[TTM]" + +enum ttm_global_types { + TTM_GLOBAL_TTM_MEM = 0, + TTM_GLOBAL_TTM_BO, + TTM_GLOBAL_TTM_OBJECT, + TTM_GLOBAL_NUM +}; + +struct ttm_global_reference { + enum ttm_global_types global_type; + size_t size; + void *object; + int (*init) (struct ttm_global_reference *); + void (*release) (struct ttm_global_reference *); +}; + +extern void ttm_global_init(void); +extern void ttm_global_release(void); +extern int ttm_global_item_ref(struct ttm_global_reference *ref); +extern void ttm_global_item_unref(struct ttm_global_reference *ref); + +#endif /* _TTM_MODULE_H_ */ diff --git a/include/drm/ttm/ttm_placement.h b/include/drm/ttm/ttm_placement.h new file mode 100644 index 00000000000..c84ff153a56 --- /dev/null +++ b/include/drm/ttm/ttm_placement.h @@ -0,0 +1,92 @@ +/************************************************************************** + * + * 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_PLACEMENT_H_ +#define _TTM_PLACEMENT_H_ +/* + * Memory regions for data placement. + */ + +#define TTM_PL_SYSTEM 0 +#define TTM_PL_TT 1 +#define TTM_PL_VRAM 2 +#define TTM_PL_PRIV0 3 +#define TTM_PL_PRIV1 4 +#define TTM_PL_PRIV2 5 +#define TTM_PL_PRIV3 6 +#define TTM_PL_PRIV4 7 +#define TTM_PL_PRIV5 8 +#define TTM_PL_SWAPPED 15 + +#define TTM_PL_FLAG_SYSTEM (1 << TTM_PL_SYSTEM) +#define TTM_PL_FLAG_TT (1 << TTM_PL_TT) +#define TTM_PL_FLAG_VRAM (1 << TTM_PL_VRAM) +#define TTM_PL_FLAG_PRIV0 (1 << TTM_PL_PRIV0) +#define TTM_PL_FLAG_PRIV1 (1 << TTM_PL_PRIV1) +#define TTM_PL_FLAG_PRIV2 (1 << TTM_PL_PRIV2) +#define TTM_PL_FLAG_PRIV3 (1 << TTM_PL_PRIV3) +#define TTM_PL_FLAG_PRIV4 (1 << TTM_PL_PRIV4) +#define TTM_PL_FLAG_PRIV5 (1 << TTM_PL_PRIV5) +#define TTM_PL_FLAG_SWAPPED (1 << TTM_PL_SWAPPED) +#define TTM_PL_MASK_MEM 0x0000FFFF + +/* + * Other flags that affects data placement. + * TTM_PL_FLAG_CACHED indicates cache-coherent mappings + * if available. + * TTM_PL_FLAG_SHARED means that another application may + * reference the buffer. + * TTM_PL_FLAG_NO_EVICT means that the buffer may never + * be evicted to make room for other buffers. + */ + +#define TTM_PL_FLAG_CACHED (1 << 16) +#define TTM_PL_FLAG_UNCACHED (1 << 17) +#define TTM_PL_FLAG_WC (1 << 18) +#define TTM_PL_FLAG_SHARED (1 << 20) +#define TTM_PL_FLAG_NO_EVICT (1 << 21) + +#define TTM_PL_MASK_CACHING (TTM_PL_FLAG_CACHED | \ + TTM_PL_FLAG_UNCACHED | \ + TTM_PL_FLAG_WC) + +#define TTM_PL_MASK_MEMTYPE (TTM_PL_MASK_MEM | TTM_PL_MASK_CACHING) + +/* + * Access flags to be used for CPU- and GPU- mappings. + * The idea is that the TTM synchronization mechanism will + * allow concurrent READ access and exclusive write access. + * Currently GPU- and CPU accesses are exclusive. + */ + +#define TTM_ACCESS_READ (1 << 0) +#define TTM_ACCESS_WRITE (1 << 1) + +#endif diff --git a/include/linux/bio.h b/include/linux/bio.h index 12737be5860..2a04eb54c0d 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -590,6 +590,11 @@ static inline void bio_list_merge_head(struct bio_list *bl, bl->head = bl2->head; } +static inline struct bio *bio_list_peek(struct bio_list *bl) +{ + return bl->head; +} + static inline struct bio *bio_list_pop(struct bio_list *bl) { struct bio *bio = bl->head; diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 0b1a6cae9de..8963d9149b5 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -926,6 +926,7 @@ extern void blk_queue_alignment_offset(struct request_queue *q, unsigned int alignment); extern void blk_queue_io_min(struct request_queue *q, unsigned int min); extern void blk_queue_io_opt(struct request_queue *q, unsigned int opt); +extern void blk_set_default_limits(struct queue_limits *lim); extern int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, sector_t offset); extern void disk_stack_limits(struct gendisk *disk, struct block_device *bdev, diff --git a/include/linux/bug.h b/include/linux/bug.h index 54398d2c6d8..d276b5510c8 100644 --- a/include/linux/bug.h +++ b/include/linux/bug.h @@ -1,7 +1,6 @@ #ifndef _LINUX_BUG_H #define _LINUX_BUG_H -#include <linux/module.h> #include <asm/bug.h> enum bug_trap_type { @@ -24,10 +23,6 @@ const struct bug_entry *find_bug(unsigned long bugaddr); enum bug_trap_type report_bug(unsigned long bug_addr, struct pt_regs *regs); -int module_bug_finalize(const Elf_Ehdr *, const Elf_Shdr *, - struct module *); -void module_bug_cleanup(struct module *); - /* These are defined by the architecture */ int is_valid_bugaddr(unsigned long addr); @@ -38,13 +33,6 @@ static inline enum bug_trap_type report_bug(unsigned long bug_addr, { return BUG_TRAP_TYPE_BUG; } -static inline int module_bug_finalize(const Elf_Ehdr *hdr, - const Elf_Shdr *sechdrs, - struct module *mod) -{ - return 0; -} -static inline void module_bug_cleanup(struct module *mod) {} #endif /* CONFIG_GENERIC_BUG */ #endif /* _LINUX_BUG_H */ diff --git a/include/linux/c2port.h b/include/linux/c2port.h index 7b5a2388ba6..2a5cd867c36 100644 --- a/include/linux/c2port.h +++ b/include/linux/c2port.h @@ -10,6 +10,7 @@ */ #include <linux/device.h> +#include <linux/kmemcheck.h> #define C2PORT_NAME_LEN 32 @@ -20,8 +21,10 @@ /* Main struct */ struct c2port_ops; struct c2port_device { + kmemcheck_bitfield_begin(flags); unsigned int access:1; unsigned int flash_access:1; + kmemcheck_bitfield_end(flags); int id; char name[C2PORT_NAME_LEN]; diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h index 05ea1dd7d68..a5740fc4d04 100644 --- a/include/linux/cpuset.h +++ b/include/linux/cpuset.h @@ -18,7 +18,6 @@ extern int number_of_cpusets; /* How many cpusets are defined in system? */ -extern int cpuset_init_early(void); extern int cpuset_init(void); extern void cpuset_init_smp(void); extern void cpuset_cpus_allowed(struct task_struct *p, struct cpumask *mask); @@ -27,7 +26,6 @@ extern void cpuset_cpus_allowed_locked(struct task_struct *p, extern nodemask_t cpuset_mems_allowed(struct task_struct *p); #define cpuset_current_mems_allowed (current->mems_allowed) void cpuset_init_current_mems_allowed(void); -void cpuset_update_task_memory_state(void); int cpuset_nodemask_valid_mems_allowed(nodemask_t *nodemask); extern int __cpuset_node_allowed_softwall(int node, gfp_t gfp_mask); @@ -92,9 +90,13 @@ extern void rebuild_sched_domains(void); extern void cpuset_print_task_mems_allowed(struct task_struct *p); +static inline void set_mems_allowed(nodemask_t nodemask) +{ + current->mems_allowed = nodemask; +} + #else /* !CONFIG_CPUSETS */ -static inline int cpuset_init_early(void) { return 0; } static inline int cpuset_init(void) { return 0; } static inline void cpuset_init_smp(void) {} @@ -116,7 +118,6 @@ static inline nodemask_t cpuset_mems_allowed(struct task_struct *p) #define cpuset_current_mems_allowed (node_states[N_HIGH_MEMORY]) static inline void cpuset_init_current_mems_allowed(void) {} -static inline void cpuset_update_task_memory_state(void) {} static inline int cpuset_nodemask_valid_mems_allowed(nodemask_t *nodemask) { @@ -188,6 +189,10 @@ static inline void cpuset_print_task_mems_allowed(struct task_struct *p) { } +static inline void set_mems_allowed(nodemask_t nodemask) +{ +} + #endif /* !CONFIG_CPUSETS */ #endif /* _LINUX_CPUSET_H */ diff --git a/include/linux/device.h b/include/linux/device.h index a4a7b10aaa4..ed4e39f2c42 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -114,6 +114,8 @@ extern int bus_unregister_notifier(struct bus_type *bus, #define BUS_NOTIFY_BOUND_DRIVER 0x00000003 /* driver bound to device */ #define BUS_NOTIFY_UNBIND_DRIVER 0x00000004 /* driver about to be unbound */ +#define BUS_NOTIFY_UNBOUND_DRIVER 0x00000005 /* driver is unbound + from the device */ extern struct kset *bus_get_kset(struct bus_type *bus); extern struct klist *bus_get_device_klist(struct bus_type *bus); @@ -192,6 +194,7 @@ struct class { struct kobject *dev_kobj; int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env); + char *(*nodename)(struct device *dev); void (*class_release)(struct class *class); void (*dev_release)(struct device *dev); @@ -287,6 +290,7 @@ struct device_type { const char *name; struct attribute_group **groups; int (*uevent)(struct device *dev, struct kobj_uevent_env *env); + char *(*nodename)(struct device *dev); void (*release)(struct device *dev); struct dev_pm_ops *pm; @@ -486,6 +490,7 @@ extern struct device *device_find_child(struct device *dev, void *data, extern int device_rename(struct device *dev, char *new_name); extern int device_move(struct device *dev, struct device *new_parent, enum dpm_order dpm_order); +extern const char *device_get_nodename(struct device *dev, const char **tmp); /* * Root device objects for grouping under /sys/devices diff --git a/include/linux/eisa.h b/include/linux/eisa.h index e61c0be2a45..6925249a5ac 100644 --- a/include/linux/eisa.h +++ b/include/linux/eisa.h @@ -78,12 +78,12 @@ static inline void eisa_driver_unregister (struct eisa_driver *edrv) { } /* Mimics pci.h... */ static inline void *eisa_get_drvdata (struct eisa_device *edev) { - return edev->dev.driver_data; + return dev_get_drvdata(&edev->dev); } static inline void eisa_set_drvdata (struct eisa_device *edev, void *data) { - edev->dev.driver_data = data; + dev_set_drvdata(&edev->dev, data); } /* The EISA root device. There's rumours about machines with multiple diff --git a/include/linux/fb.h b/include/linux/fb.h index 330c4b1bfca..dd68358996b 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -677,6 +677,9 @@ struct fb_ops { /* get capability given var */ void (*fb_get_caps)(struct fb_info *info, struct fb_blit_caps *caps, struct fb_var_screeninfo *var); + + /* teardown any resources to do with this framebuffer */ + void (*fb_destroy)(struct fb_info *info); }; #ifdef CONFIG_FB_TILEBLITTING @@ -786,6 +789,8 @@ struct fb_tile_ops { #define FBINFO_MISC_USEREVENT 0x10000 /* event request from userspace */ #define FBINFO_MISC_TILEBLITTING 0x20000 /* use tile blitting */ +#define FBINFO_MISC_FIRMWARE 0x40000 /* a replaceable firmware + inited framebuffer */ /* A driver may set this flag to indicate that it does want a set_par to be * called every time when fbcon_switch is executed. The advantage is that with @@ -854,7 +859,12 @@ struct fb_info { u32 state; /* Hardware state i.e suspend */ void *fbcon_par; /* fbcon use-only private area */ /* From here on everything is device dependent */ - void *par; + void *par; + /* we need the PCI or similiar aperture base/size not + smem_start/size as smem_start may just be an object + allocated inside the aperture so may not actually overlap */ + resource_size_t aperture_base; + resource_size_t aperture_size; }; #ifdef MODULE @@ -893,7 +903,7 @@ struct fb_info { #define fb_writeq sbus_writeq #define fb_memset sbus_memset_io -#elif defined(__i386__) || defined(__alpha__) || defined(__x86_64__) || defined(__hppa__) || defined(__sh__) || defined(__powerpc__) || defined(__avr32__) +#elif defined(__i386__) || defined(__alpha__) || defined(__x86_64__) || defined(__hppa__) || defined(__sh__) || defined(__powerpc__) || defined(__avr32__) || defined(__bfin__) #define fb_readb __raw_readb #define fb_readw __raw_readw diff --git a/include/linux/firewire.h b/include/linux/firewire.h new file mode 100644 index 00000000000..e584b7215e8 --- /dev/null +++ b/include/linux/firewire.h @@ -0,0 +1,358 @@ +#ifndef _LINUX_FIREWIRE_H +#define _LINUX_FIREWIRE_H + +#include <linux/completion.h> +#include <linux/device.h> +#include <linux/kernel.h> +#include <linux/kref.h> +#include <linux/list.h> +#include <linux/mutex.h> +#include <linux/spinlock.h> +#include <linux/sysfs.h> +#include <linux/timer.h> +#include <linux/types.h> +#include <linux/workqueue.h> + +#include <asm/atomic.h> +#include <asm/byteorder.h> + +#define fw_notify(s, args...) printk(KERN_NOTICE KBUILD_MODNAME ": " s, ## args) +#define fw_error(s, args...) printk(KERN_ERR KBUILD_MODNAME ": " s, ## args) + +static inline void fw_memcpy_from_be32(void *_dst, void *_src, size_t size) +{ + u32 *dst = _dst; + __be32 *src = _src; + int i; + + for (i = 0; i < size / 4; i++) + dst[i] = be32_to_cpu(src[i]); +} + +static inline void fw_memcpy_to_be32(void *_dst, void *_src, size_t size) +{ + fw_memcpy_from_be32(_dst, _src, size); +} +#define CSR_REGISTER_BASE 0xfffff0000000ULL + +/* register offsets are relative to CSR_REGISTER_BASE */ +#define CSR_STATE_CLEAR 0x0 +#define CSR_STATE_SET 0x4 +#define CSR_NODE_IDS 0x8 +#define CSR_RESET_START 0xc +#define CSR_SPLIT_TIMEOUT_HI 0x18 +#define CSR_SPLIT_TIMEOUT_LO 0x1c +#define CSR_CYCLE_TIME 0x200 +#define CSR_BUS_TIME 0x204 +#define CSR_BUSY_TIMEOUT 0x210 +#define CSR_BUS_MANAGER_ID 0x21c +#define CSR_BANDWIDTH_AVAILABLE 0x220 +#define CSR_CHANNELS_AVAILABLE 0x224 +#define CSR_CHANNELS_AVAILABLE_HI 0x224 +#define CSR_CHANNELS_AVAILABLE_LO 0x228 +#define CSR_BROADCAST_CHANNEL 0x234 +#define CSR_CONFIG_ROM 0x400 +#define CSR_CONFIG_ROM_END 0x800 +#define CSR_FCP_COMMAND 0xB00 +#define CSR_FCP_RESPONSE 0xD00 +#define CSR_FCP_END 0xF00 +#define CSR_TOPOLOGY_MAP 0x1000 +#define CSR_TOPOLOGY_MAP_END 0x1400 +#define CSR_SPEED_MAP 0x2000 +#define CSR_SPEED_MAP_END 0x3000 + +#define CSR_OFFSET 0x40 +#define CSR_LEAF 0x80 +#define CSR_DIRECTORY 0xc0 + +#define CSR_DESCRIPTOR 0x01 +#define CSR_VENDOR 0x03 +#define CSR_HARDWARE_VERSION 0x04 +#define CSR_NODE_CAPABILITIES 0x0c +#define CSR_UNIT 0x11 +#define CSR_SPECIFIER_ID 0x12 +#define CSR_VERSION 0x13 +#define CSR_DEPENDENT_INFO 0x14 +#define CSR_MODEL 0x17 +#define CSR_INSTANCE 0x18 +#define CSR_DIRECTORY_ID 0x20 + +struct fw_csr_iterator { + u32 *p; + u32 *end; +}; + +void fw_csr_iterator_init(struct fw_csr_iterator *ci, u32 *p); +int fw_csr_iterator_next(struct fw_csr_iterator *ci, int *key, int *value); + +extern struct bus_type fw_bus_type; + +struct fw_card_driver; +struct fw_node; + +struct fw_card { + const struct fw_card_driver *driver; + struct device *device; + struct kref kref; + struct completion done; + + int node_id; + int generation; + int current_tlabel; + u64 tlabel_mask; + struct list_head transaction_list; + struct timer_list flush_timer; + unsigned long reset_jiffies; + + unsigned long long guid; + unsigned max_receive; + int link_speed; + int config_rom_generation; + + spinlock_t lock; /* Take this lock when handling the lists in + * this struct. */ + struct fw_node *local_node; + struct fw_node *root_node; + struct fw_node *irm_node; + u8 color; /* must be u8 to match the definition in struct fw_node */ + int gap_count; + bool beta_repeaters_present; + + int index; + + struct list_head link; + + /* Work struct for BM duties. */ + struct delayed_work work; + int bm_retries; + int bm_generation; + + bool broadcast_channel_allocated; + u32 broadcast_channel; + u32 topology_map[(CSR_TOPOLOGY_MAP_END - CSR_TOPOLOGY_MAP) / 4]; +}; + +static inline struct fw_card *fw_card_get(struct fw_card *card) +{ + kref_get(&card->kref); + + return card; +} + +void fw_card_release(struct kref *kref); + +static inline void fw_card_put(struct fw_card *card) +{ + kref_put(&card->kref, fw_card_release); +} + +struct fw_attribute_group { + struct attribute_group *groups[2]; + struct attribute_group group; + struct attribute *attrs[12]; +}; + +enum fw_device_state { + FW_DEVICE_INITIALIZING, + FW_DEVICE_RUNNING, + FW_DEVICE_GONE, + FW_DEVICE_SHUTDOWN, +}; + +/* + * Note, fw_device.generation always has to be read before fw_device.node_id. + * Use SMP memory barriers to ensure this. Otherwise requests will be sent + * to an outdated node_id if the generation was updated in the meantime due + * to a bus reset. + * + * Likewise, fw-core will take care to update .node_id before .generation so + * that whenever fw_device.generation is current WRT the actual bus generation, + * fw_device.node_id is guaranteed to be current too. + * + * The same applies to fw_device.card->node_id vs. fw_device.generation. + * + * fw_device.config_rom and fw_device.config_rom_length may be accessed during + * the lifetime of any fw_unit belonging to the fw_device, before device_del() + * was called on the last fw_unit. Alternatively, they may be accessed while + * holding fw_device_rwsem. + */ +struct fw_device { + atomic_t state; + struct fw_node *node; + int node_id; + int generation; + unsigned max_speed; + struct fw_card *card; + struct device device; + + struct mutex client_list_mutex; + struct list_head client_list; + + u32 *config_rom; + size_t config_rom_length; + int config_rom_retries; + unsigned is_local:1; + unsigned max_rec:4; + unsigned cmc:1; + unsigned irmc:1; + unsigned bc_implemented:2; + + struct delayed_work work; + struct fw_attribute_group attribute_group; +}; + +static inline struct fw_device *fw_device(struct device *dev) +{ + return container_of(dev, struct fw_device, device); +} + +static inline int fw_device_is_shutdown(struct fw_device *device) +{ + return atomic_read(&device->state) == FW_DEVICE_SHUTDOWN; +} + +static inline struct fw_device *fw_device_get(struct fw_device *device) +{ + get_device(&device->device); + + return device; +} + +static inline void fw_device_put(struct fw_device *device) +{ + put_device(&device->device); +} + +int fw_device_enable_phys_dma(struct fw_device *device); + +/* + * fw_unit.directory must not be accessed after device_del(&fw_unit.device). + */ +struct fw_unit { + struct device device; + u32 *directory; + struct fw_attribute_group attribute_group; +}; + +static inline struct fw_unit *fw_unit(struct device *dev) +{ + return container_of(dev, struct fw_unit, device); +} + +static inline struct fw_unit *fw_unit_get(struct fw_unit *unit) +{ + get_device(&unit->device); + + return unit; +} + +static inline void fw_unit_put(struct fw_unit *unit) +{ + put_device(&unit->device); +} + +static inline struct fw_device *fw_parent_device(struct fw_unit *unit) +{ + return fw_device(unit->device.parent); +} + +struct ieee1394_device_id; + +struct fw_driver { + struct device_driver driver; + /* Called when the parent device sits through a bus reset. */ + void (*update)(struct fw_unit *unit); + const struct ieee1394_device_id *id_table; +}; + +struct fw_packet; +struct fw_request; + +typedef void (*fw_packet_callback_t)(struct fw_packet *packet, + struct fw_card *card, int status); +typedef void (*fw_transaction_callback_t)(struct fw_card *card, int rcode, + void *data, size_t length, + void *callback_data); +/* + * Important note: The callback must guarantee that either fw_send_response() + * or kfree() is called on the @request. + */ +typedef void (*fw_address_callback_t)(struct fw_card *card, + struct fw_request *request, + int tcode, int destination, int source, + int generation, int speed, + unsigned long long offset, + void *data, size_t length, + void *callback_data); + +struct fw_packet { + int speed; + int generation; + u32 header[4]; + size_t header_length; + void *payload; + size_t payload_length; + dma_addr_t payload_bus; + u32 timestamp; + + /* + * This callback is called when the packet transmission has + * completed; for successful transmission, the status code is + * the ack received from the destination, otherwise it's a + * negative errno: ENOMEM, ESTALE, ETIMEDOUT, ENODEV, EIO. + * The callback can be called from tasklet context and thus + * must never block. + */ + fw_packet_callback_t callback; + int ack; + struct list_head link; + void *driver_data; +}; + +struct fw_transaction { + int node_id; /* The generation is implied; it is always the current. */ + int tlabel; + int timestamp; + struct list_head link; + + struct fw_packet packet; + + /* + * The data passed to the callback is valid only during the + * callback. + */ + fw_transaction_callback_t callback; + void *callback_data; +}; + +struct fw_address_handler { + u64 offset; + size_t length; + fw_address_callback_t address_callback; + void *callback_data; + struct list_head link; +}; + +struct fw_address_region { + u64 start; + u64 end; +}; + +extern const struct fw_address_region fw_high_memory_region; + +int fw_core_add_address_handler(struct fw_address_handler *handler, + const struct fw_address_region *region); +void fw_core_remove_address_handler(struct fw_address_handler *handler); +void fw_send_response(struct fw_card *card, + struct fw_request *request, int rcode); +void fw_send_request(struct fw_card *card, struct fw_transaction *t, + int tcode, int destination_id, int generation, int speed, + unsigned long long offset, void *payload, size_t length, + fw_transaction_callback_t callback, void *callback_data); +int fw_cancel_transaction(struct fw_card *card, + struct fw_transaction *transaction); +int fw_run_transaction(struct fw_card *card, int tcode, int destination_id, + int generation, int speed, unsigned long long offset, + void *payload, size_t length); + +#endif /* _LINUX_FIREWIRE_H */ diff --git a/include/linux/firmware-map.h b/include/linux/firmware-map.h index cca686b3912..875451f1373 100644 --- a/include/linux/firmware-map.h +++ b/include/linux/firmware-map.h @@ -24,21 +24,17 @@ */ #ifdef CONFIG_FIRMWARE_MEMMAP -int firmware_map_add(resource_size_t start, resource_size_t end, - const char *type); -int firmware_map_add_early(resource_size_t start, resource_size_t end, - const char *type); +int firmware_map_add(u64 start, u64 end, const char *type); +int firmware_map_add_early(u64 start, u64 end, const char *type); #else /* CONFIG_FIRMWARE_MEMMAP */ -static inline int firmware_map_add(resource_size_t start, resource_size_t end, - const char *type) +static inline int firmware_map_add(u64 start, u64 end, const char *type) { return 0; } -static inline int firmware_map_add_early(resource_size_t start, - resource_size_t end, const char *type) +static inline int firmware_map_add_early(u64 start, u64 end, const char *type) { return 0; } diff --git a/include/linux/firmware.h b/include/linux/firmware.h index c8ecf5b2a20..d3154462843 100644 --- a/include/linux/firmware.h +++ b/include/linux/firmware.h @@ -5,7 +5,6 @@ #include <linux/types.h> #include <linux/compiler.h> -#define FIRMWARE_NAME_MAX 30 #define FW_ACTION_NOHOTPLUG 0 #define FW_ACTION_HOTPLUG 1 diff --git a/include/linux/fs.h b/include/linux/fs.h index ede84fa7da5..74a57938c88 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -879,7 +879,7 @@ struct file_ra_state { there are only # of pages ahead */ unsigned int ra_pages; /* Maximum readahead window */ - int mmap_miss; /* Cache miss stat for mmap accesses */ + unsigned int mmap_miss; /* Cache miss stat for mmap accesses */ loff_t prev_pos; /* Cache last read() position */ }; @@ -1919,8 +1919,9 @@ extern void __init vfs_caches_init(unsigned long); extern struct kmem_cache *names_cachep; -#define __getname() kmem_cache_alloc(names_cachep, GFP_KERNEL) -#define __putname(name) kmem_cache_free(names_cachep, (void *)(name)) +#define __getname_gfp(gfp) kmem_cache_alloc(names_cachep, (gfp)) +#define __getname() __getname_gfp(GFP_KERNEL) +#define __putname(name) kmem_cache_free(names_cachep, (void *)(name)) #ifndef CONFIG_AUDITSYSCALL #define putname(name) __putname(name) #else @@ -2036,9 +2037,6 @@ extern int __invalidate_device(struct block_device *); extern int invalidate_partition(struct gendisk *, int); #endif extern int invalidate_inodes(struct super_block *); -unsigned long __invalidate_mapping_pages(struct address_space *mapping, - pgoff_t start, pgoff_t end, - bool be_atomic); unsigned long invalidate_mapping_pages(struct address_space *mapping, pgoff_t start, pgoff_t end); diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 7cbd38d363a..45fc320a53c 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -142,7 +142,7 @@ struct gendisk { * disks that can't be partitioned. */ char disk_name[DISK_NAME_LEN]; /* name of major driver */ - + char *(*nodename)(struct gendisk *gd); /* Array of pointers to partitions indexed by partno. * Protected with matching bdev lock but stat and other * non-critical accesses use RCU. Always access through diff --git a/include/linux/gfp.h b/include/linux/gfp.h index 3760e7c5de0..cfdb35d71bc 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -5,6 +5,7 @@ #include <linux/stddef.h> #include <linux/linkage.h> #include <linux/topology.h> +#include <linux/mmdebug.h> struct vm_area_struct; @@ -20,7 +21,8 @@ struct vm_area_struct; #define __GFP_DMA ((__force gfp_t)0x01u) #define __GFP_HIGHMEM ((__force gfp_t)0x02u) #define __GFP_DMA32 ((__force gfp_t)0x04u) - +#define __GFP_MOVABLE ((__force gfp_t)0x08u) /* Page is movable */ +#define GFP_ZONEMASK (__GFP_DMA|__GFP_HIGHMEM|__GFP_DMA32|__GFP_MOVABLE) /* * Action modifiers - doesn't change the zoning * @@ -50,9 +52,20 @@ struct vm_area_struct; #define __GFP_HARDWALL ((__force gfp_t)0x20000u) /* Enforce hardwall cpuset memory allocs */ #define __GFP_THISNODE ((__force gfp_t)0x40000u)/* No fallback, no policies */ #define __GFP_RECLAIMABLE ((__force gfp_t)0x80000u) /* Page is reclaimable */ -#define __GFP_MOVABLE ((__force gfp_t)0x100000u) /* Page is movable */ -#define __GFP_BITS_SHIFT 21 /* Room for 21 __GFP_FOO bits */ +#ifdef CONFIG_KMEMCHECK +#define __GFP_NOTRACK ((__force gfp_t)0x200000u) /* Don't track with kmemcheck */ +#else +#define __GFP_NOTRACK ((__force gfp_t)0) +#endif + +/* + * This may seem redundant, but it's a way of annotating false positives vs. + * allocations that simply cannot be supported (e.g. page tables). + */ +#define __GFP_NOTRACK_FALSE_POSITIVE (__GFP_NOTRACK) + +#define __GFP_BITS_SHIFT 22 /* Room for 22 __GFP_FOO bits */ #define __GFP_BITS_MASK ((__force gfp_t)((1 << __GFP_BITS_SHIFT) - 1)) /* This equals 0, but use constants in case they ever change */ @@ -115,24 +128,105 @@ static inline int allocflags_to_migratetype(gfp_t gfp_flags) ((gfp_flags & __GFP_RECLAIMABLE) != 0); } -static inline enum zone_type gfp_zone(gfp_t flags) -{ +#ifdef CONFIG_HIGHMEM +#define OPT_ZONE_HIGHMEM ZONE_HIGHMEM +#else +#define OPT_ZONE_HIGHMEM ZONE_NORMAL +#endif + #ifdef CONFIG_ZONE_DMA - if (flags & __GFP_DMA) - return ZONE_DMA; +#define OPT_ZONE_DMA ZONE_DMA +#else +#define OPT_ZONE_DMA ZONE_NORMAL #endif + #ifdef CONFIG_ZONE_DMA32 - if (flags & __GFP_DMA32) - return ZONE_DMA32; +#define OPT_ZONE_DMA32 ZONE_DMA32 +#else +#define OPT_ZONE_DMA32 ZONE_NORMAL #endif - if ((flags & (__GFP_HIGHMEM | __GFP_MOVABLE)) == - (__GFP_HIGHMEM | __GFP_MOVABLE)) - return ZONE_MOVABLE; -#ifdef CONFIG_HIGHMEM - if (flags & __GFP_HIGHMEM) - return ZONE_HIGHMEM; + +/* + * GFP_ZONE_TABLE is a word size bitstring that is used for looking up the + * zone to use given the lowest 4 bits of gfp_t. Entries are ZONE_SHIFT long + * and there are 16 of them to cover all possible combinations of + * __GFP_DMA, __GFP_DMA32, __GFP_MOVABLE and __GFP_HIGHMEM + * + * The zone fallback order is MOVABLE=>HIGHMEM=>NORMAL=>DMA32=>DMA. + * But GFP_MOVABLE is not only a zone specifier but also an allocation + * policy. Therefore __GFP_MOVABLE plus another zone selector is valid. + * Only 1bit of the lowest 3 bit (DMA,DMA32,HIGHMEM) can be set to "1". + * + * bit result + * ================= + * 0x0 => NORMAL + * 0x1 => DMA or NORMAL + * 0x2 => HIGHMEM or NORMAL + * 0x3 => BAD (DMA+HIGHMEM) + * 0x4 => DMA32 or DMA or NORMAL + * 0x5 => BAD (DMA+DMA32) + * 0x6 => BAD (HIGHMEM+DMA32) + * 0x7 => BAD (HIGHMEM+DMA32+DMA) + * 0x8 => NORMAL (MOVABLE+0) + * 0x9 => DMA or NORMAL (MOVABLE+DMA) + * 0xa => MOVABLE (Movable is valid only if HIGHMEM is set too) + * 0xb => BAD (MOVABLE+HIGHMEM+DMA) + * 0xc => DMA32 (MOVABLE+HIGHMEM+DMA32) + * 0xd => BAD (MOVABLE+DMA32+DMA) + * 0xe => BAD (MOVABLE+DMA32+HIGHMEM) + * 0xf => BAD (MOVABLE+DMA32+HIGHMEM+DMA) + * + * ZONES_SHIFT must be <= 2 on 32 bit platforms. + */ + +#if 16 * ZONES_SHIFT > BITS_PER_LONG +#error ZONES_SHIFT too large to create GFP_ZONE_TABLE integer +#endif + +#define GFP_ZONE_TABLE ( \ + (ZONE_NORMAL << 0 * ZONES_SHIFT) \ + | (OPT_ZONE_DMA << __GFP_DMA * ZONES_SHIFT) \ + | (OPT_ZONE_HIGHMEM << __GFP_HIGHMEM * ZONES_SHIFT) \ + | (OPT_ZONE_DMA32 << __GFP_DMA32 * ZONES_SHIFT) \ + | (ZONE_NORMAL << __GFP_MOVABLE * ZONES_SHIFT) \ + | (OPT_ZONE_DMA << (__GFP_MOVABLE | __GFP_DMA) * ZONES_SHIFT) \ + | (ZONE_MOVABLE << (__GFP_MOVABLE | __GFP_HIGHMEM) * ZONES_SHIFT)\ + | (OPT_ZONE_DMA32 << (__GFP_MOVABLE | __GFP_DMA32) * ZONES_SHIFT)\ +) + +/* + * GFP_ZONE_BAD is a bitmap for all combination of __GFP_DMA, __GFP_DMA32 + * __GFP_HIGHMEM and __GFP_MOVABLE that are not permitted. One flag per + * entry starting with bit 0. Bit is set if the combination is not + * allowed. + */ +#define GFP_ZONE_BAD ( \ + 1 << (__GFP_DMA | __GFP_HIGHMEM) \ + | 1 << (__GFP_DMA | __GFP_DMA32) \ + | 1 << (__GFP_DMA32 | __GFP_HIGHMEM) \ + | 1 << (__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM) \ + | 1 << (__GFP_MOVABLE | __GFP_HIGHMEM | __GFP_DMA) \ + | 1 << (__GFP_MOVABLE | __GFP_DMA32 | __GFP_DMA) \ + | 1 << (__GFP_MOVABLE | __GFP_DMA32 | __GFP_HIGHMEM) \ + | 1 << (__GFP_MOVABLE | __GFP_DMA32 | __GFP_DMA | __GFP_HIGHMEM)\ +) + +static inline enum zone_type gfp_zone(gfp_t flags) +{ + enum zone_type z; + int bit = flags & GFP_ZONEMASK; + + z = (GFP_ZONE_TABLE >> (bit * ZONES_SHIFT)) & + ((1 << ZONES_SHIFT) - 1); + + if (__builtin_constant_p(bit)) + BUILD_BUG_ON((GFP_ZONE_BAD >> bit) & 1); + else { +#ifdef CONFIG_DEBUG_VM + BUG_ON((GFP_ZONE_BAD >> bit) & 1); #endif - return ZONE_NORMAL; + } + return z; } /* @@ -172,30 +266,19 @@ static inline void arch_alloc_page(struct page *page, int order) { } #endif struct page * -__alloc_pages_internal(gfp_t gfp_mask, unsigned int order, +__alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order, struct zonelist *zonelist, nodemask_t *nodemask); static inline struct page * __alloc_pages(gfp_t gfp_mask, unsigned int order, struct zonelist *zonelist) { - return __alloc_pages_internal(gfp_mask, order, zonelist, NULL); + return __alloc_pages_nodemask(gfp_mask, order, zonelist, NULL); } -static inline struct page * -__alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order, - struct zonelist *zonelist, nodemask_t *nodemask) -{ - return __alloc_pages_internal(gfp_mask, order, zonelist, nodemask); -} - - static inline struct page *alloc_pages_node(int nid, gfp_t gfp_mask, unsigned int order) { - if (unlikely(order >= MAX_ORDER)) - return NULL; - /* Unknown node is current node */ if (nid < 0) nid = numa_node_id(); @@ -203,15 +286,20 @@ static inline struct page *alloc_pages_node(int nid, gfp_t gfp_mask, return __alloc_pages(gfp_mask, order, node_zonelist(nid, gfp_mask)); } +static inline struct page *alloc_pages_exact_node(int nid, gfp_t gfp_mask, + unsigned int order) +{ + VM_BUG_ON(nid < 0 || nid >= MAX_NUMNODES); + + return __alloc_pages(gfp_mask, order, node_zonelist(nid, gfp_mask)); +} + #ifdef CONFIG_NUMA extern struct page *alloc_pages_current(gfp_t gfp_mask, unsigned order); static inline struct page * alloc_pages(gfp_t gfp_mask, unsigned int order) { - if (unlikely(order >= MAX_ORDER)) - return NULL; - return alloc_pages_current(gfp_mask, order); } extern struct page *alloc_page_vma(gfp_t gfp_mask, @@ -248,4 +336,16 @@ void drain_zone_pages(struct zone *zone, struct per_cpu_pages *pcp); void drain_all_pages(void); void drain_local_pages(void *dummy); +extern bool oom_killer_disabled; + +static inline void oom_killer_disable(void) +{ + oom_killer_disabled = true; +} + +static inline void oom_killer_enable(void) +{ + oom_killer_disabled = false; +} + #endif /* __LINUX_GFP_H */ diff --git a/include/linux/highmem.h b/include/linux/highmem.h index 1fcb7126a01..211ff449726 100644 --- a/include/linux/highmem.h +++ b/include/linux/highmem.h @@ -55,7 +55,9 @@ static inline void *kmap(struct page *page) return page_address(page); } -#define kunmap(page) do { (void) (page); } while (0) +static inline void kunmap(struct page *page) +{ +} static inline void *kmap_atomic(struct page *page, enum km_type idx) { diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index 03be7f29ca0..a05a5ef3339 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -11,6 +11,8 @@ struct ctl_table; +int PageHuge(struct page *page); + static inline int is_vm_hugetlb_page(struct vm_area_struct *vma) { return vma->vm_flags & VM_HUGETLB; @@ -61,6 +63,11 @@ void hugetlb_change_protection(struct vm_area_struct *vma, #else /* !CONFIG_HUGETLB_PAGE */ +static inline int PageHuge(struct page *page) +{ + return 0; +} + static inline int is_vm_hugetlb_page(struct vm_area_struct *vma) { return 0; diff --git a/include/linux/init.h b/include/linux/init.h index b2189803f19..8c2c9989626 100644 --- a/include/linux/init.h +++ b/include/linux/init.h @@ -29,7 +29,7 @@ * sign followed by value, e.g.: * * static int init_variable __initdata = 0; - * static char linux_logo[] __initdata = { 0x32, 0x36, ... }; + * static const char linux_logo[] __initconst = { 0x32, 0x36, ... }; * * Don't forget to initialize data not at file scope, i.e. within a function, * as gcc otherwise puts the data into the bss section and not into the init diff --git a/include/linux/init_task.h b/include/linux/init_task.h index 28b1f30601b..5368fbdc780 100644 --- a/include/linux/init_task.h +++ b/include/linux/init_task.h @@ -15,18 +15,6 @@ extern struct files_struct init_files; extern struct fs_struct init_fs; -#define INIT_MM(name) \ -{ \ - .mm_rb = RB_ROOT, \ - .pgd = swapper_pg_dir, \ - .mm_users = ATOMIC_INIT(2), \ - .mm_count = ATOMIC_INIT(1), \ - .mmap_sem = __RWSEM_INITIALIZER(name.mmap_sem), \ - .page_table_lock = __SPIN_LOCK_UNLOCKED(name.page_table_lock), \ - .mmlist = LIST_HEAD_INIT(name.mmlist), \ - .cpu_vm_mask = CPU_MASK_ALL, \ -} - #define INIT_SIGNALS(sig) { \ .count = ATOMIC_INIT(1), \ .wait_chldexit = __WAIT_QUEUE_HEAD_INITIALIZER(sig.wait_chldexit),\ diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index c41e812e9d5..2721f07e935 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -472,6 +472,20 @@ static inline void tasklet_hi_schedule(struct tasklet_struct *t) __tasklet_hi_schedule(t); } +extern void __tasklet_hi_schedule_first(struct tasklet_struct *t); + +/* + * This version avoids touching any other tasklets. Needed for kmemcheck + * in order not to take any page faults while enqueueing this tasklet; + * consider VERY carefully whether you really need this or + * tasklet_hi_schedule()... + */ +static inline void tasklet_hi_schedule_first(struct tasklet_struct *t) +{ + if (!test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) + __tasklet_hi_schedule_first(t); +} + static inline void tasklet_disable_nosync(struct tasklet_struct *t) { diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 883cd44ff76..c5a71c38a95 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -97,12 +97,14 @@ extern const char linux_proc_banner[]; #define KERN_INFO "<6>" /* informational */ #define KERN_DEBUG "<7>" /* debug-level messages */ +/* Use the default kernel loglevel */ +#define KERN_DEFAULT "<d>" /* * Annotation for a "continued" line of log printout (only done after a * line that had no enclosing \n). Only to be used by core/arch code * during early bootup (a continued line is not SMP-safe otherwise). */ -#define KERN_CONT "" +#define KERN_CONT "<c>" extern int console_printk[]; @@ -406,7 +408,7 @@ static inline char *pack_hex_byte(char *buf, u8 byte) * * Use tracing_on/tracing_off when you want to quickly turn on or off * tracing. It simply enables or disables the recording of the trace events. - * This also corresponds to the user space debugfs/tracing/tracing_on + * This also corresponds to the user space /sys/kernel/debug/tracing/tracing_on * file, which gives a means for the kernel and userspace to interact. * Place a tracing_off() in the kernel where you want tracing to end. * From user space, examine the trace, and then echo 1 > tracing_on diff --git a/include/linux/kmemcheck.h b/include/linux/kmemcheck.h new file mode 100644 index 00000000000..47b39b7c7e8 --- /dev/null +++ b/include/linux/kmemcheck.h @@ -0,0 +1,153 @@ +#ifndef LINUX_KMEMCHECK_H +#define LINUX_KMEMCHECK_H + +#include <linux/mm_types.h> +#include <linux/types.h> + +#ifdef CONFIG_KMEMCHECK +extern int kmemcheck_enabled; + +/* The slab-related functions. */ +void kmemcheck_alloc_shadow(struct page *page, int order, gfp_t flags, int node); +void kmemcheck_free_shadow(struct page *page, int order); +void kmemcheck_slab_alloc(struct kmem_cache *s, gfp_t gfpflags, void *object, + size_t size); +void kmemcheck_slab_free(struct kmem_cache *s, void *object, size_t size); + +void kmemcheck_pagealloc_alloc(struct page *p, unsigned int order, + gfp_t gfpflags); + +void kmemcheck_show_pages(struct page *p, unsigned int n); +void kmemcheck_hide_pages(struct page *p, unsigned int n); + +bool kmemcheck_page_is_tracked(struct page *p); + +void kmemcheck_mark_unallocated(void *address, unsigned int n); +void kmemcheck_mark_uninitialized(void *address, unsigned int n); +void kmemcheck_mark_initialized(void *address, unsigned int n); +void kmemcheck_mark_freed(void *address, unsigned int n); + +void kmemcheck_mark_unallocated_pages(struct page *p, unsigned int n); +void kmemcheck_mark_uninitialized_pages(struct page *p, unsigned int n); +void kmemcheck_mark_initialized_pages(struct page *p, unsigned int n); + +int kmemcheck_show_addr(unsigned long address); +int kmemcheck_hide_addr(unsigned long address); + +#else +#define kmemcheck_enabled 0 + +static inline void +kmemcheck_alloc_shadow(struct page *page, int order, gfp_t flags, int node) +{ +} + +static inline void +kmemcheck_free_shadow(struct page *page, int order) +{ +} + +static inline void +kmemcheck_slab_alloc(struct kmem_cache *s, gfp_t gfpflags, void *object, + size_t size) +{ +} + +static inline void kmemcheck_slab_free(struct kmem_cache *s, void *object, + size_t size) +{ +} + +static inline void kmemcheck_pagealloc_alloc(struct page *p, + unsigned int order, gfp_t gfpflags) +{ +} + +static inline bool kmemcheck_page_is_tracked(struct page *p) +{ + return false; +} + +static inline void kmemcheck_mark_unallocated(void *address, unsigned int n) +{ +} + +static inline void kmemcheck_mark_uninitialized(void *address, unsigned int n) +{ +} + +static inline void kmemcheck_mark_initialized(void *address, unsigned int n) +{ +} + +static inline void kmemcheck_mark_freed(void *address, unsigned int n) +{ +} + +static inline void kmemcheck_mark_unallocated_pages(struct page *p, + unsigned int n) +{ +} + +static inline void kmemcheck_mark_uninitialized_pages(struct page *p, + unsigned int n) +{ +} + +static inline void kmemcheck_mark_initialized_pages(struct page *p, + unsigned int n) +{ +} + +#endif /* CONFIG_KMEMCHECK */ + +/* + * Bitfield annotations + * + * How to use: If you have a struct using bitfields, for example + * + * struct a { + * int x:8, y:8; + * }; + * + * then this should be rewritten as + * + * struct a { + * kmemcheck_bitfield_begin(flags); + * int x:8, y:8; + * kmemcheck_bitfield_end(flags); + * }; + * + * Now the "flags_begin" and "flags_end" members may be used to refer to the + * beginning and end, respectively, of the bitfield (and things like + * &x.flags_begin is allowed). As soon as the struct is allocated, the bit- + * fields should be annotated: + * + * struct a *a = kmalloc(sizeof(struct a), GFP_KERNEL); + * kmemcheck_annotate_bitfield(a, flags); + * + * Note: We provide the same definitions for both kmemcheck and non- + * kmemcheck kernels. This makes it harder to introduce accidental errors. It + * is also allowed to pass NULL pointers to kmemcheck_annotate_bitfield(). + */ +#define kmemcheck_bitfield_begin(name) \ + int name##_begin[0]; + +#define kmemcheck_bitfield_end(name) \ + int name##_end[0]; + +#define kmemcheck_annotate_bitfield(ptr, name) \ + do if (ptr) { \ + int _n = (long) &((ptr)->name##_end) \ + - (long) &((ptr)->name##_begin); \ + BUILD_BUG_ON(_n < 0); \ + \ + kmemcheck_mark_initialized(&((ptr)->name##_begin), _n); \ + } while (0) + +#define kmemcheck_annotate_variable(var) \ + do { \ + kmemcheck_mark_initialized(&(var), sizeof(var)); \ + } while (0) \ + +#endif /* LINUX_KMEMCHECK_H */ diff --git a/include/linux/linux_logo.h b/include/linux/linux_logo.h index 08a92969c76..ca5bd91d12e 100644 --- a/include/linux/linux_logo.h +++ b/include/linux/linux_logo.h @@ -32,6 +32,22 @@ struct linux_logo { const unsigned char *data; }; +extern const struct linux_logo logo_linux_mono; +extern const struct linux_logo logo_linux_vga16; +extern const struct linux_logo logo_linux_clut224; +extern const struct linux_logo logo_blackfin_vga16; +extern const struct linux_logo logo_blackfin_clut224; +extern const struct linux_logo logo_dec_clut224; +extern const struct linux_logo logo_mac_clut224; +extern const struct linux_logo logo_parisc_clut224; +extern const struct linux_logo logo_sgi_clut224; +extern const struct linux_logo logo_sun_clut224; +extern const struct linux_logo logo_superh_mono; +extern const struct linux_logo logo_superh_vga16; +extern const struct linux_logo logo_superh_clut224; +extern const struct linux_logo logo_m32r_clut224; +extern const struct linux_logo logo_spe_clut224; + extern const struct linux_logo *fb_find_logo(int depth); #ifdef CONFIG_FB_LOGO_EXTRA extern void fb_append_extra_logo(const struct linux_logo *logo, diff --git a/include/linux/lis3lv02d.h b/include/linux/lis3lv02d.h new file mode 100644 index 00000000000..ad651f4e45a --- /dev/null +++ b/include/linux/lis3lv02d.h @@ -0,0 +1,39 @@ +#ifndef __LIS3LV02D_H_ +#define __LIS3LV02D_H_ + +struct lis3lv02d_platform_data { + /* please note: the 'click' feature is only supported for + * LIS[32]02DL variants of the chip and will be ignored for + * others */ +#define LIS3_CLICK_SINGLE_X (1 << 0) +#define LIS3_CLICK_DOUBLE_X (1 << 1) +#define LIS3_CLICK_SINGLE_Y (1 << 2) +#define LIS3_CLICK_DOUBLE_Y (1 << 3) +#define LIS3_CLICK_SINGLE_Z (1 << 4) +#define LIS3_CLICK_DOUBLE_Z (1 << 5) + unsigned char click_flags; + unsigned char click_thresh_x; + unsigned char click_thresh_y; + unsigned char click_thresh_z; + unsigned char click_time_limit; + unsigned char click_latency; + unsigned char click_window; + +#define LIS3_IRQ1_DISABLE (0 << 0) +#define LIS3_IRQ1_FF_WU_1 (1 << 0) +#define LIS3_IRQ1_FF_WU_2 (2 << 0) +#define LIS3_IRQ1_FF_WU_12 (3 << 0) +#define LIS3_IRQ1_DATA_READY (4 << 0) +#define LIS3_IRQ1_CLICK (7 << 0) +#define LIS3_IRQ2_DISABLE (0 << 3) +#define LIS3_IRQ2_FF_WU_1 (1 << 3) +#define LIS3_IRQ2_FF_WU_2 (2 << 3) +#define LIS3_IRQ2_FF_WU_12 (3 << 3) +#define LIS3_IRQ2_DATA_READY (4 << 3) +#define LIS3_IRQ2_CLICK (7 << 3) +#define LIS3_IRQ_OPEN_DRAIN (1 << 6) +#define LIS3_IRQ_ACTIVE_HIGH (1 << 7) + unsigned char irq_cfg; +}; + +#endif /* __LIS3LV02D_H_ */ diff --git a/include/linux/major.h b/include/linux/major.h index 058ec15dd06..6a8ca98c9a9 100644 --- a/include/linux/major.h +++ b/include/linux/major.h @@ -145,6 +145,7 @@ #define UNIX98_PTY_MAJOR_COUNT 8 #define UNIX98_PTY_SLAVE_MAJOR (UNIX98_PTY_MASTER_MAJOR+UNIX98_PTY_MAJOR_COUNT) +#define DRBD_MAJOR 147 #define RTF_MAJOR 150 #define RAW_MAJOR 162 diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 25b9ca93d23..45add35dda1 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -94,6 +94,7 @@ extern void mem_cgroup_note_reclaim_priority(struct mem_cgroup *mem, extern void mem_cgroup_record_reclaim_priority(struct mem_cgroup *mem, int priority); int mem_cgroup_inactive_anon_is_low(struct mem_cgroup *memcg); +int mem_cgroup_inactive_file_is_low(struct mem_cgroup *memcg); unsigned long mem_cgroup_zone_nr_pages(struct mem_cgroup *memcg, struct zone *zone, enum lru_list lru); @@ -239,6 +240,12 @@ mem_cgroup_inactive_anon_is_low(struct mem_cgroup *memcg) return 1; } +static inline int +mem_cgroup_inactive_file_is_low(struct mem_cgroup *memcg) +{ + return 1; +} + static inline unsigned long mem_cgroup_zone_nr_pages(struct mem_cgroup *memcg, struct zone *zone, enum lru_list lru) diff --git a/include/linux/mg_disk.h b/include/linux/mg_disk.h new file mode 100644 index 00000000000..e11f4d9f1c2 --- /dev/null +++ b/include/linux/mg_disk.h @@ -0,0 +1,45 @@ +/* + * include/linux/mg_disk.c + * + * Private data for mflash platform driver + * + * (c) 2008 mGine Co.,LTD + * (c) 2008 unsik Kim <donari75@gmail.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 __MG_DISK_H__ +#define __MG_DISK_H__ + +/* name for platform device */ +#define MG_DEV_NAME "mg_disk" + +/* names of GPIO resource */ +#define MG_RST_PIN "mg_rst" +/* except MG_BOOT_DEV, reset-out pin should be assigned */ +#define MG_RSTOUT_PIN "mg_rstout" + +/* device attribution */ +/* use mflash as boot device */ +#define MG_BOOT_DEV (1 << 0) +/* use mflash as storage device */ +#define MG_STORAGE_DEV (1 << 1) +/* same as MG_STORAGE_DEV, but bootloader already done reset sequence */ +#define MG_STORAGE_DEV_SKIP_RST (1 << 2) + +/* private driver data */ +struct mg_drv_data { + /* disk resource */ + u32 use_polling; + + /* device attribution */ + u32 dev_attr; + + /* internally used */ + void *host; +}; + +#endif diff --git a/include/linux/miscdevice.h b/include/linux/miscdevice.h index beb6ec99cfe..05211774462 100644 --- a/include/linux/miscdevice.h +++ b/include/linux/miscdevice.h @@ -41,6 +41,7 @@ struct miscdevice { struct list_head list; struct device *parent; struct device *this_device; + const char *devnode; }; extern int misc_register(struct miscdevice * misc); diff --git a/include/linux/mm.h b/include/linux/mm.h index ad613ed66ab..d88d6fc530a 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -7,7 +7,6 @@ #include <linux/gfp.h> #include <linux/list.h> -#include <linux/mmdebug.h> #include <linux/mmzone.h> #include <linux/rbtree.h> #include <linux/prio_tree.h> @@ -725,7 +724,7 @@ static inline int shmem_lock(struct file *file, int lock, return 0; } #endif -struct file *shmem_file_setup(char *name, loff_t size, unsigned long flags); +struct file *shmem_file_setup(const char *name, loff_t size, unsigned long flags); int shmem_zero_setup(struct vm_area_struct *); @@ -793,6 +792,8 @@ int copy_page_range(struct mm_struct *dst, struct mm_struct *src, struct vm_area_struct *vma); void unmap_mapping_range(struct address_space *mapping, loff_t const holebegin, loff_t const holelen, int even_cows); +int follow_pfn(struct vm_area_struct *vma, unsigned long address, + unsigned long *pfn); int follow_phys(struct vm_area_struct *vma, unsigned long address, unsigned int flags, unsigned long *prot, resource_size_t *phys); int generic_access_phys(struct vm_area_struct *vma, unsigned long addr, @@ -824,8 +825,11 @@ static inline int handle_mm_fault(struct mm_struct *mm, extern int make_pages_present(unsigned long addr, unsigned long end); extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write); -int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, unsigned long start, - int len, int write, int force, struct page **pages, struct vm_area_struct **vmas); +int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, + unsigned long start, int len, int write, int force, + struct page **pages, struct vm_area_struct **vmas); +int get_user_pages_fast(unsigned long start, int nr_pages, int write, + struct page **pages); extern int try_to_release_page(struct page * page, gfp_t gfp_mask); extern void do_invalidatepage(struct page *page, unsigned long offset); @@ -850,19 +854,6 @@ extern int mprotect_fixup(struct vm_area_struct *vma, unsigned long end, unsigned long newflags); /* - * get_user_pages_fast provides equivalent functionality to get_user_pages, - * operating on current and current->mm (force=0 and doesn't return any vmas). - * - * get_user_pages_fast may take mmap_sem and page tables, so no assumptions - * can be made about locking. get_user_pages_fast is to be implemented in a - * way that is advantageous (vs get_user_pages()) when the user memory area is - * already faulted in and present in ptes. However if the pages have to be - * faulted in, it may turn out to be slightly slower). - */ -int get_user_pages_fast(unsigned long start, int nr_pages, int write, - struct page **pages); - -/* * A callback you can register to apply pressure to ageable caches. * * 'shrink' is passed a count 'nr_to_scan' and a 'gfpmask'. It should @@ -1061,7 +1052,8 @@ extern int __meminit __early_pfn_to_nid(unsigned long pfn); extern void set_dma_reserve(unsigned long new_dma_reserve); extern void memmap_init_zone(unsigned long, int, unsigned long, unsigned long, enum memmap_context); -extern void setup_per_zone_pages_min(void); +extern void setup_per_zone_wmarks(void); +extern void calculate_zone_inactive_ratio(struct zone *zone); extern void mem_init(void); extern void __init mmap_init(void); extern void show_mem(void); @@ -1178,8 +1170,6 @@ void task_dirty_inc(struct task_struct *tsk); #define VM_MAX_READAHEAD 128 /* kbytes */ #define VM_MIN_READAHEAD 16 /* kbytes (includes current page) */ -int do_page_cache_readahead(struct address_space *mapping, struct file *filp, - pgoff_t offset, unsigned long nr_to_read); int force_page_cache_readahead(struct address_space *mapping, struct file *filp, pgoff_t offset, unsigned long nr_to_read); @@ -1197,6 +1187,9 @@ void page_cache_async_readahead(struct address_space *mapping, unsigned long size); unsigned long max_sane_readahead(unsigned long nr); +unsigned long ra_submit(struct file_ra_state *ra, + struct address_space *mapping, + struct file *filp); /* Do stack extension */ extern int expand_stack(struct vm_area_struct *vma, unsigned long address); diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 0e80e26ecf2..7acc8439d9b 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -98,6 +98,14 @@ struct page { #ifdef CONFIG_WANT_PAGE_DEBUG_FLAGS unsigned long debug_flags; /* Use atomic bitops on this */ #endif + +#ifdef CONFIG_KMEMCHECK + /* + * kmemcheck wants to track the status of each byte in a page; this + * is a pointer to such a status block. NULL if not tracked. + */ + void *shadow; +#endif }; /* @@ -232,6 +240,8 @@ struct mm_struct { unsigned long saved_auxv[AT_VECTOR_SIZE]; /* for /proc/PID/auxv */ + s8 oom_adj; /* OOM kill score adjustment (bit shift) */ + cpumask_t cpu_vm_mask; /* Architecture-specific MM context */ diff --git a/include/linux/mmc/sdio_ids.h b/include/linux/mmc/sdio_ids.h index c7211ab6dd4..39751c8cde9 100644 --- a/include/linux/mmc/sdio_ids.h +++ b/include/linux/mmc/sdio_ids.h @@ -28,4 +28,12 @@ #define SDIO_DEVICE_ID_MARVELL_8688WLAN 0x9104 #define SDIO_DEVICE_ID_MARVELL_8688BT 0x9105 +#define SDIO_VENDOR_ID_SIANO 0x039a +#define SDIO_DEVICE_ID_SIANO_NOVA_B0 0x0201 +#define SDIO_DEVICE_ID_SIANO_NICE 0x0202 +#define SDIO_DEVICE_ID_SIANO_VEGA_A0 0x0300 +#define SDIO_DEVICE_ID_SIANO_VENICE 0x0301 +#define SDIO_DEVICE_ID_SIANO_NOVA_A0 0x1100 +#define SDIO_DEVICE_ID_SIANO_STELLAR 0x5347 + #endif diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index a47c879e130..88959853737 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -50,9 +50,6 @@ extern int page_group_by_mobility_disabled; static inline int get_pageblock_migratetype(struct page *page) { - if (unlikely(page_group_by_mobility_disabled)) - return MIGRATE_UNMOVABLE; - return get_pageblock_flags_group(page, PB_migrate, PB_migrate_end); } @@ -86,13 +83,8 @@ enum zone_stat_item { NR_ACTIVE_ANON, /* " " " " " */ NR_INACTIVE_FILE, /* " " " " " */ NR_ACTIVE_FILE, /* " " " " " */ -#ifdef CONFIG_UNEVICTABLE_LRU NR_UNEVICTABLE, /* " " " " " */ NR_MLOCK, /* mlock()ed pages found and moved off LRU */ -#else - NR_UNEVICTABLE = NR_ACTIVE_FILE, /* avoid compiler errors in dead code */ - NR_MLOCK = NR_ACTIVE_FILE, -#endif NR_ANON_PAGES, /* Mapped anonymous pages */ NR_FILE_MAPPED, /* pagecache pages mapped into pagetables. only modified from process context */ @@ -135,11 +127,7 @@ enum lru_list { LRU_ACTIVE_ANON = LRU_BASE + LRU_ACTIVE, LRU_INACTIVE_FILE = LRU_BASE + LRU_FILE, LRU_ACTIVE_FILE = LRU_BASE + LRU_FILE + LRU_ACTIVE, -#ifdef CONFIG_UNEVICTABLE_LRU LRU_UNEVICTABLE, -#else - LRU_UNEVICTABLE = LRU_ACTIVE_FILE, /* avoid compiler errors in dead code */ -#endif NR_LRU_LISTS }; @@ -159,13 +147,20 @@ static inline int is_active_lru(enum lru_list l) static inline int is_unevictable_lru(enum lru_list l) { -#ifdef CONFIG_UNEVICTABLE_LRU return (l == LRU_UNEVICTABLE); -#else - return 0; -#endif } +enum zone_watermarks { + WMARK_MIN, + WMARK_LOW, + WMARK_HIGH, + NR_WMARK +}; + +#define min_wmark_pages(z) (z->watermark[WMARK_MIN]) +#define low_wmark_pages(z) (z->watermark[WMARK_LOW]) +#define high_wmark_pages(z) (z->watermark[WMARK_HIGH]) + struct per_cpu_pages { int count; /* number of pages in the list */ int high; /* high watermark, emptying needed */ @@ -278,7 +273,10 @@ struct zone_reclaim_stat { struct zone { /* Fields commonly accessed by the page allocator */ - unsigned long pages_min, pages_low, pages_high; + + /* zone watermarks, access with *_wmark_pages(zone) macros */ + unsigned long watermark[NR_WMARK]; + /* * We don't know if the memory that we're going to allocate will be freeable * or/and it will be released eventually, so to avoid totally wasting several @@ -323,9 +321,9 @@ struct zone { /* Fields commonly accessed by the page reclaim scanner */ spinlock_t lru_lock; - struct { + struct zone_lru { struct list_head list; - unsigned long nr_scan; + unsigned long nr_saved_scan; /* accumulated for batching */ } lru[NR_LRU_LISTS]; struct zone_reclaim_stat reclaim_stat; diff --git a/include/linux/module.h b/include/linux/module.h index a7bc6e7b43a..505f20dcc1c 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -697,4 +697,21 @@ static inline void module_remove_modinfo_attrs(struct module *mod) #define __MODULE_STRING(x) __stringify(x) + +#ifdef CONFIG_GENERIC_BUG +int module_bug_finalize(const Elf_Ehdr *, const Elf_Shdr *, + struct module *); +void module_bug_cleanup(struct module *); + +#else /* !CONFIG_GENERIC_BUG */ + +static inline int module_bug_finalize(const Elf_Ehdr *hdr, + const Elf_Shdr *sechdrs, + struct module *mod) +{ + return 0; +} +static inline void module_bug_cleanup(struct module *mod) {} +#endif /* CONFIG_GENERIC_BUG */ + #endif /* _LINUX_MODULE_H */ diff --git a/include/linux/nls.h b/include/linux/nls.h index 52b1a76c1b4..d47beef08df 100644 --- a/include/linux/nls.h +++ b/include/linux/nls.h @@ -3,8 +3,23 @@ #include <linux/init.h> -/* unicode character */ -typedef __u16 wchar_t; +/* Unicode has changed over the years. Unicode code points no longer + * fit into 16 bits; as of Unicode 5 valid code points range from 0 + * to 0x10ffff (17 planes, where each plane holds 65536 code points). + * + * The original decision to represent Unicode characters as 16-bit + * wchar_t values is now outdated. But plane 0 still includes the + * most commonly used characters, so we will retain it. The newer + * 32-bit unicode_t type can be used when it is necessary to + * represent the full Unicode character set. + */ + +/* Plane-0 Unicode character */ +typedef u16 wchar_t; +#define MAX_WCHAR_T 0xffff + +/* Arbitrary Unicode character */ +typedef u32 unicode_t; struct nls_table { const char *charset; @@ -21,6 +36,13 @@ struct nls_table { /* this value hold the maximum octet of charset */ #define NLS_MAX_CHARSET_SIZE 6 /* for UTF-8 */ +/* Byte order for UTF-16 strings */ +enum utf16_endian { + UTF16_HOST_ENDIAN, + UTF16_LITTLE_ENDIAN, + UTF16_BIG_ENDIAN +}; + /* nls.c */ extern int register_nls(struct nls_table *); extern int unregister_nls(struct nls_table *); @@ -28,10 +50,11 @@ extern struct nls_table *load_nls(char *); extern void unload_nls(struct nls_table *); extern struct nls_table *load_nls_default(void); -extern int utf8_mbtowc(wchar_t *, const __u8 *, int); -extern int utf8_mbstowcs(wchar_t *, const __u8 *, int); -extern int utf8_wctomb(__u8 *, wchar_t, int); -extern int utf8_wcstombs(__u8 *, const wchar_t *, int); +extern int utf8_to_utf32(const u8 *s, int len, unicode_t *pu); +extern int utf32_to_utf8(unicode_t u, u8 *s, int maxlen); +extern int utf8s_to_utf16s(const u8 *s, int len, wchar_t *pwcs); +extern int utf16s_to_utf8s(const wchar_t *pwcs, int len, + enum utf16_endian endian, u8 *s, int maxlen); static inline unsigned char nls_tolower(struct nls_table *t, unsigned char c) { diff --git a/include/linux/nodemask.h b/include/linux/nodemask.h index 848025cd708..829b94b156f 100644 --- a/include/linux/nodemask.h +++ b/include/linux/nodemask.h @@ -408,6 +408,19 @@ static inline int num_node_state(enum node_states state) #define next_online_node(nid) next_node((nid), node_states[N_ONLINE]) extern int nr_node_ids; +extern int nr_online_nodes; + +static inline void node_set_online(int nid) +{ + node_set_state(nid, N_ONLINE); + nr_online_nodes = num_node_state(N_ONLINE); +} + +static inline void node_set_offline(int nid) +{ + node_clear_state(nid, N_ONLINE); + nr_online_nodes = num_node_state(N_ONLINE); +} #else static inline int node_state(int node, enum node_states state) @@ -434,7 +447,10 @@ static inline int num_node_state(enum node_states state) #define first_online_node 0 #define next_online_node(nid) (MAX_NUMNODES) #define nr_node_ids 1 +#define nr_online_nodes 1 +#define node_set_online(node) node_set_state((node), N_ONLINE) +#define node_set_offline(node) node_clear_state((node), N_ONLINE) #endif #define node_online_map node_states[N_ONLINE] @@ -454,9 +470,6 @@ static inline int num_node_state(enum node_states state) #define node_online(node) node_state((node), N_ONLINE) #define node_possible(node) node_state((node), N_POSSIBLE) -#define node_set_online(node) node_set_state((node), N_ONLINE) -#define node_set_offline(node) node_clear_state((node), N_ONLINE) - #define for_each_node(node) for_each_node_state(node, N_POSSIBLE) #define for_each_online_node(node) for_each_node_state(node, N_ONLINE) diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h index 62214c7d2d9..d6792f88a17 100644 --- a/include/linux/page-flags.h +++ b/include/linux/page-flags.h @@ -95,9 +95,7 @@ enum pageflags { PG_reclaim, /* To be reclaimed asap */ PG_buddy, /* Page is free, on buddy lists */ PG_swapbacked, /* Page is backed by RAM/swap */ -#ifdef CONFIG_UNEVICTABLE_LRU PG_unevictable, /* Page is "unevictable" */ -#endif #ifdef CONFIG_HAVE_MLOCKED_PAGE_BIT PG_mlocked, /* Page is vma mlocked */ #endif @@ -248,14 +246,8 @@ PAGEFLAG_FALSE(SwapCache) SETPAGEFLAG_NOOP(SwapCache) CLEARPAGEFLAG_NOOP(SwapCache) #endif -#ifdef CONFIG_UNEVICTABLE_LRU PAGEFLAG(Unevictable, unevictable) __CLEARPAGEFLAG(Unevictable, unevictable) TESTCLEARFLAG(Unevictable, unevictable) -#else -PAGEFLAG_FALSE(Unevictable) TESTCLEARFLAG_FALSE(Unevictable) - SETPAGEFLAG_NOOP(Unevictable) CLEARPAGEFLAG_NOOP(Unevictable) - __CLEARPAGEFLAG_NOOP(Unevictable) -#endif #ifdef CONFIG_HAVE_MLOCKED_PAGE_BIT #define MLOCK_PAGES 1 @@ -382,12 +374,6 @@ static inline void __ClearPageTail(struct page *page) #endif /* !PAGEFLAGS_EXTENDED */ -#ifdef CONFIG_UNEVICTABLE_LRU -#define __PG_UNEVICTABLE (1 << PG_unevictable) -#else -#define __PG_UNEVICTABLE 0 -#endif - #ifdef CONFIG_HAVE_MLOCKED_PAGE_BIT #define __PG_MLOCKED (1 << PG_mlocked) #else @@ -403,7 +389,7 @@ static inline void __ClearPageTail(struct page *page) 1 << PG_private | 1 << PG_private_2 | \ 1 << PG_buddy | 1 << PG_writeback | 1 << PG_reserved | \ 1 << PG_slab | 1 << PG_swapcache | 1 << PG_active | \ - __PG_UNEVICTABLE | __PG_MLOCKED) + 1 << PG_unevictable | __PG_MLOCKED) /* * Flags checked when a page is prepped for return by the page allocator. diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index 34da5230faa..aec3252afcf 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h @@ -22,9 +22,7 @@ enum mapping_flags { AS_EIO = __GFP_BITS_SHIFT + 0, /* IO error on async write */ AS_ENOSPC = __GFP_BITS_SHIFT + 1, /* ENOSPC on async write */ AS_MM_ALL_LOCKS = __GFP_BITS_SHIFT + 2, /* under mm_take_all_locks() */ -#ifdef CONFIG_UNEVICTABLE_LRU AS_UNEVICTABLE = __GFP_BITS_SHIFT + 3, /* e.g., ramdisk, SHM_LOCK */ -#endif }; static inline void mapping_set_error(struct address_space *mapping, int error) @@ -37,8 +35,6 @@ static inline void mapping_set_error(struct address_space *mapping, int error) } } -#ifdef CONFIG_UNEVICTABLE_LRU - static inline void mapping_set_unevictable(struct address_space *mapping) { set_bit(AS_UNEVICTABLE, &mapping->flags); @@ -55,14 +51,6 @@ static inline int mapping_unevictable(struct address_space *mapping) return test_bit(AS_UNEVICTABLE, &mapping->flags); return !!mapping; } -#else -static inline void mapping_set_unevictable(struct address_space *mapping) { } -static inline void mapping_clear_unevictable(struct address_space *mapping) { } -static inline int mapping_unevictable(struct address_space *mapping) -{ - return 0; -} -#endif static inline gfp_t mapping_gfp_mask(struct address_space * mapping) { diff --git a/include/linux/pci.h b/include/linux/pci.h index 72698d89e76..8e366bb0705 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -124,6 +124,14 @@ typedef int __bitwise pci_power_t; #define PCI_UNKNOWN ((pci_power_t __force) 5) #define PCI_POWER_ERROR ((pci_power_t __force) -1) +/* Remember to update this when the list above changes! */ +extern const char *pci_power_names[]; + +static inline const char *pci_power_name(pci_power_t state) +{ + return pci_power_names[1 + (int) state]; +} + #define PCI_PM_D2_DELAY 200 #define PCI_PM_D3_WAIT 10 #define PCI_PM_BUS_WAIT 50 diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index aa01d38c997..a3b00036579 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -104,6 +104,7 @@ #define PCI_CLASS_SERIAL_USB_UHCI 0x0c0300 #define PCI_CLASS_SERIAL_USB_OHCI 0x0c0310 #define PCI_CLASS_SERIAL_USB_EHCI 0x0c0320 +#define PCI_CLASS_SERIAL_USB_XHCI 0x0c0330 #define PCI_CLASS_SERIAL_FIBER 0x0c04 #define PCI_CLASS_SERIAL_SMBUS 0x0c05 diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h index b67bb5d7b22..8dc5123b630 100644 --- a/include/linux/platform_device.h +++ b/include/linux/platform_device.h @@ -36,8 +36,8 @@ extern struct device platform_bus; extern struct resource *platform_get_resource(struct platform_device *, unsigned int, unsigned int); extern int platform_get_irq(struct platform_device *, unsigned int); -extern struct resource *platform_get_resource_byname(struct platform_device *, unsigned int, char *); -extern int platform_get_irq_byname(struct platform_device *, char *); +extern struct resource *platform_get_resource_byname(struct platform_device *, unsigned int, const char *); +extern int platform_get_irq_byname(struct platform_device *, const char *); extern int platform_add_devices(struct platform_device **, int); extern struct platform_device *platform_device_register_simple(const char *, int id, diff --git a/include/linux/poll.h b/include/linux/poll.h index 8c24ef8d997..fa287f25138 100644 --- a/include/linux/poll.h +++ b/include/linux/poll.h @@ -32,6 +32,7 @@ typedef void (*poll_queue_proc)(struct file *, wait_queue_head_t *, struct poll_ typedef struct poll_table_struct { poll_queue_proc qproc; + unsigned long key; } poll_table; static inline void poll_wait(struct file * filp, wait_queue_head_t * wait_address, poll_table *p) @@ -43,10 +44,12 @@ static inline void poll_wait(struct file * filp, wait_queue_head_t * wait_addres static inline void init_poll_funcptr(poll_table *pt, poll_queue_proc qproc) { pt->qproc = qproc; + pt->key = ~0UL; /* all events enabled */ } struct poll_table_entry { struct file *filp; + unsigned long key; wait_queue_t wait; wait_queue_head_t *wait_address; }; diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h index 355f6e80db0..c5da7491809 100644 --- a/include/linux/radix-tree.h +++ b/include/linux/radix-tree.h @@ -167,6 +167,8 @@ radix_tree_gang_lookup_slot(struct radix_tree_root *root, void ***results, unsigned long first_index, unsigned int max_items); unsigned long radix_tree_next_hole(struct radix_tree_root *root, unsigned long index, unsigned long max_scan); +unsigned long radix_tree_prev_hole(struct radix_tree_root *root, + unsigned long index, unsigned long max_scan); int radix_tree_preload(gfp_t gfp_mask); void radix_tree_init(void); void *radix_tree_tag_set(struct radix_tree_root *root, diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h index 8670f1575fe..29f8599e6be 100644 --- a/include/linux/ring_buffer.h +++ b/include/linux/ring_buffer.h @@ -1,6 +1,7 @@ #ifndef _LINUX_RING_BUFFER_H #define _LINUX_RING_BUFFER_H +#include <linux/kmemcheck.h> #include <linux/mm.h> #include <linux/seq_file.h> @@ -11,7 +12,10 @@ struct ring_buffer_iter; * Don't refer to this struct directly, use functions below. */ struct ring_buffer_event { + kmemcheck_bitfield_begin(bitfield); u32 type_len:5, time_delta:27; + kmemcheck_bitfield_end(bitfield); + u32 array[]; }; diff --git a/include/linux/rmap.h b/include/linux/rmap.h index b35bc0e19cd..216d024f830 100644 --- a/include/linux/rmap.h +++ b/include/linux/rmap.h @@ -83,7 +83,8 @@ static inline void page_dup_rmap(struct page *page, struct vm_area_struct *vma, /* * Called from mm/vmscan.c to handle paging out */ -int page_referenced(struct page *, int is_locked, struct mem_cgroup *cnt); +int page_referenced(struct page *, int is_locked, + struct mem_cgroup *cnt, unsigned long *vm_flags); int try_to_unmap(struct page *, int ignore_refs); /* @@ -105,18 +106,11 @@ unsigned long page_address_in_vma(struct page *, struct vm_area_struct *); */ int page_mkclean(struct page *); -#ifdef CONFIG_UNEVICTABLE_LRU /* * called in munlock()/munmap() path to check for other vmas holding * the page mlocked. */ int try_to_munlock(struct page *); -#else -static inline int try_to_munlock(struct page *page) -{ - return 0; /* a.k.a. SWAP_SUCCESS */ -} -#endif #else /* !CONFIG_MMU */ @@ -124,7 +118,7 @@ static inline int try_to_munlock(struct page *page) #define anon_vma_prepare(vma) (0) #define anon_vma_link(vma) do {} while (0) -#define page_referenced(page,l,cnt) TestClearPageReferenced(page) +#define page_referenced(page, locked, cnt, flags) TestClearPageReferenced(page) #define try_to_unmap(page, refs) SWAP_FAIL static inline int page_mkclean(struct page *page) diff --git a/include/linux/sched.h b/include/linux/sched.h index c900aa53007..02042e7f219 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -674,7 +674,7 @@ struct user_struct { struct task_group *tg; #ifdef CONFIG_SYSFS struct kobject kobj; - struct work_struct work; + struct delayed_work work; #endif #endif @@ -1178,7 +1178,6 @@ struct task_struct { * a short time */ unsigned char fpu_counter; - s8 oomkilladj; /* OOM kill score adjustment (bit shift). */ #ifdef CONFIG_BLK_DEV_IO_TRACE unsigned int btrace_seq; #endif @@ -1318,7 +1317,8 @@ struct task_struct { /* Thread group tracking */ u32 parent_exec_id; u32 self_exec_id; -/* Protection of (de-)allocation: mm, files, fs, tty, keyrings */ +/* Protection of (de-)allocation: mm, files, fs, tty, keyrings, mems_allowed, + * mempolicy */ spinlock_t alloc_lock; #ifdef CONFIG_GENERIC_HARDIRQS @@ -1386,8 +1386,7 @@ struct task_struct { cputime_t acct_timexpd; /* stime + utime since last update */ #endif #ifdef CONFIG_CPUSETS - nodemask_t mems_allowed; - int cpuset_mems_generation; + nodemask_t mems_allowed; /* Protected by alloc_lock */ int cpuset_mem_spread_rotor; #endif #ifdef CONFIG_CGROUPS @@ -1410,7 +1409,7 @@ struct task_struct { struct list_head perf_counter_list; #endif #ifdef CONFIG_NUMA - struct mempolicy *mempolicy; + struct mempolicy *mempolicy; /* Protected by alloc_lock */ short il_next; #endif atomic_t fs_excl; /* holding fs exclusive resources */ diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index fa51293f270..63ef24bc01d 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -15,6 +15,7 @@ #define _LINUX_SKBUFF_H #include <linux/kernel.h> +#include <linux/kmemcheck.h> #include <linux/compiler.h> #include <linux/time.h> #include <linux/cache.h> @@ -343,6 +344,7 @@ struct sk_buff { }; }; __u32 priority; + kmemcheck_bitfield_begin(flags1); __u8 local_df:1, cloned:1, ip_summed:2, @@ -353,6 +355,7 @@ struct sk_buff { ipvs_property:1, peeked:1, nf_trace:1; + kmemcheck_bitfield_end(flags1); __be16 protocol; void (*destructor)(struct sk_buff *skb); @@ -372,12 +375,16 @@ struct sk_buff { __u16 tc_verd; /* traffic control verdict */ #endif #endif + + kmemcheck_bitfield_begin(flags2); #ifdef CONFIG_IPV6_NDISC_NODETYPE __u8 ndisc_nodetype:2; #endif #if defined(CONFIG_MAC80211) || defined(CONFIG_MAC80211_MODULE) __u8 do_not_encrypt:1; #endif + kmemcheck_bitfield_end(flags2); + /* 0/13/14 bit hole */ #ifdef CONFIG_NET_DMA diff --git a/include/linux/slab.h b/include/linux/slab.h index 219b8fb4651..2da8372519f 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -64,6 +64,13 @@ #define SLAB_NOLEAKTRACE 0x00800000UL /* Avoid kmemleak tracing */ +/* Don't track use of uninitialized memory */ +#ifdef CONFIG_KMEMCHECK +# define SLAB_NOTRACK 0x01000000UL +#else +# define SLAB_NOTRACK 0x00000000UL +#endif + /* The following flags affect the page allocator grouping pages by mobility */ #define SLAB_RECLAIM_ACCOUNT 0x00020000UL /* Objects are reclaimable */ #define SLAB_TEMPORARY SLAB_RECLAIM_ACCOUNT /* Objects are short-lived */ diff --git a/include/linux/slab_def.h b/include/linux/slab_def.h index 713f841ecaa..850d057500d 100644 --- a/include/linux/slab_def.h +++ b/include/linux/slab_def.h @@ -16,6 +16,87 @@ #include <linux/compiler.h> #include <linux/kmemtrace.h> +/* + * struct kmem_cache + * + * manages a cache. + */ + +struct kmem_cache { +/* 1) per-cpu data, touched during every alloc/free */ + struct array_cache *array[NR_CPUS]; +/* 2) Cache tunables. Protected by cache_chain_mutex */ + unsigned int batchcount; + unsigned int limit; + unsigned int shared; + + unsigned int buffer_size; + u32 reciprocal_buffer_size; +/* 3) touched by every alloc & free from the backend */ + + unsigned int flags; /* constant flags */ + unsigned int num; /* # of objs per slab */ + +/* 4) cache_grow/shrink */ + /* order of pgs per slab (2^n) */ + unsigned int gfporder; + + /* force GFP flags, e.g. GFP_DMA */ + gfp_t gfpflags; + + size_t colour; /* cache colouring range */ + unsigned int colour_off; /* colour offset */ + struct kmem_cache *slabp_cache; + unsigned int slab_size; + unsigned int dflags; /* dynamic flags */ + + /* constructor func */ + void (*ctor)(void *obj); + +/* 5) cache creation/removal */ + const char *name; + struct list_head next; + +/* 6) statistics */ +#ifdef CONFIG_DEBUG_SLAB + unsigned long num_active; + unsigned long num_allocations; + unsigned long high_mark; + unsigned long grown; + unsigned long reaped; + unsigned long errors; + unsigned long max_freeable; + unsigned long node_allocs; + unsigned long node_frees; + unsigned long node_overflow; + atomic_t allochit; + atomic_t allocmiss; + atomic_t freehit; + atomic_t freemiss; + + /* + * If debugging is enabled, then the allocator can add additional + * fields and/or padding to every object. buffer_size contains the total + * object size including these internal fields, the following two + * variables contain the offset to the user object and its size. + */ + int obj_offset; + int obj_size; +#endif /* CONFIG_DEBUG_SLAB */ + + /* + * We put nodelists[] at the end of kmem_cache, because we want to size + * this array to nr_node_ids slots instead of MAX_NUMNODES + * (see kmem_cache_init()) + * We still use [MAX_NUMNODES] and not [1] or [0] because cache_cache + * is statically defined, so we reserve the max number of nodes. + */ + struct kmem_list3 *nodelists[MAX_NUMNODES]; + /* + * Do not add fields after nodelists[] + */ +}; + /* Size description struct for general caches. */ struct cache_sizes { size_t cs_size; diff --git a/include/linux/smp.h b/include/linux/smp.h index a69db820eed..9e3d8af0920 100644 --- a/include/linux/smp.h +++ b/include/linux/smp.h @@ -177,7 +177,6 @@ static inline void init_call_single_data(void) #define get_cpu() ({ preempt_disable(); smp_processor_id(); }) #define put_cpu() preempt_enable() -#define put_cpu_no_resched() preempt_enable_no_resched() /* * Callback to arch code if there's nosmp or maxcpus=0 on the diff --git a/include/linux/stacktrace.h b/include/linux/stacktrace.h index 1a8cecc4f38..51efbef38fb 100644 --- a/include/linux/stacktrace.h +++ b/include/linux/stacktrace.h @@ -4,6 +4,8 @@ struct task_struct; #ifdef CONFIG_STACKTRACE +struct task_struct; + struct stack_trace { unsigned int nr_entries, max_entries; unsigned long *entries; @@ -11,6 +13,7 @@ struct stack_trace { }; extern void save_stack_trace(struct stack_trace *trace); +extern void save_stack_trace_bp(struct stack_trace *trace, unsigned long bp); extern void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace); diff --git a/include/linux/swap.h b/include/linux/swap.h index d476aad3ff5..0cedf31af0b 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -129,9 +129,10 @@ enum { #define SWAP_CLUSTER_MAX 32 -#define SWAP_MAP_MAX 0x7fff -#define SWAP_MAP_BAD 0x8000 - +#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) /* * The in-memory structure used to track swap areas. */ @@ -235,7 +236,6 @@ static inline int zone_reclaim(struct zone *z, gfp_t mask, unsigned int order) } #endif -#ifdef CONFIG_UNEVICTABLE_LRU extern int page_evictable(struct page *page, struct vm_area_struct *vma); extern void scan_mapping_unevictable_pages(struct address_space *); @@ -244,24 +244,6 @@ extern int scan_unevictable_handler(struct ctl_table *, int, struct file *, void __user *, size_t *, loff_t *); extern int scan_unevictable_register_node(struct node *node); extern void scan_unevictable_unregister_node(struct node *node); -#else -static inline int page_evictable(struct page *page, - struct vm_area_struct *vma) -{ - return 1; -} - -static inline void scan_mapping_unevictable_pages(struct address_space *mapping) -{ -} - -static inline int scan_unevictable_register_node(struct node *node) -{ - return 0; -} - -static inline void scan_unevictable_unregister_node(struct node *node) { } -#endif extern int kswapd_run(int nid); @@ -274,7 +256,7 @@ extern void swap_unplug_io_fn(struct backing_dev_info *, struct page *); #ifdef CONFIG_SWAP /* linux/mm/page_io.c */ -extern int swap_readpage(struct file *, struct page *); +extern int swap_readpage(struct page *); extern int swap_writepage(struct page *page, struct writeback_control *wbc); extern void end_swap_bio_read(struct bio *bio, int err); @@ -300,9 +282,11 @@ 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 int swap_duplicate(swp_entry_t); +extern void swap_duplicate(swp_entry_t); +extern int swapcache_prepare(swp_entry_t); extern int valid_swaphandles(swp_entry_t, unsigned long *); 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); @@ -370,12 +354,20 @@ static inline void show_swap_cache_info(void) } #define free_swap_and_cache(swp) is_migration_entry(swp) -#define swap_duplicate(swp) is_migration_entry(swp) +#define swapcache_prepare(swp) is_migration_entry(swp) + +static inline void swap_duplicate(swp_entry_t swp) +{ +} static inline void swap_free(swp_entry_t swp) { } +static inline void swapcache_free(swp_entry_t swp, struct page *page) +{ +} + static inline struct page *swapin_readahead(swp_entry_t swp, gfp_t gfp_mask, struct vm_area_struct *vma, unsigned long addr) { diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 418d90f5eff..fa4242cdade 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -434,6 +434,7 @@ asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg); asmlinkage long sys_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg); #endif +asmlinkage long sys_pipe(int __user *fildes); asmlinkage long sys_pipe2(int __user *fildes, int flags); asmlinkage long sys_dup(unsigned int fildes); asmlinkage long sys_dup2(unsigned int oldfd, unsigned int newfd); @@ -751,8 +752,6 @@ asmlinkage long sys_pselect6(int, fd_set __user *, fd_set __user *, asmlinkage long sys_ppoll(struct pollfd __user *, unsigned int, struct timespec __user *, const sigset_t __user *, size_t); -asmlinkage long sys_pipe2(int __user *, int); -asmlinkage long sys_pipe(int __user *); int kernel_execve(const char *filename, char *const argv[], char *const envp[]); diff --git a/include/linux/timex.h b/include/linux/timex.h index 9910e3bd5b3..e6967d10d9e 100644 --- a/include/linux/timex.h +++ b/include/linux/timex.h @@ -280,6 +280,9 @@ extern int do_adjtimex(struct timex *); int read_current_timer(unsigned long *timer_val); +/* The clock frequency of the i8253/i8254 PIT */ +#define PIT_TICK_RATE 1193182ul + #endif /* KERNEL */ #endif /* LINUX_TIMEX_H */ diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h index 14df7e635d4..b9dc4ca0246 100644 --- a/include/linux/tracepoint.h +++ b/include/linux/tracepoint.h @@ -198,7 +198,7 @@ static inline void tracepoint_synchronize_unregister(void) * * This is how the trace record is structured and will * * be saved into the ring buffer. These are the fields * * that will be exposed to user-space in - * * /debug/tracing/events/<*>/format. + * * /sys/kernel/debug/tracing/events/<*>/format. * * * * The declared 'local variable' is called '__entry' * * @@ -258,7 +258,7 @@ static inline void tracepoint_synchronize_unregister(void) * tracepoint callback (this is used by programmatic plugins and * can also by used by generic instrumentation like SystemTap), and * it is also used to expose a structured trace record in - * /debug/tracing/events/. + * /sys/kernel/debug/tracing/events/. */ #define TRACE_EVENT(name, proto, args, struct, assign, print) \ diff --git a/include/linux/usb.h b/include/linux/usb.h index 3aa2cd1f8d0..84929e91403 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -36,6 +36,7 @@ struct wusb_dev; * - configs have one (often) or more interfaces; * - interfaces have one (usually) or more settings; * - each interface setting has zero or (usually) more endpoints. + * - a SuperSpeed endpoint has a companion descriptor * * And there might be other descriptors mixed in with those. * @@ -44,6 +45,19 @@ struct wusb_dev; struct ep_device; +/* For SS devices */ +/** + * struct usb_host_ss_ep_comp - Valid for SuperSpeed devices only + * @desc: endpoint companion descriptor, wMaxPacketSize in native byteorder + * @extra: descriptors following this endpoint companion descriptor + * @extralen: how many bytes of "extra" are valid + */ +struct usb_host_ss_ep_comp { + struct usb_ss_ep_comp_descriptor desc; + unsigned char *extra; /* Extra descriptors */ + int extralen; +}; + /** * struct usb_host_endpoint - host-side endpoint descriptor and queue * @desc: descriptor for this endpoint, wMaxPacketSize in native byteorder @@ -51,6 +65,7 @@ struct ep_device; * @hcpriv: for use by HCD; typically holds hardware dma queue head (QH) * with one or more transfer descriptors (TDs) per urb * @ep_dev: ep_device for sysfs info + * @ss_ep_comp: companion descriptor information for this endpoint * @extra: descriptors following this endpoint in the configuration * @extralen: how many bytes of "extra" are valid * @enabled: URBs may be submitted to this endpoint @@ -63,6 +78,7 @@ struct usb_host_endpoint { struct list_head urb_list; void *hcpriv; struct ep_device *ep_dev; /* For sysfs info */ + struct usb_host_ss_ep_comp *ss_ep_comp; /* For SS devices */ unsigned char *extra; /* Extra descriptors */ int extralen; @@ -336,7 +352,6 @@ struct usb_bus { #ifdef CONFIG_USB_DEVICEFS struct dentry *usbfs_dentry; /* usbfs dentry entry for the bus */ #endif - struct device *dev; /* device for this bus */ #if defined(CONFIG_USB_MON) || defined(CONFIG_USB_MON_MODULE) struct mon_bus *mon_bus; /* non-null when associated */ @@ -363,6 +378,7 @@ struct usb_tt; * struct usb_device - kernel's representation of a USB device * @devnum: device number; address on a USB bus * @devpath: device ID string for use in messages (e.g., /port/...) + * @route: tree topology hex string for use with xHCI * @state: device state: configured, not attached, etc. * @speed: device speed: high/full/low (or error) * @tt: Transaction Translator info; used with low/full speed dev, highspeed hub @@ -420,6 +436,7 @@ struct usb_tt; * @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. + * @slot_id: Slot ID assigned by xHCI * * Notes: * Usbcore drivers should not set usbdev->state directly. Instead use @@ -428,6 +445,7 @@ struct usb_tt; struct usb_device { int devnum; char devpath [16]; + u32 route; enum usb_device_state state; enum usb_device_speed speed; @@ -503,6 +521,7 @@ struct usb_device { unsigned skip_sys_resume:1; #endif struct wusb_dev *wusb_dev; + int slot_id; }; #define to_usb_device(d) container_of(d, struct usb_device, dev) @@ -869,6 +888,8 @@ struct usb_driver { * struct usb_device_driver - identifies USB device driver to usbcore * @name: The driver name should be unique among USB drivers, * and should normally be the same as the module name. + * @nodename: Callback to provide a naming hint for a possible + * device node to create. * @probe: Called to see if the driver is willing to manage a particular * device. If it is, probe returns zero and uses dev_set_drvdata() * to associate driver-specific data with the device. If unwilling @@ -912,6 +933,7 @@ extern struct bus_type usb_bus_type; */ struct usb_class_driver { char *name; + char *(*nodename)(struct device *dev); const struct file_operations *fops; int minor_base; }; @@ -1041,7 +1063,9 @@ typedef void (*usb_complete_t)(struct urb *); * @setup_dma: For control transfers with URB_NO_SETUP_DMA_MAP set, the * device driver has provided this DMA address for the setup packet. * The host controller driver should use this in preference to - * setup_packet. + * setup_packet, but the HCD may chose to ignore the address if it must + * copy the setup packet into internal structures. Therefore, setup_packet + * must always point to a valid buffer. * @start_frame: Returns the initial frame for isochronous transfers. * @number_of_packets: Lists the number of ISO transfer buffers. * @interval: Specifies the polling interval for interrupt or isochronous @@ -1177,6 +1201,8 @@ struct urb { unsigned int transfer_flags; /* (in) URB_SHORT_NOT_OK | ...*/ void *transfer_buffer; /* (in) associated data buffer */ dma_addr_t transfer_dma; /* (in) dma addr for transfer_buffer */ + struct usb_sg_request *sg; /* (in) scatter gather buffer list */ + int num_sgs; /* (in) number of entries in the sg list */ u32 transfer_buffer_length; /* (in) data buffer length */ u32 actual_length; /* (return) actual transfer length */ unsigned char *setup_packet; /* (in) setup packet (control only) */ @@ -1422,8 +1448,8 @@ struct usb_sg_request { int status; size_t bytes; - /* - * members below are private: to usbcore, + /* private: + * members below are private to usbcore, * and are not provided for driver access! */ spinlock_t lock; @@ -1558,6 +1584,9 @@ extern void usb_unregister_notify(struct notifier_block *nb); #define err(format, arg...) printk(KERN_ERR KBUILD_MODNAME ": " \ format "\n" , ## arg) +/* debugfs stuff */ +extern struct dentry *usb_debug_root; + #endif /* __KERNEL__ */ #endif diff --git a/include/linux/usb/audio.h b/include/linux/usb/audio.h index 8cb025fef63..b5744bc218a 100644 --- a/include/linux/usb/audio.h +++ b/include/linux/usb/audio.h @@ -24,10 +24,75 @@ #define USB_SUBCLASS_AUDIOCONTROL 0x01 #define USB_SUBCLASS_AUDIOSTREAMING 0x02 #define USB_SUBCLASS_MIDISTREAMING 0x03 +#define USB_SUBCLASS_VENDOR_SPEC 0xff +/* A.5 Audio Class-Specific AC interface Descriptor Subtypes*/ +#define HEADER 0x01 +#define INPUT_TERMINAL 0x02 +#define OUTPUT_TERMINAL 0x03 +#define MIXER_UNIT 0x04 +#define SELECTOR_UNIT 0x05 +#define FEATURE_UNIT 0x06 +#define PROCESSING_UNIT 0x07 +#define EXTENSION_UNIT 0x08 + +#define AS_GENERAL 0x01 +#define FORMAT_TYPE 0x02 +#define FORMAT_SPECIFIC 0x03 + +#define EP_GENERAL 0x01 + +#define MS_GENERAL 0x01 +#define MIDI_IN_JACK 0x02 +#define MIDI_OUT_JACK 0x03 + +/* endpoint attributes */ +#define EP_ATTR_MASK 0x0c +#define EP_ATTR_ASYNC 0x04 +#define EP_ATTR_ADAPTIVE 0x08 +#define EP_ATTR_SYNC 0x0c + +/* cs endpoint attributes */ +#define EP_CS_ATTR_SAMPLE_RATE 0x01 +#define EP_CS_ATTR_PITCH_CONTROL 0x02 +#define EP_CS_ATTR_FILL_MAX 0x80 + +/* Audio Class specific Request Codes */ +#define USB_AUDIO_SET_INTF 0x21 +#define USB_AUDIO_SET_ENDPOINT 0x22 +#define USB_AUDIO_GET_INTF 0xa1 +#define USB_AUDIO_GET_ENDPOINT 0xa2 + +#define SET_ 0x00 +#define GET_ 0x80 + +#define _CUR 0x1 +#define _MIN 0x2 +#define _MAX 0x3 +#define _RES 0x4 +#define _MEM 0x5 + +#define SET_CUR (SET_ | _CUR) +#define GET_CUR (GET_ | _CUR) +#define SET_MIN (SET_ | _MIN) +#define GET_MIN (GET_ | _MIN) +#define SET_MAX (SET_ | _MAX) +#define GET_MAX (GET_ | _MAX) +#define SET_RES (SET_ | _RES) +#define GET_RES (GET_ | _RES) +#define SET_MEM (SET_ | _MEM) +#define GET_MEM (GET_ | _MEM) + +#define GET_STAT 0xff + +#define USB_AC_TERMINAL_UNDEFINED 0x100 +#define USB_AC_TERMINAL_STREAMING 0x101 +#define USB_AC_TERMINAL_VENDOR_SPEC 0x1FF + +/* Terminal Control Selectors */ /* 4.3.2 Class-Specific AC Interface Descriptor */ struct usb_ac_header_descriptor { - __u8 bLength; /* 8+n */ + __u8 bLength; /* 8 + n */ __u8 bDescriptorType; /* USB_DT_CS_INTERFACE */ __u8 bDescriptorSubtype; /* USB_MS_HEADER */ __le16 bcdADC; /* 0x0100 */ @@ -36,7 +101,7 @@ struct usb_ac_header_descriptor { __u8 baInterfaceNr[]; /* [n] */ } __attribute__ ((packed)); -#define USB_DT_AC_HEADER_SIZE(n) (8+(n)) +#define USB_DT_AC_HEADER_SIZE(n) (8 + (n)) /* As above, but more useful for defining your own descriptors: */ #define DECLARE_USB_AC_HEADER_DESCRIPTOR(n) \ @@ -50,4 +115,200 @@ struct usb_ac_header_descriptor_##n { \ __u8 baInterfaceNr[n]; \ } __attribute__ ((packed)) +/* 4.3.2.1 Input Terminal Descriptor */ +struct usb_input_terminal_descriptor { + __u8 bLength; /* in bytes: 12 */ + __u8 bDescriptorType; /* CS_INTERFACE descriptor type */ + __u8 bDescriptorSubtype; /* INPUT_TERMINAL descriptor subtype */ + __u8 bTerminalID; /* Constant uniquely terminal ID */ + __le16 wTerminalType; /* USB Audio Terminal Types */ + __u8 bAssocTerminal; /* ID of the Output Terminal associated */ + __u8 bNrChannels; /* Number of logical output channels */ + __le16 wChannelConfig; + __u8 iChannelNames; + __u8 iTerminal; +} __attribute__ ((packed)); + +#define USB_DT_AC_INPUT_TERMINAL_SIZE 12 + +#define USB_AC_INPUT_TERMINAL_UNDEFINED 0x200 +#define USB_AC_INPUT_TERMINAL_MICROPHONE 0x201 +#define USB_AC_INPUT_TERMINAL_DESKTOP_MICROPHONE 0x202 +#define USB_AC_INPUT_TERMINAL_PERSONAL_MICROPHONE 0x203 +#define USB_AC_INPUT_TERMINAL_OMNI_DIR_MICROPHONE 0x204 +#define USB_AC_INPUT_TERMINAL_MICROPHONE_ARRAY 0x205 +#define USB_AC_INPUT_TERMINAL_PROC_MICROPHONE_ARRAY 0x206 + +/* 4.3.2.2 Output Terminal Descriptor */ +struct usb_output_terminal_descriptor { + __u8 bLength; /* in bytes: 9 */ + __u8 bDescriptorType; /* CS_INTERFACE descriptor type */ + __u8 bDescriptorSubtype; /* OUTPUT_TERMINAL descriptor subtype */ + __u8 bTerminalID; /* Constant uniquely terminal ID */ + __le16 wTerminalType; /* USB Audio Terminal Types */ + __u8 bAssocTerminal; /* ID of the Input Terminal associated */ + __u8 bSourceID; /* ID of the connected Unit or Terminal*/ + __u8 iTerminal; +} __attribute__ ((packed)); + +#define USB_DT_AC_OUTPUT_TERMINAL_SIZE 9 + +#define USB_AC_OUTPUT_TERMINAL_UNDEFINED 0x300 +#define USB_AC_OUTPUT_TERMINAL_SPEAKER 0x301 +#define USB_AC_OUTPUT_TERMINAL_HEADPHONES 0x302 +#define USB_AC_OUTPUT_TERMINAL_HEAD_MOUNTED_DISPLAY_AUDIO 0x303 +#define USB_AC_OUTPUT_TERMINAL_DESKTOP_SPEAKER 0x304 +#define USB_AC_OUTPUT_TERMINAL_ROOM_SPEAKER 0x305 +#define USB_AC_OUTPUT_TERMINAL_COMMUNICATION_SPEAKER 0x306 +#define USB_AC_OUTPUT_TERMINAL_LOW_FREQ_EFFECTS_SPEAKER 0x307 + +/* Set bControlSize = 2 as default setting */ +#define USB_DT_AC_FEATURE_UNIT_SIZE(ch) (7 + ((ch) + 1) * 2) + +/* As above, but more useful for defining your own descriptors: */ +#define DECLARE_USB_AC_FEATURE_UNIT_DESCRIPTOR(ch) \ +struct usb_ac_feature_unit_descriptor_##ch { \ + __u8 bLength; \ + __u8 bDescriptorType; \ + __u8 bDescriptorSubtype; \ + __u8 bUnitID; \ + __u8 bSourceID; \ + __u8 bControlSize; \ + __le16 bmaControls[ch + 1]; \ + __u8 iFeature; \ +} __attribute__ ((packed)) + +/* 4.5.2 Class-Specific AS Interface Descriptor */ +struct usb_as_header_descriptor { + __u8 bLength; /* in bytes: 7 */ + __u8 bDescriptorType; /* USB_DT_CS_INTERFACE */ + __u8 bDescriptorSubtype; /* AS_GENERAL */ + __u8 bTerminalLink; /* Terminal ID of connected Terminal */ + __u8 bDelay; /* Delay introduced by the data path */ + __le16 wFormatTag; /* The Audio Data Format */ +} __attribute__ ((packed)); + +#define USB_DT_AS_HEADER_SIZE 7 + +#define USB_AS_AUDIO_FORMAT_TYPE_I_UNDEFINED 0x0 +#define USB_AS_AUDIO_FORMAT_TYPE_I_PCM 0x1 +#define USB_AS_AUDIO_FORMAT_TYPE_I_PCM8 0x2 +#define USB_AS_AUDIO_FORMAT_TYPE_I_IEEE_FLOAT 0x3 +#define USB_AS_AUDIO_FORMAT_TYPE_I_ALAW 0x4 +#define USB_AS_AUDIO_FORMAT_TYPE_I_MULAW 0x5 + +struct usb_as_format_type_i_continuous_descriptor { + __u8 bLength; /* in bytes: 8 + (ns * 3) */ + __u8 bDescriptorType; /* USB_DT_CS_INTERFACE */ + __u8 bDescriptorSubtype; /* FORMAT_TYPE */ + __u8 bFormatType; /* FORMAT_TYPE_1 */ + __u8 bNrChannels; /* physical channels in the stream */ + __u8 bSubframeSize; /* */ + __u8 bBitResolution; + __u8 bSamFreqType; + __u8 tLowerSamFreq[3]; + __u8 tUpperSamFreq[3]; +} __attribute__ ((packed)); + +#define USB_AS_FORMAT_TYPE_I_CONTINUOUS_DESC_SIZE 14 + +struct usb_as_formate_type_i_discrete_descriptor { + __u8 bLength; /* in bytes: 8 + (ns * 3) */ + __u8 bDescriptorType; /* USB_DT_CS_INTERFACE */ + __u8 bDescriptorSubtype; /* FORMAT_TYPE */ + __u8 bFormatType; /* FORMAT_TYPE_1 */ + __u8 bNrChannels; /* physical channels in the stream */ + __u8 bSubframeSize; /* */ + __u8 bBitResolution; + __u8 bSamFreqType; + __u8 tSamFreq[][3]; +} __attribute__ ((packed)); + +#define DECLARE_USB_AS_FORMAT_TYPE_I_DISCRETE_DESC(n) \ +struct usb_as_formate_type_i_discrete_descriptor_##n { \ + __u8 bLength; \ + __u8 bDescriptorType; \ + __u8 bDescriptorSubtype; \ + __u8 bFormatType; \ + __u8 bNrChannels; \ + __u8 bSubframeSize; \ + __u8 bBitResolution; \ + __u8 bSamFreqType; \ + __u8 tSamFreq[n][3]; \ +} __attribute__ ((packed)) + +#define USB_AS_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(n) (8 + (n * 3)) + +#define USB_AS_FORMAT_TYPE_UNDEFINED 0x0 +#define USB_AS_FORMAT_TYPE_I 0x1 +#define USB_AS_FORMAT_TYPE_II 0x2 +#define USB_AS_FORMAT_TYPE_III 0x3 + +#define USB_AS_ENDPOINT_ASYNC (1 << 2) +#define USB_AS_ENDPOINT_ADAPTIVE (2 << 2) +#define USB_AS_ENDPOINT_SYNC (3 << 2) + +struct usb_as_iso_endpoint_descriptor { + __u8 bLength; /* in bytes: 7 */ + __u8 bDescriptorType; /* USB_DT_CS_ENDPOINT */ + __u8 bDescriptorSubtype; /* EP_GENERAL */ + __u8 bmAttributes; + __u8 bLockDelayUnits; + __le16 wLockDelay; +}; +#define USB_AS_ISO_ENDPOINT_DESC_SIZE 7 + +#define FU_CONTROL_UNDEFINED 0x00 +#define MUTE_CONTROL 0x01 +#define VOLUME_CONTROL 0x02 +#define BASS_CONTROL 0x03 +#define MID_CONTROL 0x04 +#define TREBLE_CONTROL 0x05 +#define GRAPHIC_EQUALIZER_CONTROL 0x06 +#define AUTOMATIC_GAIN_CONTROL 0x07 +#define DELAY_CONTROL 0x08 +#define BASS_BOOST_CONTROL 0x09 +#define LOUDNESS_CONTROL 0x0a + +#define FU_MUTE (1 << (MUTE_CONTROL - 1)) +#define FU_VOLUME (1 << (VOLUME_CONTROL - 1)) +#define FU_BASS (1 << (BASS_CONTROL - 1)) +#define FU_MID (1 << (MID_CONTROL - 1)) +#define FU_TREBLE (1 << (TREBLE_CONTROL - 1)) +#define FU_GRAPHIC_EQ (1 << (GRAPHIC_EQUALIZER_CONTROL - 1)) +#define FU_AUTO_GAIN (1 << (AUTOMATIC_GAIN_CONTROL - 1)) +#define FU_DELAY (1 << (DELAY_CONTROL - 1)) +#define FU_BASS_BOOST (1 << (BASS_BOOST_CONTROL - 1)) +#define FU_LOUDNESS (1 << (LOUDNESS_CONTROL - 1)) + +struct usb_audio_control { + struct list_head list; + const char *name; + u8 type; + int data[5]; + int (*set)(struct usb_audio_control *con, u8 cmd, int value); + int (*get)(struct usb_audio_control *con, u8 cmd); +}; + +static inline int generic_set_cmd(struct usb_audio_control *con, u8 cmd, int value) +{ + con->data[cmd] = value; + + return 0; +} + +static inline int generic_get_cmd(struct usb_audio_control *con, u8 cmd) +{ + return con->data[cmd]; +} + +struct usb_audio_control_selector { + struct list_head list; + struct list_head control; + u8 id; + const char *name; + u8 type; + struct usb_descriptor_header *desc; +}; + #endif /* __LINUX_USB_AUDIO_H */ diff --git a/include/linux/usb/ch9.h b/include/linux/usb/ch9.h index b145119a90d..93223638f70 100644 --- a/include/linux/usb/ch9.h +++ b/include/linux/usb/ch9.h @@ -191,6 +191,8 @@ struct usb_ctrlrequest { #define USB_DT_WIRE_ADAPTER 0x21 #define USB_DT_RPIPE 0x22 #define USB_DT_CS_RADIO_CONTROL 0x23 +/* From the USB 3.0 spec */ +#define USB_DT_SS_ENDPOINT_COMP 0x30 /* Conventional codes for class-specific descriptors. The convention is * defined in the USB "Common Class" Spec (3.11). Individual class specs @@ -535,6 +537,20 @@ static inline int usb_endpoint_is_isoc_out( /*-------------------------------------------------------------------------*/ +/* USB_DT_SS_ENDPOINT_COMP: SuperSpeed Endpoint Companion descriptor */ +struct usb_ss_ep_comp_descriptor { + __u8 bLength; + __u8 bDescriptorType; + + __u8 bMaxBurst; + __u8 bmAttributes; + __u16 wBytesPerInterval; +} __attribute__ ((packed)); + +#define USB_DT_SS_EP_COMP_SIZE 6 + +/*-------------------------------------------------------------------------*/ + /* USB_DT_DEVICE_QUALIFIER: Device Qualifier descriptor */ struct usb_qualifier_descriptor { __u8 bLength; @@ -752,6 +768,7 @@ enum usb_device_speed { USB_SPEED_LOW, USB_SPEED_FULL, /* usb 1.1 */ USB_SPEED_HIGH, /* usb 2.0 */ USB_SPEED_VARIABLE, /* wireless (usb 2.5) */ + USB_SPEED_SUPER, /* usb 3.0 */ }; enum usb_device_state { diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index acd7b0f06c8..4f6bb3d2160 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h @@ -124,6 +124,7 @@ struct usb_function { void (*suspend)(struct usb_function *); void (*resume)(struct usb_function *); + /* private: */ /* internals */ struct list_head list; }; @@ -219,6 +220,7 @@ struct usb_configuration { struct usb_composite_dev *cdev; + /* private: */ /* internals */ struct list_head list; struct list_head functions; @@ -321,6 +323,7 @@ struct usb_composite_dev { struct usb_configuration *config; + /* private: */ /* internals */ struct usb_device_descriptor desc; struct list_head configs; diff --git a/include/linux/usb/langwell_otg.h b/include/linux/usb/langwell_otg.h new file mode 100644 index 00000000000..e115ae6df1d --- /dev/null +++ b/include/linux/usb/langwell_otg.h @@ -0,0 +1,177 @@ +/* + * Intel Langwell USB OTG transceiver driver + * Copyright (C) 2008, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#ifndef __LANGWELL_OTG_H__ +#define __LANGWELL_OTG_H__ + +/* notify transceiver driver about OTG events */ +extern void langwell_update_transceiver(void); +/* HCD register bus driver */ +extern int langwell_register_host(struct pci_driver *host_driver); +/* HCD unregister bus driver */ +extern void langwell_unregister_host(struct pci_driver *host_driver); +/* DCD register bus driver */ +extern int langwell_register_peripheral(struct pci_driver *client_driver); +/* DCD unregister bus driver */ +extern void langwell_unregister_peripheral(struct pci_driver *client_driver); +/* No silent failure, output warning message */ +extern void langwell_otg_nsf_msg(unsigned long message); + +#define CI_USBCMD 0x30 +# define USBCMD_RST BIT(1) +# define USBCMD_RS BIT(0) +#define CI_USBSTS 0x34 +# define USBSTS_SLI BIT(8) +# define USBSTS_URI BIT(6) +# define USBSTS_PCI BIT(2) +#define CI_PORTSC1 0x74 +# define PORTSC_PP BIT(12) +# define PORTSC_LS (BIT(11) | BIT(10)) +# define PORTSC_SUSP BIT(7) +# define PORTSC_CCS BIT(0) +#define CI_HOSTPC1 0xb4 +# define HOSTPC1_PHCD BIT(22) +#define CI_OTGSC 0xf4 +# define OTGSC_DPIE BIT(30) +# define OTGSC_1MSE BIT(29) +# define OTGSC_BSEIE BIT(28) +# define OTGSC_BSVIE BIT(27) +# define OTGSC_ASVIE BIT(26) +# define OTGSC_AVVIE BIT(25) +# define OTGSC_IDIE BIT(24) +# define OTGSC_DPIS BIT(22) +# define OTGSC_1MSS BIT(21) +# define OTGSC_BSEIS BIT(20) +# define OTGSC_BSVIS BIT(19) +# define OTGSC_ASVIS BIT(18) +# define OTGSC_AVVIS BIT(17) +# define OTGSC_IDIS BIT(16) +# define OTGSC_DPS BIT(14) +# define OTGSC_1MST BIT(13) +# define OTGSC_BSE BIT(12) +# define OTGSC_BSV BIT(11) +# define OTGSC_ASV BIT(10) +# define OTGSC_AVV BIT(9) +# define OTGSC_ID BIT(8) +# define OTGSC_HABA BIT(7) +# define OTGSC_HADP BIT(6) +# define OTGSC_IDPU BIT(5) +# define OTGSC_DP BIT(4) +# define OTGSC_OT BIT(3) +# define OTGSC_HAAR BIT(2) +# define OTGSC_VC BIT(1) +# define OTGSC_VD BIT(0) +# define OTGSC_INTEN_MASK (0x7f << 24) +# define OTGSC_INTSTS_MASK (0x7f << 16) +#define CI_USBMODE 0xf8 +# define USBMODE_CM (BIT(1) | BIT(0)) +# define USBMODE_IDLE 0 +# define USBMODE_DEVICE 0x2 +# define USBMODE_HOST 0x3 + +#define INTR_DUMMY_MASK (USBSTS_SLI | USBSTS_URI | USBSTS_PCI) + +struct otg_hsm { + /* Input */ + int a_bus_resume; + int a_bus_suspend; + int a_conn; + int a_sess_vld; + int a_srp_det; + int a_vbus_vld; + int b_bus_resume; + int b_bus_suspend; + int b_conn; + int b_se0_srp; + int b_sess_end; + int b_sess_vld; + int id; + + /* Internal variables */ + int a_set_b_hnp_en; + int b_srp_done; + int b_hnp_enable; + + /* Timeout indicator for timers */ + int a_wait_vrise_tmout; + int a_wait_bcon_tmout; + int a_aidl_bdis_tmout; + int b_ase0_brst_tmout; + int b_bus_suspend_tmout; + int b_srp_res_tmout; + + /* Informative variables */ + int a_bus_drop; + int a_bus_req; + int a_clr_err; + int a_suspend_req; + int b_bus_req; + + /* Output */ + int drv_vbus; + int loc_conn; + int loc_sof; + + /* Others */ + int b_bus_suspend_vld; +}; + +#define TA_WAIT_VRISE 100 +#define TA_WAIT_BCON 30000 +#define TA_AIDL_BDIS 15000 +#define TB_ASE0_BRST 5000 +#define TB_SE0_SRP 2 +#define TB_SRP_RES 100 +#define TB_BUS_SUSPEND 500 + +struct langwell_otg_timer { + unsigned long expires; /* Number of count increase to timeout */ + unsigned long count; /* Tick counter */ + void (*function)(unsigned long); /* Timeout function */ + unsigned long data; /* Data passed to function */ + struct list_head list; +}; + +struct langwell_otg { + struct otg_transceiver otg; + struct otg_hsm hsm; + void __iomem *regs; + unsigned region; + struct pci_driver *host_ops; + struct pci_driver *client_ops; + struct pci_dev *pdev; + struct work_struct work; + struct workqueue_struct *qwork; + spinlock_t lock; + spinlock_t wq_lock; +}; + +static inline struct langwell_otg *otg_to_langwell(struct otg_transceiver *otg) +{ + return container_of(otg, struct langwell_otg, otg); +} + +#ifdef DEBUG +#define otg_dbg(fmt, args...) \ + printk(KERN_DEBUG fmt , ## args) +#else +#define otg_dbg(fmt, args...) \ + do { } while (0) +#endif /* DEBUG */ +#endif /* __LANGWELL_OTG_H__ */ diff --git a/include/linux/usb/langwell_udc.h b/include/linux/usb/langwell_udc.h new file mode 100644 index 00000000000..c949178a653 --- /dev/null +++ b/include/linux/usb/langwell_udc.h @@ -0,0 +1,310 @@ +/* + * Intel Langwell USB Device Controller driver + * Copyright (C) 2008-2009, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#ifndef __LANGWELL_UDC_H +#define __LANGWELL_UDC_H + + +/* MACRO defines */ +#define CAP_REG_OFFSET 0x0 +#define OP_REG_OFFSET 0x28 + +#define DMA_ADDR_INVALID (~(dma_addr_t)0) + +#define DQH_ALIGNMENT 2048 +#define DTD_ALIGNMENT 64 +#define DMA_BOUNDARY 4096 + +#define EP0_MAX_PKT_SIZE 64 +#define EP_DIR_IN 1 +#define EP_DIR_OUT 0 + +#define FLUSH_TIMEOUT 1000 +#define RESET_TIMEOUT 1000 +#define SETUPSTAT_TIMEOUT 100 +#define PRIME_TIMEOUT 100 + + +/* device memory space registers */ + +/* Capability Registers, BAR0 + CAP_REG_OFFSET */ +struct langwell_cap_regs { + /* offset: 0x0 */ + u8 caplength; /* offset of Operational Register */ + u8 _reserved3; + u16 hciversion; /* H: BCD encoding of host version */ + u32 hcsparams; /* H: host port steering logic capability */ + u32 hccparams; /* H: host multiple mode control capability */ +#define HCC_LEN BIT(17) /* Link power management (LPM) capability */ + u8 _reserved4[0x20-0xc]; + /* offset: 0x20 */ + u16 dciversion; /* BCD encoding of device version */ + u8 _reserved5[0x24-0x22]; + u32 dccparams; /* overall device controller capability */ +#define HOSTCAP BIT(8) /* host capable */ +#define DEVCAP BIT(7) /* device capable */ +#define DEN(d) \ + (((d)>>0)&0x1f) /* bits 4:0, device endpoint number */ +} __attribute__ ((packed)); + + +/* Operational Registers, BAR0 + OP_REG_OFFSET */ +struct langwell_op_regs { + /* offset: 0x28 */ + u32 extsts; +#define EXTS_TI1 BIT(4) /* general purpose timer interrupt 1 */ +#define EXTS_TI1TI0 BIT(3) /* general purpose timer interrupt 0 */ +#define EXTS_TI1UPI BIT(2) /* USB host periodic interrupt */ +#define EXTS_TI1UAI BIT(1) /* USB host asynchronous interrupt */ +#define EXTS_TI1NAKI BIT(0) /* NAK interrupt */ + u32 extintr; +#define EXTI_TIE1 BIT(4) /* general purpose timer interrupt enable 1 */ +#define EXTI_TIE0 BIT(3) /* general purpose timer interrupt enable 0 */ +#define EXTI_UPIE BIT(2) /* USB host periodic interrupt enable */ +#define EXTI_UAIE BIT(1) /* USB host asynchronous interrupt enable */ +#define EXTI_NAKE BIT(0) /* NAK interrupt enable */ + /* offset: 0x30 */ + u32 usbcmd; +#define CMD_HIRD(u) \ + (((u)>>24)&0xf) /* bits 27:24, host init resume duration */ +#define CMD_ITC(u) \ + (((u)>>16)&0xff) /* bits 23:16, interrupt threshold control */ +#define CMD_PPE BIT(15) /* per-port change events enable */ +#define CMD_ATDTW BIT(14) /* add dTD tripwire */ +#define CMD_SUTW BIT(13) /* setup tripwire */ +#define CMD_ASPE BIT(11) /* asynchronous schedule park mode enable */ +#define CMD_FS2 BIT(10) /* frame list size */ +#define CMD_ASP1 BIT(9) /* asynchronous schedule park mode count */ +#define CMD_ASP0 BIT(8) +#define CMD_LR BIT(7) /* light host/device controller reset */ +#define CMD_IAA BIT(6) /* interrupt on async advance doorbell */ +#define CMD_ASE BIT(5) /* asynchronous schedule enable */ +#define CMD_PSE BIT(4) /* periodic schedule enable */ +#define CMD_FS1 BIT(3) +#define CMD_FS0 BIT(2) +#define CMD_RST BIT(1) /* controller reset */ +#define CMD_RUNSTOP BIT(0) /* run/stop */ + u32 usbsts; +#define STS_PPCI(u) \ + (((u)>>16)&0xffff) /* bits 31:16, port-n change detect */ +#define STS_AS BIT(15) /* asynchronous schedule status */ +#define STS_PS BIT(14) /* periodic schedule status */ +#define STS_RCL BIT(13) /* reclamation */ +#define STS_HCH BIT(12) /* HC halted */ +#define STS_ULPII BIT(10) /* ULPI interrupt */ +#define STS_SLI BIT(8) /* DC suspend */ +#define STS_SRI BIT(7) /* SOF received */ +#define STS_URI BIT(6) /* USB reset received */ +#define STS_AAI BIT(5) /* interrupt on async advance */ +#define STS_SEI BIT(4) /* system error */ +#define STS_FRI BIT(3) /* frame list rollover */ +#define STS_PCI BIT(2) /* port change detect */ +#define STS_UEI BIT(1) /* USB error interrupt */ +#define STS_UI BIT(0) /* USB interrupt */ + u32 usbintr; +/* bits 31:16, per-port interrupt enable */ +#define INTR_PPCE(u) (((u)>>16)&0xffff) +#define INTR_ULPIE BIT(10) /* ULPI enable */ +#define INTR_SLE BIT(8) /* DC sleep/suspend enable */ +#define INTR_SRE BIT(7) /* SOF received enable */ +#define INTR_URE BIT(6) /* USB reset enable */ +#define INTR_AAE BIT(5) /* interrupt on async advance enable */ +#define INTR_SEE BIT(4) /* system error enable */ +#define INTR_FRE BIT(3) /* frame list rollover enable */ +#define INTR_PCE BIT(2) /* port change detect enable */ +#define INTR_UEE BIT(1) /* USB error interrupt enable */ +#define INTR_UE BIT(0) /* USB interrupt enable */ + u32 frindex; /* frame index */ +#define FRINDEX_MASK (0x3fff << 0) + u32 ctrldssegment; /* not used */ + u32 deviceaddr; +#define USBADR_SHIFT 25 +#define USBADR(d) \ + (((d)>>25)&0x7f) /* bits 31:25, device address */ +#define USBADR_MASK (0x7f << 25) +#define USBADRA BIT(24) /* device address advance */ + u32 endpointlistaddr;/* endpoint list top memory address */ +/* bits 31:11, endpoint list pointer */ +#define EPBASE(d) (((d)>>11)&0x1fffff) +#define ENDPOINTLISTADDR_MASK (0x1fffff << 11) + u32 ttctrl; /* H: TT operatin, not used */ + /* offset: 0x50 */ + u32 burstsize; /* burst size of data movement */ +#define TXPBURST(b) \ + (((b)>>8)&0xff) /* bits 15:8, TX burst length */ +#define RXPBURST(b) \ + (((b)>>0)&0xff) /* bits 7:0, RX burst length */ + u32 txfilltuning; /* TX tuning */ + u32 txttfilltuning; /* H: TX TT tuning */ + u32 ic_usb; /* control the IC_USB FS/LS transceiver */ + /* offset: 0x60 */ + u32 ulpi_viewport; /* indirect access to ULPI PHY */ +#define ULPIWU BIT(31) /* ULPI wakeup */ +#define ULPIRUN BIT(30) /* ULPI read/write run */ +#define ULPIRW BIT(29) /* ULPI read/write control */ +#define ULPISS BIT(27) /* ULPI sync state */ +#define ULPIPORT(u) \ + (((u)>>24)&7) /* bits 26:24, ULPI port number */ +#define ULPIADDR(u) \ + (((u)>>16)&0xff) /* bits 23:16, ULPI data address */ +#define ULPIDATRD(u) \ + (((u)>>8)&0xff) /* bits 15:8, ULPI data read */ +#define ULPIDATWR(u) \ + (((u)>>0)&0xff) /* bits 7:0, ULPI date write */ + u8 _reserved6[0x70-0x64]; + /* offset: 0x70 */ + u32 configflag; /* H: not used */ + u32 portsc1; /* port status */ +#define DA(p) \ + (((p)>>25)&0x7f) /* bits 31:25, device address */ +#define PORTS_SSTS (BIT(24) | BIT(23)) /* suspend status */ +#define PORTS_WKOC BIT(22) /* wake on over-current enable */ +#define PORTS_WKDS BIT(21) /* wake on disconnect enable */ +#define PORTS_WKCN BIT(20) /* wake on connect enable */ +#define PORTS_PTC(p) (((p)>>16)&0xf) /* bits 19:16, port test control */ +#define PORTS_PIC (BIT(15) | BIT(14)) /* port indicator control */ +#define PORTS_PO BIT(13) /* port owner */ +#define PORTS_PP BIT(12) /* port power */ +#define PORTS_LS (BIT(11) | BIT(10)) /* line status */ +#define PORTS_SLP BIT(9) /* suspend using L1 */ +#define PORTS_PR BIT(8) /* port reset */ +#define PORTS_SUSP BIT(7) /* suspend */ +#define PORTS_FPR BIT(6) /* force port resume */ +#define PORTS_OCC BIT(5) /* over-current change */ +#define PORTS_OCA BIT(4) /* over-current active */ +#define PORTS_PEC BIT(3) /* port enable/disable change */ +#define PORTS_PE BIT(2) /* port enable/disable */ +#define PORTS_CSC BIT(1) /* connect status change */ +#define PORTS_CCS BIT(0) /* current connect status */ + u8 _reserved7[0xb4-0x78]; + /* offset: 0xb4 */ + u32 devlc; /* control LPM and each USB port behavior */ +/* bits 31:29, parallel transceiver select */ +#define LPM_PTS(d) (((d)>>29)&7) +#define LPM_STS BIT(28) /* serial transceiver select */ +#define LPM_PTW BIT(27) /* parallel transceiver width */ +#define LPM_PSPD(d) (((d)>>25)&3) /* bits 26:25, port speed */ +#define LPM_PSPD_MASK (BIT(26) | BIT(25)) +#define LPM_SPEED_FULL 0 +#define LPM_SPEED_LOW 1 +#define LPM_SPEED_HIGH 2 +#define LPM_SRT BIT(24) /* shorten reset time */ +#define LPM_PFSC BIT(23) /* port force full speed connect */ +#define LPM_PHCD BIT(22) /* PHY low power suspend clock disable */ +#define LPM_STL BIT(16) /* STALL reply to LPM token */ +#define LPM_BA(d) \ + (((d)>>1)&0x7ff) /* bits 11:1, BmAttributes */ +#define LPM_NYT_ACK BIT(0) /* NYET/ACK reply to LPM token */ + u8 _reserved8[0xf4-0xb8]; + /* offset: 0xf4 */ + u32 otgsc; /* On-The-Go status and control */ +#define OTGSC_DPIE BIT(30) /* data pulse interrupt enable */ +#define OTGSC_MSE BIT(29) /* 1 ms timer interrupt enable */ +#define OTGSC_BSEIE BIT(28) /* B session end interrupt enable */ +#define OTGSC_BSVIE BIT(27) /* B session valid interrupt enable */ +#define OTGSC_ASVIE BIT(26) /* A session valid interrupt enable */ +#define OTGSC_AVVIE BIT(25) /* A VBUS valid interrupt enable */ +#define OTGSC_IDIE BIT(24) /* USB ID interrupt enable */ +#define OTGSC_DPIS BIT(22) /* data pulse interrupt status */ +#define OTGSC_MSS BIT(21) /* 1 ms timer interrupt status */ +#define OTGSC_BSEIS BIT(20) /* B session end interrupt status */ +#define OTGSC_BSVIS BIT(19) /* B session valid interrupt status */ +#define OTGSC_ASVIS BIT(18) /* A session valid interrupt status */ +#define OTGSC_AVVIS BIT(17) /* A VBUS valid interrupt status */ +#define OTGSC_IDIS BIT(16) /* USB ID interrupt status */ +#define OTGSC_DPS BIT(14) /* data bus pulsing status */ +#define OTGSC_MST BIT(13) /* 1 ms timer toggle */ +#define OTGSC_BSE BIT(12) /* B session end */ +#define OTGSC_BSV BIT(11) /* B session valid */ +#define OTGSC_ASV BIT(10) /* A session valid */ +#define OTGSC_AVV BIT(9) /* A VBUS valid */ +#define OTGSC_USBID BIT(8) /* USB ID */ +#define OTGSC_HABA BIT(7) /* hw assist B-disconnect to A-connect */ +#define OTGSC_HADP BIT(6) /* hw assist data pulse */ +#define OTGSC_IDPU BIT(5) /* ID pullup */ +#define OTGSC_DP BIT(4) /* data pulsing */ +#define OTGSC_OT BIT(3) /* OTG termination */ +#define OTGSC_HAAR BIT(2) /* hw assist auto reset */ +#define OTGSC_VC BIT(1) /* VBUS charge */ +#define OTGSC_VD BIT(0) /* VBUS discharge */ + u32 usbmode; +#define MODE_VBPS BIT(5) /* R/W VBUS power select */ +#define MODE_SDIS BIT(4) /* R/W stream disable mode */ +#define MODE_SLOM BIT(3) /* R/W setup lockout mode */ +#define MODE_ENSE BIT(2) /* endian select */ +#define MODE_CM(u) (((u)>>0)&3) /* bits 1:0, controller mode */ +#define MODE_IDLE 0 +#define MODE_DEVICE 2 +#define MODE_HOST 3 + u8 _reserved9[0x100-0xfc]; + /* offset: 0x100 */ + u32 endptnak; +#define EPTN(e) \ + (((e)>>16)&0xffff) /* bits 31:16, TX endpoint NAK */ +#define EPRN(e) \ + (((e)>>0)&0xffff) /* bits 15:0, RX endpoint NAK */ + u32 endptnaken; +#define EPTNE(e) \ + (((e)>>16)&0xffff) /* bits 31:16, TX endpoint NAK enable */ +#define EPRNE(e) \ + (((e)>>0)&0xffff) /* bits 15:0, RX endpoint NAK enable */ + u32 endptsetupstat; +#define SETUPSTAT_MASK (0xffff << 0) /* bits 15:0 */ +#define EP0SETUPSTAT_MASK 1 + u32 endptprime; +/* bits 31:16, prime endpoint transmit buffer */ +#define PETB(e) (((e)>>16)&0xffff) +/* bits 15:0, prime endpoint receive buffer */ +#define PERB(e) (((e)>>0)&0xffff) + /* offset: 0x110 */ + u32 endptflush; +/* bits 31:16, flush endpoint transmit buffer */ +#define FETB(e) (((e)>>16)&0xffff) +/* bits 15:0, flush endpoint receive buffer */ +#define FERB(e) (((e)>>0)&0xffff) + u32 endptstat; +/* bits 31:16, endpoint transmit buffer ready */ +#define ETBR(e) (((e)>>16)&0xffff) +/* bits 15:0, endpoint receive buffer ready */ +#define ERBR(e) (((e)>>0)&0xffff) + u32 endptcomplete; +/* bits 31:16, endpoint transmit complete event */ +#define ETCE(e) (((e)>>16)&0xffff) +/* bits 15:0, endpoint receive complete event */ +#define ERCE(e) (((e)>>0)&0xffff) + /* offset: 0x11c */ + u32 endptctrl[16]; +#define EPCTRL_TXE BIT(23) /* TX endpoint enable */ +#define EPCTRL_TXR BIT(22) /* TX data toggle reset */ +#define EPCTRL_TXI BIT(21) /* TX data toggle inhibit */ +#define EPCTRL_TXT(e) (((e)>>18)&3) /* bits 19:18, TX endpoint type */ +#define EPCTRL_TXT_SHIFT 18 +#define EPCTRL_TXD BIT(17) /* TX endpoint data source */ +#define EPCTRL_TXS BIT(16) /* TX endpoint STALL */ +#define EPCTRL_RXE BIT(7) /* RX endpoint enable */ +#define EPCTRL_RXR BIT(6) /* RX data toggle reset */ +#define EPCTRL_RXI BIT(5) /* RX data toggle inhibit */ +#define EPCTRL_RXT(e) (((e)>>2)&3) /* bits 3:2, RX endpoint type */ +#define EPCTRL_RXT_SHIFT 2 /* bits 19:18, TX endpoint type */ +#define EPCTRL_RXD BIT(1) /* RX endpoint data sink */ +#define EPCTRL_RXS BIT(0) /* RX endpoint STALL */ +} __attribute__ ((packed)); + +#endif /* __LANGWELL_UDC_H */ + diff --git a/include/linux/usb/otg.h b/include/linux/usb/otg.h index 1aaa826396a..2443c0e7a80 100644 --- a/include/linux/usb/otg.h +++ b/include/linux/usb/otg.h @@ -80,10 +80,10 @@ struct otg_transceiver { /* for board-specific init logic */ extern int otg_set_transceiver(struct otg_transceiver *); -#ifdef CONFIG_NOP_USB_XCEIV + +/* sometimes transceivers are accessed only through e.g. ULPI */ extern void usb_nop_xceiv_register(void); extern void usb_nop_xceiv_unregister(void); -#endif /* for usb host and peripheral controller drivers */ diff --git a/include/linux/usb/r8a66597.h b/include/linux/usb/r8a66597.h new file mode 100644 index 00000000000..e9f0384fa20 --- /dev/null +++ b/include/linux/usb/r8a66597.h @@ -0,0 +1,44 @@ +/* + * R8A66597 driver platform data + * + * Copyright (C) 2009 Renesas Solutions Corp. + * + * Author : Yoshihiro Shimoda <shimoda.yoshihiro@renesas.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; version 2 of the License. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __LINUX_USB_R8A66597_H +#define __LINUX_USB_R8A66597_H + +#define R8A66597_PLATDATA_XTAL_12MHZ 0x01 +#define R8A66597_PLATDATA_XTAL_24MHZ 0x02 +#define R8A66597_PLATDATA_XTAL_48MHZ 0x03 + +struct r8a66597_platdata { + /* This ops can controll port power instead of DVSTCTR register. */ + void (*port_power)(int port, int power); + + /* (external controller only) set R8A66597_PLATDATA_XTAL_nnMHZ */ + unsigned xtal:2; + + /* set one = 3.3V, set zero = 1.5V */ + unsigned vif:1; + + /* set one = big endian, set zero = little endian */ + unsigned endian:1; +}; +#endif + diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h index 8cdfed738fe..44801d26a37 100644 --- a/include/linux/usb/serial.h +++ b/include/linux/usb/serial.h @@ -15,6 +15,7 @@ #include <linux/kref.h> #include <linux/mutex.h> +#include <linux/sysrq.h> #define SERIAL_TTY_MAJOR 188 /* Nice legal number now */ #define SERIAL_TTY_MINORS 254 /* loads of devices :) */ @@ -26,6 +27,13 @@ /* parity check flag */ #define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) +enum port_dev_state { + PORT_UNREGISTERED, + PORT_REGISTERING, + PORT_REGISTERED, + PORT_UNREGISTERING, +}; + /** * usb_serial_port: structure for the specific ports of a device. * @serial: pointer back to the struct usb_serial owner of this port. @@ -91,12 +99,17 @@ struct usb_serial_port { int write_urb_busy; __u8 bulk_out_endpointAddress; + int tx_bytes_flight; + int urbs_in_flight; + wait_queue_head_t write_wait; struct work_struct work; char throttled; char throttle_req; char console; + unsigned long sysrq; /* sysrq timeout */ struct device dev; + enum port_dev_state dev_state; }; #define to_usb_serial_port(d) container_of(d, struct usb_serial_port, dev) @@ -181,8 +194,10 @@ static inline void usb_set_serial_data(struct usb_serial *serial, void *data) * This will be called when the struct usb_serial structure is fully set * set up. Do any local initialization of the device, or any private * memory structure allocation at this point in time. - * @shutdown: pointer to the driver's shutdown function. This will be - * called when the device is removed from the system. + * @disconnect: pointer to the driver's disconnect function. This will be + * called when the device is unplugged or unbound from the driver. + * @release: pointer to the driver's release function. This will be called + * when the usb_serial data structure is about to be destroyed. * @usb_driver: pointer to the struct usb_driver that controls this * device. This is necessary to allow dynamic ids to be added to * the driver from sysfs. @@ -207,12 +222,14 @@ struct usb_serial_driver { struct device_driver driver; struct usb_driver *usb_driver; struct usb_dynids dynids; + int max_in_flight_urbs; int (*probe)(struct usb_serial *serial, const struct usb_device_id *id); int (*attach)(struct usb_serial *serial); int (*calc_num_ports) (struct usb_serial *serial); - void (*shutdown)(struct usb_serial *serial); + void (*disconnect)(struct usb_serial *serial); + void (*release)(struct usb_serial *serial); int (*port_probe)(struct usb_serial_port *port); int (*port_remove)(struct usb_serial_port *port); @@ -294,9 +311,16 @@ extern void usb_serial_generic_read_bulk_callback(struct urb *urb); extern void usb_serial_generic_write_bulk_callback(struct urb *urb); extern void usb_serial_generic_throttle(struct tty_struct *tty); extern void usb_serial_generic_unthrottle(struct tty_struct *tty); -extern void usb_serial_generic_shutdown(struct usb_serial *serial); +extern void usb_serial_generic_disconnect(struct usb_serial *serial); +extern void usb_serial_generic_release(struct usb_serial *serial); extern int usb_serial_generic_register(int debug); extern void usb_serial_generic_deregister(void); +extern void usb_serial_generic_resubmit_read_urb(struct usb_serial_port *port, + gfp_t mem_flags); +extern int usb_serial_handle_sysrq_char(struct usb_serial_port *port, + unsigned int ch); +extern int usb_serial_handle_break(struct usb_serial_port *port); + extern int usb_serial_bus_register(struct usb_serial_driver *device); extern void usb_serial_bus_deregister(struct usb_serial_driver *device); diff --git a/include/linux/utsname.h b/include/linux/utsname.h index 11232676bff..3656b300de3 100644 --- a/include/linux/utsname.h +++ b/include/linux/utsname.h @@ -22,12 +22,12 @@ struct old_utsname { }; struct new_utsname { - char sysname[65]; - char nodename[65]; - char release[65]; - char version[65]; - char machine[65]; - char domainname[65]; + char sysname[__NEW_UTS_LEN + 1]; + char nodename[__NEW_UTS_LEN + 1]; + char release[__NEW_UTS_LEN + 1]; + char version[__NEW_UTS_LEN + 1]; + char machine[__NEW_UTS_LEN + 1]; + char domainname[__NEW_UTS_LEN + 1]; }; #ifdef __KERNEL__ diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index ebb2ea6b499..f24eceecc5a 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -347,7 +347,8 @@ struct v4l2_pix_format { #define V4L2_PIX_FMT_MR97310A v4l2_fourcc('M', '3', '1', '0') /* compressed BGGR bayer */ #define V4L2_PIX_FMT_SQ905C v4l2_fourcc('9', '0', '5', 'C') /* compressed RGGB bayer */ #define V4L2_PIX_FMT_PJPG v4l2_fourcc('P', 'J', 'P', 'G') /* Pixart 73xx JPEG */ -#define V4L2_PIX_FMT_YVYU v4l2_fourcc('Y', 'V', 'Y', 'U') /* 16 YVU 4:2:2 */ +#define V4L2_PIX_FMT_YVYU v4l2_fourcc('Y', 'V', 'Y', 'U') /* 16 YVU 4:2:2 */ +#define V4L2_PIX_FMT_OV518 v4l2_fourcc('O', '5', '1', '8') /* ov518 JPEG */ /* * F O R M A T E N U M E R A T I O N diff --git a/include/linux/vlynq.h b/include/linux/vlynq.h new file mode 100644 index 00000000000..8f6a95882b0 --- /dev/null +++ b/include/linux/vlynq.h @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2006, 2007 Eugene Konev <ejka@openwrt.org> + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __VLYNQ_H__ +#define __VLYNQ_H__ + +#include <linux/device.h> +#include <linux/module.h> +#include <linux/types.h> + +#define VLYNQ_NUM_IRQS 32 + +struct vlynq_mapping { + u32 size; + u32 offset; +}; + +enum vlynq_divisor { + vlynq_div_auto = 0, + vlynq_ldiv1, + vlynq_ldiv2, + vlynq_ldiv3, + vlynq_ldiv4, + vlynq_ldiv5, + vlynq_ldiv6, + vlynq_ldiv7, + vlynq_ldiv8, + vlynq_rdiv1, + vlynq_rdiv2, + vlynq_rdiv3, + vlynq_rdiv4, + vlynq_rdiv5, + vlynq_rdiv6, + vlynq_rdiv7, + vlynq_rdiv8, + vlynq_div_external +}; + +struct vlynq_device_id { + u32 id; + enum vlynq_divisor divisor; + unsigned long driver_data; +}; + +struct vlynq_regs; +struct vlynq_device { + u32 id, dev_id; + int local_irq; + int remote_irq; + enum vlynq_divisor divisor; + u32 regs_start, regs_end; + u32 mem_start, mem_end; + u32 irq_start, irq_end; + int irq; + int enabled; + struct vlynq_regs *local; + struct vlynq_regs *remote; + struct device dev; +}; + +struct vlynq_driver { + char *name; + struct vlynq_device_id *id_table; + int (*probe)(struct vlynq_device *dev, struct vlynq_device_id *id); + void (*remove)(struct vlynq_device *dev); + struct device_driver driver; +}; + +struct plat_vlynq_ops { + int (*on)(struct vlynq_device *dev); + void (*off)(struct vlynq_device *dev); +}; + +static inline struct vlynq_driver *to_vlynq_driver(struct device_driver *drv) +{ + return container_of(drv, struct vlynq_driver, driver); +} + +static inline struct vlynq_device *to_vlynq_device(struct device *device) +{ + return container_of(device, struct vlynq_device, dev); +} + +extern struct bus_type vlynq_bus_type; + +extern int __vlynq_register_driver(struct vlynq_driver *driver, + struct module *owner); + +static inline int vlynq_register_driver(struct vlynq_driver *driver) +{ + return __vlynq_register_driver(driver, THIS_MODULE); +} + +static inline void *vlynq_get_drvdata(struct vlynq_device *dev) +{ + return dev_get_drvdata(&dev->dev); +} + +static inline void vlynq_set_drvdata(struct vlynq_device *dev, void *data) +{ + dev_set_drvdata(&dev->dev, data); +} + +static inline u32 vlynq_mem_start(struct vlynq_device *dev) +{ + return dev->mem_start; +} + +static inline u32 vlynq_mem_end(struct vlynq_device *dev) +{ + return dev->mem_end; +} + +static inline u32 vlynq_mem_len(struct vlynq_device *dev) +{ + return dev->mem_end - dev->mem_start + 1; +} + +static inline int vlynq_virq_to_irq(struct vlynq_device *dev, int virq) +{ + int irq = dev->irq_start + virq; + if ((irq < dev->irq_start) || (irq > dev->irq_end)) + return -EINVAL; + + return irq; +} + +static inline int vlynq_irq_to_virq(struct vlynq_device *dev, int irq) +{ + if ((irq < dev->irq_start) || (irq > dev->irq_end)) + return -EINVAL; + + return irq - dev->irq_start; +} + +extern void vlynq_unregister_driver(struct vlynq_driver *driver); +extern int vlynq_enable_device(struct vlynq_device *dev); +extern void vlynq_disable_device(struct vlynq_device *dev); +extern int vlynq_set_local_mapping(struct vlynq_device *dev, u32 tx_offset, + struct vlynq_mapping *mapping); +extern int vlynq_set_remote_mapping(struct vlynq_device *dev, u32 tx_offset, + struct vlynq_mapping *mapping); +extern int vlynq_set_local_irq(struct vlynq_device *dev, int virq); +extern int vlynq_set_remote_irq(struct vlynq_device *dev, int virq); + +#endif /* __VLYNQ_H__ */ diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h index 524cd1b28ec..81a97cf8f0a 100644 --- a/include/linux/vmstat.h +++ b/include/linux/vmstat.h @@ -36,12 +36,14 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT, FOR_ALL_ZONES(PGSTEAL), FOR_ALL_ZONES(PGSCAN_KSWAPD), FOR_ALL_ZONES(PGSCAN_DIRECT), +#ifdef CONFIG_NUMA + PGSCAN_ZONE_RECLAIM_FAILED, +#endif PGINODESTEAL, SLABS_SCANNED, KSWAPD_STEAL, KSWAPD_INODESTEAL, PAGEOUTRUN, ALLOCSTALL, PGROTATED, #ifdef CONFIG_HUGETLB_PAGE HTLB_BUDDY_PGALLOC, HTLB_BUDDY_PGALLOC_FAIL, #endif -#ifdef CONFIG_UNEVICTABLE_LRU UNEVICTABLE_PGCULLED, /* culled to noreclaim list */ UNEVICTABLE_PGSCANNED, /* scanned for reclaimability */ UNEVICTABLE_PGRESCUED, /* rescued from noreclaim list */ @@ -50,7 +52,6 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT, UNEVICTABLE_PGCLEARED, /* on COW, page truncate */ UNEVICTABLE_PGSTRANDED, /* unable to isolate on unlock */ UNEVICTABLE_MLOCKFREED, -#endif NR_VM_EVENT_ITEMS }; diff --git a/include/media/adv7343.h b/include/media/adv7343.h new file mode 100644 index 00000000000..d6f8a4e1a1f --- /dev/null +++ b/include/media/adv7343.h @@ -0,0 +1,23 @@ +/* + * ADV7343 header file + * + * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.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 version 2. + * + * This program is distributed .as is. WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef ADV7343_H +#define ADV7343_H + +#define ADV7343_COMPOSITE_ID (0) +#define ADV7343_COMPONENT_ID (1) +#define ADV7343_SVIDEO_ID (2) + +#endif /* End of #ifndef ADV7343_H */ diff --git a/include/media/ir-kbd-i2c.h b/include/media/ir-kbd-i2c.h index 07963d70540..3ad4ed5402f 100644 --- a/include/media/ir-kbd-i2c.h +++ b/include/media/ir-kbd-i2c.h @@ -7,7 +7,7 @@ struct IR_i2c; struct IR_i2c { IR_KEYTAB_TYPE *ir_codes; - struct i2c_client c; + struct i2c_client *c; struct input_dev *input; struct ir_input_state ir; @@ -15,7 +15,15 @@ struct IR_i2c { unsigned char old; struct delayed_work work; + char name[32]; char phys[32]; int (*get_key)(struct IR_i2c*, u32*, u32*); }; + +/* Can be passed when instantiating an ir_video i2c device */ +struct IR_i2c_init_data { + IR_KEYTAB_TYPE *ir_codes; + const char *name; + int (*get_key)(struct IR_i2c*, u32*, u32*); +}; #endif diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h index 37013688af4..23ecead35e7 100644 --- a/include/media/soc_camera.h +++ b/include/media/soc_camera.h @@ -60,7 +60,7 @@ struct soc_camera_file { struct soc_camera_host { struct list_head list; - struct device dev; + struct device *dev; unsigned char nr; /* Host number */ void *priv; const char *drv_name; @@ -92,11 +92,16 @@ struct soc_camera_host_ops { #define SOCAM_SENSOR_INVERT_VSYNC (1 << 3) #define SOCAM_SENSOR_INVERT_DATA (1 << 4) +struct i2c_board_info; + struct soc_camera_link { /* Camera bus id, used to match a camera and a bus */ int bus_id; /* Per camera SOCAM_SENSOR_* bus flags */ unsigned long flags; + int i2c_adapter_id; + struct i2c_board_info *board_info; + const char *module_name; /* Optional callbacks to power on or off and reset the sensor */ int (*power)(struct device *, int); int (*reset)(struct device *); @@ -107,6 +112,7 @@ struct soc_camera_link { */ int (*set_bus_param)(struct soc_camera_link *, unsigned long flags); unsigned long (*query_bus_param)(struct soc_camera_link *); + void (*free_bus)(struct soc_camera_link *); }; static inline struct soc_camera_device *to_soc_camera_dev(struct device *dev) @@ -116,7 +122,7 @@ static inline struct soc_camera_device *to_soc_camera_dev(struct device *dev) static inline struct soc_camera_host *to_soc_camera_host(struct device *dev) { - return container_of(dev, struct soc_camera_host, dev); + return dev_get_drvdata(dev); } extern int soc_camera_host_register(struct soc_camera_host *ici); diff --git a/include/media/tuner.h b/include/media/tuner.h index 7d4e2db7807..cbf97f45fbe 100644 --- a/include/media/tuner.h +++ b/include/media/tuner.h @@ -124,6 +124,8 @@ #define TUNER_XC5000 76 /* Xceive Silicon Tuner */ #define TUNER_TCL_MF02GIP_5N 77 /* TCL MF02GIP_5N */ #define TUNER_PHILIPS_FMD1216MEX_MK3 78 +#define TUNER_PHILIPS_FM1216MK5 79 +#define TUNER_PHILIPS_FQ1216LME_MK3 80 /* Active loopthrough, no FM */ /* tv card specific */ #define TDA9887_PRESENT (1<<0) diff --git a/include/media/v4l2-chip-ident.h b/include/media/v4l2-chip-ident.h index 1be461a2907..4d7e2272c42 100644 --- a/include/media/v4l2-chip-ident.h +++ b/include/media/v4l2-chip-ident.h @@ -137,6 +137,12 @@ enum { /* module saa7191: just ident 7191 */ V4L2_IDENT_SAA7191 = 7191, + /* module ths7303: just ident 7303 */ + V4L2_IDENT_THS7303 = 7303, + + /* module adv7343: just ident 7343 */ + V4L2_IDENT_ADV7343 = 7343, + /* module wm8739: just ident 8739 */ V4L2_IDENT_WM8739 = 8739, diff --git a/include/media/v4l2-device.h b/include/media/v4l2-device.h index 0dd3e8e8653..5d5d550e63a 100644 --- a/include/media/v4l2-device.h +++ b/include/media/v4l2-device.h @@ -30,7 +30,7 @@ basic V4L2 device-level support. */ -#define V4L2_DEVICE_NAME_SIZE (BUS_ID_SIZE + 16) +#define V4L2_DEVICE_NAME_SIZE (20 + 16) struct v4l2_device { /* dev->driver_data points to this struct. @@ -53,10 +53,31 @@ struct v4l2_device { dev may be NULL in rare cases (ISA devices). In that case you must fill in the v4l2_dev->name field before calling this function. */ int __must_check v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev); + +/* Optional function to initialize the name field of struct v4l2_device using + the driver name and a driver-global atomic_t instance. + This function will increment the instance counter and returns the instance + value used in the name. + + Example: + + static atomic_t drv_instance = ATOMIC_INIT(0); + + ... + + instance = v4l2_device_set_name(&v4l2_dev, "foo", &drv_instance); + + The first time this is called the name field will be set to foo0 and + this function returns 0. If the name ends with a digit (e.g. cx18), + then the name will be set to cx18-0 since cx180 looks really odd. */ +int v4l2_device_set_name(struct v4l2_device *v4l2_dev, const char *basename, + atomic_t *instance); + /* Set v4l2_dev->dev to NULL. Call when the USB parent disconnects. Since the parent disappears this ensures that v4l2_dev doesn't have an invalid parent pointer. */ void v4l2_device_disconnect(struct v4l2_device *v4l2_dev); + /* Unregister all sub-devices and any other resources related to v4l2_dev. */ void v4l2_device_unregister(struct v4l2_device *v4l2_dev); diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index 17856081c80..a503e1cee78 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -230,12 +230,16 @@ struct v4l2_subdev_ops { #define V4L2_SUBDEV_NAME_SIZE 32 +/* Set this flag if this subdev is a i2c device. */ +#define V4L2_SUBDEV_FL_IS_I2C (1U << 0) + /* Each instance of a subdev driver should create this struct, either stand-alone or embedded in a larger struct. */ struct v4l2_subdev { struct list_head list; struct module *owner; + u32 flags; struct v4l2_device *v4l2_dev; const struct v4l2_subdev_ops *ops; /* name must be unique */ @@ -264,6 +268,7 @@ static inline void v4l2_subdev_init(struct v4l2_subdev *sd, BUG_ON(!ops || !ops->core); sd->ops = ops; sd->v4l2_dev = NULL; + sd->flags = 0; sd->name[0] = '\0'; sd->grp_id = 0; sd->priv = NULL; diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h index 20a6957af87..47004f35cc7 100644 --- a/include/net/inet_sock.h +++ b/include/net/inet_sock.h @@ -17,6 +17,7 @@ #define _INET_SOCK_H +#include <linux/kmemcheck.h> #include <linux/string.h> #include <linux/types.h> #include <linux/jhash.h> @@ -66,14 +67,16 @@ struct inet_request_sock { __be32 loc_addr; __be32 rmt_addr; __be16 rmt_port; - u16 snd_wscale : 4, - rcv_wscale : 4, + kmemcheck_bitfield_begin(flags); + u16 snd_wscale : 4, + rcv_wscale : 4, tstamp_ok : 1, sack_ok : 1, wscale_ok : 1, ecn_ok : 1, acked : 1, no_srccheck: 1; + kmemcheck_bitfield_end(flags); struct ip_options *opt; }; @@ -199,9 +202,12 @@ static inline int inet_sk_ehashfn(const struct sock *sk) static inline struct request_sock *inet_reqsk_alloc(struct request_sock_ops *ops) { struct request_sock *req = reqsk_alloc(ops); + struct inet_request_sock *ireq = inet_rsk(req); - if (req != NULL) - inet_rsk(req)->opt = NULL; + if (req != NULL) { + kmemcheck_annotate_bitfield(ireq, flags); + ireq->opt = NULL; + } return req; } diff --git a/include/net/inet_timewait_sock.h b/include/net/inet_timewait_sock.h index 4b8ece22b8e..b63b80fac56 100644 --- a/include/net/inet_timewait_sock.h +++ b/include/net/inet_timewait_sock.h @@ -16,6 +16,7 @@ #define _INET_TIMEWAIT_SOCK_ +#include <linux/kmemcheck.h> #include <linux/list.h> #include <linux/module.h> #include <linux/timer.h> @@ -127,10 +128,12 @@ struct inet_timewait_sock { __be32 tw_rcv_saddr; __be16 tw_dport; __u16 tw_num; + kmemcheck_bitfield_begin(flags); /* And these are ours. */ __u8 tw_ipv6only:1, tw_transparent:1; - /* 15 bits hole, try to pack */ + /* 14 bits hole, try to pack */ + kmemcheck_bitfield_end(flags); __u16 tw_ipv6_offset; unsigned long tw_ttd; struct inet_bind_bucket *tw_tb; diff --git a/include/net/sock.h b/include/net/sock.h index 010e14a93c9..95bd3fd75f9 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -218,9 +218,11 @@ struct sock { #define sk_hash __sk_common.skc_hash #define sk_prot __sk_common.skc_prot #define sk_net __sk_common.skc_net + kmemcheck_bitfield_begin(flags); unsigned char sk_shutdown : 2, sk_no_check : 2, sk_userlocks : 4; + kmemcheck_bitfield_end(flags); unsigned char sk_protocol; unsigned short sk_type; int sk_rcvbuf; diff --git a/include/video/s1d13xxxfb.h b/include/video/s1d13xxxfb.h index c3b2a2aa714..f0736cff2ca 100644 --- a/include/video/s1d13xxxfb.h +++ b/include/video/s1d13xxxfb.h @@ -136,6 +136,15 @@ #define S1DREG_DELAYOFF 0xFFFE #define S1DREG_DELAYON 0xFFFF +#define BBLT_FIFO_EMPTY 0x00 +#define BBLT_FIFO_NOT_EMPTY 0x40 +#define BBLT_FIFO_NOT_FULL 0x30 +#define BBLT_FIFO_HALF_FULL 0x20 +#define BBLT_FIFO_FULL 0x10 + +#define BBLT_SOLID_FILL 0x0c + + /* Note: all above defines should go in separate header files when implementing other S1D13xxx chip support. */ |