From e7cb55b946a2182c347047dc903c6ed0daef100c Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Wed, 28 Oct 2009 13:33:08 +0000 Subject: kmemleak: Do not use off-slab management with SLAB_NOLEAKTRACE With the slab allocator, if off-slab management is enabled for the kmem_caches used by kmemleak, it leads to recursive calls into kmemleak_alloc(). Off-slab management can be triggered by other config options increasing the slab size, e.g. DEBUG_PAGEALLOC. Reported-by: Tetsuo Handa Reviewed-by: Pekka Enberg Cc: Christoph Lameter Signed-off-by: Catalin Marinas diff --git a/mm/slab.c b/mm/slab.c index 7dfa481..646db30 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -2261,9 +2261,11 @@ kmem_cache_create (const char *name, size_t size, size_t align, /* * Determine if the slab management is 'on' or 'off' slab. * (bootstrapping cannot cope with offslab caches so don't do - * it too early on.) + * it too early on. Always use on-slab management when + * SLAB_NOLEAKTRACE to avoid recursive calls into kmemleak) */ - if ((size >= (PAGE_SIZE >> 3)) && !slab_early_init) + if ((size >= (PAGE_SIZE >> 3)) && !slab_early_init && + !(flags & SLAB_NOLEAKTRACE)) /* * Size is large, assume best to place the slab management obj * off-slab (should allow better packing of objs). -- cgit v0.10.2 From c017b4be3e84176cab10eca5e6c4faeb8cfc6f3e Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Wed, 28 Oct 2009 13:33:09 +0000 Subject: kmemleak: Simplify the kmemleak_scan_area() function prototype This function was taking non-necessary arguments which can be determined by kmemleak. The patch also modifies the calling sites. Signed-off-by: Catalin Marinas Cc: Pekka Enberg Cc: Christoph Lameter Cc: Rusty Russell diff --git a/include/linux/kmemleak.h b/include/linux/kmemleak.h index 3c7497d..99d9a67 100644 --- a/include/linux/kmemleak.h +++ b/include/linux/kmemleak.h @@ -32,8 +32,7 @@ extern void kmemleak_padding(const void *ptr, unsigned long offset, size_t size) __ref; extern void kmemleak_not_leak(const void *ptr) __ref; extern void kmemleak_ignore(const void *ptr) __ref; -extern void kmemleak_scan_area(const void *ptr, unsigned long offset, - size_t length, gfp_t gfp) __ref; +extern void kmemleak_scan_area(const void *ptr, size_t size, gfp_t gfp) __ref; extern void kmemleak_no_scan(const void *ptr) __ref; static inline void kmemleak_alloc_recursive(const void *ptr, size_t size, @@ -84,8 +83,7 @@ static inline void kmemleak_not_leak(const void *ptr) static inline void kmemleak_ignore(const void *ptr) { } -static inline void kmemleak_scan_area(const void *ptr, unsigned long offset, - size_t length, gfp_t gfp) +static inline void kmemleak_scan_area(const void *ptr, size_t size, gfp_t gfp) { } static inline void kmemleak_erase(void **ptr) diff --git a/kernel/module.c b/kernel/module.c index 8b7d880..1eb9520 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -2043,9 +2043,7 @@ static void kmemleak_load_module(struct module *mod, Elf_Ehdr *hdr, unsigned int i; /* only scan the sections containing data */ - kmemleak_scan_area(mod->module_core, (unsigned long)mod - - (unsigned long)mod->module_core, - sizeof(struct module), GFP_KERNEL); + kmemleak_scan_area(mod, sizeof(struct module), GFP_KERNEL); for (i = 1; i < hdr->e_shnum; i++) { if (!(sechdrs[i].sh_flags & SHF_ALLOC)) @@ -2054,8 +2052,7 @@ static void kmemleak_load_module(struct module *mod, Elf_Ehdr *hdr, && strncmp(secstrings + sechdrs[i].sh_name, ".bss", 4) != 0) continue; - kmemleak_scan_area(mod->module_core, sechdrs[i].sh_addr - - (unsigned long)mod->module_core, + kmemleak_scan_area((void *)sechdrs[i].sh_addr, sechdrs[i].sh_size, GFP_KERNEL); } } diff --git a/mm/kmemleak.c b/mm/kmemleak.c index 8bf765c..9610635 100644 --- a/mm/kmemleak.c +++ b/mm/kmemleak.c @@ -119,8 +119,8 @@ /* scanning area inside a memory block */ struct kmemleak_scan_area { struct hlist_node node; - unsigned long offset; - size_t length; + unsigned long start; + size_t size; }; #define KMEMLEAK_GREY 0 @@ -241,8 +241,6 @@ struct early_log { const void *ptr; /* allocated/freed memory block */ size_t size; /* memory block size */ int min_count; /* minimum reference count */ - unsigned long offset; /* scan area offset */ - size_t length; /* scan area length */ unsigned long trace[MAX_TRACE]; /* stack trace */ unsigned int trace_len; /* stack trace length */ }; @@ -720,14 +718,13 @@ static void make_black_object(unsigned long ptr) * Add a scanning area to the object. If at least one such area is added, * kmemleak will only scan these ranges rather than the whole memory block. */ -static void add_scan_area(unsigned long ptr, unsigned long offset, - size_t length, gfp_t gfp) +static void add_scan_area(unsigned long ptr, size_t size, gfp_t gfp) { unsigned long flags; struct kmemleak_object *object; struct kmemleak_scan_area *area; - object = find_and_get_object(ptr, 0); + object = find_and_get_object(ptr, 1); if (!object) { kmemleak_warn("Adding scan area to unknown object at 0x%08lx\n", ptr); @@ -741,7 +738,7 @@ static void add_scan_area(unsigned long ptr, unsigned long offset, } spin_lock_irqsave(&object->lock, flags); - if (offset + length > object->size) { + if (ptr + size > object->pointer + object->size) { kmemleak_warn("Scan area larger than object 0x%08lx\n", ptr); dump_object_info(object); kmem_cache_free(scan_area_cache, area); @@ -749,8 +746,8 @@ static void add_scan_area(unsigned long ptr, unsigned long offset, } INIT_HLIST_NODE(&area->node); - area->offset = offset; - area->length = length; + area->start = ptr; + area->size = size; hlist_add_head(&area->node, &object->area_list); out_unlock: @@ -786,7 +783,7 @@ static void object_no_scan(unsigned long ptr) * processed later once kmemleak is fully initialized. */ static void __init log_early(int op_type, const void *ptr, size_t size, - int min_count, unsigned long offset, size_t length) + int min_count) { unsigned long flags; struct early_log *log; @@ -808,8 +805,6 @@ static void __init log_early(int op_type, const void *ptr, size_t size, log->ptr = ptr; log->size = size; log->min_count = min_count; - log->offset = offset; - log->length = length; if (op_type == KMEMLEAK_ALLOC) log->trace_len = __save_stack_trace(log->trace); crt_early_log++; @@ -858,7 +853,7 @@ void __ref kmemleak_alloc(const void *ptr, size_t size, int min_count, if (atomic_read(&kmemleak_enabled) && ptr && !IS_ERR(ptr)) create_object((unsigned long)ptr, size, min_count, gfp); else if (atomic_read(&kmemleak_early_log)) - log_early(KMEMLEAK_ALLOC, ptr, size, min_count, 0, 0); + log_early(KMEMLEAK_ALLOC, ptr, size, min_count); } EXPORT_SYMBOL_GPL(kmemleak_alloc); @@ -873,7 +868,7 @@ void __ref kmemleak_free(const void *ptr) if (atomic_read(&kmemleak_enabled) && ptr && !IS_ERR(ptr)) delete_object_full((unsigned long)ptr); else if (atomic_read(&kmemleak_early_log)) - log_early(KMEMLEAK_FREE, ptr, 0, 0, 0, 0); + log_early(KMEMLEAK_FREE, ptr, 0, 0); } EXPORT_SYMBOL_GPL(kmemleak_free); @@ -888,7 +883,7 @@ void __ref kmemleak_free_part(const void *ptr, size_t size) if (atomic_read(&kmemleak_enabled) && ptr && !IS_ERR(ptr)) delete_object_part((unsigned long)ptr, size); else if (atomic_read(&kmemleak_early_log)) - log_early(KMEMLEAK_FREE_PART, ptr, size, 0, 0, 0); + log_early(KMEMLEAK_FREE_PART, ptr, size, 0); } EXPORT_SYMBOL_GPL(kmemleak_free_part); @@ -903,7 +898,7 @@ void __ref kmemleak_not_leak(const void *ptr) if (atomic_read(&kmemleak_enabled) && ptr && !IS_ERR(ptr)) make_gray_object((unsigned long)ptr); else if (atomic_read(&kmemleak_early_log)) - log_early(KMEMLEAK_NOT_LEAK, ptr, 0, 0, 0, 0); + log_early(KMEMLEAK_NOT_LEAK, ptr, 0, 0); } EXPORT_SYMBOL(kmemleak_not_leak); @@ -919,22 +914,21 @@ void __ref kmemleak_ignore(const void *ptr) if (atomic_read(&kmemleak_enabled) && ptr && !IS_ERR(ptr)) make_black_object((unsigned long)ptr); else if (atomic_read(&kmemleak_early_log)) - log_early(KMEMLEAK_IGNORE, ptr, 0, 0, 0, 0); + log_early(KMEMLEAK_IGNORE, ptr, 0, 0); } EXPORT_SYMBOL(kmemleak_ignore); /* * Limit the range to be scanned in an allocated memory block. */ -void __ref kmemleak_scan_area(const void *ptr, unsigned long offset, - size_t length, gfp_t gfp) +void __ref kmemleak_scan_area(const void *ptr, size_t size, gfp_t gfp) { pr_debug("%s(0x%p)\n", __func__, ptr); if (atomic_read(&kmemleak_enabled) && ptr && !IS_ERR(ptr)) - add_scan_area((unsigned long)ptr, offset, length, gfp); + add_scan_area((unsigned long)ptr, size, gfp); else if (atomic_read(&kmemleak_early_log)) - log_early(KMEMLEAK_SCAN_AREA, ptr, 0, 0, offset, length); + log_early(KMEMLEAK_SCAN_AREA, ptr, size, 0); } EXPORT_SYMBOL(kmemleak_scan_area); @@ -948,7 +942,7 @@ void __ref kmemleak_no_scan(const void *ptr) if (atomic_read(&kmemleak_enabled) && ptr && !IS_ERR(ptr)) object_no_scan((unsigned long)ptr); else if (atomic_read(&kmemleak_early_log)) - log_early(KMEMLEAK_NO_SCAN, ptr, 0, 0, 0, 0); + log_early(KMEMLEAK_NO_SCAN, ptr, 0, 0); } EXPORT_SYMBOL(kmemleak_no_scan); @@ -1075,9 +1069,9 @@ static void scan_object(struct kmemleak_object *object) } } else hlist_for_each_entry(area, elem, &object->area_list, node) - scan_block((void *)(object->pointer + area->offset), - (void *)(object->pointer + area->offset - + area->length), object, 0); + scan_block((void *)area->start, + (void *)(area->start + area->size), + object, 0); out: spin_unlock_irqrestore(&object->lock, flags); } @@ -1642,8 +1636,7 @@ void __init kmemleak_init(void) kmemleak_ignore(log->ptr); break; case KMEMLEAK_SCAN_AREA: - kmemleak_scan_area(log->ptr, log->offset, log->length, - GFP_KERNEL); + kmemleak_scan_area(log->ptr, log->size, GFP_KERNEL); break; case KMEMLEAK_NO_SCAN: kmemleak_no_scan(log->ptr); diff --git a/mm/slab.c b/mm/slab.c index 646db30..d2713a9 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -2584,8 +2584,8 @@ static struct slab *alloc_slabmgmt(struct kmem_cache *cachep, void *objp, * kmemleak does not treat the ->s_mem pointer as a reference * to the object. Otherwise we will not report the leak. */ - kmemleak_scan_area(slabp, offsetof(struct slab, list), - sizeof(struct list_head), local_flags); + kmemleak_scan_area(&slabp->list, sizeof(struct list_head), + local_flags); if (!slabp) return NULL; } else { -- cgit v0.10.2 From a6f5aa1ea05686ad6e84593a00a04161e6dfb3a3 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Wed, 28 Oct 2009 13:33:10 +0000 Subject: kmemleak: Scan the _ftrace_events section in modules This section contains pointers to allocated objects and not scanning it leads to false positives. Reported-by: Zdenek Kabelac Acked-by: Rusty Russell Signed-off-by: Catalin Marinas diff --git a/kernel/module.c b/kernel/module.c index 1eb9520..dd29ba4 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -2380,6 +2380,12 @@ static noinline struct module *load_module(void __user *umod, "_ftrace_events", sizeof(*mod->trace_events), &mod->num_trace_events); + /* + * This section contains pointers to allocated objects in the trace + * code and not scanning it leads to false positives. + */ + kmemleak_scan_area(mod->trace_events, sizeof(*mod->trace_events) * + mod->num_trace_events, GFP_KERNEL); #endif #ifdef CONFIG_FTRACE_MCOUNT_RECORD /* sechdrs[0].sh_size is always zero */ -- cgit v0.10.2 From 0587da40be78d3704a48d3e9a619183891727f5f Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Wed, 28 Oct 2009 13:33:11 +0000 Subject: kmemleak: Release the object lock before calling put_object() The put_object() function may free the object if the use_count dropped to 0. There shouldn't be further accesses to such object unless it is known that the use_count is non-zero. Signed-off-by: Catalin Marinas diff --git a/mm/kmemleak.c b/mm/kmemleak.c index 9610635..f06c092 100644 --- a/mm/kmemleak.c +++ b/mm/kmemleak.c @@ -1025,11 +1025,14 @@ static void scan_block(void *_start, void *_end, * added to the gray_list. */ object->count++; - if (color_gray(object)) + if (color_gray(object)) { list_add_tail(&object->gray_list, &gray_list); - else - put_object(object); + spin_unlock_irqrestore(&object->lock, flags); + continue; + } + spin_unlock_irqrestore(&object->lock, flags); + put_object(object); } } -- cgit v0.10.2 From fefdd336b2a2f7617e0c8a0777c731d9ed6454ae Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Wed, 28 Oct 2009 13:33:12 +0000 Subject: kmemleak: Show the age of an unreferenced object The jiffies shown for unreferenced objects isn't always meaningful to people debugging kernel memory leaks. This patch adds the age as well to the displayed information. Signed-off-by: Catalin Marinas diff --git a/mm/kmemleak.c b/mm/kmemleak.c index f06c092..ce79d91 100644 --- a/mm/kmemleak.c +++ b/mm/kmemleak.c @@ -346,11 +346,13 @@ static void print_unreferenced(struct seq_file *seq, struct kmemleak_object *object) { int i; + unsigned int msecs_age = jiffies_to_msecs(jiffies - object->jiffies); seq_printf(seq, "unreferenced object 0x%08lx (size %zu):\n", object->pointer, object->size); - seq_printf(seq, " comm \"%s\", pid %d, jiffies %lu\n", - object->comm, object->pid, object->jiffies); + seq_printf(seq, " comm \"%s\", pid %d, jiffies %lu (age %d.%03ds)\n", + object->comm, object->pid, object->jiffies, + msecs_age / 1000, msecs_age % 1000); hex_dump_object(seq, object); seq_printf(seq, " backtrace:\n"); -- cgit v0.10.2 From 04609ccc40c4e8f3eabe8894eb0de881c8b984fd Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Wed, 28 Oct 2009 13:33:12 +0000 Subject: kmemleak: Reduce the false positives by checking for modified objects If an object was modified since it was previously suspected as leak, do not report it. The modification check is done by calculating the checksum (CRC32) of such object. Several false positives are caused by objects being removed from linked lists (e.g. allocation pools) and temporarily breaking the reference chain since kmemleak runs concurrently with such list mutation primitives. Signed-off-by: Catalin Marinas diff --git a/mm/kmemleak.c b/mm/kmemleak.c index ce79d91..002adc3 100644 --- a/mm/kmemleak.c +++ b/mm/kmemleak.c @@ -93,6 +93,7 @@ #include #include #include +#include #include #include @@ -108,7 +109,6 @@ #define MSECS_MIN_AGE 5000 /* minimum object age for reporting */ #define SECS_FIRST_SCAN 60 /* delay before the first scan */ #define SECS_SCAN_WAIT 600 /* subsequent auto scanning delay */ -#define GRAY_LIST_PASSES 25 /* maximum number of gray list scans */ #define MAX_SCAN_SIZE 4096 /* maximum size of a scanned block */ #define BYTES_PER_POINTER sizeof(void *) @@ -149,6 +149,8 @@ struct kmemleak_object { int min_count; /* the total number of pointers found pointing to this object */ int count; + /* checksum for detecting modified objects */ + u32 checksum; /* memory ranges to be scanned inside an object (empty for all) */ struct hlist_head area_list; unsigned long trace[MAX_TRACE]; @@ -164,8 +166,6 @@ struct kmemleak_object { #define OBJECT_REPORTED (1 << 1) /* flag set to not scan the object */ #define OBJECT_NO_SCAN (1 << 2) -/* flag set on newly allocated objects */ -#define OBJECT_NEW (1 << 3) /* number of bytes to print per line; must be 16 or 32 */ #define HEX_ROW_SIZE 16 @@ -321,11 +321,6 @@ static bool color_gray(const struct kmemleak_object *object) object->count >= object->min_count; } -static bool color_black(const struct kmemleak_object *object) -{ - return object->min_count == KMEMLEAK_BLACK; -} - /* * Objects are considered unreferenced only if their color is white, they have * not be deleted and have a minimum age to avoid false positives caused by @@ -333,7 +328,7 @@ static bool color_black(const struct kmemleak_object *object) */ static bool unreferenced_object(struct kmemleak_object *object) { - return (object->flags & OBJECT_ALLOCATED) && color_white(object) && + return (color_white(object) && object->flags & OBJECT_ALLOCATED) && time_before_eq(object->jiffies + jiffies_min_age, jiffies_last_scan); } @@ -381,6 +376,7 @@ static void dump_object_info(struct kmemleak_object *object) pr_notice(" min_count = %d\n", object->min_count); pr_notice(" count = %d\n", object->count); pr_notice(" flags = 0x%lx\n", object->flags); + pr_notice(" checksum = %d\n", object->checksum); pr_notice(" backtrace:\n"); print_stack_trace(&trace, 4); } @@ -522,12 +518,13 @@ static struct kmemleak_object *create_object(unsigned long ptr, size_t size, INIT_HLIST_HEAD(&object->area_list); spin_lock_init(&object->lock); atomic_set(&object->use_count, 1); - object->flags = OBJECT_ALLOCATED | OBJECT_NEW; + object->flags = OBJECT_ALLOCATED; object->pointer = ptr; object->size = size; object->min_count = min_count; - object->count = -1; /* no color initially */ + object->count = 0; /* white color initially */ object->jiffies = jiffies; + object->checksum = 0; /* task information */ if (in_irq()) { @@ -949,6 +946,20 @@ void __ref kmemleak_no_scan(const void *ptr) EXPORT_SYMBOL(kmemleak_no_scan); /* + * Update an object's checksum and return true if it was modified. + */ +static bool update_checksum(struct kmemleak_object *object) +{ + u32 old_csum = object->checksum; + + if (!kmemcheck_is_obj_initialized(object->pointer, object->size)) + return false; + + object->checksum = crc32(0, (void *)object->pointer, object->size); + return object->checksum != old_csum; +} + +/* * Memory scanning is a long process and it needs to be interruptable. This * function checks whether such interrupt condition occured. */ @@ -1082,6 +1093,39 @@ out: } /* + * Scan the objects already referenced (gray objects). More objects will be + * referenced and, if there are no memory leaks, all the objects are scanned. + */ +static void scan_gray_list(void) +{ + struct kmemleak_object *object, *tmp; + + /* + * The list traversal is safe for both tail additions and removals + * from inside the loop. The kmemleak objects cannot be freed from + * outside the loop because their use_count was incremented. + */ + object = list_entry(gray_list.next, typeof(*object), gray_list); + while (&object->gray_list != &gray_list) { + cond_resched(); + + /* may add new objects to the list */ + if (!scan_should_stop()) + scan_object(object); + + tmp = list_entry(object->gray_list.next, typeof(*object), + gray_list); + + /* remove the object from the list and release it */ + list_del(&object->gray_list); + put_object(object); + + object = tmp; + } + WARN_ON(!list_empty(&gray_list)); +} + +/* * Scan data sections and all the referenced memory blocks allocated via the * kernel's standard allocators. This function must be called with the * scan_mutex held. @@ -1089,10 +1133,9 @@ out: static void kmemleak_scan(void) { unsigned long flags; - struct kmemleak_object *object, *tmp; + struct kmemleak_object *object; int i; int new_leaks = 0; - int gray_list_pass = 0; jiffies_last_scan = jiffies; @@ -1113,7 +1156,6 @@ static void kmemleak_scan(void) #endif /* reset the reference count (whiten the object) */ object->count = 0; - object->flags &= ~OBJECT_NEW; if (color_gray(object) && get_object(object)) list_add_tail(&object->gray_list, &gray_list); @@ -1171,62 +1213,36 @@ static void kmemleak_scan(void) /* * Scan the objects already referenced from the sections scanned - * above. More objects will be referenced and, if there are no memory - * leaks, all the objects will be scanned. The list traversal is safe - * for both tail additions and removals from inside the loop. The - * kmemleak objects cannot be freed from outside the loop because their - * use_count was increased. + * above. */ -repeat: - object = list_entry(gray_list.next, typeof(*object), gray_list); - while (&object->gray_list != &gray_list) { - cond_resched(); - - /* may add new objects to the list */ - if (!scan_should_stop()) - scan_object(object); - - tmp = list_entry(object->gray_list.next, typeof(*object), - gray_list); - - /* remove the object from the list and release it */ - list_del(&object->gray_list); - put_object(object); - - object = tmp; - } - - if (scan_should_stop() || ++gray_list_pass >= GRAY_LIST_PASSES) - goto scan_end; + scan_gray_list(); /* - * Check for new objects allocated during this scanning and add them - * to the gray list. + * Check for new or unreferenced objects modified since the previous + * scan and color them gray until the next scan. */ rcu_read_lock(); list_for_each_entry_rcu(object, &object_list, object_list) { spin_lock_irqsave(&object->lock, flags); - if ((object->flags & OBJECT_NEW) && !color_black(object) && - get_object(object)) { - object->flags &= ~OBJECT_NEW; + if (color_white(object) && (object->flags & OBJECT_ALLOCATED) + && update_checksum(object) && get_object(object)) { + /* color it gray temporarily */ + object->count = object->min_count; list_add_tail(&object->gray_list, &gray_list); } spin_unlock_irqrestore(&object->lock, flags); } rcu_read_unlock(); - if (!list_empty(&gray_list)) - goto repeat; - -scan_end: - WARN_ON(!list_empty(&gray_list)); + /* + * Re-scan the gray list for modified unreferenced objects. + */ + scan_gray_list(); /* - * If scanning was stopped or new objects were being allocated at a - * higher rate than gray list scanning, do not report any new - * unreferenced objects. + * If scanning was stopped do not report any new unreferenced objects. */ - if (scan_should_stop() || gray_list_pass >= GRAY_LIST_PASSES) + if (scan_should_stop()) return; /* -- cgit v0.10.2 From e6aabe0cac14a495d42f629a803c5e221089bae8 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Thu, 15 Oct 2009 14:54:03 +0200 Subject: ocfs2: Always include ACL support To become consistent with filesystems such as XFS or BTRFS, make posix ACLs always available. This also reduces possibility of misconfiguration on admin's side. Signed-off-by: Jan Kara Signed-off-by: Joel Becker diff --git a/fs/ocfs2/Kconfig b/fs/ocfs2/Kconfig index 701b7a3..0d84066 100644 --- a/fs/ocfs2/Kconfig +++ b/fs/ocfs2/Kconfig @@ -6,6 +6,7 @@ config OCFS2_FS select CRC32 select QUOTA select QUOTA_TREE + select FS_POSIX_ACL help OCFS2 is a general purpose extent based shared disk cluster file system with many similarities to ext3. It supports 64 bit inode @@ -74,12 +75,3 @@ config OCFS2_DEBUG_FS This option will enable expensive consistency checks. Enable this option for debugging only as it is likely to decrease performance of the filesystem. - -config OCFS2_FS_POSIX_ACL - bool "OCFS2 POSIX Access Control Lists" - depends on OCFS2_FS - select FS_POSIX_ACL - default n - help - Posix Access Control Lists (ACLs) support permissions for users and - groups beyond the owner/group/world scheme. diff --git a/fs/ocfs2/Makefile b/fs/ocfs2/Makefile index 31f25ce..600d2d2 100644 --- a/fs/ocfs2/Makefile +++ b/fs/ocfs2/Makefile @@ -39,11 +39,8 @@ ocfs2-objs := \ ver.o \ quota_local.o \ quota_global.o \ - xattr.o - -ifeq ($(CONFIG_OCFS2_FS_POSIX_ACL),y) -ocfs2-objs += acl.o -endif + xattr.o \ + acl.o ocfs2_stackglue-objs := stackglue.o ocfs2_stack_o2cb-objs := stack_o2cb.o diff --git a/fs/ocfs2/acl.h b/fs/ocfs2/acl.h index 8f6389e..5c5d31f 100644 --- a/fs/ocfs2/acl.h +++ b/fs/ocfs2/acl.h @@ -26,8 +26,6 @@ struct ocfs2_acl_entry { __le32 e_id; }; -#ifdef CONFIG_OCFS2_FS_POSIX_ACL - extern int ocfs2_check_acl(struct inode *, int); extern int ocfs2_acl_chmod(struct inode *); extern int ocfs2_init_acl(handle_t *, struct inode *, struct inode *, @@ -35,24 +33,4 @@ extern int ocfs2_init_acl(handle_t *, struct inode *, struct inode *, struct ocfs2_alloc_context *, struct ocfs2_alloc_context *); -#else /* CONFIG_OCFS2_FS_POSIX_ACL*/ - -#define ocfs2_check_acl NULL -static inline int ocfs2_acl_chmod(struct inode *inode) -{ - return 0; -} -static inline int ocfs2_init_acl(handle_t *handle, - struct inode *inode, - struct inode *dir, - struct buffer_head *di_bh, - struct buffer_head *dir_bh, - struct ocfs2_alloc_context *meta_ac, - struct ocfs2_alloc_context *data_ac) -{ - return 0; -} - -#endif /* CONFIG_OCFS2_FS_POSIX_ACL*/ - #endif /* OCFS2_ACL_H */ diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index 9606730..da7d33a 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c @@ -1413,19 +1413,12 @@ static int ocfs2_parse_options(struct super_block *sb, } mopt->mount_opt |= OCFS2_MOUNT_GRPQUOTA; break; -#ifdef CONFIG_OCFS2_FS_POSIX_ACL case Opt_acl: mopt->mount_opt |= OCFS2_MOUNT_POSIX_ACL; break; case Opt_noacl: mopt->mount_opt &= ~OCFS2_MOUNT_POSIX_ACL; break; -#else - case Opt_acl: - case Opt_noacl: - printk(KERN_INFO "ocfs2 (no)acl options not supported\n"); - break; -#endif default: mlog(ML_ERROR, "Unrecognized mount option \"%s\" " @@ -1502,12 +1495,10 @@ static int ocfs2_show_options(struct seq_file *s, struct vfsmount *mnt) if (opts & OCFS2_MOUNT_INODE64) seq_printf(s, ",inode64"); -#ifdef CONFIG_OCFS2_FS_POSIX_ACL if (opts & OCFS2_MOUNT_POSIX_ACL) seq_printf(s, ",acl"); else seq_printf(s, ",noacl"); -#endif return 0; } diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c index fe34190..923e950e 100644 --- a/fs/ocfs2/xattr.c +++ b/fs/ocfs2/xattr.c @@ -98,10 +98,8 @@ static struct ocfs2_xattr_def_value_root def_xv = { struct xattr_handler *ocfs2_xattr_handlers[] = { &ocfs2_xattr_user_handler, -#ifdef CONFIG_OCFS2_FS_POSIX_ACL &ocfs2_xattr_acl_access_handler, &ocfs2_xattr_acl_default_handler, -#endif &ocfs2_xattr_trusted_handler, &ocfs2_xattr_security_handler, NULL @@ -109,12 +107,10 @@ struct xattr_handler *ocfs2_xattr_handlers[] = { static struct xattr_handler *ocfs2_xattr_handler_map[OCFS2_XATTR_MAX] = { [OCFS2_XATTR_INDEX_USER] = &ocfs2_xattr_user_handler, -#ifdef CONFIG_OCFS2_FS_POSIX_ACL [OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS] = &ocfs2_xattr_acl_access_handler, [OCFS2_XATTR_INDEX_POSIX_ACL_DEFAULT] = &ocfs2_xattr_acl_default_handler, -#endif [OCFS2_XATTR_INDEX_TRUSTED] = &ocfs2_xattr_trusted_handler, [OCFS2_XATTR_INDEX_SECURITY] = &ocfs2_xattr_security_handler, }; diff --git a/fs/ocfs2/xattr.h b/fs/ocfs2/xattr.h index 08e3638..abd72a4 100644 --- a/fs/ocfs2/xattr.h +++ b/fs/ocfs2/xattr.h @@ -40,10 +40,8 @@ struct ocfs2_security_xattr_info { extern struct xattr_handler ocfs2_xattr_user_handler; extern struct xattr_handler ocfs2_xattr_trusted_handler; extern struct xattr_handler ocfs2_xattr_security_handler; -#ifdef CONFIG_OCFS2_FS_POSIX_ACL extern struct xattr_handler ocfs2_xattr_acl_access_handler; extern struct xattr_handler ocfs2_xattr_acl_default_handler; -#endif extern struct xattr_handler *ocfs2_xattr_handlers[]; ssize_t ocfs2_listxattr(struct dentry *, char *, size_t); -- cgit v0.10.2 From 5297aad80cd3a3e62116e0a0b29116ccd8ae397d Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Thu, 15 Oct 2009 14:54:04 +0200 Subject: ocfs2: Make acl use the default Change acl mount options handling to match the one of XFS and BTRFS and hopefully it is also easier to use now. When admin does not specify any acl mount option, acls are enabled if and only if the filesystem has xattr feature enabled. If admin specifies 'acl' mount option, we fail the mount if the filesystem does not have xattr feature and thus acls cannot be enabled. Signed-off-by: Jan Kara Signed-off-by: Joel Becker diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h index eae4046..35ad46c 100644 --- a/fs/ocfs2/ocfs2.h +++ b/fs/ocfs2/ocfs2.h @@ -250,9 +250,11 @@ enum ocfs2_mount_options OCFS2_MOUNT_LOCALFLOCKS = 1 << 5, /* No cluster aware user file locks */ OCFS2_MOUNT_NOUSERXATTR = 1 << 6, /* No user xattr */ OCFS2_MOUNT_INODE64 = 1 << 7, /* Allow inode numbers > 2^32 */ - OCFS2_MOUNT_POSIX_ACL = 1 << 8, /* POSIX access control lists */ - OCFS2_MOUNT_USRQUOTA = 1 << 9, /* We support user quotas */ - OCFS2_MOUNT_GRPQUOTA = 1 << 10, /* We support group quotas */ + OCFS2_MOUNT_POSIX_ACL = 1 << 8, /* Force POSIX access control lists */ + OCFS2_MOUNT_NO_POSIX_ACL = 1 << 9, /* Disable POSIX access + control lists */ + OCFS2_MOUNT_USRQUOTA = 1 << 10, /* We support user quotas */ + OCFS2_MOUNT_GRPQUOTA = 1 << 11, /* We support group quotas */ }; #define OCFS2_OSB_SOFT_RO 0x0001 diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index da7d33a..a5116b9 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c @@ -100,6 +100,8 @@ struct mount_options static int ocfs2_parse_options(struct super_block *sb, char *options, struct mount_options *mopt, int is_remount); +static int ocfs2_check_set_options(struct super_block *sb, + struct mount_options *options); static int ocfs2_show_options(struct seq_file *s, struct vfsmount *mnt); static void ocfs2_put_super(struct super_block *sb); static int ocfs2_mount_volume(struct super_block *sb); @@ -600,7 +602,8 @@ static int ocfs2_remount(struct super_block *sb, int *flags, char *data) lock_kernel(); - if (!ocfs2_parse_options(sb, data, &parsed_options, 1)) { + if (!ocfs2_parse_options(sb, data, &parsed_options, 1) || + !ocfs2_check_set_options(sb, &parsed_options)) { ret = -EINVAL; goto out; } @@ -691,8 +694,6 @@ unlock_osb: if (!ret) { /* Only save off the new mount options in case of a successful * remount. */ - if (!(osb->s_feature_incompat & OCFS2_FEATURE_INCOMPAT_XATTR)) - parsed_options.mount_opt &= ~OCFS2_MOUNT_POSIX_ACL; osb->s_mount_opt = parsed_options.mount_opt; osb->s_atime_quantum = parsed_options.atime_quantum; osb->preferred_slot = parsed_options.slot; @@ -1011,31 +1012,16 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent) brelse(bh); bh = NULL; - if (!(osb->s_feature_incompat & OCFS2_FEATURE_INCOMPAT_XATTR)) - parsed_options.mount_opt &= ~OCFS2_MOUNT_POSIX_ACL; - + if (!ocfs2_check_set_options(sb, &parsed_options)) { + status = -EINVAL; + goto read_super_error; + } osb->s_mount_opt = parsed_options.mount_opt; osb->s_atime_quantum = parsed_options.atime_quantum; osb->preferred_slot = parsed_options.slot; osb->osb_commit_interval = parsed_options.commit_interval; osb->local_alloc_default_bits = ocfs2_megabytes_to_clusters(sb, parsed_options.localalloc_opt); osb->local_alloc_bits = osb->local_alloc_default_bits; - if (osb->s_mount_opt & OCFS2_MOUNT_USRQUOTA && - !OCFS2_HAS_RO_COMPAT_FEATURE(sb, - OCFS2_FEATURE_RO_COMPAT_USRQUOTA)) { - status = -EINVAL; - mlog(ML_ERROR, "User quotas were requested, but this " - "filesystem does not have the feature enabled.\n"); - goto read_super_error; - } - if (osb->s_mount_opt & OCFS2_MOUNT_GRPQUOTA && - !OCFS2_HAS_RO_COMPAT_FEATURE(sb, - OCFS2_FEATURE_RO_COMPAT_GRPQUOTA)) { - status = -EINVAL; - mlog(ML_ERROR, "Group quotas were requested, but this " - "filesystem does not have the feature enabled.\n"); - goto read_super_error; - } status = ocfs2_verify_userspace_stack(osb, &parsed_options); if (status) @@ -1245,6 +1231,40 @@ static struct file_system_type ocfs2_fs_type = { .next = NULL }; +static int ocfs2_check_set_options(struct super_block *sb, + struct mount_options *options) +{ + if (options->mount_opt & OCFS2_MOUNT_USRQUOTA && + !OCFS2_HAS_RO_COMPAT_FEATURE(sb, + OCFS2_FEATURE_RO_COMPAT_USRQUOTA)) { + mlog(ML_ERROR, "User quotas were requested, but this " + "filesystem does not have the feature enabled.\n"); + return 0; + } + if (options->mount_opt & OCFS2_MOUNT_GRPQUOTA && + !OCFS2_HAS_RO_COMPAT_FEATURE(sb, + OCFS2_FEATURE_RO_COMPAT_GRPQUOTA)) { + mlog(ML_ERROR, "Group quotas were requested, but this " + "filesystem does not have the feature enabled.\n"); + return 0; + } + if (options->mount_opt & OCFS2_MOUNT_POSIX_ACL && + !OCFS2_HAS_INCOMPAT_FEATURE(sb, OCFS2_FEATURE_INCOMPAT_XATTR)) { + mlog(ML_ERROR, "ACL support requested but extended attributes " + "feature is not enabled\n"); + return 0; + } + /* No ACL setting specified? Use XATTR feature... */ + if (!(options->mount_opt & (OCFS2_MOUNT_POSIX_ACL | + OCFS2_MOUNT_NO_POSIX_ACL))) { + if (OCFS2_HAS_INCOMPAT_FEATURE(sb, OCFS2_FEATURE_INCOMPAT_XATTR)) + options->mount_opt |= OCFS2_MOUNT_POSIX_ACL; + else + options->mount_opt |= OCFS2_MOUNT_NO_POSIX_ACL; + } + return 1; +} + static int ocfs2_parse_options(struct super_block *sb, char *options, struct mount_options *mopt, @@ -1392,31 +1412,17 @@ static int ocfs2_parse_options(struct super_block *sb, mopt->mount_opt |= OCFS2_MOUNT_INODE64; break; case Opt_usrquota: - /* We check only on remount, otherwise features - * aren't yet initialized. */ - if (is_remount && !OCFS2_HAS_RO_COMPAT_FEATURE(sb, - OCFS2_FEATURE_RO_COMPAT_USRQUOTA)) { - mlog(ML_ERROR, "User quota requested but " - "filesystem feature is not set\n"); - status = 0; - goto bail; - } mopt->mount_opt |= OCFS2_MOUNT_USRQUOTA; break; case Opt_grpquota: - if (is_remount && !OCFS2_HAS_RO_COMPAT_FEATURE(sb, - OCFS2_FEATURE_RO_COMPAT_GRPQUOTA)) { - mlog(ML_ERROR, "Group quota requested but " - "filesystem feature is not set\n"); - status = 0; - goto bail; - } mopt->mount_opt |= OCFS2_MOUNT_GRPQUOTA; break; case Opt_acl: mopt->mount_opt |= OCFS2_MOUNT_POSIX_ACL; + mopt->mount_opt &= ~OCFS2_MOUNT_NO_POSIX_ACL; break; case Opt_noacl: + mopt->mount_opt |= OCFS2_MOUNT_NO_POSIX_ACL; mopt->mount_opt &= ~OCFS2_MOUNT_POSIX_ACL; break; default: -- cgit v0.10.2 From 57b09bb5e492c37c1e4273fe4e435ffd1d2ddbe0 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Thu, 15 Oct 2009 14:54:05 +0200 Subject: ocfs2: Set MS_POSIXACL on remount We have to set MS_POSIXACL on remount as well. Otherwise VFS would not know we started supporting ACLs after remount and thus ACLs would not work. Signed-off-by: Jan Kara Signed-off-by: Joel Becker diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index a5116b9..45d654c 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c @@ -702,6 +702,10 @@ unlock_osb: if (!ocfs2_is_hard_readonly(osb)) ocfs2_set_journal_params(osb); + + sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | + ((osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL) ? + MS_POSIXACL : 0); } out: unlock_kernel(); -- cgit v0.10.2 From b60e26a2f03d963f8c79ad7920d64abc4d38ecbc Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 6 Nov 2009 15:33:45 -0800 Subject: kmemleak: fix kconfig for crc32 build error kmemleak uses crc32 functions so it needs to select CRC32. Fixes build error: kmemleak.c:(.text+0x7ce62): undefined reference to `crc32_le' Signed-off-by: Randy Dunlap Signed-off-by: Catalin Marinas diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 30df586..732b9f6 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -352,6 +352,7 @@ config DEBUG_KMEMLEAK select DEBUG_FS if SYSFS select STACKTRACE if STACKTRACE_SUPPORT select KALLSYMS + select CRC32 help Say Y here if you want to enable the memory leak detector. The memory allocation/freeing is traced in a way -- cgit v0.10.2 From 38a04e432768ec0b016f3c687b4de31ac111ae59 Mon Sep 17 00:00:00 2001 From: Tao Ma Date: Mon, 30 Nov 2009 14:32:19 +0800 Subject: ocfs2: Find proper end cpos for a leaf refcount block. ocfs2 refcount tree is stored as an extent tree while the leaf ocfs2_refcount_rec points to a refcount block. The following step can trip a kernel panic. mkfs.ocfs2 -b 512 -C 1M --fs-features=refcount $DEVICE mount -t ocfs2 $DEVICE $MNT_DIR FILE_NAME=$RANDOM FILE_NAME_1=$RANDOM FILE_REF="${FILE_NAME}_ref" FILE_REF_1="${FILE_NAME}_ref_1" for((i=0;i<305;i++)) do # /mnt/1048576 is a file with 1048576 sizes. cat /mnt/1048576 >> $MNT_DIR/$FILE_NAME cat /mnt/1048576 >> $MNT_DIR/$FILE_NAME_1 done for((i=0;i<3;i++)) do cat /mnt/1048576 >> $MNT_DIR/$FILE_NAME done for((i=0;i<2;i++)) do cat /mnt/1048576 >> $MNT_DIR/$FILE_NAME cat /mnt/1048576 >> $MNT_DIR/$FILE_NAME_1 done cat /mnt/1048576 >> $MNT_DIR/$FILE_NAME for((i=0;i<11;i++)) do cat /mnt/1048576 >> $MNT_DIR/$FILE_NAME cat /mnt/1048576 >> $MNT_DIR/$FILE_NAME_1 done reflink $MNT_DIR/$FILE_NAME $MNT_DIR/$FILE_REF # write_f is a program which will write some bytes to a file at offset. # write_f -f file_name -l offset -w write_bytes. ./write_f -f $MNT_DIR/$FILE_REF -l $[310*1048576] -w 4096 ./write_f -f $MNT_DIR/$FILE_REF -l $[306*1048576] -w 4096 ./write_f -f $MNT_DIR/$FILE_REF -l $[311*1048576] -w 4096 ./write_f -f $MNT_DIR/$FILE_NAME -l $[310*1048576] -w 4096 ./write_f -f $MNT_DIR/$FILE_NAME -l $[311*1048576] -w 4096 reflink $MNT_DIR/$FILE_NAME $MNT_DIR/$FILE_REF_1 ./write_f -f $MNT_DIR/$FILE_NAME -l $[311*1048576] -w 4096 #kernel panic here. The reason is that if the ocfs2_extent_rec is the last record in a leaf extent block, the old solution fails to find the suitable end cpos. So this patch try to walk through the b-tree, find the next sub root and get the c_pos the next sub-tree starts from. btw, I have runned tristan's test case against the patched kernel for several days and this type of kernel panic never happens again. Signed-off-by: Tao Ma Signed-off-by: Joel Becker diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index 38a42f5..5661db1 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c @@ -1765,9 +1765,9 @@ set_and_inc: * * The array index of the subtree root is passed back. */ -static int ocfs2_find_subtree_root(struct ocfs2_extent_tree *et, - struct ocfs2_path *left, - struct ocfs2_path *right) +int ocfs2_find_subtree_root(struct ocfs2_extent_tree *et, + struct ocfs2_path *left, + struct ocfs2_path *right) { int i = 0; @@ -2872,8 +2872,8 @@ out: * This looks similar, but is subtly different to * ocfs2_find_cpos_for_left_leaf(). */ -static int ocfs2_find_cpos_for_right_leaf(struct super_block *sb, - struct ocfs2_path *path, u32 *cpos) +int ocfs2_find_cpos_for_right_leaf(struct super_block *sb, + struct ocfs2_path *path, u32 *cpos) { int i, j, ret = 0; u64 blkno; diff --git a/fs/ocfs2/alloc.h b/fs/ocfs2/alloc.h index 9c122d57..1db4359 100644 --- a/fs/ocfs2/alloc.h +++ b/fs/ocfs2/alloc.h @@ -317,4 +317,9 @@ int ocfs2_path_bh_journal_access(handle_t *handle, int ocfs2_journal_access_path(struct ocfs2_caching_info *ci, handle_t *handle, struct ocfs2_path *path); +int ocfs2_find_cpos_for_right_leaf(struct super_block *sb, + struct ocfs2_path *path, u32 *cpos); +int ocfs2_find_subtree_root(struct ocfs2_extent_tree *et, + struct ocfs2_path *left, + struct ocfs2_path *right); #endif /* OCFS2_ALLOC_H */ diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c index 3a0df7a..9c3956f 100644 --- a/fs/ocfs2/refcounttree.c +++ b/fs/ocfs2/refcounttree.c @@ -969,6 +969,103 @@ out: } /* + * Find the end range for a leaf refcount block indicated by + * el->l_recs[index].e_blkno. + */ +static int ocfs2_get_refcount_cpos_end(struct ocfs2_caching_info *ci, + struct buffer_head *ref_root_bh, + struct ocfs2_extent_block *eb, + struct ocfs2_extent_list *el, + int index, u32 *cpos_end) +{ + int ret, i, subtree_root; + u32 cpos; + u64 blkno; + struct super_block *sb = ocfs2_metadata_cache_get_super(ci); + struct ocfs2_path *left_path = NULL, *right_path = NULL; + struct ocfs2_extent_tree et; + struct ocfs2_extent_list *tmp_el; + + if (index < le16_to_cpu(el->l_next_free_rec) - 1) { + /* + * We have a extent rec after index, so just use the e_cpos + * of the next extent rec. + */ + *cpos_end = le32_to_cpu(el->l_recs[index+1].e_cpos); + return 0; + } + + if (!eb || (eb && !eb->h_next_leaf_blk)) { + /* + * We are the last extent rec, so any high cpos should + * be stored in this leaf refcount block. + */ + *cpos_end = UINT_MAX; + return 0; + } + + /* + * If the extent block isn't the last one, we have to find + * the subtree root between this extent block and the next + * leaf extent block and get the corresponding e_cpos from + * the subroot. Otherwise we may corrupt the b-tree. + */ + ocfs2_init_refcount_extent_tree(&et, ci, ref_root_bh); + + left_path = ocfs2_new_path_from_et(&et); + if (!left_path) { + ret = -ENOMEM; + mlog_errno(ret); + goto out; + } + + cpos = le32_to_cpu(eb->h_list.l_recs[index].e_cpos); + ret = ocfs2_find_path(ci, left_path, cpos); + if (ret) { + mlog_errno(ret); + goto out; + } + + right_path = ocfs2_new_path_from_path(left_path); + if (!right_path) { + ret = -ENOMEM; + mlog_errno(ret); + goto out; + } + + ret = ocfs2_find_cpos_for_right_leaf(sb, left_path, &cpos); + if (ret) { + mlog_errno(ret); + goto out; + } + + ret = ocfs2_find_path(ci, right_path, cpos); + if (ret) { + mlog_errno(ret); + goto out; + } + + subtree_root = ocfs2_find_subtree_root(&et, left_path, + right_path); + + tmp_el = left_path->p_node[subtree_root].el; + blkno = left_path->p_node[subtree_root+1].bh->b_blocknr; + for (i = 0; i < le32_to_cpu(tmp_el->l_next_free_rec); i++) { + if (le64_to_cpu(tmp_el->l_recs[i].e_blkno) == blkno) { + *cpos_end = le32_to_cpu(tmp_el->l_recs[i+1].e_cpos); + break; + } + } + + BUG_ON(i == le32_to_cpu(tmp_el->l_next_free_rec)); + +out: + ocfs2_free_path(left_path); + ocfs2_free_path(right_path); + return ret; +} + +/* * Given a cpos and len, try to find the refcount record which contains cpos. * 1. If cpos can be found in one refcount record, return the record. * 2. If cpos can't be found, return a fake record which start from cpos @@ -983,10 +1080,10 @@ static int ocfs2_get_refcount_rec(struct ocfs2_caching_info *ci, struct buffer_head **ret_bh) { int ret = 0, i, found; - u32 low_cpos; + u32 low_cpos, uninitialized_var(cpos_end); struct ocfs2_extent_list *el; - struct ocfs2_extent_rec *tmp, *rec = NULL; - struct ocfs2_extent_block *eb; + struct ocfs2_extent_rec *rec = NULL; + struct ocfs2_extent_block *eb = NULL; struct buffer_head *eb_bh = NULL, *ref_leaf_bh = NULL; struct super_block *sb = ocfs2_metadata_cache_get_super(ci); struct ocfs2_refcount_block *rb = @@ -1034,12 +1131,16 @@ static int ocfs2_get_refcount_rec(struct ocfs2_caching_info *ci, } } - /* adjust len when we have ocfs2_extent_rec after it. */ - if (found && i < le16_to_cpu(el->l_next_free_rec) - 1) { - tmp = &el->l_recs[i+1]; + if (found) { + ret = ocfs2_get_refcount_cpos_end(ci, ref_root_bh, + eb, el, i, &cpos_end); + if (ret) { + mlog_errno(ret); + goto out; + } - if (le32_to_cpu(tmp->e_cpos) < cpos + len) - len = le32_to_cpu(tmp->e_cpos) - cpos; + if (cpos_end < low_cpos + len) + len = cpos_end - low_cpos; } ret = ocfs2_read_refcount_block(ci, le64_to_cpu(rec->e_blkno), -- cgit v0.10.2 From 12d4cec988a8a20927a9795dbf2c6d9ef2f85baa Mon Sep 17 00:00:00 2001 From: Tao Ma Date: Mon, 30 Nov 2009 15:08:40 +0800 Subject: ocfs2: refcounttree.c cleanup. sparse check finds some endian problem and some other minor issues. There is an obsolete function which should be removed. So this patch resolve all these. Signed-off-by: Tao Ma Signed-off-by: Joel Becker diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c index 9c3956f..c7ffba8 100644 --- a/fs/ocfs2/refcounttree.c +++ b/fs/ocfs2/refcounttree.c @@ -276,7 +276,7 @@ static void ocfs2_erase_refcount_tree_from_list(struct ocfs2_super *osb, spin_unlock(&osb->osb_lock); } -void ocfs2_kref_remove_refcount_tree(struct kref *kref) +static void ocfs2_kref_remove_refcount_tree(struct kref *kref) { struct ocfs2_refcount_tree *tree = container_of(kref, struct ocfs2_refcount_tree, rf_getcnt); @@ -524,23 +524,6 @@ out: return ret; } -int ocfs2_lock_refcount_tree_by_inode(struct inode *inode, int rw, - struct ocfs2_refcount_tree **ret_tree, - struct buffer_head **ref_bh) -{ - int ret; - u64 ref_blkno; - - ret = ocfs2_get_refcount_block(inode, &ref_blkno); - if (ret) { - mlog_errno(ret); - return ret; - } - - return ocfs2_lock_refcount_tree(OCFS2_SB(inode->i_sb), ref_blkno, - rw, ret_tree, ref_bh); -} - void ocfs2_unlock_refcount_tree(struct ocfs2_super *osb, struct ocfs2_refcount_tree *tree, int rw) { @@ -1519,7 +1502,7 @@ static int ocfs2_divide_leaf_refcount_block(struct buffer_head *ref_leaf_bh, /* change old and new rl_used accordingly. */ le16_add_cpu(&rl->rl_used, -num_moved); - new_rl->rl_used = cpu_to_le32(num_moved); + new_rl->rl_used = cpu_to_le16(num_moved); sort(&rl->rl_recs, le16_to_cpu(rl->rl_used), sizeof(struct ocfs2_refcount_rec), @@ -1898,7 +1881,8 @@ static int ocfs2_split_refcount_rec(handle_t *handle, recs_need++; /* If the leaf block don't have enough record, expand it. */ - if (le16_to_cpu(rf_list->rl_used) + recs_need > rf_list->rl_count) { + if (le16_to_cpu(rf_list->rl_used) + recs_need > + le16_to_cpu(rf_list->rl_count)) { struct ocfs2_refcount_rec tmp_rec; u64 cpos = le64_to_cpu(orig_rec->r_cpos); len = le32_to_cpu(orig_rec->r_clusters); @@ -1960,7 +1944,7 @@ static int ocfs2_split_refcount_rec(handle_t *handle, memcpy(tail_rec, orig_rec, sizeof(struct ocfs2_refcount_rec)); le64_add_cpu(&tail_rec->r_cpos, le32_to_cpu(tail_rec->r_clusters) - len); - tail_rec->r_clusters = le32_to_cpu(len); + tail_rec->r_clusters = cpu_to_le32(len); } /* @@ -3941,8 +3925,7 @@ static int ocfs2_add_refcounted_extent(struct inode *inode, } ret = ocfs2_insert_extent(handle, et, cpos, - cpu_to_le64(ocfs2_clusters_to_blocks(inode->i_sb, - p_cluster)), + ocfs2_clusters_to_blocks(inode->i_sb, p_cluster), num_clusters, ext_flags, meta_ac); if (ret) { mlog_errno(ret); @@ -4354,8 +4337,8 @@ static int ocfs2_user_path_parent(const char __user *path, * @new_dentry: target dentry * @preserve: if true, preserve all file attributes */ -int ocfs2_vfs_reflink(struct dentry *old_dentry, struct inode *dir, - struct dentry *new_dentry, bool preserve) +static int ocfs2_vfs_reflink(struct dentry *old_dentry, struct inode *dir, + struct dentry *new_dentry, bool preserve) { struct inode *inode = old_dentry->d_inode; int error; -- cgit v0.10.2 From f6656d26d17b2598f43cd41be088853fa2a03397 Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Tue, 17 Nov 2009 16:29:19 -0800 Subject: ocfs2/cluster: Make fence method configurable - v2 By default, o2cb fences the box by calling emergency_restart(). While this scheme works well in production, it comes in the way during testing as it does not let the tester take stack/core dumps for analysis. This patch allows user to dynamically change the fence method to panic() by: # echo "panic" > /sys/kernel/config/cluster//fence_method Signed-off-by: Sunil Mushran Signed-off-by: Joel Becker diff --git a/fs/ocfs2/cluster/nodemanager.c b/fs/ocfs2/cluster/nodemanager.c index 7ee6188..c81142e 100644 --- a/fs/ocfs2/cluster/nodemanager.c +++ b/fs/ocfs2/cluster/nodemanager.c @@ -35,6 +35,10 @@ * cluster references throughout where nodes are looked up */ struct o2nm_cluster *o2nm_single_cluster = NULL; +char *o2nm_fence_method_desc[O2NM_FENCE_METHODS] = { + "reset", /* O2NM_FENCE_RESET */ + "panic", /* O2NM_FENCE_PANIC */ +}; struct o2nm_node *o2nm_get_node_by_num(u8 node_num) { @@ -579,6 +583,43 @@ static ssize_t o2nm_cluster_attr_reconnect_delay_ms_write( return o2nm_cluster_attr_write(page, count, &cluster->cl_reconnect_delay_ms); } + +static ssize_t o2nm_cluster_attr_fence_method_read( + struct o2nm_cluster *cluster, char *page) +{ + ssize_t ret = 0; + + if (cluster) + ret = sprintf(page, "%s\n", + o2nm_fence_method_desc[cluster->cl_fence_method]); + return ret; +} + +static ssize_t o2nm_cluster_attr_fence_method_write( + struct o2nm_cluster *cluster, const char *page, size_t count) +{ + unsigned int i; + + if (page[count - 1] != '\n') + goto bail; + + for (i = 0; i < O2NM_FENCE_METHODS; ++i) { + if (count != strlen(o2nm_fence_method_desc[i]) + 1) + continue; + if (strncasecmp(page, o2nm_fence_method_desc[i], count - 1)) + continue; + if (cluster->cl_fence_method != i) { + printk(KERN_INFO "ocfs2: Changing fence method to %s\n", + o2nm_fence_method_desc[i]); + cluster->cl_fence_method = i; + } + return count; + } + +bail: + return -EINVAL; +} + static struct o2nm_cluster_attribute o2nm_cluster_attr_idle_timeout_ms = { .attr = { .ca_owner = THIS_MODULE, .ca_name = "idle_timeout_ms", @@ -603,10 +644,19 @@ static struct o2nm_cluster_attribute o2nm_cluster_attr_reconnect_delay_ms = { .store = o2nm_cluster_attr_reconnect_delay_ms_write, }; +static struct o2nm_cluster_attribute o2nm_cluster_attr_fence_method = { + .attr = { .ca_owner = THIS_MODULE, + .ca_name = "fence_method", + .ca_mode = S_IRUGO | S_IWUSR }, + .show = o2nm_cluster_attr_fence_method_read, + .store = o2nm_cluster_attr_fence_method_write, +}; + static struct configfs_attribute *o2nm_cluster_attrs[] = { &o2nm_cluster_attr_idle_timeout_ms.attr, &o2nm_cluster_attr_keepalive_delay_ms.attr, &o2nm_cluster_attr_reconnect_delay_ms.attr, + &o2nm_cluster_attr_fence_method.attr, NULL, }; static ssize_t o2nm_cluster_show(struct config_item *item, @@ -778,6 +828,7 @@ static struct config_group *o2nm_cluster_group_make_group(struct config_group *g cluster->cl_reconnect_delay_ms = O2NET_RECONNECT_DELAY_MS_DEFAULT; cluster->cl_idle_timeout_ms = O2NET_IDLE_TIMEOUT_MS_DEFAULT; cluster->cl_keepalive_delay_ms = O2NET_KEEPALIVE_DELAY_MS_DEFAULT; + cluster->cl_fence_method = O2NM_FENCE_RESET; ret = &cluster->cl_group; o2nm_single_cluster = cluster; diff --git a/fs/ocfs2/cluster/nodemanager.h b/fs/ocfs2/cluster/nodemanager.h index c992ea0..09ea2d3 100644 --- a/fs/ocfs2/cluster/nodemanager.h +++ b/fs/ocfs2/cluster/nodemanager.h @@ -33,6 +33,12 @@ #include #include +enum o2nm_fence_method { + O2NM_FENCE_RESET = 0, + O2NM_FENCE_PANIC, + O2NM_FENCE_METHODS, /* Number of fence methods */ +}; + struct o2nm_node { spinlock_t nd_lock; struct config_item nd_item; @@ -58,6 +64,7 @@ struct o2nm_cluster { unsigned int cl_idle_timeout_ms; unsigned int cl_keepalive_delay_ms; unsigned int cl_reconnect_delay_ms; + enum o2nm_fence_method cl_fence_method; /* this bitmap is part of a hack for disk bitmap.. will go eventually. - zab */ unsigned long cl_nodes_bitmap[BITS_TO_LONGS(O2NM_MAX_NODES)]; diff --git a/fs/ocfs2/cluster/quorum.c b/fs/ocfs2/cluster/quorum.c index bbacf7d..6390240 100644 --- a/fs/ocfs2/cluster/quorum.c +++ b/fs/ocfs2/cluster/quorum.c @@ -74,8 +74,20 @@ static void o2quo_fence_self(void) * threads can still schedule, etc, etc */ o2hb_stop_all_regions(); - printk("ocfs2 is very sorry to be fencing this system by restarting\n"); - emergency_restart(); + switch (o2nm_single_cluster->cl_fence_method) { + case O2NM_FENCE_PANIC: + panic("*** ocfs2 is very sorry to be fencing this system by " + "panicing ***\n"); + break; + default: + WARN_ON(o2nm_single_cluster->cl_fence_method >= + O2NM_FENCE_METHODS); + case O2NM_FENCE_RESET: + printk(KERN_ERR "*** ocfs2 is very sorry to be fencing this " + "system by restarting ***\n"); + emergency_restart(); + break; + }; } /* Indicate that a timeout occured on a hearbeat region write. The -- cgit v0.10.2 From aad1b15310b9bcd59fa81ab8f2b1513b59553ea8 Mon Sep 17 00:00:00 2001 From: Tiger Yang Date: Thu, 19 Nov 2009 10:17:46 +0800 Subject: ocfs2: return -EAGAIN instead of EAGAIN in dlm We used to return positive EAGAIN to indicate a retry action is needed in dlm_begin_reco_handler(). Now we return negative -EAGAIN to erase the confusion caused by this error code. Signed-off-by: Tiger Yang Signed-off-by: Joel Becker diff --git a/fs/ocfs2/dlm/dlmrecovery.c b/fs/ocfs2/dlm/dlmrecovery.c index d9fa3d2..2f9e4e1 100644 --- a/fs/ocfs2/dlm/dlmrecovery.c +++ b/fs/ocfs2/dlm/dlmrecovery.c @@ -2589,6 +2589,14 @@ retry: "begin reco msg (%d)\n", dlm->name, nodenum, ret); ret = 0; } + if (ret == -EAGAIN) { + mlog(0, "%s: trying to start recovery of node " + "%u, but node %u is waiting for last recovery " + "to complete, backoff for a bit\n", dlm->name, + dead_node, nodenum); + msleep(100); + goto retry; + } if (ret < 0) { struct dlm_lock_resource *res; /* this is now a serious problem, possibly ENOMEM @@ -2608,14 +2616,6 @@ retry: * another ENOMEM */ msleep(100); goto retry; - } else if (ret == EAGAIN) { - mlog(0, "%s: trying to start recovery of node " - "%u, but node %u is waiting for last recovery " - "to complete, backoff for a bit\n", dlm->name, - dead_node, nodenum); - /* TODO Look into replacing msleep with cond_resched() */ - msleep(100); - goto retry; } } @@ -2639,7 +2639,7 @@ int dlm_begin_reco_handler(struct o2net_msg *msg, u32 len, void *data, dlm->name, br->node_idx, br->dead_node, dlm->reco.dead_node, dlm->reco.new_master); spin_unlock(&dlm->spinlock); - return EAGAIN; + return -EAGAIN; } spin_unlock(&dlm->spinlock); -- cgit v0.10.2 From a2934c7b363ddcc001964f2444649f909e583bef Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Thu, 3 Dec 2009 08:09:41 -0500 Subject: cifs: NULL out tcon, pSesInfo, and srvTcp pointers when chasing DFS referrals The scenario is this: The kernel gets EREMOTE and starts chasing a DFS referral at mount time. The tcon reference is put, which puts the session reference too, but neither pointer is zeroed out. The mount gets retried (goto try_mount_again) with new mount info. Session setup fails fails and rc ends up being non-zero. The code then falls through to the end and tries to put the previously freed tcon pointer again. Oops at: cifs_put_smb_ses+0x14/0xd0 Fix this by moving the initialization of the rc variable and the tcon, pSesInfo and srvTcp pointers below the try_mount_again label. Also, add a FreeXid() before the goto to prevent xid "leaks". Signed-off-by: Jeff Layton Reported-by: Gustavo Carvalho Homem CC: stable Signed-off-by: Steve French diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 63ea83f..3bbcaa7 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -2287,12 +2287,12 @@ int cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, char *mount_data_global, const char *devname) { - int rc = 0; + int rc; int xid; struct smb_vol *volume_info; - struct cifsSesInfo *pSesInfo = NULL; - struct cifsTconInfo *tcon = NULL; - struct TCP_Server_Info *srvTcp = NULL; + struct cifsSesInfo *pSesInfo; + struct cifsTconInfo *tcon; + struct TCP_Server_Info *srvTcp; char *full_path; char *mount_data = mount_data_global; #ifdef CONFIG_CIFS_DFS_UPCALL @@ -2301,6 +2301,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, int referral_walks_count = 0; try_mount_again: #endif + rc = 0; + tcon = NULL; + pSesInfo = NULL; + srvTcp = NULL; full_path = NULL; xid = GetXid(); @@ -2597,6 +2601,7 @@ remote_path_check: cleanup_volume_info(&volume_info); referral_walks_count++; + FreeXid(xid); goto try_mount_again; } #else /* No DFS support, return error on mount */ -- cgit v0.10.2 From a994b8fa669f16c50728328c3735722a3f20652e Mon Sep 17 00:00:00 2001 From: Steve French Date: Mon, 7 Dec 2009 05:44:46 +0000 Subject: [CIFS] Enable mmap on forcedirectio mounts openoffice and gedit failed with 'direct' options Signed-off-by: Pavel Shilovsky Signed-off-by: Steve French diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index 094ea65..7b2600b 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES @@ -5,7 +5,9 @@ have duplicated data). Fix oops in cifs_lookup. Workaround problem mounting to OS/400 Netserve. Fix oops in cifs_get_tcp_session. Disable use of server inode numbers when server only partially supports them (e.g. for one server querying inode numbers on -FindFirst fails but QPathInfo queries works). +FindFirst fails but QPathInfo queries works). Fix oops with dfs in +cifs_put_smb_ses. Fix mmap to work on directio mounts (needed +for OpenOffice when on forcedirectio mount e.g.) Version 1.60 ------------- diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 29f1da7..8c6a036 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -758,7 +758,7 @@ const struct file_operations cifs_file_ops = { }; const struct file_operations cifs_file_direct_ops = { - /* no mmap, no aio, no readv - + /* no aio, no readv - BB reevaluate whether they can be done with directio, no cache */ .read = cifs_user_read, .write = cifs_user_write, @@ -767,6 +767,7 @@ const struct file_operations cifs_file_direct_ops = { .lock = cifs_lock, .fsync = cifs_fsync, .flush = cifs_flush, + .mmap = cifs_file_mmap, .splice_read = generic_file_splice_read, #ifdef CONFIG_CIFS_POSIX .unlocked_ioctl = cifs_ioctl, -- cgit v0.10.2 From f0e5d2c959d5f14dd3bc879c8f9390aa2c049423 Mon Sep 17 00:00:00 2001 From: Saeed Bishara Date: Sun, 6 Dec 2009 18:06:43 +0200 Subject: ARM: dove: fix the mm mmu flags of the pj4 procinfo ... to be the same as proc-v6 Signed-off-by: Saeed Bishara Signed-off-by: Nicolas Pitre diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S index 5485c82..395cc90 100644 --- a/arch/arm/mm/proc-v6.S +++ b/arch/arm/mm/proc-v6.S @@ -254,10 +254,9 @@ __pj4_v6_proc_info: .long 0x560f5810 .long 0xff0ffff0 .long PMD_TYPE_SECT | \ - PMD_SECT_BUFFERABLE | \ - PMD_SECT_CACHEABLE | \ PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ + PMD_SECT_AP_READ | \ + PMD_FLAGS .long PMD_TYPE_SECT | \ PMD_SECT_XN | \ PMD_SECT_AP_WRITE | \ -- cgit v0.10.2 From f93611fac7eed3aa175795fb8e452aa30af33b6a Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Tue, 8 Dec 2009 01:54:35 +0300 Subject: powerpc/fsl_pci: Fix P2P bridge handling for MPC83xx PCIe controllers It appears that we wrongly calculate dev_base for type1 config cycles. The thing is: we shouldn't subtract hose->first_busno because PCI core sets PCI primary, secondary and subordinate bus numbers, and PCIe controller actually takes the registers into account. So we should use just bus->number. Also, according to MPC8315 reference manual, primary bus number should always remain 0. We have PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS quirk in indirect_pci.c, but since 83xx is somewhat special, it doesn't use indirect_pci.c routines, so we have to implement the quirk specifically for 83xx PCIe controllers. Signed-off-by: Anton Vorontsov Signed-off-by: Kumar Gala diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index 4e3a3e3..e1a028c 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c @@ -464,8 +464,7 @@ static void __iomem *mpc83xx_pcie_remap_cfg(struct pci_bus *bus, { struct pci_controller *hose = pci_bus_to_host(bus); struct mpc83xx_pcie_priv *pcie = hose->dn->data; - u8 bus_no = bus->number - hose->first_busno; - u32 dev_base = bus_no << 24 | devfn << 16; + u32 dev_base = bus->number << 24 | devfn << 16; int ret; ret = mpc83xx_pcie_exclude_device(bus, devfn); @@ -515,12 +514,17 @@ static int mpc83xx_pcie_read_config(struct pci_bus *bus, unsigned int devfn, static int mpc83xx_pcie_write_config(struct pci_bus *bus, unsigned int devfn, int offset, int len, u32 val) { + struct pci_controller *hose = pci_bus_to_host(bus); void __iomem *cfg_addr; cfg_addr = mpc83xx_pcie_remap_cfg(bus, devfn, offset); if (!cfg_addr) return PCIBIOS_DEVICE_NOT_FOUND; + /* PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS */ + if (offset == PCI_PRIMARY_BUS && bus->number == hose->first_busno) + val &= 0xffffff00; + switch (len) { case 1: out_8(cfg_addr, val); -- cgit v0.10.2 From 196f0082d8e77f647edd21ea27b5a9bba8116396 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Sun, 6 Dec 2009 12:32:47 +0100 Subject: powerpc/fsl: try to explain why the interrupt numbers are off by 16 Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Kumar Gala diff --git a/Documentation/powerpc/dts-bindings/fsl/mpic.txt b/Documentation/powerpc/dts-bindings/fsl/mpic.txt new file mode 100644 index 0000000..71e39cf --- /dev/null +++ b/Documentation/powerpc/dts-bindings/fsl/mpic.txt @@ -0,0 +1,42 @@ +* OpenPIC and its interrupt numbers on Freescale's e500/e600 cores + +The OpenPIC specification does not specify which interrupt source has to +become which interrupt number. This is up to the software implementation +of the interrupt controller. The only requirement is that every +interrupt source has to have an unique interrupt number / vector number. +To accomplish this the current implementation assigns the number zero to +the first source, the number one to the second source and so on until +all interrupt sources have their unique number. +Usually the assigned vector number equals the interrupt number mentioned +in the documentation for a given core / CPU. This is however not true +for the e500 cores (MPC85XX CPUs) where the documentation distinguishes +between internal and external interrupt sources and starts counting at +zero for both of them. + +So what to write for external interrupt source X or internal interrupt +source Y into the device tree? Here is an example: + +The memory map for the interrupt controller in the MPC8544[0] shows, +that the first interrupt source starts at 0x5_0000 (PIC Register Address +Map-Interrupt Source Configuration Registers). This source becomes the +number zero therefore: + External interrupt 0 = interrupt number 0 + External interrupt 1 = interrupt number 1 + External interrupt 2 = interrupt number 2 + ... +Every interrupt number allocates 0x20 bytes register space. So to get +its number it is sufficient to shift the lower 16bits to right by five. +So for the external interrupt 10 we have: + 0x0140 >> 5 = 10 + +After the external sources, the internal sources follow. The in core I2C +controller on the MPC8544 for instance has the internal source number +27. Oo obtain its interrupt number we take the lower 16bits of its memory +address (0x5_0560) and shift it right: + 0x0560 >> 5 = 43 + +Therefore the I2C device node for the MPC8544 CPU has to have the +interrupt number 43 specified in the device tree. + +[0] MPC8544E PowerQUICCTM III, Integrated Host Processor Family Reference Manual + MPC8544ERM Rev. 1 10/2007 -- cgit v0.10.2 From 9174e4989ecf53eca69767229deb9ad85efd55fe Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Mon, 16 Nov 2009 16:58:51 +0300 Subject: powerpc/83xx: mpc8349emitx - add gpio controller declarations mpc8349 bears two GPIO controllers. Enable support for them. Signed-off-by: Dmitry Eremin-Solenikov Signed-off-by: Kumar Gala diff --git a/arch/powerpc/boot/dts/mpc8349emitx.dts b/arch/powerpc/boot/dts/mpc8349emitx.dts index feeeb7f..16872c9 100644 --- a/arch/powerpc/boot/dts/mpc8349emitx.dts +++ b/arch/powerpc/boot/dts/mpc8349emitx.dts @@ -63,6 +63,24 @@ reg = <0x200 0x100>; }; + gpio1: gpio-controller@c00 { + #gpio-cells = <2>; + compatible = "fsl,mpc8349-gpio"; + reg = <0xc00 0x100>; + interrupts = <74 0x8>; + interrupt-parent = <&ipic>; + gpio-controller; + }; + + gpio2: gpio-controller@d00 { + #gpio-cells = <2>; + compatible = "fsl,mpc8349-gpio"; + reg = <0xd00 0x100>; + interrupts = <75 0x8>; + interrupt-parent = <&ipic>; + gpio-controller; + }; + i2c@3000 { #address-cells = <1>; #size-cells = <0>; -- cgit v0.10.2 From 3320cf844f3183870e66059174ce73f9662e523b Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Mon, 16 Nov 2009 16:58:52 +0300 Subject: powerpc/83xx: mpc8349emitx - populate I2C busses in device tree Add OF descriptions of EEPROM, two GPIO extenders and SPD hanging on I2C on this board. Signed-off-by: Dmitry Eremin-Solenikov Signed-off-by: Kumar Gala diff --git a/arch/powerpc/boot/dts/mpc8349emitx.dts b/arch/powerpc/boot/dts/mpc8349emitx.dts index 16872c9..0fb78b2 100644 --- a/arch/powerpc/boot/dts/mpc8349emitx.dts +++ b/arch/powerpc/boot/dts/mpc8349emitx.dts @@ -90,6 +90,12 @@ interrupts = <14 0x8>; interrupt-parent = <&ipic>; dfsrr; + + eeprom: at24@50 { + compatible = "st-micro,24c256"; + reg = <0x50>; + }; + }; i2c@3100 { @@ -109,6 +115,25 @@ interrupt-parent = <&ipic>; }; + pcf1: iexp@38 { + #gpio-cells = <2>; + compatible = "ti,pcf8574a"; + reg = <0x38>; + gpio-controller; + }; + + pcf2: iexp@39 { + #gpio-cells = <2>; + compatible = "ti,pcf8574a"; + reg = <0x39>; + gpio-controller; + }; + + spd: at24@51 { + compatible = "at24,spd"; + reg = <0x51>; + }; + mcu_pio: mcu@a { #gpio-cells = <2>; compatible = "fsl,mc9s08qg8-mpc8349emitx", -- cgit v0.10.2 From 1d88fd11a2484b1bc0a36010781dc410446bef29 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Mon, 16 Nov 2009 23:51:20 +0300 Subject: powerpc/83xx: mpc8349emitx - add OF descriptions of LocalBus devices Describe all LocalBus chipselects on MPC8349E-MITX board. Also add flash bindings. Signed-off-by: Dmitry Eremin-Solenikov Signed-off-by: Kumar Gala diff --git a/arch/powerpc/boot/dts/mpc8349emitx.dts b/arch/powerpc/boot/dts/mpc8349emitx.dts index 0fb78b2..346d1ba 100644 --- a/arch/powerpc/boot/dts/mpc8349emitx.dts +++ b/arch/powerpc/boot/dts/mpc8349emitx.dts @@ -374,7 +374,26 @@ compatible = "fsl,mpc8349e-localbus", "fsl,pq2pro-localbus"; reg = <0xe0005000 0xd8>; - ranges = <0x3 0x0 0xf0000000 0x210>; + ranges = <0x0 0x0 0xfe000000 0x1000000 /* flash */ + 0x1 0x0 0xf8000000 0x20000 /* VSC 7385 */ + 0x2 0x0 0xf9000000 0x200000 /* exp slot */ + 0x3 0x0 0xf0000000 0x210>; /* CF slot */ + + flash@0,0 { + compatible = "cfi-flash"; + reg = <0x0 0x0 0x800000>; + bank-width = <2>; + device-width = <1>; + }; + + flash@0,800000 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "cfi-flash"; + reg = <0x0 0x800000 0x800000>; + bank-width = <2>; + device-width = <1>; + }; pata@3,0 { compatible = "fsl,mpc8349emitx-pata", "ata-generic"; -- cgit v0.10.2 From b387dfe902c352d5be4690a135412ece4868b531 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Mon, 16 Nov 2009 16:58:54 +0300 Subject: powerpc/83xx: mpc8349emitx - add leds-gpio binding Signed-off-by: Dmitry Eremin-Solenikov Signed-off-by: Kumar Gala diff --git a/arch/powerpc/boot/dts/mpc8349emitx.dts b/arch/powerpc/boot/dts/mpc8349emitx.dts index 346d1ba..b53d1df 100644 --- a/arch/powerpc/boot/dts/mpc8349emitx.dts +++ b/arch/powerpc/boot/dts/mpc8349emitx.dts @@ -318,6 +318,24 @@ reg = <0x700 0x100>; device_type = "ipic"; }; + + gpio-leds { + compatible = "gpio-leds"; + + green { + label = "Green"; + gpios = <&pcf1 0 1>; + linux,default-trigger = "heartbeat"; + }; + + yellow { + label = "Yellow"; + gpios = <&pcf1 1 1>; + /* linux,default-trigger = "heartbeat"; */ + default-state = "on"; + }; + }; + }; pci0: pci@e0008500 { -- cgit v0.10.2 From 8e68597d087977d3e4fd3e735d290ab45fd0b5ea Mon Sep 17 00:00:00 2001 From: Michael Reed Date: Fri, 18 Sep 2009 12:02:05 -0500 Subject: [SCSI] lpfc: fix hang on SGI ia64 platform In testing 2.6.31 on one of our ia64 platforms I've encountered a hang due to the driver using hardware ATEs which are a limited resource. This is because the driver does not set the dma consistent mask to 64 bits. Signed-off-by: Michael Reed Acked-by: James Smart Signed-off-by: James Bottomley diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 226920d..d4da6bd 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -4506,9 +4506,13 @@ lpfc_sli_pci_mem_setup(struct lpfc_hba *phba) pdev = phba->pcidev; /* Set the device DMA mask size */ - if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0) - if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) + if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0 + || pci_set_consistent_dma_mask(pdev,DMA_BIT_MASK(64)) != 0) { + if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0 + || pci_set_consistent_dma_mask(pdev,DMA_BIT_MASK(32)) != 0) { return error; + } + } /* Get the bus address of Bar0 and Bar2 and the number of bytes * required by each mapping. @@ -6021,9 +6025,13 @@ lpfc_sli4_pci_mem_setup(struct lpfc_hba *phba) pdev = phba->pcidev; /* Set the device DMA mask size */ - if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0) - if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) + if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0 + || pci_set_consistent_dma_mask(pdev,DMA_BIT_MASK(64)) != 0) { + if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0 + || pci_set_consistent_dma_mask(pdev,DMA_BIT_MASK(32)) != 0) { return error; + } + } /* Get the bus address of SLI4 device Bar0, Bar1, and Bar2 and the * number of bytes required by each mapping. They are actually -- cgit v0.10.2 From 6f4fdda41b01100cfe02afb1b84bf422cbf557d4 Mon Sep 17 00:00:00 2001 From: "Moger, Babu" Date: Wed, 4 Nov 2009 12:36:16 -0700 Subject: [SCSI] scsi_dh_rdac: Add two new IBM devices to rdac_dev_list This patch adds two new IBM storage devices which can use rdac device handlers. Signed-off-by: Babu Moger Signed-off-by: James Bottomley diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c index 47cfe1c..1a66019 100644 --- a/drivers/scsi/device_handler/scsi_dh_rdac.c +++ b/drivers/scsi/device_handler/scsi_dh_rdac.c @@ -748,6 +748,8 @@ static const struct scsi_dh_devlist rdac_dev_list[] = { {"IBM", "1724"}, {"IBM", "1726"}, {"IBM", "1742"}, + {"IBM", "1745"}, + {"IBM", "1746"}, {"IBM", "1814"}, {"IBM", "1815"}, {"IBM", "1818"}, -- cgit v0.10.2 From d685c262083dcd5fd98b7499b22a377a3225229c Mon Sep 17 00:00:00 2001 From: "Kashyap, Desai" Date: Tue, 17 Nov 2009 13:16:37 +0530 Subject: [SCSI] mpt2sas: add missing initialization of scsih_cmds Internal command scsih_cmds init is included in mpt2sas_base_attach. Signed-off-by: Kashyap Desai Cc: Stable Tree Signed-off-by: James Bottomley diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c index 6422e25..89d0240 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.c +++ b/drivers/scsi/mpt2sas/mpt2sas_base.c @@ -3583,6 +3583,11 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) ioc->transport_cmds.status = MPT2_CMD_NOT_USED; mutex_init(&ioc->transport_cmds.mutex); + /* scsih internal command bits */ + ioc->scsih_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); + ioc->scsih_cmds.status = MPT2_CMD_NOT_USED; + mutex_init(&ioc->scsih_cmds.mutex); + /* task management internal command bits */ ioc->tm_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); ioc->tm_cmds.status = MPT2_CMD_NOT_USED; -- cgit v0.10.2 From 48de68a40aef032a2e198437f4781a83bfb938db Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Tue, 17 Nov 2009 21:25:16 -0600 Subject: [SCSI] fc class: fix fc_transport_init error handling If transport_class_register fails we should unregister any registered classes, or we will leak memory or other resources. I did a quick modprobe of scsi_transport_fc to test the patch. Signed-off-by: Mike Christie Cc: Stable Tree Signed-off-by: James Bottomley diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index 6531c91..ddfcecd 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c @@ -649,11 +649,22 @@ static __init int fc_transport_init(void) return error; error = transport_class_register(&fc_vport_class); if (error) - return error; + goto unreg_host_class; error = transport_class_register(&fc_rport_class); if (error) - return error; - return transport_class_register(&fc_transport_class); + goto unreg_vport_class; + error = transport_class_register(&fc_transport_class); + if (error) + goto unreg_rport_class; + return 0; + +unreg_rport_class: + transport_class_unregister(&fc_rport_class); +unreg_vport_class: + transport_class_unregister(&fc_vport_class); +unreg_host_class: + transport_class_unregister(&fc_host_class); + return error; } static void __exit fc_transport_exit(void) -- cgit v0.10.2 From 729c845666be7092a52bf6fcdcf223fe4d9287a4 Mon Sep 17 00:00:00 2001 From: Anil Ravindranath Date: Fri, 20 Nov 2009 09:39:30 -0800 Subject: [SCSI] pmcraid: support SMI-S object model of storage pool PMC-Sierra mgmt application uses SMI-S model. According to SMI-S, the object model exposed by the SMI-S provider should show an StoragePool which contains member disks of a RAID Virtual disk and StorageVolume based on the StoragePool. But according to SMI-S, there is a possibility where StoragePool is created but StorageVolume is not yet created. To satisfy this scenario, we are trying a hidden RAID Virtual disk. The hidden RAID virtual disk will not be exposed to OS. Once a StorageVolume is created for this RAID virtual disk it is exposed. Signed-off-by: Anil Ravindranath Signed-off-by: James Bottomley diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c index 34c6b89..e7d2688 100644 --- a/drivers/scsi/pmcraid.c +++ b/drivers/scsi/pmcraid.c @@ -1,7 +1,8 @@ /* * pmcraid.c -- driver for PMC Sierra MaxRAID controller adapters * - * Written By: PMC Sierra Corporation + * Written By: Anil Ravindranath + * PMC-Sierra Inc * * Copyright (C) 2008, 2009 PMC Sierra Inc * @@ -79,7 +80,7 @@ DECLARE_BITMAP(pmcraid_minor, PMCRAID_MAX_ADAPTERS); /* * Module parameters */ -MODULE_AUTHOR("PMC Sierra Corporation, anil_ravindranath@pmc-sierra.com"); +MODULE_AUTHOR("Anil Ravindranath"); MODULE_DESCRIPTION("PMC Sierra MaxRAID Controller Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(PMCRAID_DRIVER_VERSION); @@ -162,10 +163,10 @@ static int pmcraid_slave_alloc(struct scsi_device *scsi_dev) spin_lock_irqsave(&pinstance->resource_lock, lock_flags); list_for_each_entry(temp, &pinstance->used_res_q, queue) { - /* do not expose VSETs with order-ids >= 240 */ + /* do not expose VSETs with order-ids > MAX_VSET_TARGETS */ if (RES_IS_VSET(temp->cfg_entry)) { target = temp->cfg_entry.unique_flags1; - if (target >= PMCRAID_MAX_VSET_TARGETS) + if (target > PMCRAID_MAX_VSET_TARGETS) continue; bus = PMCRAID_VSET_BUS_ID; lun = 0; @@ -1210,7 +1211,7 @@ static int pmcraid_expose_resource(struct pmcraid_config_table_entry *cfgte) int retval = 0; if (cfgte->resource_type == RES_TYPE_VSET) - retval = ((cfgte->unique_flags1 & 0xFF) < 0xFE); + retval = ((cfgte->unique_flags1 & 0x80) == 0); else if (cfgte->resource_type == RES_TYPE_GSCSI) retval = (RES_BUS(cfgte->resource_address) != PMCRAID_VIRTUAL_ENCL_BUS_ID); @@ -1361,6 +1362,7 @@ static int pmcraid_notify_aen(struct pmcraid_instance *pinstance, u8 type) * Return value: * none */ + static void pmcraid_handle_config_change(struct pmcraid_instance *pinstance) { struct pmcraid_config_table_entry *cfg_entry; @@ -1368,9 +1370,10 @@ static void pmcraid_handle_config_change(struct pmcraid_instance *pinstance) struct pmcraid_cmd *cmd; struct pmcraid_cmd *cfgcmd; struct pmcraid_resource_entry *res = NULL; - u32 new_entry = 1; unsigned long lock_flags; unsigned long host_lock_flags; + u32 new_entry = 1; + u32 hidden_entry = 0; int rc; ccn_hcam = (struct pmcraid_hcam_ccn *)pinstance->ccn.hcam; @@ -1406,9 +1409,15 @@ static void pmcraid_handle_config_change(struct pmcraid_instance *pinstance) } /* If this resource is not going to be added to mid-layer, just notify - * applications and return + * applications and return. If this notification is about hiding a VSET + * resource, check if it was exposed already. */ - if (!pmcraid_expose_resource(cfg_entry)) + if (pinstance->ccn.hcam->notification_type == + NOTIFICATION_TYPE_ENTRY_CHANGED && + cfg_entry->resource_type == RES_TYPE_VSET && + cfg_entry->unique_flags1 & 0x80) { + hidden_entry = 1; + } else if (!pmcraid_expose_resource(cfg_entry)) goto out_notify_apps; spin_lock_irqsave(&pinstance->resource_lock, lock_flags); @@ -1424,6 +1433,12 @@ static void pmcraid_handle_config_change(struct pmcraid_instance *pinstance) if (new_entry) { + if (hidden_entry) { + spin_unlock_irqrestore(&pinstance->resource_lock, + lock_flags); + goto out_notify_apps; + } + /* If there are more number of resources than what driver can * manage, do not notify the applications about the CCN. Just * ignore this notifications and re-register the same HCAM @@ -1454,8 +1469,9 @@ static void pmcraid_handle_config_change(struct pmcraid_instance *pinstance) sizeof(struct pmcraid_config_table_entry)); if (pinstance->ccn.hcam->notification_type == - NOTIFICATION_TYPE_ENTRY_DELETED) { + NOTIFICATION_TYPE_ENTRY_DELETED || hidden_entry) { if (res->scsi_dev) { + res->cfg_entry.unique_flags1 &= 0x7F; res->change_detected = RES_CHANGE_DEL; res->cfg_entry.resource_handle = PMCRAID_INVALID_RES_HANDLE; diff --git a/drivers/scsi/pmcraid.h b/drivers/scsi/pmcraid.h index 2752b56..92f89d5 100644 --- a/drivers/scsi/pmcraid.h +++ b/drivers/scsi/pmcraid.h @@ -1,6 +1,9 @@ /* * pmcraid.h -- PMC Sierra MaxRAID controller driver header file * + * Written By: Anil Ravindranath + * PMC-Sierra Inc + * * Copyright (C) 2008, 2009 PMC Sierra Inc. * * This program is free software; you can redistribute it and/or modify @@ -106,7 +109,7 @@ #define PMCRAID_VSET_LUN_ID 0x0 #define PMCRAID_PHYS_BUS_ID 0x0 #define PMCRAID_VIRTUAL_ENCL_BUS_ID 0x8 -#define PMCRAID_MAX_VSET_TARGETS 240 +#define PMCRAID_MAX_VSET_TARGETS 0x7F #define PMCRAID_MAX_VSET_LUNS_PER_TARGET 8 #define PMCRAID_IOA_MAX_SECTORS 32767 -- cgit v0.10.2 From 7ec4ad0125db0222e397508c190b01c8f2b5f7cd Mon Sep 17 00:00:00 2001 From: Srinivas Date: Tue, 24 Nov 2009 20:07:39 +0530 Subject: [SCSI] mvsas: add support for Adaptec ASC-1045/1405 SAS/SATA HBA This is support for Adaptec ASC-1045/1405 SAS/SATA HBA on mvsas, which is based on Marvell 88SE6440 chipset. Signed-off-by: Srinivas Cc: Andy Yan Signed-off-by: James Bottomley diff --git a/drivers/scsi/mvsas/mv_init.c b/drivers/scsi/mvsas/mv_init.c index c790d45..cae6b2c 100644 --- a/drivers/scsi/mvsas/mv_init.c +++ b/drivers/scsi/mvsas/mv_init.c @@ -657,6 +657,7 @@ static struct pci_device_id __devinitdata mvs_pci_table[] = { { PCI_VDEVICE(MARVELL, 0x9180), chip_9180 }, { PCI_VDEVICE(ARECA, PCI_DEVICE_ID_ARECA_1300), chip_1300 }, { PCI_VDEVICE(ARECA, PCI_DEVICE_ID_ARECA_1320), chip_1320 }, + { PCI_VDEVICE(ADAPTEC2, 0x0450), chip_6440 }, { } /* terminate list */ }; -- cgit v0.10.2 From 78b9fb6d38b1caf1c11cba5b10bb859e3cce071f Mon Sep 17 00:00:00 2001 From: Jayamohan Kallickal Date: Wed, 25 Nov 2009 01:41:37 +0530 Subject: [SCSI] be2iscsi: Adding support for various Async messages from chip This patch allows for future addition of various async messages from the chip. This ensures that the driver won't hit a BUG_ON if the Firmware used is newer than inbox driver and so is using latest async messages. Signed-off-by: Jayamohan Kallickal Reviewed-by: Mike Christie Signed-off-by: James Bottomley diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c index 698a527..f008708 100644 --- a/drivers/scsi/be2iscsi/be_cmds.c +++ b/drivers/scsi/be2iscsi/be_cmds.c @@ -135,11 +135,15 @@ int beiscsi_process_mcc(struct beiscsi_hba *phba) while ((compl = be_mcc_compl_get(phba))) { if (compl->flags & CQE_FLAGS_ASYNC_MASK) { /* Interpret flags as an async trailer */ - BUG_ON(!is_link_state_evt(compl->flags)); + if (is_link_state_evt(compl->flags)) + /* Interpret compl as a async link evt */ + beiscsi_async_link_state_process(phba, + (struct be_async_event_link_state *) compl); + else + SE_DEBUG(DBG_LVL_1, + " Unsupported Async Event, flags" + " = 0x%08x \n", compl->flags); - /* Interpret compl as a async link evt */ - beiscsi_async_link_state_process(phba, - (struct be_async_event_link_state *) compl); } else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) { status = be_mcc_compl_process(ctrl, compl); atomic_dec(&phba->ctrl.mcc_obj.q.used); -- cgit v0.10.2 From c982c368bb90adbd312faa05d0cfd842e9ab45a7 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Thu, 26 Nov 2009 09:24:13 +0900 Subject: [SCSI] st: fix mdata->page_order handling dio transfer always resets mdata->page_order to zero. It breaks high-order pages previously allocated for non-dio transfer. This patches adds reserved_page_order to st_buffer structure to save page order for non-dio transfer. http://bugzilla.kernel.org/show_bug.cgi?id=14563 When enlarge_buffer() allocates 524288 from 0, st uses six-order page allocation. So mdata->page_order is 6 and frp_seg is 2. After that, if st uses dio, sgl_map_user_pages() sets mdata->page_order to 0 for st_do_scsi(). After that, when we call normalize_buffer(), it frees only free frp_seg * PAGE_SIZE (2 * 4096) though we should free frp_seg * PAGE_SIZE << 6 (2 * 4096 << 6). So we see buffer_size is set to 516096 (524288 - 8192). Reported-by: Joachim Breuer Tested-by: Joachim Breuer Acked-by: Kai Makisara Signed-off-by: FUJITA Tomonori Cc: stable@kernel.org Signed-off-by: James Bottomley diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index ad59abb..d04ea9a 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -552,13 +552,15 @@ st_do_scsi(struct st_request * SRpnt, struct scsi_tape * STp, unsigned char *cmd SRpnt->waiting = waiting; if (STp->buffer->do_dio) { + mdata->page_order = 0; mdata->nr_entries = STp->buffer->sg_segs; mdata->pages = STp->buffer->mapped_pages; } else { + mdata->page_order = STp->buffer->reserved_page_order; mdata->nr_entries = DIV_ROUND_UP(bytes, PAGE_SIZE << mdata->page_order); - STp->buffer->map_data.pages = STp->buffer->reserved_pages; - STp->buffer->map_data.offset = 0; + mdata->pages = STp->buffer->reserved_pages; + mdata->offset = 0; } memcpy(SRpnt->cmd, cmd, sizeof(SRpnt->cmd)); @@ -3719,7 +3721,7 @@ static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dm priority |= __GFP_ZERO; if (STbuffer->frp_segs) { - order = STbuffer->map_data.page_order; + order = STbuffer->reserved_page_order; b_size = PAGE_SIZE << order; } else { for (b_size = PAGE_SIZE, order = 0; @@ -3752,7 +3754,7 @@ static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dm segs++; } STbuffer->b_data = page_address(STbuffer->reserved_pages[0]); - STbuffer->map_data.page_order = order; + STbuffer->reserved_page_order = order; return 1; } @@ -3765,7 +3767,7 @@ static void clear_buffer(struct st_buffer * st_bp) for (i=0; i < st_bp->frp_segs; i++) memset(page_address(st_bp->reserved_pages[i]), 0, - PAGE_SIZE << st_bp->map_data.page_order); + PAGE_SIZE << st_bp->reserved_page_order); st_bp->cleared = 1; } @@ -3773,7 +3775,7 @@ static void clear_buffer(struct st_buffer * st_bp) /* Release the extra buffer */ static void normalize_buffer(struct st_buffer * STbuffer) { - int i, order = STbuffer->map_data.page_order; + int i, order = STbuffer->reserved_page_order; for (i = 0; i < STbuffer->frp_segs; i++) { __free_pages(STbuffer->reserved_pages[i], order); @@ -3781,7 +3783,7 @@ static void normalize_buffer(struct st_buffer * STbuffer) } STbuffer->frp_segs = 0; STbuffer->sg_segs = 0; - STbuffer->map_data.page_order = 0; + STbuffer->reserved_page_order = 0; STbuffer->map_data.offset = 0; } @@ -3791,7 +3793,7 @@ static void normalize_buffer(struct st_buffer * STbuffer) static int append_to_buffer(const char __user *ubp, struct st_buffer * st_bp, int do_count) { int i, cnt, res, offset; - int length = PAGE_SIZE << st_bp->map_data.page_order; + int length = PAGE_SIZE << st_bp->reserved_page_order; for (i = 0, offset = st_bp->buffer_bytes; i < st_bp->frp_segs && offset >= length; i++) @@ -3823,7 +3825,7 @@ static int append_to_buffer(const char __user *ubp, struct st_buffer * st_bp, in static int from_buffer(struct st_buffer * st_bp, char __user *ubp, int do_count) { int i, cnt, res, offset; - int length = PAGE_SIZE << st_bp->map_data.page_order; + int length = PAGE_SIZE << st_bp->reserved_page_order; for (i = 0, offset = st_bp->read_pointer; i < st_bp->frp_segs && offset >= length; i++) @@ -3856,7 +3858,7 @@ static void move_buffer_data(struct st_buffer * st_bp, int offset) { int src_seg, dst_seg, src_offset = 0, dst_offset; int count, total; - int length = PAGE_SIZE << st_bp->map_data.page_order; + int length = PAGE_SIZE << st_bp->reserved_page_order; if (offset == 0) return; @@ -4578,7 +4580,6 @@ static int sgl_map_user_pages(struct st_buffer *STbp, } mdata->offset = uaddr & ~PAGE_MASK; - mdata->page_order = 0; STbp->mapped_pages = pages; return nr_pages; diff --git a/drivers/scsi/st.h b/drivers/scsi/st.h index 544dc6b..f91a67c 100644 --- a/drivers/scsi/st.h +++ b/drivers/scsi/st.h @@ -46,6 +46,7 @@ struct st_buffer { struct st_request *last_SRpnt; struct st_cmdstatus cmdstat; struct page **reserved_pages; + int reserved_page_order; struct page **mapped_pages; struct rq_map_data map_data; unsigned char *b_data; -- cgit v0.10.2 From cc9b2e9f6603190c009e5d2629ce8e3f99571346 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Thu, 26 Nov 2009 09:50:20 -0600 Subject: [SCSI] enclosure: fix oops while iterating enclosure_status array Based on patch originally by Jeff Mahoney enclosure_status is expected to be a NULL terminated array of strings but isn't actually NULL terminated. When writing an invalid value to /sys/class/enclosure/.../.../status, it goes off the end of the array and Oopses. Fix by making the assumption true and adding NULL at the end. Reported-by: Artur Wojcik Signed-off-by: James Bottomley diff --git a/drivers/misc/enclosure.c b/drivers/misc/enclosure.c index e9eae4a..1eac626 100644 --- a/drivers/misc/enclosure.c +++ b/drivers/misc/enclosure.c @@ -391,6 +391,7 @@ static const char *const enclosure_status [] = { [ENCLOSURE_STATUS_NOT_INSTALLED] = "not installed", [ENCLOSURE_STATUS_UNKNOWN] = "unknown", [ENCLOSURE_STATUS_UNAVAILABLE] = "unavailable", + [ENCLOSURE_STATUS_MAX] = NULL, }; static const char *const enclosure_type [] = { diff --git a/include/linux/enclosure.h b/include/linux/enclosure.h index 90d1c21..9a33c5f 100644 --- a/include/linux/enclosure.h +++ b/include/linux/enclosure.h @@ -42,6 +42,8 @@ enum enclosure_status { ENCLOSURE_STATUS_NOT_INSTALLED, ENCLOSURE_STATUS_UNKNOWN, ENCLOSURE_STATUS_UNAVAILABLE, + /* last element for counting purposes */ + ENCLOSURE_STATUS_MAX }; /* SFF-8485 activity light settings */ -- cgit v0.10.2 From e339c1a7c09ef736dca7b3a4353c7742557d9f8f Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Thu, 26 Nov 2009 12:00:40 -0500 Subject: [SCSI] sd: WRITE SAME(16) / UNMAP support Implement a function for handling discard requests that sends either WRITE SAME(16) or UNMAP(10) depending on parameters indicated by the device in the block limits VPD. Extract unmap constraints and report them to the block layer. Based in part by a patch by Christoph Hellwig . Signed-off-by: Martin K. Petersen Signed-off-by: James Bottomley diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 9093c72..255da53 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -264,6 +264,15 @@ sd_show_app_tag_own(struct device *dev, struct device_attribute *attr, return snprintf(buf, 20, "%u\n", sdkp->ATO); } +static ssize_t +sd_show_thin_provisioning(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct scsi_disk *sdkp = to_scsi_disk(dev); + + return snprintf(buf, 20, "%u\n", sdkp->thin_provisioning); +} + static struct device_attribute sd_disk_attrs[] = { __ATTR(cache_type, S_IRUGO|S_IWUSR, sd_show_cache_type, sd_store_cache_type), @@ -274,6 +283,7 @@ static struct device_attribute sd_disk_attrs[] = { sd_store_manage_start_stop), __ATTR(protection_type, S_IRUGO, sd_show_protection_type, NULL), __ATTR(app_tag_own, S_IRUGO, sd_show_app_tag_own, NULL), + __ATTR(thin_provisioning, S_IRUGO, sd_show_thin_provisioning, NULL), __ATTR_NULL, }; @@ -399,6 +409,57 @@ static void sd_prot_op(struct scsi_cmnd *scmd, unsigned int dif) } /** + * sd_prepare_discard - unmap blocks on thinly provisioned device + * @rq: Request to prepare + * + * Will issue either UNMAP or WRITE SAME(16) depending on preference + * indicated by target device. + **/ +static int sd_prepare_discard(struct request *rq) +{ + struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); + struct bio *bio = rq->bio; + sector_t sector = bio->bi_sector; + unsigned int num = bio_sectors(bio); + + if (sdkp->device->sector_size == 4096) { + sector >>= 3; + num >>= 3; + } + + rq->cmd_type = REQ_TYPE_BLOCK_PC; + rq->timeout = SD_TIMEOUT; + + memset(rq->cmd, 0, rq->cmd_len); + + if (sdkp->unmap) { + char *buf = kmap_atomic(bio_page(bio), KM_USER0); + + rq->cmd[0] = UNMAP; + rq->cmd[8] = 24; + rq->cmd_len = 10; + + /* Ensure that data length matches payload */ + rq->__data_len = bio->bi_size = bio->bi_io_vec->bv_len = 24; + + put_unaligned_be16(6 + 16, &buf[0]); + put_unaligned_be16(16, &buf[2]); + put_unaligned_be64(sector, &buf[8]); + put_unaligned_be32(num, &buf[16]); + + kunmap_atomic(buf, KM_USER0); + } else { + rq->cmd[0] = WRITE_SAME_16; + rq->cmd[1] = 0x8; /* UNMAP */ + put_unaligned_be64(sector, &rq->cmd[2]); + put_unaligned_be32(num, &rq->cmd[10]); + rq->cmd_len = 16; + } + + return BLKPREP_OK; +} + +/** * sd_init_command - build a scsi (read or write) command from * information in the request structure. * @SCpnt: pointer to mid-level's per scsi command structure that @@ -418,6 +479,13 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) int ret, host_dif; unsigned char protect; + /* + * Discard request come in as REQ_TYPE_FS but we turn them into + * block PC requests to make life easier. + */ + if (blk_discard_rq(rq)) + ret = sd_prepare_discard(rq); + if (rq->cmd_type == REQ_TYPE_BLOCK_PC) { ret = scsi_setup_blk_pc_cmnd(sdp, rq); goto out; @@ -1432,6 +1500,19 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp, sd_printk(KERN_NOTICE, sdkp, "physical block alignment offset: %u\n", alignment); + if (buffer[14] & 0x80) { /* TPE */ + struct request_queue *q = sdp->request_queue; + + sdkp->thin_provisioning = 1; + q->limits.discard_granularity = sdkp->hw_sector_size; + q->limits.max_discard_sectors = 0xffffffff; + + if (buffer[14] & 0x40) /* TPRZ */ + q->limits.discard_zeroes_data = 1; + + queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q); + } + sdkp->capacity = lba + 1; return sector_size; } @@ -1863,6 +1944,7 @@ void sd_read_app_tag_own(struct scsi_disk *sdkp, unsigned char *buffer) */ static void sd_read_block_limits(struct scsi_disk *sdkp) { + struct request_queue *q = sdkp->disk->queue; unsigned int sector_sz = sdkp->device->sector_size; char *buffer; @@ -1877,6 +1959,31 @@ static void sd_read_block_limits(struct scsi_disk *sdkp) blk_queue_io_opt(sdkp->disk->queue, get_unaligned_be32(&buffer[12]) * sector_sz); + /* Thin provisioning enabled and page length indicates TP support */ + if (sdkp->thin_provisioning && buffer[3] == 0x3c) { + unsigned int lba_count, desc_count, granularity; + + lba_count = get_unaligned_be32(&buffer[20]); + desc_count = get_unaligned_be32(&buffer[24]); + + if (lba_count) { + q->limits.max_discard_sectors = + lba_count * sector_sz >> 9; + + if (desc_count) + sdkp->unmap = 1; + } + + granularity = get_unaligned_be32(&buffer[28]); + + if (granularity) + q->limits.discard_granularity = granularity * sector_sz; + + if (buffer[32] & 0x80) + q->limits.discard_alignment = + get_unaligned_be32(&buffer[32]) & ~(1 << 31); + } + kfree(buffer); } diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h index e374804..43d3caf 100644 --- a/drivers/scsi/sd.h +++ b/drivers/scsi/sd.h @@ -60,6 +60,8 @@ struct scsi_disk { unsigned RCD : 1; /* state of disk RCD bit, unused */ unsigned DPOFUA : 1; /* state of disk DPOFUA bit */ unsigned first_scan : 1; + unsigned thin_provisioning : 1; + unsigned unmap : 1; }; #define to_scsi_disk(obj) container_of(obj,struct scsi_disk,dev) -- cgit v0.10.2 From d8705f11d89cfabf4a9f0ea234d4809b22abb33e Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Thu, 26 Nov 2009 12:00:41 -0500 Subject: [SCSI] Correctly handle thin provisioning write error A thin provisioned device may temporarily be out of sufficient allocation units to fulfill a write request. In that case it will return a space allocation in progress error. Wait a bit and retry the write. Signed-off-by: Martin K. Petersen Signed-off-by: James Bottomley diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index e495d38..d892768 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -859,6 +859,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) case 0x07: /* operation in progress */ case 0x08: /* Long write in progress */ case 0x09: /* self test in progress */ + case 0x14: /* space allocation in progress */ action = ACTION_DELAYED_RETRY; break; default: -- cgit v0.10.2 From aeab3fd7b865bc4086a80a83cfdd67dded3b41a0 Mon Sep 17 00:00:00 2001 From: Noriyuki Fujii Date: Fri, 20 Nov 2009 16:27:20 +0900 Subject: [SCSI] megaraid_sas: make driver PCI legacy I/O port free driver On the large servers, I/O port resource may not be assigned to all the PCI devices since it is limited (to 64KB on Intel Architecture[1]) and it may also be fragmented (I/O base register of PCI-to-PCI bridge will usually be aligned to a 4KB boundary[2]). If no I/O port resource is assigned to devices, those devices do not work. [1] Some machines support 64KB I/O port space per PCI segment. [2] Some P2P bridges support optional 1KB aligned I/O base. Therefore, I made a patch for MegaRAID SAS driver to make PCI legacy I/O port free. I have also tested the patch and it had no problem. The way to make PCI legacy I/O port free is the same as Fusion-MPT driver's and it has been merged into 2.6.30.4. This has already been fixed in e1000 and lpfc. As a result of the above, the driver can handle its device even when there are a huge number of PCI devices being used on the system and no I/O port region assigned to the device. Signed-off-by: Noriyuki Fujii Acked-by: "Yang, Bo" Signed-off-by: James Bottomley diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c index 134c63e..99ff99e 100644 --- a/drivers/scsi/megaraid/megaraid_sas.c +++ b/drivers/scsi/megaraid/megaraid_sas.c @@ -2501,7 +2501,9 @@ static int megasas_init_mfi(struct megasas_instance *instance) instance->base_addr = pci_resource_start(instance->pdev, 0); } - if (pci_request_regions(instance->pdev, "megasas: LSI")) { + if (pci_request_selected_regions(instance->pdev, + pci_select_bars(instance->pdev, IORESOURCE_MEM), + "megasas: LSI")) { printk(KERN_DEBUG "megasas: IO memory region busy!\n"); return -EBUSY; } @@ -2642,7 +2644,8 @@ static int megasas_init_mfi(struct megasas_instance *instance) iounmap(instance->reg_set); fail_ioremap: - pci_release_regions(instance->pdev); + pci_release_selected_regions(instance->pdev, + pci_select_bars(instance->pdev, IORESOURCE_MEM)); return -EINVAL; } @@ -2662,7 +2665,8 @@ static void megasas_release_mfi(struct megasas_instance *instance) iounmap(instance->reg_set); - pci_release_regions(instance->pdev); + pci_release_selected_regions(instance->pdev, + pci_select_bars(instance->pdev, IORESOURCE_MEM)); } /** @@ -2971,7 +2975,7 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) /* * PCI prepping: enable device set bus mastering and dma mask */ - rval = pci_enable_device(pdev); + rval = pci_enable_device_mem(pdev); if (rval) { return rval; @@ -3276,7 +3280,7 @@ megasas_resume(struct pci_dev *pdev) /* * PCI prepping: enable device set bus mastering and dma mask */ - rval = pci_enable_device(pdev); + rval = pci_enable_device_mem(pdev); if (rval) { printk(KERN_ERR "megasas: Enable device failed\n"); -- cgit v0.10.2 From 5d0961fd1f25e117f907f3af3aaa870637049252 Mon Sep 17 00:00:00 2001 From: Boaz Harrosh Date: Tue, 1 Dec 2009 17:36:21 +0200 Subject: [SCSI] libosd: Fix blk_put_request locking again So libosd has decided to sacrifice some code simplicity for the sake of a clean API. One of these things is the possibility for users to call osd_end_request, in any condition at any state. This opens up some problems with calling blk_put_request when out-side of the completion callback but calling __blk_put_request when detecting a from-completion state. The current hack was working just fine until exofs decided to operate on all devices in parallel and wait for the sum of the requests, before deallocating all osd-requests at once. There are two new possible cases 1. All request in a group are deallocated as part of the last request's async-done, request_queue is locked. 2. All request in a group where executed asynchronously, but de-allocation was delayed to after the async-done, in the context of another thread. Async execution but request_queue is not locked. The solution I chose was to separate the deallocation of the osd_request which has the information users need, from the deallocation of the internal(2) requests which impose the locking problem. The internal block-requests are freed unconditionally inside the async-done-callback, when we know the queue is always locked. If at osd_end_request time we still have a bock-request, then we know it did not come from within an async-done-callback and we can call the regular blk_put_request. The internal requests were used for carrying error information after execution. This information is now copied to osd_request members for later analysis by user code. The external API and behaviour was unchanged, except now it really supports what was previously advertised. Reported-by: Vineet Agarwal Signed-off-by: Boaz Harrosh Cc: Stable Tree Signed-off-by: James Bottomley diff --git a/drivers/scsi/osd/osd_initiator.c b/drivers/scsi/osd/osd_initiator.c index 950202a..2422347 100644 --- a/drivers/scsi/osd/osd_initiator.c +++ b/drivers/scsi/osd/osd_initiator.c @@ -432,30 +432,23 @@ static void _osd_free_seg(struct osd_request *or __unused, seg->alloc_size = 0; } -static void _put_request(struct request *rq , bool is_async) +static void _put_request(struct request *rq) { - if (is_async) { - WARN_ON(rq->bio); - __blk_put_request(rq->q, rq); - } else { - /* - * If osd_finalize_request() was called but the request was not - * executed through the block layer, then we must release BIOs. - * TODO: Keep error code in or->async_error. Need to audit all - * code paths. - */ - if (unlikely(rq->bio)) - blk_end_request(rq, -ENOMEM, blk_rq_bytes(rq)); - else - blk_put_request(rq); - } + /* + * If osd_finalize_request() was called but the request was not + * executed through the block layer, then we must release BIOs. + * TODO: Keep error code in or->async_error. Need to audit all + * code paths. + */ + if (unlikely(rq->bio)) + blk_end_request(rq, -ENOMEM, blk_rq_bytes(rq)); + else + blk_put_request(rq); } void osd_end_request(struct osd_request *or) { struct request *rq = or->request; - /* IMPORTANT: make sure this agrees with osd_execute_request_async */ - bool is_async = (or->request->end_io_data == or); _osd_free_seg(or, &or->set_attr); _osd_free_seg(or, &or->enc_get_attr); @@ -463,20 +456,34 @@ void osd_end_request(struct osd_request *or) if (rq) { if (rq->next_rq) { - _put_request(rq->next_rq, is_async); + _put_request(rq->next_rq); rq->next_rq = NULL; } - _put_request(rq, is_async); + _put_request(rq); } _osd_request_free(or); } EXPORT_SYMBOL(osd_end_request); +static void _set_error_resid(struct osd_request *or, struct request *req, + int error) +{ + or->async_error = error; + or->req_errors = req->errors ? : error; + or->sense_len = req->sense_len; + if (or->out.req) + or->out.residual = or->out.req->resid_len; + if (or->in.req) + or->in.residual = or->in.req->resid_len; +} + int osd_execute_request(struct osd_request *or) { - return or->async_error = - blk_execute_rq(or->request->q, NULL, or->request, 0); + int error = blk_execute_rq(or->request->q, NULL, or->request, 0); + + _set_error_resid(or, or->request, error); + return error; } EXPORT_SYMBOL(osd_execute_request); @@ -484,15 +491,17 @@ static void osd_request_async_done(struct request *req, int error) { struct osd_request *or = req->end_io_data; - or->async_error = error; - - if (unlikely(error)) { - OSD_DEBUG("osd_request_async_done error recieved %d " - "errors 0x%x\n", error, req->errors); - if (!req->errors) /* don't miss out on this one */ - req->errors = error; + _set_error_resid(or, req, error); + if (req->next_rq) { + __blk_put_request(req->q, req->next_rq); + req->next_rq = NULL; } + __blk_put_request(req->q, req); + or->request = NULL; + or->in.req = NULL; + or->out.req = NULL; + if (or->async_done) or->async_done(or, or->async_private); else @@ -1489,21 +1498,18 @@ int osd_req_decode_sense_full(struct osd_request *or, #endif int ret; - if (likely(!or->request->errors)) { - osi->out_resid = 0; - osi->in_resid = 0; + if (likely(!or->req_errors)) return 0; - } osi = osi ? : &local_osi; memset(osi, 0, sizeof(*osi)); - ssdb = or->request->sense; - sense_len = or->request->sense_len; + ssdb = (typeof(ssdb))or->sense; + sense_len = or->sense_len; if ((sense_len < (int)sizeof(*ssdb) || !ssdb->sense_key)) { OSD_ERR("Block-layer returned error(0x%x) but " "sense_len(%u) || key(%d) is empty\n", - or->request->errors, sense_len, ssdb->sense_key); + or->req_errors, sense_len, ssdb->sense_key); goto analyze; } @@ -1525,7 +1531,7 @@ int osd_req_decode_sense_full(struct osd_request *or, "additional_code=0x%x async_error=%d errors=0x%x\n", osi->key, original_sense_len, sense_len, osi->additional_code, or->async_error, - or->request->errors); + or->req_errors); if (original_sense_len < sense_len) sense_len = original_sense_len; @@ -1695,10 +1701,10 @@ analyze: ret = -EIO; } - if (or->out.req) - osi->out_resid = or->out.req->resid_len ?: or->out.total_bytes; - if (or->in.req) - osi->in_resid = or->in.req->resid_len ?: or->in.total_bytes; + if (!or->out.residual) + or->out.residual = or->out.total_bytes; + if (!or->in.residual) + or->in.residual = or->in.total_bytes; return ret; } diff --git a/include/scsi/osd_initiator.h b/include/scsi/osd_initiator.h index 39d6d10..a8f3701 100644 --- a/include/scsi/osd_initiator.h +++ b/include/scsi/osd_initiator.h @@ -142,6 +142,7 @@ struct osd_request { struct _osd_io_info { struct bio *bio; u64 total_bytes; + u64 residual; struct request *req; struct _osd_req_data_segment *last_seg; u8 *pad_buff; @@ -150,12 +151,14 @@ struct osd_request { gfp_t alloc_flags; unsigned timeout; unsigned retries; + unsigned sense_len; u8 sense[OSD_MAX_SENSE_LEN]; enum osd_attributes_mode attributes_mode; osd_req_done_fn *async_done; void *async_private; int async_error; + int req_errors; }; static inline bool osd_req_is_ver1(struct osd_request *or) @@ -297,8 +300,6 @@ enum osd_err_priority { }; struct osd_sense_info { - u64 out_resid; /* Zero on success otherwise out residual */ - u64 in_resid; /* Zero on success otherwise in residual */ enum osd_err_priority osd_err_pri; int key; /* one of enum scsi_sense_keys */ -- cgit v0.10.2 From 1486400f7edd009d49550da968d5744e246dc7f8 Mon Sep 17 00:00:00 2001 From: Michael Reed Date: Wed, 2 Dec 2009 09:11:16 -0600 Subject: [SCSI] qla2xxx: dpc thread can execute before scsi host has been added Fix crash in qla2x00_fdmi_register() due to the dpc thread executing before the scsi host has been fully added. Unable to handle kernel NULL pointer dereference (address 00000000000001d0) qla2xxx_7_dpc[4140]: Oops 8813272891392 [1] Call Trace: [] show_stack+0x50/0xa0 sp=e00000b07c59f930 bsp=e00000b07c591400 [] show_regs+0x820/0x860 sp=e00000b07c59fb00 bsp=e00000b07c5913a0 [] die+0x1a0/0x2e0 sp=e00000b07c59fb00 bsp=e00000b07c591360 [] ia64_do_page_fault+0x8c0/0x9e0 sp=e00000b07c59fb00 bsp=e00000b07c591310 [] ia64_native_leave_kernel+0x0/0x270 sp=e00000b07c59fb90 bsp=e00000b07c591310 [] qla2x00_fdmi_register+0x850/0xbe0 [qla2xxx] sp=e00000b07c59fd60 bsp=e00000b07c591290 [] qla2x00_configure_loop+0x1930/0x34c0 [qla2xxx] sp=e00000b07c59fd60 bsp=e00000b07c591128 [] qla2x00_loop_resync+0x1b0/0x2e0 [qla2xxx] sp=e00000b07c59fdf0 bsp=e00000b07c5910c0 [] qla2x00_do_dpc+0x9a0/0xce0 [qla2xxx] sp=e00000b07c59fdf0 bsp=e00000b07c590fa0 [] kthread+0x110/0x140 sp=e00000b07c59fe00 bsp=e00000b07c590f68 [] kernel_thread_helper+0xd0/0x100 sp=e00000b07c59fe30 bsp=e00000b07c590f40 [] start_kernel_thread+0x20/0x40 sp=e00000b07c59fe30 bsp=e00000b07c590f40 crash> dis a000000207197350 0xa000000207197350 : [MMI] ld1 r45=[r14];; crash> scsi_qla_host.host 0xe00000b058c73ff8 host = 0xe00000b058c73be0, crash> Scsi_Host.shost_data 0xe00000b058c73be0 shost_data = 0x0, <<<<<<<<<<< The fc_transport fc_* workqueue threads have yet to be created. crash> ps | grep _7 3891 2 2 e00000b075c80000 IN 0.0 0 0 [scsi_eh_7] 4140 2 3 e00000b07c590000 RU 0.0 0 0 [qla2xxx_7_dpc] The thread creating adding the Scsi_Host is blocked due to other activity in sysfs. crash> bt 3762 PID: 3762 TASK: e00000b071e70000 CPU: 3 COMMAND: "modprobe" #0 [BSP:e00000b071e71548] schedule at a000000100727e00 #1 [BSP:e00000b071e714c8] __mutex_lock_slowpath at a0000001007295a0 #2 [BSP:e00000b071e714a8] mutex_lock at a000000100729830 #3 [BSP:e00000b071e71478] sysfs_addrm_start at a0000001002584f0 #4 [BSP:e00000b071e71440] create_dir at a000000100259350 #5 [BSP:e00000b071e71410] sysfs_create_subdir at a000000100259510 #6 [BSP:e00000b071e713b0] internal_create_group at a00000010025c880 #7 [BSP:e00000b071e71388] sysfs_create_group at a00000010025cc50 #8 [BSP:e00000b071e71368] dpm_sysfs_add at a000000100425050 #9 [BSP:e00000b071e71310] device_add at a000000100417d90 #10 [BSP:e00000b071e712d8] scsi_add_host at a00000010045a380 #11 [BSP:e00000b071e71268] qla2x00_probe_one at a0000002071be950 #12 [BSP:e00000b071e71248] local_pci_probe at a00000010032e490 #13 [BSP:e00000b071e71218] pci_device_probe at a00000010032ecd0 #14 [BSP:e00000b071e711d8] driver_probe_device at a00000010041d480 #15 [BSP:e00000b071e711a8] __driver_attach at a00000010041d6e0 #16 [BSP:e00000b071e71170] bus_for_each_dev at a00000010041c240 #17 [BSP:e00000b071e71150] driver_attach at a00000010041d0a0 #18 [BSP:e00000b071e71108] bus_add_driver at a00000010041b080 #19 [BSP:e00000b071e710c0] driver_register at a00000010041dea0 #20 [BSP:e00000b071e71088] __pci_register_driver at a00000010032f610 #21 [BSP:e00000b071e71058] (unknown) at a000000207200270 #22 [BSP:e00000b071e71018] do_one_initcall at a00000010000a9c0 #23 [BSP:e00000b071e70f98] sys_init_module at a0000001000fef00 #24 [BSP:e00000b071e70f98] ia64_ret_from_syscall at a00000010000c740 So, it appears that qla2xxx dpc thread is moving forward before the scsi host has been completely added. This patch moves the setting of the init_done (and online) flag to after the call to scsi_add_host() to hold off the dpc thread. Found via large lun count testing using 2.6.31. Signed-off-by: Michael Reed Acked-by: Giridhar Malavali Cc: stable@kernel.org Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 4166935..58edc0d 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -2003,13 +2003,13 @@ skip_dpc: DEBUG2(printk("DEBUG: detect hba %ld at address = %p\n", base_vha->host_no, ha)); - base_vha->flags.init_done = 1; - base_vha->flags.online = 1; - ret = scsi_add_host(host, &pdev->dev); if (ret) goto probe_failed; + base_vha->flags.init_done = 1; + base_vha->flags.online = 1; + ha->isp_ops->enable_intrs(ha); scsi_scan_host(host); -- cgit v0.10.2 From c45dd30551c371cb1e7a742136b8b36f6aba63f8 Mon Sep 17 00:00:00 2001 From: Giridhar Malavali Date: Wed, 2 Dec 2009 10:36:54 -0800 Subject: [SCSI] qla2xxx: Queue depth ramp up/down modification changes. Removed the module parameters ql2xqfulltracking and ql2xqfullrampup since the queue depth ramp up/down functionality is moved to scsi-ml. Signed-off-by: Giridhar Malavali Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 6b9bf23..7a81e98 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -1570,9 +1570,6 @@ typedef struct fc_port { struct fc_rport *rport, *drport; u32 supported_classes; - unsigned long last_queue_full; - unsigned long last_ramp_up; - uint16_t vp_idx; } fc_port_t; diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index e218513..0b6801f 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -72,8 +72,6 @@ extern int ql2xloginretrycount; extern int ql2xfdmienable; extern int ql2xallocfwdump; extern int ql2xextended_error_logging; -extern int ql2xqfullrampup; -extern int ql2xqfulltracking; extern int ql2xiidmaenable; extern int ql2xmaxqueues; extern int ql2xmultique_tag; diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 8049873..bc07d83 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -811,78 +811,6 @@ skip_rio: qla2x00_alert_all_vps(rsp, mb); } -static void -qla2x00_adjust_sdev_qdepth_up(struct scsi_device *sdev, void *data) -{ - fc_port_t *fcport = data; - struct scsi_qla_host *vha = fcport->vha; - struct qla_hw_data *ha = vha->hw; - struct req_que *req = NULL; - - if (!ql2xqfulltracking) - return; - - req = vha->req; - if (!req) - return; - if (req->max_q_depth <= sdev->queue_depth) - return; - - if (sdev->ordered_tags) - scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, - sdev->queue_depth + 1); - else - scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, - sdev->queue_depth + 1); - - fcport->last_ramp_up = jiffies; - - DEBUG2(qla_printk(KERN_INFO, ha, - "scsi(%ld:%d:%d:%d): Queue depth adjusted-up to %d.\n", - fcport->vha->host_no, sdev->channel, sdev->id, sdev->lun, - sdev->queue_depth)); -} - -static void -qla2x00_adjust_sdev_qdepth_down(struct scsi_device *sdev, void *data) -{ - fc_port_t *fcport = data; - - if (!scsi_track_queue_full(sdev, sdev->queue_depth - 1)) - return; - - DEBUG2(qla_printk(KERN_INFO, fcport->vha->hw, - "scsi(%ld:%d:%d:%d): Queue depth adjusted-down to %d.\n", - fcport->vha->host_no, sdev->channel, sdev->id, sdev->lun, - sdev->queue_depth)); -} - -static inline void -qla2x00_ramp_up_queue_depth(scsi_qla_host_t *vha, struct req_que *req, - srb_t *sp) -{ - fc_port_t *fcport; - struct scsi_device *sdev; - - if (!ql2xqfulltracking) - return; - - sdev = sp->cmd->device; - if (sdev->queue_depth >= req->max_q_depth) - return; - - fcport = sp->fcport; - if (time_before(jiffies, - fcport->last_ramp_up + ql2xqfullrampup * HZ)) - return; - if (time_before(jiffies, - fcport->last_queue_full + ql2xqfullrampup * HZ)) - return; - - starget_for_each_device(sdev->sdev_target, fcport, - qla2x00_adjust_sdev_qdepth_up); -} - /** * qla2x00_process_completed_request() - Process a Fast Post response. * @ha: SCSI driver HA context @@ -913,8 +841,6 @@ qla2x00_process_completed_request(struct scsi_qla_host *vha, /* Save ISP completion status */ sp->cmd->result = DID_OK << 16; - - qla2x00_ramp_up_queue_depth(vha, req, sp); qla2x00_sp_compl(ha, sp); } else { DEBUG2(printk("scsi(%ld) Req:%d: Invalid ISP SCSI completion" @@ -1435,13 +1361,6 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) "scsi(%ld): QUEUE FULL status detected " "0x%x-0x%x.\n", vha->host_no, comp_status, scsi_status)); - - /* Adjust queue depth for all luns on the port. */ - if (!ql2xqfulltracking) - break; - fcport->last_queue_full = jiffies; - starget_for_each_device(cp->device->sdev_target, - fcport, qla2x00_adjust_sdev_qdepth_down); break; } if (lscsi_status != SS_CHECK_CONDITION) @@ -1516,17 +1435,6 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) "scsi(%ld): QUEUE FULL status detected " "0x%x-0x%x.\n", vha->host_no, comp_status, scsi_status)); - - /* - * Adjust queue depth for all luns on the - * port. - */ - if (!ql2xqfulltracking) - break; - fcport->last_queue_full = jiffies; - starget_for_each_device( - cp->device->sdev_target, fcport, - qla2x00_adjust_sdev_qdepth_down); break; } if (lscsi_status != SS_CHECK_CONDITION) diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 58edc0d..2f873d2 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -78,21 +78,6 @@ module_param(ql2xmaxqdepth, int, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(ql2xmaxqdepth, "Maximum queue depth to report for target devices."); -int ql2xqfulltracking = 1; -module_param(ql2xqfulltracking, int, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(ql2xqfulltracking, - "Controls whether the driver tracks queue full status " - "returns and dynamically adjusts a scsi device's queue " - "depth. Default is 1, perform tracking. Set to 0 to " - "disable dynamic tracking and adjustment of queue depth."); - -int ql2xqfullrampup = 120; -module_param(ql2xqfullrampup, int, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(ql2xqfullrampup, - "Number of seconds to wait to begin to ramp-up the queue " - "depth for a device after a queue-full condition has been " - "detected. Default is 120 seconds."); - int ql2xiidmaenable=1; module_param(ql2xiidmaenable, int, S_IRUGO|S_IRUSR); MODULE_PARM_DESC(ql2xiidmaenable, @@ -1217,13 +1202,61 @@ qla2xxx_slave_destroy(struct scsi_device *sdev) sdev->hostdata = NULL; } +static void qla2x00_handle_queue_full(struct scsi_device *sdev, int qdepth) +{ + fc_port_t *fcport = (struct fc_port *) sdev->hostdata; + + if (!scsi_track_queue_full(sdev, qdepth)) + return; + + DEBUG2(qla_printk(KERN_INFO, fcport->vha->hw, + "scsi(%ld:%d:%d:%d): Queue depth adjusted-down to %d.\n", + fcport->vha->host_no, sdev->channel, sdev->id, sdev->lun, + sdev->queue_depth)); +} + +static void qla2x00_adjust_sdev_qdepth_up(struct scsi_device *sdev, int qdepth) +{ + fc_port_t *fcport = sdev->hostdata; + struct scsi_qla_host *vha = fcport->vha; + struct qla_hw_data *ha = vha->hw; + struct req_que *req = NULL; + + req = vha->req; + if (!req) + return; + + if (req->max_q_depth <= sdev->queue_depth || req->max_q_depth < qdepth) + return; + + if (sdev->ordered_tags) + scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, qdepth); + else + scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, qdepth); + + DEBUG2(qla_printk(KERN_INFO, ha, + "scsi(%ld:%d:%d:%d): Queue depth adjusted-up to %d.\n", + fcport->vha->host_no, sdev->channel, sdev->id, sdev->lun, + sdev->queue_depth)); +} + static int qla2x00_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason) { - if (reason != SCSI_QDEPTH_DEFAULT) - return -EOPNOTSUPP; + switch (reason) { + case SCSI_QDEPTH_DEFAULT: + scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth); + break; + case SCSI_QDEPTH_QFULL: + qla2x00_handle_queue_full(sdev, qdepth); + break; + case SCSI_QDEPTH_RAMP_UP: + qla2x00_adjust_sdev_qdepth_up(sdev, qdepth); + break; + default: + return EOPNOTSUPP; + } - scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth); return sdev->queue_depth; } -- cgit v0.10.2 From 3155754a6b7985a80c41d84dd06530ff543f52a8 Mon Sep 17 00:00:00 2001 From: Anirban Chakraborty Date: Wed, 2 Dec 2009 10:36:55 -0800 Subject: [SCSI] qla2xxx: fix for multiqueue in MISX disabled case Fix to accommodate a hardware bug in multiqueue mode that does not work properly when acknowledgement of MSIX Interrupts is disabled. Signed-off-by: Anirban Chakraborty Signed-off-by: Giridhar Malavali Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 7a81e98..384afda 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -2262,6 +2262,7 @@ struct qla_hw_data { uint32_t port0 :1; uint32_t running_gold_fw :1; uint32_t cpu_affinity_enabled :1; + uint32_t disable_msix_handshake :1; } flags; /* This spinlock is used to protect "io transactions", you must @@ -2384,6 +2385,7 @@ struct qla_hw_data { #define IS_QLA81XX(ha) (IS_QLA8001(ha)) #define IS_QLA2XXX_MIDTYPE(ha) (IS_QLA24XX(ha) || IS_QLA84XX(ha) || \ IS_QLA25XX(ha) || IS_QLA81XX(ha)) +#define IS_MSIX_NACK_CAPABLE(ha) (IS_QLA81XX(ha)) #define IS_NOPOLLING_TYPE(ha) ((IS_QLA25XX(ha) || IS_QLA81XX(ha)) && \ (ha)->flags.msix_enabled) #define IS_FAC_REQUIRED(ha) (IS_QLA81XX(ha)) diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index b74924b..73a7935 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -1442,7 +1442,17 @@ qla24xx_config_rings(struct scsi_qla_host *vha) icb->firmware_options_2 |= __constant_cpu_to_le32(BIT_18); - icb->firmware_options_2 &= __constant_cpu_to_le32(~BIT_22); + /* Use Disable MSIX Handshake mode for capable adapters */ + if (IS_MSIX_NACK_CAPABLE(ha)) { + icb->firmware_options_2 &= + __constant_cpu_to_le32(~BIT_22); + ha->flags.disable_msix_handshake = 1; + qla_printk(KERN_INFO, ha, + "MSIX Handshake Disable Mode turned on\n"); + } else { + icb->firmware_options_2 |= + __constant_cpu_to_le32(BIT_22); + } icb->firmware_options_2 |= __constant_cpu_to_le32(BIT_23); WRT_REG_DWORD(®->isp25mq.req_q_in, 0); diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index bc07d83..1692a88 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -1928,7 +1928,7 @@ qla24xx_msix_rsp_q(int irq, void *dev_id) vha = qla25xx_get_host(rsp); qla24xx_process_response_queue(vha, rsp); - if (!ha->mqenable) { + if (!ha->flags.disable_msix_handshake) { WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); RD_REG_DWORD_RELAXED(®->hccr); } @@ -1942,6 +1942,7 @@ qla25xx_msix_rsp_q(int irq, void *dev_id) { struct qla_hw_data *ha; struct rsp_que *rsp; + struct device_reg_24xx __iomem *reg; rsp = (struct rsp_que *) dev_id; if (!rsp) { @@ -1951,6 +1952,14 @@ qla25xx_msix_rsp_q(int irq, void *dev_id) } ha = rsp->hw; + /* Clear the interrupt, if enabled, for this response queue */ + if (rsp->options & ~BIT_6) { + reg = &ha->iobase->isp24; + spin_lock_irq(&ha->hardware_lock); + WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); + RD_REG_DWORD_RELAXED(®->hccr); + spin_unlock_irq(&ha->hardware_lock); + } queue_work_on((int) (rsp->id - 1), ha->wq, &rsp->q_work); return IRQ_HANDLED; diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index a47d343..2a4c7f4 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c @@ -696,6 +696,10 @@ qla25xx_create_rsp_que(struct qla_hw_data *ha, uint16_t options, /* Use alternate PCI devfn */ if (LSB(rsp->rid)) options |= BIT_5; + /* Enable MSIX handshake mode on for uncapable adapters */ + if (!IS_MSIX_NACK_CAPABLE(ha)) + options |= BIT_6; + rsp->options = options; rsp->id = que_id; reg = ISP_QUE_REG(ha, que_id); -- cgit v0.10.2 From 7729cb785d27afef500cc7e7071de8c01d7dfdae Mon Sep 17 00:00:00 2001 From: Giridhar Malavali Date: Wed, 2 Dec 2009 10:36:56 -0800 Subject: [SCSI] qla2xxx: Update version number to 8.03.01-k8. Signed-off-by: Giridhar Malavali Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index 807e0db..c482220 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h @@ -7,7 +7,7 @@ /* * Driver version */ -#define QLA2XXX_VERSION "8.03.01-k7" +#define QLA2XXX_VERSION "8.03.01-k8" #define QLA_DRIVER_MAJOR_VER 8 #define QLA_DRIVER_MINOR_VER 3 -- cgit v0.10.2 From e46b63b37c3296f0aca92d8b62bbf130f2bec7dd Mon Sep 17 00:00:00 2001 From: Pravin Bathija Date: Wed, 2 Dec 2009 17:51:46 -0800 Subject: [SCSI] mpt fusion: Fix 32 bit platforms with 64 bit resources. Powerpc 44x uses 36 bit real address while the real address defined in MPT Fusion driver is of type 32 bit. This causes ioremap to fail and driver fails to initialize. This fix changes the data types representing the real address from unsigned long 32-bit types to resource_size_t which is 64-bit. The driver has been tested, the disks get discovered correctly and can do IO. [jejb: added printk fix for resource_size_t object] Signed-off-by: Pravin Bathija Acked-by: "Desai, Kashyap" Signed-off-by: James Bottomley diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 610e914..85bc6a6 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c @@ -1587,7 +1587,7 @@ mpt_mapresources(MPT_ADAPTER *ioc) { u8 __iomem *mem; int ii; - unsigned long mem_phys; + resource_size_t mem_phys; unsigned long port; u32 msize; u32 psize; @@ -1677,8 +1677,8 @@ mpt_mapresources(MPT_ADAPTER *ioc) return -EINVAL; } ioc->memmap = mem; - dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "mem = %p, mem_phys = %lx\n", - ioc->name, mem, mem_phys)); + dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "mem = %p, mem_phys = %llx\n", + ioc->name, mem, (unsigned long long)mem_phys)); ioc->mem_phys = mem_phys; ioc->chip = (SYSIF_REGS __iomem *)mem; -- cgit v0.10.2 From dcece412da92aa619c0d891a17306b9adf86ab0e Mon Sep 17 00:00:00 2001 From: Yi Zou Date: Fri, 20 Nov 2009 15:22:21 -0800 Subject: [SCSI] fcoe: Use LLD's WWPN and WWNN for lport if LLD supports ndo_fcoe_get_wwn If the LLD wants its own WWNN/WWPN to be used, it should implement the netdev_ops.ndo_fcoe_get_wwn(). If that is the case, we query the LLD and use the queried WWNN/WWPN from the LLD. Signed-off-by: Yi Zou Signed-off-by: Robert Love Signed-off-by: James Bottomley diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index a30ffaa..9b6aebb 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c @@ -545,6 +545,23 @@ static void fcoe_queue_timer(ulong lport) } /** + * fcoe_get_wwn() - Get the world wide name from LLD if it supports it + * @netdev: the associated net device + * @wwn: the output WWN + * @type: the type of WWN (WWPN or WWNN) + * + * Returns: 0 for success + */ +static int fcoe_get_wwn(struct net_device *netdev, u64 *wwn, int type) +{ + const struct net_device_ops *ops = netdev->netdev_ops; + + if (ops->ndo_fcoe_get_wwn) + return ops->ndo_fcoe_get_wwn(netdev, wwn, type); + return -EINVAL; +} + +/** * fcoe_netdev_config() - Set up net devive for SW FCoE * @lport: The local port that is associated with the net device * @netdev: The associated net device @@ -611,9 +628,13 @@ static int fcoe_netdev_config(struct fc_lport *lport, struct net_device *netdev) */ if (netdev->priv_flags & IFF_802_1Q_VLAN) vid = vlan_dev_vlan_id(netdev); - wwnn = fcoe_wwn_from_mac(fcoe->ctlr.ctl_src_addr, 1, 0); + + if (fcoe_get_wwn(netdev, &wwnn, NETDEV_FCOE_WWNN)) + wwnn = fcoe_wwn_from_mac(fcoe->ctlr.ctl_src_addr, 1, 0); fc_set_wwnn(lport, wwnn); - wwpn = fcoe_wwn_from_mac(fcoe->ctlr.ctl_src_addr, 2, vid); + if (fcoe_get_wwn(netdev, &wwpn, NETDEV_FCOE_WWPN)) + wwpn = fcoe_wwn_from_mac(fcoe->ctlr.ctl_src_addr, + 2, vid); fc_set_wwpn(lport, wwpn); } -- cgit v0.10.2 From 99c965dd9ee1a004efc083c3d760ba982bb76adf Mon Sep 17 00:00:00 2001 From: Kleber Sacilotto de Souza Date: Wed, 25 Nov 2009 20:13:43 -0200 Subject: [SCSI] ipr: fix EEH recovery After commits c82f63e411f1b58427c103bd95af2863b1c96dd1 (PCI: check saved state before restore) and 4b77b0a2ba27d64f58f16d8d4d48d8319dda36ff (PCI: Clear saved_state after the state has been restored) PCI drivers are prevented from restoring the device standard configuration registers twice in a row. These changes introduced a regression on ipr EEH recovery. The ipr device driver saves the PCI state only during the device probe and restores it on ipr_reset_restore_cfg_space() during IOA resets. This behavior is causing the EEH recovery to fail after the second error detected, since the registers are not being restored. One possible solution would be saving the registers after restoring them. The problem with this approach is that while recovering from an EEH error if pci_save_state() results in an EEH error, the adapter/slot will be reset, and end up back in ipr_reset_restore_cfg_space(), but it won't have a valid saved state to restore, so pci_restore_state() will fail. The following patch introduces a workaround for this problem, hacking around the PCI API by setting pdev->state_saved = true before we do the restore. It fixes the EEH regression and prevents that we hit another EEH error during EEH recovery. [jejb: fix is a hack ... Jesse and Rafael will fix properly] Signed-off-by: Kleber Sacilotto de Souza Acked-by: Brian King Cc: Jesse Barnes Cc: stable@kernel.org Signed-off-by: James Bottomley diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 206c2fa..83a6b92 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -6521,6 +6521,7 @@ static int ipr_reset_restore_cfg_space(struct ipr_cmnd *ipr_cmd) int rc; ENTER; + ioa_cfg->pdev->state_saved = true; rc = pci_restore_state(ioa_cfg->pdev); if (rc != PCIBIOS_SUCCESSFUL) { -- cgit v0.10.2 From 5d9e1fa99c2a9a5977f5757f4e0fd02697c995c2 Mon Sep 17 00:00:00 2001 From: Anil Veerabhadrappa Date: Mon, 7 Dec 2009 11:39:33 -0800 Subject: [SCSI] bnx2i: Add 5771E device support to bnx2i driver Signed-off-by: Anil Veerabhadrappa Reviewed-by: Mike Christie Signed-off-by: James Bottomley diff --git a/drivers/scsi/bnx2i/bnx2i_init.c b/drivers/scsi/bnx2i/bnx2i_init.c index 0c4210d..1dba86c 100644 --- a/drivers/scsi/bnx2i/bnx2i_init.c +++ b/drivers/scsi/bnx2i/bnx2i_init.c @@ -83,8 +83,12 @@ void bnx2i_identify_device(struct bnx2i_hba *hba) set_bit(BNX2I_NX2_DEV_5709, &hba->cnic_dev_type); hba->mail_queue_access = BNX2I_MQ_BIN_MODE; } else if (hba->pci_did == PCI_DEVICE_ID_NX2_57710 || - hba->pci_did == PCI_DEVICE_ID_NX2_57711) + hba->pci_did == PCI_DEVICE_ID_NX2_57711 || + hba->pci_did == PCI_DEVICE_ID_NX2_57711E) set_bit(BNX2I_NX2_DEV_57710, &hba->cnic_dev_type); + else + printk(KERN_ALERT "bnx2i: unknown device, 0x%x\n", + hba->pci_did); } -- cgit v0.10.2 From f8c9abe797c54e798b4025b54d71e5d2054c929a Mon Sep 17 00:00:00 2001 From: Anil Veerabhadrappa Date: Mon, 7 Dec 2009 11:39:54 -0800 Subject: [SCSI] bnx2i: Adjust sq_size module parametr to power of 2 only if a non-zero value is specified This issue was discovered during 10G iscsi testing Default value of 'sq_size' module parameter is '0' which means driver should use predefined SQ queue size when setting up iscsi connection. roundup_pow_of_two(0) results in '1' and forces driver to setup connections with send queue size of '1' and results in lower performance as well Signed-off-by: Anil Veerabhadrappa Reviewed-by: Mike Christie Signed-off-by: James Bottomley diff --git a/drivers/scsi/bnx2i/bnx2i_init.c b/drivers/scsi/bnx2i/bnx2i_init.c index 1dba86c..0307f85 100644 --- a/drivers/scsi/bnx2i/bnx2i_init.c +++ b/drivers/scsi/bnx2i/bnx2i_init.c @@ -367,7 +367,7 @@ static int __init bnx2i_mod_init(void) printk(KERN_INFO "%s", version); - if (!is_power_of_2(sq_size)) + if (sq_size && !is_power_of_2(sq_size)) sq_size = roundup_pow_of_two(sq_size); mutex_init(&bnx2i_dev_lock); -- cgit v0.10.2 From 8776193bc308553ac0011b3bb2dd1837e0c6ab28 Mon Sep 17 00:00:00 2001 From: Anil Veerabhadrappa Date: Mon, 7 Dec 2009 11:40:18 -0800 Subject: [SCSI] bnx2i: update CQ arming algorith for 5771x chipsets Only affects 5771x (10G chipsets) devices This is an optimized CQ arming algoritm which takes into account the number of outstanding tasks Signed-off-by: Anil Veerabhadrappa Signed-off-by: James Bottomley diff --git a/drivers/scsi/bnx2i/bnx2i.h b/drivers/scsi/bnx2i/bnx2i.h index 2b973f3..6cf9dc3 100644 --- a/drivers/scsi/bnx2i/bnx2i.h +++ b/drivers/scsi/bnx2i/bnx2i.h @@ -684,6 +684,7 @@ extern unsigned int error_mask1, error_mask2; extern u64 iscsi_error_mask; extern unsigned int en_tcp_dack; extern unsigned int event_coal_div; +extern unsigned int event_coal_min; extern struct scsi_transport_template *bnx2i_scsi_xport_template; extern struct iscsi_transport bnx2i_iscsi_transport; diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c index 5c8d763..bb69a14 100644 --- a/drivers/scsi/bnx2i/bnx2i_hwi.c +++ b/drivers/scsi/bnx2i/bnx2i_hwi.c @@ -133,20 +133,38 @@ void bnx2i_arm_cq_event_coalescing(struct bnx2i_endpoint *ep, u8 action) { struct bnx2i_5771x_cq_db *cq_db; u16 cq_index; + u16 next_index; + u32 num_active_cmds; + + /* Coalesce CQ entries only on 10G devices */ if (!test_bit(BNX2I_NX2_DEV_57710, &ep->hba->cnic_dev_type)) return; + /* Do not update CQ DB multiple times before firmware writes + * '0xFFFF' to CQDB->SQN field. Deviation may cause spurious + * interrupts and other unwanted results + */ + cq_db = (struct bnx2i_5771x_cq_db *) ep->qp.cq_pgtbl_virt; + if (cq_db->sqn[0] && cq_db->sqn[0] != 0xFFFF) + return; + if (action == CNIC_ARM_CQE) { - cq_index = ep->qp.cqe_exp_seq_sn + - ep->num_active_cmds / event_coal_div; - cq_index %= (ep->qp.cqe_size * 2 + 1); - if (!cq_index) { + num_active_cmds = ep->num_active_cmds; + if (num_active_cmds <= event_coal_min) + next_index = 1; + else + next_index = event_coal_min + + (num_active_cmds - event_coal_min) / event_coal_div; + if (!next_index) + next_index = 1; + cq_index = ep->qp.cqe_exp_seq_sn + next_index - 1; + if (cq_index > ep->qp.cqe_size * 2) + cq_index -= ep->qp.cqe_size * 2; + if (!cq_index) cq_index = 1; - cq_db = (struct bnx2i_5771x_cq_db *) - ep->qp.cq_pgtbl_virt; - cq_db->sqn[0] = cq_index; - } + + cq_db->sqn[0] = cq_index; } } diff --git a/drivers/scsi/bnx2i/bnx2i_init.c b/drivers/scsi/bnx2i/bnx2i_init.c index 0307f85..465241d 100644 --- a/drivers/scsi/bnx2i/bnx2i_init.c +++ b/drivers/scsi/bnx2i/bnx2i_init.c @@ -32,6 +32,10 @@ MODULE_VERSION(DRV_MODULE_VERSION); static DEFINE_MUTEX(bnx2i_dev_lock); +unsigned int event_coal_min = 24; +module_param(event_coal_min, int, 0664); +MODULE_PARM_DESC(event_coal_min, "Event Coalescing Minimum Commands"); + unsigned int event_coal_div = 1; module_param(event_coal_div, int, 0664); MODULE_PARM_DESC(event_coal_div, "Event Coalescing Divide Factor"); -- cgit v0.10.2 From 85fef20222bda1ee41f97ff94a927180ef0b97e6 Mon Sep 17 00:00:00 2001 From: Anil Veerabhadrappa Date: Mon, 7 Dec 2009 11:40:29 -0800 Subject: [SCSI] bnx2i: Task management ABORT TASK fixes Due to typo error driver was failing TMF Abort Task request when ctask->sc != NULL. Fixed code to fail TMF ABORT Task request only when ctask->sc == NULL. Clear age component (19 most significant bits) of reference ITT carried in iSCSI TMF PDU. Age component is internal to initiator side and only lower bits of ITT as defined by ISCSI_ITT_MASK is is sent on wire. Retrieve LUN directly from the ref_sc and update SQ wqe as per chip HSI (Host Software Interface) specification Signed-off-by: Anil Veerabhadrappa Reviewed-by: Mike Christie Signed-off-by: James Bottomley diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c index bb69a14..1af578d 100644 --- a/drivers/scsi/bnx2i/bnx2i_hwi.c +++ b/drivers/scsi/bnx2i/bnx2i_hwi.c @@ -384,6 +384,7 @@ int bnx2i_send_iscsi_tmf(struct bnx2i_conn *bnx2i_conn, struct bnx2i_cmd *bnx2i_cmd; struct bnx2i_tmf_request *tmfabort_wqe; u32 dword; + u32 scsi_lun[2]; bnx2i_cmd = (struct bnx2i_cmd *)mtask->dd_data; tmfabort_hdr = (struct iscsi_tm *)mtask->hdr; @@ -394,27 +395,35 @@ int bnx2i_send_iscsi_tmf(struct bnx2i_conn *bnx2i_conn, tmfabort_wqe->op_attr = 0; tmfabort_wqe->op_attr = ISCSI_TMF_REQUEST_ALWAYS_ONE | ISCSI_TM_FUNC_ABORT_TASK; - tmfabort_wqe->lun[0] = be32_to_cpu(tmfabort_hdr->lun[0]); - tmfabort_wqe->lun[1] = be32_to_cpu(tmfabort_hdr->lun[1]); tmfabort_wqe->itt = (mtask->itt | (ISCSI_TASK_TYPE_MPATH << 14)); tmfabort_wqe->reserved2 = 0; tmfabort_wqe->cmd_sn = be32_to_cpu(tmfabort_hdr->cmdsn); ctask = iscsi_itt_to_task(conn, tmfabort_hdr->rtt); - if (!ctask || ctask->sc) + if (!ctask || !ctask->sc) /* * the iscsi layer must have completed the cmd while this * was starting up. + * + * Note: In the case of a SCSI cmd timeout, the task's sc + * is still active; hence ctask->sc != 0 + * In this case, the task must be aborted */ return 0; + ref_sc = ctask->sc; + /* Retrieve LUN directly from the ref_sc */ + int_to_scsilun(ref_sc->device->lun, (struct scsi_lun *) scsi_lun); + tmfabort_wqe->lun[0] = be32_to_cpu(scsi_lun[0]); + tmfabort_wqe->lun[1] = be32_to_cpu(scsi_lun[1]); + if (ref_sc->sc_data_direction == DMA_TO_DEVICE) dword = (ISCSI_TASK_TYPE_WRITE << ISCSI_CMD_REQUEST_TYPE_SHIFT); else dword = (ISCSI_TASK_TYPE_READ << ISCSI_CMD_REQUEST_TYPE_SHIFT); - tmfabort_wqe->ref_itt = (dword | tmfabort_hdr->rtt); + tmfabort_wqe->ref_itt = (dword | (tmfabort_hdr->rtt & ISCSI_ITT_MASK)); tmfabort_wqe->ref_cmd_sn = be32_to_cpu(tmfabort_hdr->refcmdsn); tmfabort_wqe->bd_list_addr_lo = (u32) bnx2i_conn->hba->mp_bd_dma; -- cgit v0.10.2 From 45ca38e753016432a266a18679268a4c4674fb52 Mon Sep 17 00:00:00 2001 From: Anil Veerabhadrappa Date: Mon, 7 Dec 2009 11:40:39 -0800 Subject: [SCSI] bnx2i: minor code cleanup and update driver version Removed duplicate function call and not-so-useful comment line Signed-off-by: Anil Veerabhadrappa Reviewed-by: Mike Christie Signed-off-by: James Bottomley diff --git a/drivers/scsi/bnx2i/bnx2i_init.c b/drivers/scsi/bnx2i/bnx2i_init.c index 465241d..6d8172e 100644 --- a/drivers/scsi/bnx2i/bnx2i_init.c +++ b/drivers/scsi/bnx2i/bnx2i_init.c @@ -17,8 +17,8 @@ static struct list_head adapter_list = LIST_HEAD_INIT(adapter_list); static u32 adapter_count; #define DRV_MODULE_NAME "bnx2i" -#define DRV_MODULE_VERSION "2.0.1e" -#define DRV_MODULE_RELDATE "June 22, 2009" +#define DRV_MODULE_VERSION "2.1.0" +#define DRV_MODULE_RELDATE "Dec 06, 2009" static char version[] __devinitdata = "Broadcom NetXtreme II iSCSI Driver " DRV_MODULE_NAME \ diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c index 132898c..33b2294 100644 --- a/drivers/scsi/bnx2i/bnx2i_iscsi.c +++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c @@ -485,7 +485,6 @@ static int bnx2i_setup_cmd_pool(struct bnx2i_hba *hba, struct iscsi_task *task = session->cmds[i]; struct bnx2i_cmd *cmd = task->dd_data; - /* Anil */ task->hdr = &cmd->hdr; task->hdr_max = sizeof(struct iscsi_hdr); @@ -765,7 +764,6 @@ struct bnx2i_hba *bnx2i_alloc_hba(struct cnic_dev *cnic) hba->pci_svid = hba->pcidev->subsystem_vendor; hba->pci_func = PCI_FUNC(hba->pcidev->devfn); hba->pci_devno = PCI_SLOT(hba->pcidev->devfn); - bnx2i_identify_device(hba); bnx2i_identify_device(hba); bnx2i_setup_host_queue_size(hba, shost); -- cgit v0.10.2 From 0109abffbf91b76e2a34e324a407d780a55fc1ab Mon Sep 17 00:00:00 2001 From: "kxie@chelsio.com" Date: Wed, 9 Dec 2009 21:25:36 -0800 Subject: [SCSI] cxgb3i: always use negative errno in case of error Signed-off-by: Karen Xie Signed-off-by: James Bottomley diff --git a/drivers/scsi/cxgb3i/cxgb3i_offload.c b/drivers/scsi/cxgb3i/cxgb3i_offload.c index c1d5be4..26ffdcd 100644 --- a/drivers/scsi/cxgb3i/cxgb3i_offload.c +++ b/drivers/scsi/cxgb3i/cxgb3i_offload.c @@ -291,7 +291,7 @@ static void act_open_req_arp_failure(struct t3cdev *dev, struct sk_buff *skb) c3cn_hold(c3cn); spin_lock_bh(&c3cn->lock); if (c3cn->state == C3CN_STATE_CONNECTING) - fail_act_open(c3cn, EHOSTUNREACH); + fail_act_open(c3cn, -EHOSTUNREACH); spin_unlock_bh(&c3cn->lock); c3cn_put(c3cn); __kfree_skb(skb); @@ -792,18 +792,18 @@ static int act_open_rpl_status_to_errno(int status) { switch (status) { case CPL_ERR_CONN_RESET: - return ECONNREFUSED; + return -ECONNREFUSED; case CPL_ERR_ARP_MISS: - return EHOSTUNREACH; + return -EHOSTUNREACH; case CPL_ERR_CONN_TIMEDOUT: - return ETIMEDOUT; + return -ETIMEDOUT; case CPL_ERR_TCAM_FULL: - return ENOMEM; + return -ENOMEM; case CPL_ERR_CONN_EXIST: cxgb3i_log_error("ACTIVE_OPEN_RPL: 4-tuple in use\n"); - return EADDRINUSE; + return -EADDRINUSE; default: - return EIO; + return -EIO; } } @@ -817,7 +817,7 @@ static void act_open_retry_timer(unsigned long data) spin_lock_bh(&c3cn->lock); skb = alloc_skb(sizeof(struct cpl_act_open_req), GFP_ATOMIC); if (!skb) - fail_act_open(c3cn, ENOMEM); + fail_act_open(c3cn, -ENOMEM); else { skb->sk = (struct sock *)c3cn; set_arp_failure_handler(skb, act_open_req_arp_failure); @@ -966,14 +966,14 @@ static int abort_status_to_errno(struct s3_conn *c3cn, int abort_reason, case CPL_ERR_BAD_SYN: /* fall through */ case CPL_ERR_CONN_RESET: return c3cn->state > C3CN_STATE_ESTABLISHED ? - EPIPE : ECONNRESET; + -EPIPE : -ECONNRESET; case CPL_ERR_XMIT_TIMEDOUT: case CPL_ERR_PERSIST_TIMEDOUT: case CPL_ERR_FINWAIT2_TIMEDOUT: case CPL_ERR_KEEPALIVE_TIMEDOUT: - return ETIMEDOUT; + return -ETIMEDOUT; default: - return EIO; + return -EIO; } } @@ -1563,7 +1563,7 @@ free_tid: s3_free_atid(cdev, c3cn->tid); c3cn->tid = 0; out_err: - return -1; + return -EINVAL; } diff --git a/drivers/scsi/cxgb3i/cxgb3i_pdu.c b/drivers/scsi/cxgb3i/cxgb3i_pdu.c index 7091050..1fe3b0f 100644 --- a/drivers/scsi/cxgb3i/cxgb3i_pdu.c +++ b/drivers/scsi/cxgb3i/cxgb3i_pdu.c @@ -388,8 +388,8 @@ int cxgb3i_conn_xmit_pdu(struct iscsi_task *task) if (err > 0) { int pdulen = err; - cxgb3i_tx_debug("task 0x%p, skb 0x%p, len %u/%u, rv %d.\n", - task, skb, skb->len, skb->data_len, err); + cxgb3i_tx_debug("task 0x%p, skb 0x%p, len %u/%u, rv %d.\n", + task, skb, skb->len, skb->data_len, err); if (task->conn->hdrdgst_en) pdulen += ISCSI_DIGEST_SIZE; -- cgit v0.10.2 From edd163687ea59f01d6b43c9e1fdaa0126fa30191 Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Tue, 8 Dec 2009 14:09:11 -0800 Subject: [SCSI] hpsa: add driver for HP Smart Array controllers. This driver supports a subset of HP Smart Array Controllers. It is a SCSI alternative to the cciss driver. [akpm@linux-foundation.org: avoid helpful cleanup patches] [achiang@hp.com: make device attrs static] [akpm@linux-foundation.org: msleep() does set_current_state() itself] Signed-off-by: Stephen M. Cameron Signed-off-by: Mike Miller Signed-off-by: Alex Chiang Signed-off-by: Andrew Morton Signed-off-by: James Bottomley diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 36900c7..9191d1e 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -388,6 +388,16 @@ config BLK_DEV_3W_XXXX_RAID Please read the comments at the top of . +config SCSI_HPSA + tristate "HP Smart Array SCSI driver" + depends on PCI && SCSI + help + This driver supports HP Smart Array Controllers (circa 2009). + It is a SCSI alternative to the cciss driver, which is a block + driver. Anyone wishing to use HP Smart Array controllers who + would prefer the devices be presented to linux as SCSI devices, + rather than as generic block devices should say Y here. + config SCSI_3W_9XXX tristate "3ware 9xxx SATA-RAID support" depends on PCI && SCSI diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index 280d3c657..92a8c50 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile @@ -91,6 +91,7 @@ obj-$(CONFIG_SCSI_BFA_FC) += bfa/ obj-$(CONFIG_SCSI_PAS16) += pas16.o obj-$(CONFIG_SCSI_T128) += t128.o obj-$(CONFIG_SCSI_DMX3191D) += dmx3191d.o +obj-$(CONFIG_SCSI_HPSA) += hpsa.o obj-$(CONFIG_SCSI_DTC3280) += dtc.o obj-$(CONFIG_SCSI_SYM53C8XX_2) += sym53c8xx_2/ obj-$(CONFIG_SCSI_ZALON) += zalon7xx.o diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c new file mode 100644 index 0000000..bb96fdd --- /dev/null +++ b/drivers/scsi/hpsa.c @@ -0,0 +1,3531 @@ +/* + * Disk Array driver for HP Smart Array SAS controllers + * Copyright 2000, 2009 Hewlett-Packard Development Company, L.P. + * + * 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, GOOD TITLE or + * NON INFRINGEMENT. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Questions/Comments/Bugfixes to iss_storagedev@hp.com + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "hpsa_cmd.h" +#include "hpsa.h" + +/* HPSA_DRIVER_VERSION must be 3 byte values (0-255) separated by '.' */ +#define HPSA_DRIVER_VERSION "1.0.0" +#define DRIVER_NAME "HP HPSA Driver (v " HPSA_DRIVER_VERSION ")" + +/* How long to wait (in milliseconds) for board to go into simple mode */ +#define MAX_CONFIG_WAIT 30000 +#define MAX_IOCTL_CONFIG_WAIT 1000 + +/*define how many times we will try a command because of bus resets */ +#define MAX_CMD_RETRIES 3 + +/* Embedded module documentation macros - see modules.h */ +MODULE_AUTHOR("Hewlett-Packard Company"); +MODULE_DESCRIPTION("Driver for HP Smart Array Controller version " \ + HPSA_DRIVER_VERSION); +MODULE_SUPPORTED_DEVICE("HP Smart Array Controllers"); +MODULE_VERSION(HPSA_DRIVER_VERSION); +MODULE_LICENSE("GPL"); + +static int hpsa_allow_any; +module_param(hpsa_allow_any, int, S_IRUGO|S_IWUSR); +MODULE_PARM_DESC(hpsa_allow_any, + "Allow hpsa driver to access unknown HP Smart Array hardware"); + +/* define the PCI info for the cards we can control */ +static const struct pci_device_id hpsa_pci_device_id[] = { + {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC, 0x103C, 0x3223}, + {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC, 0x103C, 0x3234}, + {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC, 0x103C, 0x323D}, + {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3241}, + {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3243}, + {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3245}, + {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3247}, + {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3249}, + {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x324a}, + {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x324b}, + {PCI_VENDOR_ID_HP, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, + PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0}, + {0,} +}; + +MODULE_DEVICE_TABLE(pci, hpsa_pci_device_id); + +/* board_id = Subsystem Device ID & Vendor ID + * product = Marketing Name for the board + * access = Address of the struct of function pointers + */ +static struct board_type products[] = { + {0x3223103C, "Smart Array P800", &SA5_access}, + {0x3234103C, "Smart Array P400", &SA5_access}, + {0x323d103c, "Smart Array P700M", &SA5_access}, + {0x3241103C, "Smart Array P212", &SA5_access}, + {0x3243103C, "Smart Array P410", &SA5_access}, + {0x3245103C, "Smart Array P410i", &SA5_access}, + {0x3247103C, "Smart Array P411", &SA5_access}, + {0x3249103C, "Smart Array P812", &SA5_access}, + {0x324a103C, "Smart Array P712m", &SA5_access}, + {0x324b103C, "Smart Array P711m", &SA5_access}, + {0xFFFF103C, "Unknown Smart Array", &SA5_access}, +}; + +static int number_of_controllers; + +static irqreturn_t do_hpsa_intr(int irq, void *dev_id); +static int hpsa_ioctl(struct scsi_device *dev, int cmd, void *arg); +static void start_io(struct ctlr_info *h); + +#ifdef CONFIG_COMPAT +static int hpsa_compat_ioctl(struct scsi_device *dev, int cmd, void *arg); +#endif + +static void cmd_free(struct ctlr_info *h, struct CommandList *c); +static void cmd_special_free(struct ctlr_info *h, struct CommandList *c); +static struct CommandList *cmd_alloc(struct ctlr_info *h); +static struct CommandList *cmd_special_alloc(struct ctlr_info *h); +static void fill_cmd(struct CommandList *c, __u8 cmd, struct ctlr_info *h, + void *buff, size_t size, __u8 page_code, unsigned char *scsi3addr, + int cmd_type); + +static int hpsa_scsi_queue_command(struct scsi_cmnd *cmd, + void (*done)(struct scsi_cmnd *)); + +static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd); +static int hpsa_slave_alloc(struct scsi_device *sdev); +static void hpsa_slave_destroy(struct scsi_device *sdev); + +static ssize_t raid_level_show(struct device *dev, + struct device_attribute *attr, char *buf); +static ssize_t lunid_show(struct device *dev, + struct device_attribute *attr, char *buf); +static ssize_t unique_id_show(struct device *dev, + struct device_attribute *attr, char *buf); +static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno); +static ssize_t host_store_rescan(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count); +static int check_for_unit_attention(struct ctlr_info *h, + struct CommandList *c); +static void check_ioctl_unit_attention(struct ctlr_info *h, + struct CommandList *c); + +static DEVICE_ATTR(raid_level, S_IRUGO, raid_level_show, NULL); +static DEVICE_ATTR(lunid, S_IRUGO, lunid_show, NULL); +static DEVICE_ATTR(unique_id, S_IRUGO, unique_id_show, NULL); +static DEVICE_ATTR(rescan, S_IWUSR, NULL, host_store_rescan); + +static struct device_attribute *hpsa_sdev_attrs[] = { + &dev_attr_raid_level, + &dev_attr_lunid, + &dev_attr_unique_id, + NULL, +}; + +static struct device_attribute *hpsa_shost_attrs[] = { + &dev_attr_rescan, + NULL, +}; + +static struct scsi_host_template hpsa_driver_template = { + .module = THIS_MODULE, + .name = "hpsa", + .proc_name = "hpsa", + .queuecommand = hpsa_scsi_queue_command, + .can_queue = 512, + .this_id = -1, + .sg_tablesize = MAXSGENTRIES, + .cmd_per_lun = 512, + .use_clustering = ENABLE_CLUSTERING, + .eh_device_reset_handler = hpsa_eh_device_reset_handler, + .ioctl = hpsa_ioctl, + .slave_alloc = hpsa_slave_alloc, + .slave_destroy = hpsa_slave_destroy, +#ifdef CONFIG_COMPAT + .compat_ioctl = hpsa_compat_ioctl, +#endif + .sdev_attrs = hpsa_sdev_attrs, + .shost_attrs = hpsa_shost_attrs, +}; + +static inline struct ctlr_info *sdev_to_hba(struct scsi_device *sdev) +{ + unsigned long *priv = shost_priv(sdev->host); + return (struct ctlr_info *) *priv; +} + +static struct task_struct *hpsa_scan_thread; +static DEFINE_MUTEX(hpsa_scan_mutex); +static LIST_HEAD(hpsa_scan_q); +static int hpsa_scan_func(void *data); + +/** + * add_to_scan_list() - add controller to rescan queue + * @h: Pointer to the controller. + * + * Adds the controller to the rescan queue if not already on the queue. + * + * returns 1 if added to the queue, 0 if skipped (could be on the + * queue already, or the controller could be initializing or shutting + * down). + **/ +static int add_to_scan_list(struct ctlr_info *h) +{ + struct ctlr_info *test_h; + int found = 0; + int ret = 0; + + if (h->busy_initializing) + return 0; + + /* + * If we don't get the lock, it means the driver is unloading + * and there's no point in scheduling a new scan. + */ + if (!mutex_trylock(&h->busy_shutting_down)) + return 0; + + mutex_lock(&hpsa_scan_mutex); + list_for_each_entry(test_h, &hpsa_scan_q, scan_list) { + if (test_h == h) { + found = 1; + break; + } + } + if (!found && !h->busy_scanning) { + INIT_COMPLETION(h->scan_wait); + list_add_tail(&h->scan_list, &hpsa_scan_q); + ret = 1; + } + mutex_unlock(&hpsa_scan_mutex); + mutex_unlock(&h->busy_shutting_down); + + return ret; +} + +/** + * remove_from_scan_list() - remove controller from rescan queue + * @h: Pointer to the controller. + * + * Removes the controller from the rescan queue if present. Blocks if + * the controller is currently conducting a rescan. The controller + * can be in one of three states: + * 1. Doesn't need a scan + * 2. On the scan list, but not scanning yet (we remove it) + * 3. Busy scanning (and not on the list). In this case we want to wait for + * the scan to complete to make sure the scanning thread for this + * controller is completely idle. + **/ +static void remove_from_scan_list(struct ctlr_info *h) +{ + struct ctlr_info *test_h, *tmp_h; + + mutex_lock(&hpsa_scan_mutex); + list_for_each_entry_safe(test_h, tmp_h, &hpsa_scan_q, scan_list) { + if (test_h == h) { /* state 2. */ + list_del(&h->scan_list); + complete_all(&h->scan_wait); + mutex_unlock(&hpsa_scan_mutex); + return; + } + } + if (h->busy_scanning) { /* state 3. */ + mutex_unlock(&hpsa_scan_mutex); + wait_for_completion(&h->scan_wait); + } else { /* state 1, nothing to do. */ + mutex_unlock(&hpsa_scan_mutex); + } +} + +/* hpsa_scan_func() - kernel thread used to rescan controllers + * @data: Ignored. + * + * A kernel thread used scan for drive topology changes on + * controllers. The thread processes only one controller at a time + * using a queue. Controllers are added to the queue using + * add_to_scan_list() and removed from the queue either after done + * processing or using remove_from_scan_list(). + * + * returns 0. + **/ +static int hpsa_scan_func(__attribute__((unused)) void *data) +{ + struct ctlr_info *h; + int host_no; + + while (1) { + set_current_state(TASK_INTERRUPTIBLE); + schedule(); + if (kthread_should_stop()) + break; + + while (1) { + mutex_lock(&hpsa_scan_mutex); + if (list_empty(&hpsa_scan_q)) { + mutex_unlock(&hpsa_scan_mutex); + break; + } + h = list_entry(hpsa_scan_q.next, struct ctlr_info, + scan_list); + list_del(&h->scan_list); + h->busy_scanning = 1; + mutex_unlock(&hpsa_scan_mutex); + host_no = h->scsi_host ? h->scsi_host->host_no : -1; + hpsa_update_scsi_devices(h, host_no); + complete_all(&h->scan_wait); + mutex_lock(&hpsa_scan_mutex); + h->busy_scanning = 0; + mutex_unlock(&hpsa_scan_mutex); + } + } + return 0; +} + +static int check_for_unit_attention(struct ctlr_info *h, + struct CommandList *c) +{ + if (c->err_info->SenseInfo[2] != UNIT_ATTENTION) + return 0; + + switch (c->err_info->SenseInfo[12]) { + case STATE_CHANGED: + dev_warn(&h->pdev->dev, "hpsa%d: a state change " + "detected, command retried\n", h->ctlr); + break; + case LUN_FAILED: + dev_warn(&h->pdev->dev, "hpsa%d: LUN failure " + "detected, action required\n", h->ctlr); + break; + case REPORT_LUNS_CHANGED: + dev_warn(&h->pdev->dev, "hpsa%d: report LUN data " + "changed\n", h->ctlr); + /* + * Here, we could call add_to_scan_list and wake up the scan thread, + * except that it's quite likely that we will get more than one + * REPORT_LUNS_CHANGED condition in quick succession, which means + * that those which occur after the first one will likely happen + * *during* the hpsa_scan_thread's rescan. And the rescan code is not + * robust enough to restart in the middle, undoing what it has already + * done, and it's not clear that it's even possible to do this, since + * part of what it does is notify the SCSI mid layer, which starts + * doing it's own i/o to read partition tables and so on, and the + * driver doesn't have visibility to know what might need undoing. + * In any event, if possible, it is horribly complicated to get right + * so we just don't do it for now. + * + * Note: this REPORT_LUNS_CHANGED condition only occurs on the MSA2012. + */ + break; + case POWER_OR_RESET: + dev_warn(&h->pdev->dev, "hpsa%d: a power on " + "or device reset detected\n", h->ctlr); + break; + case UNIT_ATTENTION_CLEARED: + dev_warn(&h->pdev->dev, "hpsa%d: unit attention " + "cleared by another initiator\n", h->ctlr); + break; + default: + dev_warn(&h->pdev->dev, "hpsa%d: unknown " + "unit attention detected\n", h->ctlr); + break; + } + return 1; +} + +static ssize_t host_store_rescan(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct ctlr_info *h; + struct Scsi_Host *shost = class_to_shost(dev); + unsigned long *priv = shost_priv(shost); + h = (struct ctlr_info *) *priv; + if (add_to_scan_list(h)) { + wake_up_process(hpsa_scan_thread); + wait_for_completion_interruptible(&h->scan_wait); + } + return count; +} + +/* Enqueuing and dequeuing functions for cmdlists. */ +static inline void addQ(struct hlist_head *list, struct CommandList *c) +{ + hlist_add_head(&c->list, list); +} + +static void enqueue_cmd_and_start_io(struct ctlr_info *h, + struct CommandList *c) +{ + unsigned long flags; + spin_lock_irqsave(&h->lock, flags); + addQ(&h->reqQ, c); + h->Qdepth++; + start_io(h); + spin_unlock_irqrestore(&h->lock, flags); +} + +static inline void removeQ(struct CommandList *c) +{ + if (WARN_ON(hlist_unhashed(&c->list))) + return; + hlist_del_init(&c->list); +} + +static inline int is_hba_lunid(unsigned char scsi3addr[]) +{ + return memcmp(scsi3addr, RAID_CTLR_LUNID, 8) == 0; +} + +static inline int is_logical_dev_addr_mode(unsigned char scsi3addr[]) +{ + return (scsi3addr[3] & 0xC0) == 0x40; +} + +static const char *raid_label[] = { "0", "4", "1(1+0)", "5", "5+1", "ADG", + "UNKNOWN" +}; +#define RAID_UNKNOWN (ARRAY_SIZE(raid_label) - 1) + +static ssize_t raid_level_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t l = 0; + int rlevel; + struct ctlr_info *h; + struct scsi_device *sdev; + struct hpsa_scsi_dev_t *hdev; + unsigned long flags; + + sdev = to_scsi_device(dev); + h = sdev_to_hba(sdev); + spin_lock_irqsave(&h->lock, flags); + hdev = sdev->hostdata; + if (!hdev) { + spin_unlock_irqrestore(&h->lock, flags); + return -ENODEV; + } + + /* Is this even a logical drive? */ + if (!is_logical_dev_addr_mode(hdev->scsi3addr)) { + spin_unlock_irqrestore(&h->lock, flags); + l = snprintf(buf, PAGE_SIZE, "N/A\n"); + return l; + } + + rlevel = hdev->raid_level; + spin_unlock_irqrestore(&h->lock, flags); + if (rlevel < 0 || rlevel > RAID_UNKNOWN) + rlevel = RAID_UNKNOWN; + l = snprintf(buf, PAGE_SIZE, "RAID %s\n", raid_label[rlevel]); + return l; +} + +static ssize_t lunid_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ctlr_info *h; + struct scsi_device *sdev; + struct hpsa_scsi_dev_t *hdev; + unsigned long flags; + unsigned char lunid[8]; + + sdev = to_scsi_device(dev); + h = sdev_to_hba(sdev); + spin_lock_irqsave(&h->lock, flags); + hdev = sdev->hostdata; + if (!hdev) { + spin_unlock_irqrestore(&h->lock, flags); + return -ENODEV; + } + memcpy(lunid, hdev->scsi3addr, sizeof(lunid)); + spin_unlock_irqrestore(&h->lock, flags); + return snprintf(buf, 20, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n", + lunid[0], lunid[1], lunid[2], lunid[3], + lunid[4], lunid[5], lunid[6], lunid[7]); +} + +static ssize_t unique_id_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ctlr_info *h; + struct scsi_device *sdev; + struct hpsa_scsi_dev_t *hdev; + unsigned long flags; + unsigned char sn[16]; + + sdev = to_scsi_device(dev); + h = sdev_to_hba(sdev); + spin_lock_irqsave(&h->lock, flags); + hdev = sdev->hostdata; + if (!hdev) { + spin_unlock_irqrestore(&h->lock, flags); + return -ENODEV; + } + memcpy(sn, hdev->device_id, sizeof(sn)); + spin_unlock_irqrestore(&h->lock, flags); + return snprintf(buf, 16 * 2 + 2, + "%02X%02X%02X%02X%02X%02X%02X%02X" + "%02X%02X%02X%02X%02X%02X%02X%02X\n", + sn[0], sn[1], sn[2], sn[3], + sn[4], sn[5], sn[6], sn[7], + sn[8], sn[9], sn[10], sn[11], + sn[12], sn[13], sn[14], sn[15]); +} + +static int hpsa_find_target_lun(struct ctlr_info *h, + unsigned char scsi3addr[], int bus, int *target, int *lun) +{ + /* finds an unused bus, target, lun for a new physical device + * assumes h->devlock is held + */ + int i, found = 0; + DECLARE_BITMAP(lun_taken, HPSA_MAX_SCSI_DEVS_PER_HBA); + + memset(&lun_taken[0], 0, HPSA_MAX_SCSI_DEVS_PER_HBA >> 3); + + for (i = 0; i < h->ndevices; i++) { + if (h->dev[i]->bus == bus && h->dev[i]->target != -1) + set_bit(h->dev[i]->target, lun_taken); + } + + for (i = 0; i < HPSA_MAX_SCSI_DEVS_PER_HBA; i++) { + if (!test_bit(i, lun_taken)) { + /* *bus = 1; */ + *target = i; + *lun = 0; + found = 1; + break; + } + } + return !found; +} + +/* Add an entry into h->dev[] array. */ +static int hpsa_scsi_add_entry(struct ctlr_info *h, int hostno, + struct hpsa_scsi_dev_t *device, + struct hpsa_scsi_dev_t *added[], int *nadded) +{ + /* assumes h->devlock is held */ + int n = h->ndevices; + int i; + unsigned char addr1[8], addr2[8]; + struct hpsa_scsi_dev_t *sd; + + if (n >= HPSA_MAX_SCSI_DEVS_PER_HBA) { + dev_err(&h->pdev->dev, "too many devices, some will be " + "inaccessible.\n"); + return -1; + } + + /* physical devices do not have lun or target assigned until now. */ + if (device->lun != -1) + /* Logical device, lun is already assigned. */ + goto lun_assigned; + + /* If this device a non-zero lun of a multi-lun device + * byte 4 of the 8-byte LUN addr will contain the logical + * unit no, zero otherise. + */ + if (device->scsi3addr[4] == 0) { + /* This is not a non-zero lun of a multi-lun device */ + if (hpsa_find_target_lun(h, device->scsi3addr, + device->bus, &device->target, &device->lun) != 0) + return -1; + goto lun_assigned; + } + + /* This is a non-zero lun of a multi-lun device. + * Search through our list and find the device which + * has the same 8 byte LUN address, excepting byte 4. + * Assign the same bus and target for this new LUN. + * Use the logical unit number from the firmware. + */ + memcpy(addr1, device->scsi3addr, 8); + addr1[4] = 0; + for (i = 0; i < n; i++) { + sd = h->dev[i]; + memcpy(addr2, sd->scsi3addr, 8); + addr2[4] = 0; + /* differ only in byte 4? */ + if (memcmp(addr1, addr2, 8) == 0) { + device->bus = sd->bus; + device->target = sd->target; + device->lun = device->scsi3addr[4]; + break; + } + } + if (device->lun == -1) { + dev_warn(&h->pdev->dev, "physical device with no LUN=0," + " suspect firmware bug or unsupported hardware " + "configuration.\n"); + return -1; + } + +lun_assigned: + + h->dev[n] = device; + h->ndevices++; + added[*nadded] = device; + (*nadded)++; + + /* initially, (before registering with scsi layer) we don't + * know our hostno and we don't want to print anything first + * time anyway (the scsi layer's inquiries will show that info) + */ + /* if (hostno != -1) */ + dev_info(&h->pdev->dev, "%s device c%db%dt%dl%d added.\n", + scsi_device_type(device->devtype), hostno, + device->bus, device->target, device->lun); + return 0; +} + +/* Remove an entry from h->dev[] array. */ +static void hpsa_scsi_remove_entry(struct ctlr_info *h, int hostno, int entry, + struct hpsa_scsi_dev_t *removed[], int *nremoved) +{ + /* assumes h->devlock is held */ + int i; + struct hpsa_scsi_dev_t *sd; + + if (entry < 0 || entry >= HPSA_MAX_SCSI_DEVS_PER_HBA) + BUG(); + + sd = h->dev[entry]; + removed[*nremoved] = h->dev[entry]; + (*nremoved)++; + + for (i = entry; i < h->ndevices-1; i++) + h->dev[i] = h->dev[i+1]; + h->ndevices--; + dev_info(&h->pdev->dev, "%s device c%db%dt%dl%d removed.\n", + scsi_device_type(sd->devtype), hostno, sd->bus, sd->target, + sd->lun); +} + +#define SCSI3ADDR_EQ(a, b) ( \ + (a)[7] == (b)[7] && \ + (a)[6] == (b)[6] && \ + (a)[5] == (b)[5] && \ + (a)[4] == (b)[4] && \ + (a)[3] == (b)[3] && \ + (a)[2] == (b)[2] && \ + (a)[1] == (b)[1] && \ + (a)[0] == (b)[0]) + +static void fixup_botched_add(struct ctlr_info *h, + struct hpsa_scsi_dev_t *added) +{ + /* called when scsi_add_device fails in order to re-adjust + * h->dev[] to match the mid layer's view. + */ + unsigned long flags; + int i, j; + + spin_lock_irqsave(&h->lock, flags); + for (i = 0; i < h->ndevices; i++) { + if (h->dev[i] == added) { + for (j = i; j < h->ndevices-1; j++) + h->dev[j] = h->dev[j+1]; + h->ndevices--; + break; + } + } + spin_unlock_irqrestore(&h->lock, flags); + kfree(added); +} + +static inline int device_is_the_same(struct hpsa_scsi_dev_t *dev1, + struct hpsa_scsi_dev_t *dev2) +{ + if ((is_logical_dev_addr_mode(dev1->scsi3addr) || + (dev1->lun != -1 && dev2->lun != -1)) && + dev1->devtype != 0x0C) + return (memcmp(dev1, dev2, sizeof(*dev1)) == 0); + + /* we compare everything except lun and target as these + * are not yet assigned. Compare parts likely + * to differ first + */ + if (memcmp(dev1->scsi3addr, dev2->scsi3addr, + sizeof(dev1->scsi3addr)) != 0) + return 0; + if (memcmp(dev1->device_id, dev2->device_id, + sizeof(dev1->device_id)) != 0) + return 0; + if (memcmp(dev1->model, dev2->model, sizeof(dev1->model)) != 0) + return 0; + if (memcmp(dev1->vendor, dev2->vendor, sizeof(dev1->vendor)) != 0) + return 0; + if (memcmp(dev1->revision, dev2->revision, sizeof(dev1->revision)) != 0) + return 0; + if (dev1->devtype != dev2->devtype) + return 0; + if (dev1->raid_level != dev2->raid_level) + return 0; + if (dev1->bus != dev2->bus) + return 0; + return 1; +} + +/* Find needle in haystack. If exact match found, return DEVICE_SAME, + * and return needle location in *index. If scsi3addr matches, but not + * vendor, model, serial num, etc. return DEVICE_CHANGED, and return needle + * location in *index. If needle not found, return DEVICE_NOT_FOUND. + */ +static int hpsa_scsi_find_entry(struct hpsa_scsi_dev_t *needle, + struct hpsa_scsi_dev_t *haystack[], int haystack_size, + int *index) +{ + int i; +#define DEVICE_NOT_FOUND 0 +#define DEVICE_CHANGED 1 +#define DEVICE_SAME 2 + for (i = 0; i < haystack_size; i++) { + if (SCSI3ADDR_EQ(needle->scsi3addr, haystack[i]->scsi3addr)) { + *index = i; + if (device_is_the_same(needle, haystack[i])) + return DEVICE_SAME; + else + return DEVICE_CHANGED; + } + } + *index = -1; + return DEVICE_NOT_FOUND; +} + +static int adjust_hpsa_scsi_table(struct ctlr_info *h, int hostno, + struct hpsa_scsi_dev_t *sd[], int nsds) +{ + /* sd contains scsi3 addresses and devtypes, and inquiry + * data. This function takes what's in sd to be the current + * reality and updates h->dev[] to reflect that reality. + */ + int i, entry, device_change, changes = 0; + struct hpsa_scsi_dev_t *csd; + unsigned long flags; + struct hpsa_scsi_dev_t **added, **removed; + int nadded, nremoved; + struct Scsi_Host *sh = NULL; + + added = kzalloc(sizeof(*added) * HPSA_MAX_SCSI_DEVS_PER_HBA, + GFP_KERNEL); + removed = kzalloc(sizeof(*removed) * HPSA_MAX_SCSI_DEVS_PER_HBA, + GFP_KERNEL); + + if (!added || !removed) { + dev_warn(&h->pdev->dev, "out of memory in " + "adjust_hpsa_scsi_table\n"); + goto free_and_out; + } + + spin_lock_irqsave(&h->devlock, flags); + + /* find any devices in h->dev[] that are not in + * sd[] and remove them from h->dev[], and for any + * devices which have changed, remove the old device + * info and add the new device info. + */ + i = 0; + nremoved = 0; + nadded = 0; + while (i < h->ndevices) { + csd = h->dev[i]; + device_change = hpsa_scsi_find_entry(csd, sd, nsds, &entry); + if (device_change == DEVICE_NOT_FOUND) { + changes++; + hpsa_scsi_remove_entry(h, hostno, i, + removed, &nremoved); + continue; /* remove ^^^, hence i not incremented */ + } else if (device_change == DEVICE_CHANGED) { + changes++; + hpsa_scsi_remove_entry(h, hostno, i, + removed, &nremoved); + (void) hpsa_scsi_add_entry(h, hostno, sd[entry], + added, &nadded); + /* add can't fail, we just removed one. */ + sd[entry] = NULL; /* prevent it from being freed */ + } + i++; + } + + /* Now, make sure every device listed in sd[] is also + * listed in h->dev[], adding them if they aren't found + */ + + for (i = 0; i < nsds; i++) { + if (!sd[i]) /* if already added above. */ + continue; + device_change = hpsa_scsi_find_entry(sd[i], h->dev, + h->ndevices, &entry); + if (device_change == DEVICE_NOT_FOUND) { + changes++; + if (hpsa_scsi_add_entry(h, hostno, sd[i], + added, &nadded) != 0) + break; + sd[i] = NULL; /* prevent from being freed later. */ + } else if (device_change == DEVICE_CHANGED) { + /* should never happen... */ + changes++; + dev_warn(&h->pdev->dev, + "device unexpectedly changed.\n"); + /* but if it does happen, we just ignore that device */ + } + } + spin_unlock_irqrestore(&h->devlock, flags); + + /* Don't notify scsi mid layer of any changes the first time through + * (or if there are no changes) scsi_scan_host will do it later the + * first time through. + */ + if (hostno == -1 || !changes) + goto free_and_out; + + sh = h->scsi_host; + /* Notify scsi mid layer of any removed devices */ + for (i = 0; i < nremoved; i++) { + struct scsi_device *sdev = + scsi_device_lookup(sh, removed[i]->bus, + removed[i]->target, removed[i]->lun); + if (sdev != NULL) { + scsi_remove_device(sdev); + scsi_device_put(sdev); + } else { + /* We don't expect to get here. + * future cmds to this device will get selection + * timeout as if the device was gone. + */ + dev_warn(&h->pdev->dev, "didn't find c%db%dt%dl%d " + " for removal.", hostno, removed[i]->bus, + removed[i]->target, removed[i]->lun); + } + kfree(removed[i]); + removed[i] = NULL; + } + + /* Notify scsi mid layer of any added devices */ + for (i = 0; i < nadded; i++) { + if (scsi_add_device(sh, added[i]->bus, + added[i]->target, added[i]->lun) == 0) + continue; + dev_warn(&h->pdev->dev, "scsi_add_device c%db%dt%dl%d failed, " + "device not added.\n", hostno, added[i]->bus, + added[i]->target, added[i]->lun); + /* now we have to remove it from h->dev, + * since it didn't get added to scsi mid layer + */ + fixup_botched_add(h, added[i]); + } + +free_and_out: + kfree(added); + kfree(removed); + return 0; +} + +/* + * Lookup bus/target/lun and retrun corresponding struct hpsa_scsi_dev_t * + * Assume's h->devlock is held. + */ +static struct hpsa_scsi_dev_t *lookup_hpsa_scsi_dev(struct ctlr_info *h, + int bus, int target, int lun) +{ + int i; + struct hpsa_scsi_dev_t *sd; + + for (i = 0; i < h->ndevices; i++) { + sd = h->dev[i]; + if (sd->bus == bus && sd->target == target && sd->lun == lun) + return sd; + } + return NULL; +} + +/* link sdev->hostdata to our per-device structure. */ +static int hpsa_slave_alloc(struct scsi_device *sdev) +{ + struct hpsa_scsi_dev_t *sd; + unsigned long flags; + struct ctlr_info *h; + + h = sdev_to_hba(sdev); + spin_lock_irqsave(&h->devlock, flags); + sd = lookup_hpsa_scsi_dev(h, sdev_channel(sdev), + sdev_id(sdev), sdev->lun); + if (sd != NULL) + sdev->hostdata = sd; + spin_unlock_irqrestore(&h->devlock, flags); + return 0; +} + +static void hpsa_slave_destroy(struct scsi_device *sdev) +{ + return; /* nothing to do. */ +} + +static void hpsa_scsi_setup(struct ctlr_info *h) +{ + h->ndevices = 0; + h->scsi_host = NULL; + spin_lock_init(&h->devlock); + return; +} + +static void complete_scsi_command(struct CommandList *cp, + int timeout, __u32 tag) +{ + struct scsi_cmnd *cmd; + struct ctlr_info *h; + struct ErrorInfo *ei; + + unsigned char sense_key; + unsigned char asc; /* additional sense code */ + unsigned char ascq; /* additional sense code qualifier */ + + ei = cp->err_info; + cmd = (struct scsi_cmnd *) cp->scsi_cmd; + h = cp->h; + + scsi_dma_unmap(cmd); /* undo the DMA mappings */ + + cmd->result = (DID_OK << 16); /* host byte */ + cmd->result |= (COMMAND_COMPLETE << 8); /* msg byte */ + cmd->result |= (ei->ScsiStatus << 1); + + /* copy the sense data whether we need to or not. */ + memcpy(cmd->sense_buffer, ei->SenseInfo, + ei->SenseLen > SCSI_SENSE_BUFFERSIZE ? + SCSI_SENSE_BUFFERSIZE : + ei->SenseLen); + scsi_set_resid(cmd, ei->ResidualCnt); + + if (ei->CommandStatus == 0) { + cmd->scsi_done(cmd); + cmd_free(h, cp); + return; + } + + /* an error has occurred */ + switch (ei->CommandStatus) { + + case CMD_TARGET_STATUS: + if (ei->ScsiStatus) { + /* Get sense key */ + sense_key = 0xf & ei->SenseInfo[2]; + /* Get additional sense code */ + asc = ei->SenseInfo[12]; + /* Get addition sense code qualifier */ + ascq = ei->SenseInfo[13]; + } + + if (ei->ScsiStatus == SAM_STAT_CHECK_CONDITION) { + if (check_for_unit_attention(h, cp)) { + cmd->result = DID_SOFT_ERROR << 16; + break; + } + if (sense_key == ILLEGAL_REQUEST) { + /* + * SCSI REPORT_LUNS is commonly unsupported on + * Smart Array. Suppress noisy complaint. + */ + if (cp->Request.CDB[0] == REPORT_LUNS) + break; + + /* If ASC/ASCQ indicate Logical Unit + * Not Supported condition, + */ + if ((asc == 0x25) && (ascq == 0x0)) { + dev_warn(&h->pdev->dev, "cp %p " + "has check condition\n", cp); + break; + } + } + + if (sense_key == NOT_READY) { + /* If Sense is Not Ready, Logical Unit + * Not ready, Manual Intervention + * required + */ + if ((asc == 0x04) && (ascq == 0x03)) { + cmd->result = DID_NO_CONNECT << 16; + dev_warn(&h->pdev->dev, "cp %p " + "has check condition: unit " + "not ready, manual " + "intervention required\n", cp); + break; + } + } + + + /* Must be some other type of check condition */ + dev_warn(&h->pdev->dev, "cp %p has check condition: " + "unknown type: " + "Sense: 0x%x, ASC: 0x%x, ASCQ: 0x%x, " + "Returning result: 0x%x, " + "cmd=[%02x %02x %02x %02x %02x " + "%02x %02x %02x %02x %02x]\n", + cp, sense_key, asc, ascq, + cmd->result, + cmd->cmnd[0], cmd->cmnd[1], + cmd->cmnd[2], cmd->cmnd[3], + cmd->cmnd[4], cmd->cmnd[5], + cmd->cmnd[6], cmd->cmnd[7], + cmd->cmnd[8], cmd->cmnd[9]); + break; + } + + + /* Problem was not a check condition + * Pass it up to the upper layers... + */ + if (ei->ScsiStatus) { + dev_warn(&h->pdev->dev, "cp %p has status 0x%x " + "Sense: 0x%x, ASC: 0x%x, ASCQ: 0x%x, " + "Returning result: 0x%x\n", + cp, ei->ScsiStatus, + sense_key, asc, ascq, + cmd->result); + } else { /* scsi status is zero??? How??? */ + dev_warn(&h->pdev->dev, "cp %p SCSI status was 0. " + "Returning no connection.\n", cp), + + /* Ordinarily, this case should never happen, + * but there is a bug in some released firmware + * revisions that allows it to happen if, for + * example, a 4100 backplane loses power and + * the tape drive is in it. We assume that + * it's a fatal error of some kind because we + * can't show that it wasn't. We will make it + * look like selection timeout since that is + * the most common reason for this to occur, + * and it's severe enough. + */ + + cmd->result = DID_NO_CONNECT << 16; + } + break; + + case CMD_DATA_UNDERRUN: /* let mid layer handle it. */ + break; + case CMD_DATA_OVERRUN: + dev_warn(&h->pdev->dev, "cp %p has" + " completed with data overrun " + "reported\n", cp); + break; + case CMD_INVALID: { + /* print_bytes(cp, sizeof(*cp), 1, 0); + print_cmd(cp); */ + /* We get CMD_INVALID if you address a non-existent device + * instead of a selection timeout (no response). You will + * see this if you yank out a drive, then try to access it. + * This is kind of a shame because it means that any other + * CMD_INVALID (e.g. driver bug) will get interpreted as a + * missing target. */ + cmd->result = DID_NO_CONNECT << 16; + } + break; + case CMD_PROTOCOL_ERR: + dev_warn(&h->pdev->dev, "cp %p has " + "protocol error \n", cp); + break; + case CMD_HARDWARE_ERR: + cmd->result = DID_ERROR << 16; + dev_warn(&h->pdev->dev, "cp %p had hardware error\n", cp); + break; + case CMD_CONNECTION_LOST: + cmd->result = DID_ERROR << 16; + dev_warn(&h->pdev->dev, "cp %p had connection lost\n", cp); + break; + case CMD_ABORTED: + cmd->result = DID_ABORT << 16; + dev_warn(&h->pdev->dev, "cp %p was aborted with status 0x%x\n", + cp, ei->ScsiStatus); + break; + case CMD_ABORT_FAILED: + cmd->result = DID_ERROR << 16; + dev_warn(&h->pdev->dev, "cp %p reports abort failed\n", cp); + break; + case CMD_UNSOLICITED_ABORT: + cmd->result = DID_ABORT << 16; + dev_warn(&h->pdev->dev, "cp %p aborted do to an unsolicited " + "abort\n", cp); + break; + case CMD_TIMEOUT: + cmd->result = DID_TIME_OUT << 16; + dev_warn(&h->pdev->dev, "cp %p timedout\n", cp); + break; + default: + cmd->result = DID_ERROR << 16; + dev_warn(&h->pdev->dev, "cp %p returned unknown status %x\n", + cp, ei->CommandStatus); + } + cmd->scsi_done(cmd); + cmd_free(h, cp); +} + +static int hpsa_scsi_detect(struct ctlr_info *h) +{ + struct Scsi_Host *sh; + int error; + + sh = scsi_host_alloc(&hpsa_driver_template, sizeof(h)); + if (sh == NULL) + goto fail; + + sh->io_port = 0; + sh->n_io_port = 0; + sh->this_id = -1; + sh->max_channel = 3; + sh->max_cmd_len = MAX_COMMAND_SIZE; + sh->max_lun = HPSA_MAX_LUN; + sh->max_id = HPSA_MAX_LUN; + h->scsi_host = sh; + sh->hostdata[0] = (unsigned long) h; + sh->irq = h->intr[SIMPLE_MODE_INT]; + sh->unique_id = sh->irq; + error = scsi_add_host(sh, &h->pdev->dev); + if (error) + goto fail_host_put; + scsi_scan_host(sh); + return 0; + + fail_host_put: + dev_err(&h->pdev->dev, "hpsa_scsi_detect: scsi_add_host" + " failed for controller %d\n", h->ctlr); + scsi_host_put(sh); + return -1; + fail: + dev_err(&h->pdev->dev, "hpsa_scsi_detect: scsi_host_alloc" + " failed for controller %d\n", h->ctlr); + return -1; +} + +static void hpsa_pci_unmap(struct pci_dev *pdev, + struct CommandList *c, int sg_used, int data_direction) +{ + int i; + union u64bit addr64; + + for (i = 0; i < sg_used; i++) { + addr64.val32.lower = c->SG[i].Addr.lower; + addr64.val32.upper = c->SG[i].Addr.upper; + pci_unmap_single(pdev, (dma_addr_t) addr64.val, c->SG[i].Len, + data_direction); + } +} + +static void hpsa_map_one(struct pci_dev *pdev, + struct CommandList *cp, + unsigned char *buf, + size_t buflen, + int data_direction) +{ + __u64 addr64; + + if (buflen == 0 || data_direction == PCI_DMA_NONE) { + cp->Header.SGList = 0; + cp->Header.SGTotal = 0; + return; + } + + addr64 = (__u64) pci_map_single(pdev, buf, buflen, data_direction); + cp->SG[0].Addr.lower = + (__u32) (addr64 & (__u64) 0x00000000FFFFFFFF); + cp->SG[0].Addr.upper = + (__u32) ((addr64 >> 32) & (__u64) 0x00000000FFFFFFFF); + cp->SG[0].Len = buflen; + cp->Header.SGList = (__u8) 1; /* no. SGs contig in this cmd */ + cp->Header.SGTotal = (__u16) 1; /* total sgs in this cmd list */ +} + +static inline void hpsa_scsi_do_simple_cmd_core(struct ctlr_info *h, + struct CommandList *c) +{ + DECLARE_COMPLETION_ONSTACK(wait); + + c->waiting = &wait; + enqueue_cmd_and_start_io(h, c); + wait_for_completion(&wait); +} + +static void hpsa_scsi_do_simple_cmd_with_retry(struct ctlr_info *h, + struct CommandList *c, int data_direction) +{ + int retry_count = 0; + + do { + memset(c->err_info, 0, sizeof(c->err_info)); + hpsa_scsi_do_simple_cmd_core(h, c); + retry_count++; + } while (check_for_unit_attention(h, c) && retry_count <= 3); + hpsa_pci_unmap(h->pdev, c, 1, data_direction); +} + +static void hpsa_scsi_interpret_error(struct CommandList *cp) +{ + struct ErrorInfo *ei; + struct device *d = &cp->h->pdev->dev; + + ei = cp->err_info; + switch (ei->CommandStatus) { + case CMD_TARGET_STATUS: + dev_warn(d, "cmd %p has completed with errors\n", cp); + dev_warn(d, "cmd %p has SCSI Status = %x\n", cp, + ei->ScsiStatus); + if (ei->ScsiStatus == 0) + dev_warn(d, "SCSI status is abnormally zero. " + "(probably indicates selection timeout " + "reported incorrectly due to a known " + "firmware bug, circa July, 2001.)\n"); + break; + case CMD_DATA_UNDERRUN: /* let mid layer handle it. */ + dev_info(d, "UNDERRUN\n"); + break; + case CMD_DATA_OVERRUN: + dev_warn(d, "cp %p has completed with data overrun\n", cp); + break; + case CMD_INVALID: { + /* controller unfortunately reports SCSI passthru's + * to non-existent targets as invalid commands. + */ + dev_warn(d, "cp %p is reported invalid (probably means " + "target device no longer present)\n", cp); + /* print_bytes((unsigned char *) cp, sizeof(*cp), 1, 0); + print_cmd(cp); */ + } + break; + case CMD_PROTOCOL_ERR: + dev_warn(d, "cp %p has protocol error \n", cp); + break; + case CMD_HARDWARE_ERR: + /* cmd->result = DID_ERROR << 16; */ + dev_warn(d, "cp %p had hardware error\n", cp); + break; + case CMD_CONNECTION_LOST: + dev_warn(d, "cp %p had connection lost\n", cp); + break; + case CMD_ABORTED: + dev_warn(d, "cp %p was aborted\n", cp); + break; + case CMD_ABORT_FAILED: + dev_warn(d, "cp %p reports abort failed\n", cp); + break; + case CMD_UNSOLICITED_ABORT: + dev_warn(d, "cp %p aborted due to an unsolicited abort\n", cp); + break; + case CMD_TIMEOUT: + dev_warn(d, "cp %p timed out\n", cp); + break; + default: + dev_warn(d, "cp %p returned unknown status %x\n", cp, + ei->CommandStatus); + } +} + +static int hpsa_scsi_do_inquiry(struct ctlr_info *h, unsigned char *scsi3addr, + unsigned char page, unsigned char *buf, + unsigned char bufsize) +{ + int rc = IO_OK; + struct CommandList *c; + struct ErrorInfo *ei; + + c = cmd_special_alloc(h); + + if (c == NULL) { /* trouble... */ + dev_warn(&h->pdev->dev, "cmd_special_alloc returned NULL!\n"); + return -1; + } + + fill_cmd(c, HPSA_INQUIRY, h, buf, bufsize, page, scsi3addr, TYPE_CMD); + hpsa_scsi_do_simple_cmd_with_retry(h, c, PCI_DMA_FROMDEVICE); + ei = c->err_info; + if (ei->CommandStatus != 0 && ei->CommandStatus != CMD_DATA_UNDERRUN) { + hpsa_scsi_interpret_error(c); + rc = -1; + } + cmd_special_free(h, c); + return rc; +} + +static int hpsa_send_reset(struct ctlr_info *h, unsigned char *scsi3addr) +{ + int rc = IO_OK; + struct CommandList *c; + struct ErrorInfo *ei; + + c = cmd_special_alloc(h); + + if (c == NULL) { /* trouble... */ + dev_warn(&h->pdev->dev, "cmd_special_alloc returned NULL!\n"); + return -1; + } + + fill_cmd(c, HPSA_DEVICE_RESET_MSG, h, NULL, 0, 0, scsi3addr, TYPE_MSG); + hpsa_scsi_do_simple_cmd_core(h, c); + /* no unmap needed here because no data xfer. */ + + ei = c->err_info; + if (ei->CommandStatus != 0) { + hpsa_scsi_interpret_error(c); + rc = -1; + } + cmd_special_free(h, c); + return rc; +} + +static void hpsa_get_raid_level(struct ctlr_info *h, + unsigned char *scsi3addr, unsigned char *raid_level) +{ + int rc; + unsigned char *buf; + + *raid_level = RAID_UNKNOWN; + buf = kzalloc(64, GFP_KERNEL); + if (!buf) + return; + rc = hpsa_scsi_do_inquiry(h, scsi3addr, 0xC1, buf, 64); + if (rc == 0) + *raid_level = buf[8]; + if (*raid_level > RAID_UNKNOWN) + *raid_level = RAID_UNKNOWN; + kfree(buf); + return; +} + +/* Get the device id from inquiry page 0x83 */ +static int hpsa_get_device_id(struct ctlr_info *h, unsigned char *scsi3addr, + unsigned char *device_id, int buflen) +{ + int rc; + unsigned char *buf; + + if (buflen > 16) + buflen = 16; + buf = kzalloc(64, GFP_KERNEL); + if (!buf) + return -1; + rc = hpsa_scsi_do_inquiry(h, scsi3addr, 0x83, buf, 64); + if (rc == 0) + memcpy(device_id, &buf[8], buflen); + kfree(buf); + return rc != 0; +} + +static int hpsa_scsi_do_report_luns(struct ctlr_info *h, int logical, + struct ReportLUNdata *buf, int bufsize, + int extended_response) +{ + int rc = IO_OK; + struct CommandList *c; + unsigned char scsi3addr[8]; + struct ErrorInfo *ei; + + c = cmd_special_alloc(h); + if (c == NULL) { /* trouble... */ + dev_err(&h->pdev->dev, "cmd_special_alloc returned NULL!\n"); + return -1; + } + + memset(&scsi3addr[0], 0, 8); /* address the controller */ + + fill_cmd(c, logical ? HPSA_REPORT_LOG : HPSA_REPORT_PHYS, h, + buf, bufsize, 0, scsi3addr, TYPE_CMD); + if (extended_response) + c->Request.CDB[1] = extended_response; + hpsa_scsi_do_simple_cmd_with_retry(h, c, PCI_DMA_FROMDEVICE); + ei = c->err_info; + if (ei->CommandStatus != 0 && + ei->CommandStatus != CMD_DATA_UNDERRUN) { + hpsa_scsi_interpret_error(c); + rc = -1; + } + cmd_special_free(h, c); + return rc; +} + +static inline int hpsa_scsi_do_report_phys_luns(struct ctlr_info *h, + struct ReportLUNdata *buf, + int bufsize, int extended_response) +{ + return hpsa_scsi_do_report_luns(h, 0, buf, bufsize, extended_response); +} + +static inline int hpsa_scsi_do_report_log_luns(struct ctlr_info *h, + struct ReportLUNdata *buf, int bufsize) +{ + return hpsa_scsi_do_report_luns(h, 1, buf, bufsize, 0); +} + +static inline void hpsa_set_bus_target_lun(struct hpsa_scsi_dev_t *device, + int bus, int target, int lun) +{ + device->bus = bus; + device->target = target; + device->lun = lun; +} + +static int hpsa_update_device_info(struct ctlr_info *h, + unsigned char scsi3addr[], struct hpsa_scsi_dev_t *this_device) +{ +#define OBDR_TAPE_INQ_SIZE 49 + unsigned char *inq_buff = NULL; + + inq_buff = kmalloc(OBDR_TAPE_INQ_SIZE, GFP_KERNEL); + if (!inq_buff) + goto bail_out; + + memset(inq_buff, 0, OBDR_TAPE_INQ_SIZE); + /* Do an inquiry to the device to see what it is. */ + if (hpsa_scsi_do_inquiry(h, scsi3addr, 0, inq_buff, + (unsigned char) OBDR_TAPE_INQ_SIZE) != 0) { + /* Inquiry failed (msg printed already) */ + dev_err(&h->pdev->dev, + "hpsa_update_device_info: inquiry failed\n"); + goto bail_out; + } + + /* As a side effect, record the firmware version number + * if we happen to be talking to the RAID controller. + */ + if (is_hba_lunid(scsi3addr)) + memcpy(h->firm_ver, &inq_buff[32], 4); + + this_device->devtype = (inq_buff[0] & 0x1f); + memcpy(this_device->scsi3addr, scsi3addr, 8); + memcpy(this_device->vendor, &inq_buff[8], + sizeof(this_device->vendor)); + memcpy(this_device->model, &inq_buff[16], + sizeof(this_device->model)); + memcpy(this_device->revision, &inq_buff[32], + sizeof(this_device->revision)); + memset(this_device->device_id, 0, + sizeof(this_device->device_id)); + hpsa_get_device_id(h, scsi3addr, this_device->device_id, + sizeof(this_device->device_id)); + + if (this_device->devtype == TYPE_DISK && + is_logical_dev_addr_mode(scsi3addr)) + hpsa_get_raid_level(h, scsi3addr, &this_device->raid_level); + else + this_device->raid_level = RAID_UNKNOWN; + + kfree(inq_buff); + return 0; + +bail_out: + kfree(inq_buff); + return 1; +} + +static unsigned char *msa2xxx_model[] = { + "MSA2012", + "MSA2024", + "MSA2312", + "MSA2324", + NULL, +}; + +static int is_msa2xxx(struct ctlr_info *h, struct hpsa_scsi_dev_t *device) +{ + int i; + + for (i = 0; msa2xxx_model[i]; i++) + if (strncmp(device->model, msa2xxx_model[i], + strlen(msa2xxx_model[i])) == 0) + return 1; + return 0; +} + +/* Helper function to assign bus, target, lun mapping of devices. + * Puts non-msa2xxx logical volumes on bus 0, msa2xxx logical + * volumes on bus 1, physical devices on bus 2. and the hba on bus 3. + * Logical drive target and lun are assigned at this time, but + * physical device lun and target assignment are deferred (assigned + * in hpsa_find_target_lun, called by hpsa_scsi_add_entry.) + */ +static void figure_bus_target_lun(struct ctlr_info *h, + __u8 *lunaddrbytes, int *bus, int *target, int *lun, + struct hpsa_scsi_dev_t *device) +{ + + __u32 lunid; + + if (is_logical_dev_addr_mode(lunaddrbytes)) { + /* logical device */ + memcpy(&lunid, lunaddrbytes, sizeof(lunid)); + lunid = le32_to_cpu(lunid); + + if (is_msa2xxx(h, device)) { + *bus = 1; + *target = (lunid >> 16) & 0x3fff; + *lun = lunid & 0x00ff; + } else { + *bus = 0; + *lun = 0; + *target = lunid & 0x3fff; + } + } else { + /* physical device */ + if (is_hba_lunid(lunaddrbytes)) + *bus = 3; + else + *bus = 2; + *target = -1; + *lun = -1; /* we will fill these in later. */ + } +} + +/* + * If there is no lun 0 on a target, linux won't find any devices. + * For the MSA2xxx boxes, we have to manually detect the enclosure + * which is at lun zero, as CCISS_REPORT_PHYSICAL_LUNS doesn't report + * it for some reason. *tmpdevice is the target we're adding, + * this_device is a pointer into the current element of currentsd[] + * that we're building up in update_scsi_devices(), below. + * lunzerobits is a bitmap that tracks which targets already have a + * lun 0 assigned. + * Returns 1 if an enclosure was added, 0 if not. + */ +static int add_msa2xxx_enclosure_device(struct ctlr_info *h, + struct hpsa_scsi_dev_t *tmpdevice, + struct hpsa_scsi_dev_t *this_device, __u8 *lunaddrbytes, + int bus, int target, int lun, unsigned long lunzerobits[], + int *nmsa2xxx_enclosures) +{ + unsigned char scsi3addr[8]; + + if (test_bit(target, lunzerobits)) + return 0; /* There is already a lun 0 on this target. */ + + if (!is_logical_dev_addr_mode(lunaddrbytes)) + return 0; /* It's the logical targets that may lack lun 0. */ + + if (!is_msa2xxx(h, tmpdevice)) + return 0; /* It's only the MSA2xxx that have this problem. */ + + if (lun == 0) /* if lun is 0, then obviously we have a lun 0. */ + return 0; + + if (is_hba_lunid(scsi3addr)) + return 0; /* Don't add the RAID controller here. */ + +#define MAX_MSA2XXX_ENCLOSURES 32 + if (*nmsa2xxx_enclosures >= MAX_MSA2XXX_ENCLOSURES) { + dev_warn(&h->pdev->dev, "Maximum number of MSA2XXX " + "enclosures exceeded. Check your hardware " + "configuration."); + return 0; + } + + memset(scsi3addr, 0, 8); + scsi3addr[3] = target; + if (hpsa_update_device_info(h, scsi3addr, this_device)) + return 0; + (*nmsa2xxx_enclosures)++; + hpsa_set_bus_target_lun(this_device, bus, target, 0); + set_bit(target, lunzerobits); + return 1; +} + +/* + * Do CISS_REPORT_PHYS and CISS_REPORT_LOG. Data is returned in physdev, + * logdev. The number of luns in physdev and logdev are returned in + * *nphysicals and *nlogicals, respectively. + * Returns 0 on success, -1 otherwise. + */ +static int hpsa_gather_lun_info(struct ctlr_info *h, + int reportlunsize, + struct ReportLUNdata *physdev, __u32 *nphysicals, + struct ReportLUNdata *logdev, __u32 *nlogicals) +{ + if (hpsa_scsi_do_report_phys_luns(h, physdev, reportlunsize, 0)) { + dev_err(&h->pdev->dev, "report physical LUNs failed.\n"); + return -1; + } + memcpy(nphysicals, &physdev->LUNListLength[0], sizeof(*nphysicals)); + *nphysicals = be32_to_cpu(*nphysicals) / 8; +#ifdef DEBUG + dev_info(&h->pdev->dev, "number of physical luns is %d\n", *nphysicals); +#endif + if (*nphysicals > HPSA_MAX_PHYS_LUN) { + dev_warn(&h->pdev->dev, "maximum physical LUNs (%d) exceeded." + " %d LUNs ignored.\n", HPSA_MAX_PHYS_LUN, + *nphysicals - HPSA_MAX_PHYS_LUN); + *nphysicals = HPSA_MAX_PHYS_LUN; + } + if (hpsa_scsi_do_report_log_luns(h, logdev, reportlunsize)) { + dev_err(&h->pdev->dev, "report logical LUNs failed.\n"); + return -1; + } + memcpy(nlogicals, &logdev->LUNListLength[0], sizeof(*nlogicals)); + *nlogicals = be32_to_cpu(*nlogicals) / 8; +#ifdef DEBUG + dev_info(&h->pdev->dev, "number of logical luns is %d\n", *nlogicals); +#endif + /* Reject Logicals in excess of our max capability. */ + if (*nlogicals > HPSA_MAX_LUN) { + dev_warn(&h->pdev->dev, + "maximum logical LUNs (%d) exceeded. " + "%d LUNs ignored.\n", HPSA_MAX_LUN, + *nlogicals - HPSA_MAX_LUN); + *nlogicals = HPSA_MAX_LUN; + } + if (*nlogicals + *nphysicals > HPSA_MAX_PHYS_LUN) { + dev_warn(&h->pdev->dev, + "maximum logical + physical LUNs (%d) exceeded. " + "%d LUNs ignored.\n", HPSA_MAX_PHYS_LUN, + *nphysicals + *nlogicals - HPSA_MAX_PHYS_LUN); + *nlogicals = HPSA_MAX_PHYS_LUN - *nphysicals; + } + return 0; +} + +static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno) +{ + /* the idea here is we could get notified + * that some devices have changed, so we do a report + * physical luns and report logical luns cmd, and adjust + * our list of devices accordingly. + * + * The scsi3addr's of devices won't change so long as the + * adapter is not reset. That means we can rescan and + * tell which devices we already know about, vs. new + * devices, vs. disappearing devices. + */ + struct ReportLUNdata *physdev_list = NULL; + struct ReportLUNdata *logdev_list = NULL; + unsigned char *inq_buff = NULL; + __u32 nphysicals = 0; + __u32 nlogicals = 0; + __u32 ndev_allocated = 0; + struct hpsa_scsi_dev_t **currentsd, *this_device, *tmpdevice; + int ncurrent = 0; + int reportlunsize = sizeof(*physdev_list) + HPSA_MAX_PHYS_LUN * 8; + int i, nmsa2xxx_enclosures, ndevs_to_allocate; + int bus, target, lun; + DECLARE_BITMAP(lunzerobits, HPSA_MAX_TARGETS_PER_CTLR); + + currentsd = kzalloc(sizeof(*currentsd) * HPSA_MAX_SCSI_DEVS_PER_HBA, + GFP_KERNEL); + physdev_list = kzalloc(reportlunsize, GFP_KERNEL); + logdev_list = kzalloc(reportlunsize, GFP_KERNEL); + inq_buff = kmalloc(OBDR_TAPE_INQ_SIZE, GFP_KERNEL); + tmpdevice = kzalloc(sizeof(*tmpdevice), GFP_KERNEL); + + if (!currentsd || !physdev_list || !logdev_list || + !inq_buff || !tmpdevice) { + dev_err(&h->pdev->dev, "out of memory\n"); + goto out; + } + memset(lunzerobits, 0, sizeof(lunzerobits)); + + if (hpsa_gather_lun_info(h, reportlunsize, physdev_list, &nphysicals, + logdev_list, &nlogicals)) + goto out; + + /* We might see up to 32 MSA2xxx enclosures, actually 8 of them + * but each of them 4 times through different paths. The plus 1 + * is for the RAID controller. + */ + ndevs_to_allocate = nphysicals + nlogicals + MAX_MSA2XXX_ENCLOSURES + 1; + + /* Allocate the per device structures */ + for (i = 0; i < ndevs_to_allocate; i++) { + currentsd[i] = kzalloc(sizeof(*currentsd[i]), GFP_KERNEL); + if (!currentsd[i]) { + dev_warn(&h->pdev->dev, "out of memory at %s:%d\n", + __FILE__, __LINE__); + goto out; + } + ndev_allocated++; + } + + /* adjust our table of devices */ + nmsa2xxx_enclosures = 0; + for (i = 0; i < nphysicals + nlogicals + 1; i++) { + __u8 *lunaddrbytes; + + /* Figure out where the LUN ID info is coming from */ + if (i < nphysicals) + lunaddrbytes = &physdev_list->LUN[i][0]; + else + if (i < nphysicals + nlogicals) + lunaddrbytes = + &logdev_list->LUN[i-nphysicals][0]; + else /* jam in the RAID controller at the end */ + lunaddrbytes = RAID_CTLR_LUNID; + + /* skip masked physical devices. */ + if (lunaddrbytes[3] & 0xC0 && i < nphysicals) + continue; + + /* Get device type, vendor, model, device id */ + if (hpsa_update_device_info(h, lunaddrbytes, tmpdevice)) + continue; /* skip it if we can't talk to it. */ + figure_bus_target_lun(h, lunaddrbytes, &bus, &target, &lun, + tmpdevice); + this_device = currentsd[ncurrent]; + + /* + * For the msa2xxx boxes, we have to insert a LUN 0 which + * doesn't show up in CCISS_REPORT_PHYSICAL data, but there + * is nonetheless an enclosure device there. We have to + * present that otherwise linux won't find anything if + * there is no lun 0. + */ + if (add_msa2xxx_enclosure_device(h, tmpdevice, this_device, + lunaddrbytes, bus, target, lun, lunzerobits, + &nmsa2xxx_enclosures)) { + ncurrent++; + this_device = currentsd[ncurrent]; + } + + *this_device = *tmpdevice; + hpsa_set_bus_target_lun(this_device, bus, target, lun); + + switch (this_device->devtype) { + case TYPE_ROM: { + /* We don't *really* support actual CD-ROM devices, + * just "One Button Disaster Recovery" tape drive + * which temporarily pretends to be a CD-ROM drive. + * So we check that the device is really an OBDR tape + * device by checking for "$DR-10" in bytes 43-48 of + * the inquiry data. + */ + char obdr_sig[7]; +#define OBDR_TAPE_SIG "$DR-10" + strncpy(obdr_sig, &inq_buff[43], 6); + obdr_sig[6] = '\0'; + if (strncmp(obdr_sig, OBDR_TAPE_SIG, 6) != 0) + /* Not OBDR device, ignore it. */ + break; + } + ncurrent++; + break; + case TYPE_DISK: + if (i < nphysicals) + break; + ncurrent++; + break; + case TYPE_TAPE: + case TYPE_MEDIUM_CHANGER: + ncurrent++; + break; + case TYPE_RAID: + /* Only present the Smartarray HBA as a RAID controller. + * If it's a RAID controller other than the HBA itself + * (an external RAID controller, MSA500 or similar) + * don't present it. + */ + if (!is_hba_lunid(lunaddrbytes)) + break; + ncurrent++; + break; + default: + break; + } + if (ncurrent >= HPSA_MAX_SCSI_DEVS_PER_HBA) + break; + } + adjust_hpsa_scsi_table(h, hostno, currentsd, ncurrent); +out: + kfree(tmpdevice); + for (i = 0; i < ndev_allocated; i++) + kfree(currentsd[i]); + kfree(currentsd); + kfree(inq_buff); + kfree(physdev_list); + kfree(logdev_list); + return; +} + +/* hpsa_scatter_gather takes a struct scsi_cmnd, (cmd), and does the pci + * dma mapping and fills in the scatter gather entries of the + * hpsa command, cp. + */ +static int hpsa_scatter_gather(struct pci_dev *pdev, + struct CommandList *cp, + struct scsi_cmnd *cmd) +{ + unsigned int len; + struct scatterlist *sg; + __u64 addr64; + int use_sg, i; + + BUG_ON(scsi_sg_count(cmd) > MAXSGENTRIES); + + use_sg = scsi_dma_map(cmd); + if (use_sg < 0) + return use_sg; + + if (!use_sg) + goto sglist_finished; + + scsi_for_each_sg(cmd, sg, use_sg, i) { + addr64 = (__u64) sg_dma_address(sg); + len = sg_dma_len(sg); + cp->SG[i].Addr.lower = + (__u32) (addr64 & (__u64) 0x00000000FFFFFFFF); + cp->SG[i].Addr.upper = + (__u32) ((addr64 >> 32) & (__u64) 0x00000000FFFFFFFF); + cp->SG[i].Len = len; + cp->SG[i].Ext = 0; /* we are not chaining */ + } + +sglist_finished: + + cp->Header.SGList = (__u8) use_sg; /* no. SGs contig in this cmd */ + cp->Header.SGTotal = (__u16) use_sg; /* total sgs in this cmd list */ + return 0; +} + + +static int hpsa_scsi_queue_command(struct scsi_cmnd *cmd, + void (*done)(struct scsi_cmnd *)) +{ + struct ctlr_info *h; + struct hpsa_scsi_dev_t *dev; + unsigned char scsi3addr[8]; + struct CommandList *c; + unsigned long flags; + + /* Get the ptr to our adapter structure out of cmd->host. */ + h = sdev_to_hba(cmd->device); + dev = cmd->device->hostdata; + if (!dev) { + cmd->result = DID_NO_CONNECT << 16; + done(cmd); + return 0; + } + memcpy(scsi3addr, dev->scsi3addr, sizeof(scsi3addr)); + + /* Need a lock as this is being allocated from the pool */ + spin_lock_irqsave(&h->lock, flags); + c = cmd_alloc(h); + spin_unlock_irqrestore(&h->lock, flags); + if (c == NULL) { /* trouble... */ + dev_err(&h->pdev->dev, "cmd_alloc returned NULL!\n"); + return SCSI_MLQUEUE_HOST_BUSY; + } + + /* Fill in the command list header */ + + cmd->scsi_done = done; /* save this for use by completion code */ + + /* save c in case we have to abort it */ + cmd->host_scribble = (unsigned char *) c; + + c->cmd_type = CMD_SCSI; + c->scsi_cmd = cmd; + c->Header.ReplyQueue = 0; /* unused in simple mode */ + memcpy(&c->Header.LUN.LunAddrBytes[0], &scsi3addr[0], 8); + c->Header.Tag.lower = c->busaddr; /* Use k. address of cmd as tag */ + + /* Fill in the request block... */ + + c->Request.Timeout = 0; + memset(c->Request.CDB, 0, sizeof(c->Request.CDB)); + BUG_ON(cmd->cmd_len > sizeof(c->Request.CDB)); + c->Request.CDBLen = cmd->cmd_len; + memcpy(c->Request.CDB, cmd->cmnd, cmd->cmd_len); + c->Request.Type.Type = TYPE_CMD; + c->Request.Type.Attribute = ATTR_SIMPLE; + switch (cmd->sc_data_direction) { + case DMA_TO_DEVICE: + c->Request.Type.Direction = XFER_WRITE; + break; + case DMA_FROM_DEVICE: + c->Request.Type.Direction = XFER_READ; + break; + case DMA_NONE: + c->Request.Type.Direction = XFER_NONE; + break; + case DMA_BIDIRECTIONAL: + /* This can happen if a buggy application does a scsi passthru + * and sets both inlen and outlen to non-zero. ( see + * ../scsi/scsi_ioctl.c:scsi_ioctl_send_command() ) + */ + + c->Request.Type.Direction = XFER_RSVD; + /* This is technically wrong, and hpsa controllers should + * reject it with CMD_INVALID, which is the most correct + * response, but non-fibre backends appear to let it + * slide by, and give the same results as if this field + * were set correctly. Either way is acceptable for + * our purposes here. + */ + + break; + + default: + dev_err(&h->pdev->dev, "unknown data direction: %d\n", + cmd->sc_data_direction); + BUG(); + break; + } + + if (hpsa_scatter_gather(h->pdev, c, cmd) < 0) { /* Fill SG list */ + cmd_free(h, c); + return SCSI_MLQUEUE_HOST_BUSY; + } + enqueue_cmd_and_start_io(h, c); + /* the cmd'll come back via intr handler in complete_scsi_command() */ + return 0; +} + +static void hpsa_unregister_scsi(struct ctlr_info *h) +{ + /* we are being forcibly unloaded, and may not refuse. */ + scsi_remove_host(h->scsi_host); + scsi_host_put(h->scsi_host); + h->scsi_host = NULL; +} + +static int hpsa_register_scsi(struct ctlr_info *h) +{ + int rc; + + hpsa_update_scsi_devices(h, -1); + rc = hpsa_scsi_detect(h); + if (rc != 0) + dev_err(&h->pdev->dev, "hpsa_register_scsi: failed" + " hpsa_scsi_detect(), rc is %d\n", rc); + return rc; +} + +static int wait_for_device_to_become_ready(struct ctlr_info *h, + unsigned char lunaddr[]) +{ + int rc = 0; + int count = 0; + int waittime = 1; /* seconds */ + struct CommandList *c; + + c = cmd_special_alloc(h); + if (!c) { + dev_warn(&h->pdev->dev, "out of memory in " + "wait_for_device_to_become_ready.\n"); + return IO_ERROR; + } + + /* Send test unit ready until device ready, or give up. */ + while (count < HPSA_TUR_RETRY_LIMIT) { + + /* Wait for a bit. do this first, because if we send + * the TUR right away, the reset will just abort it. + */ + msleep(1000 * waittime); + count++; + + /* Increase wait time with each try, up to a point. */ + if (waittime < HPSA_MAX_WAIT_INTERVAL_SECS) + waittime = waittime * 2; + + /* Send the Test Unit Ready */ + fill_cmd(c, TEST_UNIT_READY, h, NULL, 0, 0, lunaddr, TYPE_CMD); + hpsa_scsi_do_simple_cmd_core(h, c); + /* no unmap needed here because no data xfer. */ + + if (c->err_info->CommandStatus == CMD_SUCCESS) + break; + + if (c->err_info->CommandStatus == CMD_TARGET_STATUS && + c->err_info->ScsiStatus == SAM_STAT_CHECK_CONDITION && + (c->err_info->SenseInfo[2] == NO_SENSE || + c->err_info->SenseInfo[2] == UNIT_ATTENTION)) + break; + + dev_warn(&h->pdev->dev, "waiting %d secs " + "for device to become ready.\n", waittime); + rc = 1; /* device not ready. */ + } + + if (rc) + dev_warn(&h->pdev->dev, "giving up on device.\n"); + else + dev_warn(&h->pdev->dev, "device is ready.\n"); + + cmd_special_free(h, c); + return rc; +} + +/* Need at least one of these error handlers to keep ../scsi/hosts.c from + * complaining. Doing a host- or bus-reset can't do anything good here. + */ +static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd) +{ + int rc; + struct ctlr_info *h; + struct hpsa_scsi_dev_t *dev; + + /* find the controller to which the command to be aborted was sent */ + h = sdev_to_hba(scsicmd->device); + if (h == NULL) /* paranoia */ + return FAILED; + dev_warn(&h->pdev->dev, "resetting drive\n"); + + dev = scsicmd->device->hostdata; + if (!dev) { + dev_err(&h->pdev->dev, "hpsa_eh_device_reset_handler: " + "device lookup failed.\n"); + return FAILED; + } + /* send a reset to the SCSI LUN which the command was sent to */ + rc = hpsa_send_reset(h, dev->scsi3addr); + if (rc == 0 && wait_for_device_to_become_ready(h, dev->scsi3addr) == 0) + return SUCCESS; + + dev_warn(&h->pdev->dev, "resetting device failed.\n"); + return FAILED; +} + +/* + * For operations that cannot sleep, a command block is allocated at init, + * and managed by cmd_alloc() and cmd_free() using a simple bitmap to track + * which ones are free or in use. Lock must be held when calling this. + * cmd_free() is the complement. + */ +static struct CommandList *cmd_alloc(struct ctlr_info *h) +{ + struct CommandList *c; + int i; + union u64bit temp64; + dma_addr_t cmd_dma_handle, err_dma_handle; + + do { + i = find_first_zero_bit(h->cmd_pool_bits, h->nr_cmds); + if (i == h->nr_cmds) + return NULL; + } while (test_and_set_bit + (i & (BITS_PER_LONG - 1), + h->cmd_pool_bits + (i / BITS_PER_LONG)) != 0); + c = h->cmd_pool + i; + memset(c, 0, sizeof(*c)); + cmd_dma_handle = h->cmd_pool_dhandle + + i * sizeof(*c); + c->err_info = h->errinfo_pool + i; + memset(c->err_info, 0, sizeof(*c->err_info)); + err_dma_handle = h->errinfo_pool_dhandle + + i * sizeof(*c->err_info); + h->nr_allocs++; + + c->cmdindex = i; + + INIT_HLIST_NODE(&c->list); + c->busaddr = (__u32) cmd_dma_handle; + temp64.val = (__u64) err_dma_handle; + c->ErrDesc.Addr.lower = temp64.val32.lower; + c->ErrDesc.Addr.upper = temp64.val32.upper; + c->ErrDesc.Len = sizeof(*c->err_info); + + c->h = h; + return c; +} + +/* For operations that can wait for kmalloc to possibly sleep, + * this routine can be called. Lock need not be held to call + * cmd_special_alloc. cmd_special_free() is the complement. + */ +static struct CommandList *cmd_special_alloc(struct ctlr_info *h) +{ + struct CommandList *c; + union u64bit temp64; + dma_addr_t cmd_dma_handle, err_dma_handle; + + c = pci_alloc_consistent(h->pdev, sizeof(*c), &cmd_dma_handle); + if (c == NULL) + return NULL; + memset(c, 0, sizeof(*c)); + + c->cmdindex = -1; + + c->err_info = pci_alloc_consistent(h->pdev, sizeof(*c->err_info), + &err_dma_handle); + + if (c->err_info == NULL) { + pci_free_consistent(h->pdev, + sizeof(*c), c, cmd_dma_handle); + return NULL; + } + memset(c->err_info, 0, sizeof(*c->err_info)); + + INIT_HLIST_NODE(&c->list); + c->busaddr = (__u32) cmd_dma_handle; + temp64.val = (__u64) err_dma_handle; + c->ErrDesc.Addr.lower = temp64.val32.lower; + c->ErrDesc.Addr.upper = temp64.val32.upper; + c->ErrDesc.Len = sizeof(*c->err_info); + + c->h = h; + return c; +} + +static void cmd_free(struct ctlr_info *h, struct CommandList *c) +{ + int i; + + i = c - h->cmd_pool; + clear_bit(i & (BITS_PER_LONG - 1), + h->cmd_pool_bits + (i / BITS_PER_LONG)); + h->nr_frees++; +} + +static void cmd_special_free(struct ctlr_info *h, struct CommandList *c) +{ + union u64bit temp64; + + temp64.val32.lower = c->ErrDesc.Addr.lower; + temp64.val32.upper = c->ErrDesc.Addr.upper; + pci_free_consistent(h->pdev, sizeof(*c->err_info), + c->err_info, (dma_addr_t) temp64.val); + pci_free_consistent(h->pdev, sizeof(*c), + c, (dma_addr_t) c->busaddr); +} + +#ifdef CONFIG_COMPAT + +static int do_ioctl(struct scsi_device *dev, int cmd, void *arg) +{ + int ret; + + lock_kernel(); + ret = hpsa_ioctl(dev, cmd, arg); + unlock_kernel(); + return ret; +} + +static int hpsa_ioctl32_passthru(struct scsi_device *dev, int cmd, void *arg); +static int hpsa_ioctl32_big_passthru(struct scsi_device *dev, + int cmd, void *arg); + +static int hpsa_compat_ioctl(struct scsi_device *dev, int cmd, void *arg) +{ + switch (cmd) { + case CCISS_GETPCIINFO: + case CCISS_GETINTINFO: + case CCISS_SETINTINFO: + case CCISS_GETNODENAME: + case CCISS_SETNODENAME: + case CCISS_GETHEARTBEAT: + case CCISS_GETBUSTYPES: + case CCISS_GETFIRMVER: + case CCISS_GETDRIVVER: + case CCISS_REVALIDVOLS: + case CCISS_DEREGDISK: + case CCISS_REGNEWDISK: + case CCISS_REGNEWD: + case CCISS_RESCANDISK: + case CCISS_GETLUNINFO: + return do_ioctl(dev, cmd, arg); + + case CCISS_PASSTHRU32: + return hpsa_ioctl32_passthru(dev, cmd, arg); + case CCISS_BIG_PASSTHRU32: + return hpsa_ioctl32_big_passthru(dev, cmd, arg); + + default: + return -ENOIOCTLCMD; + } +} + +static int hpsa_ioctl32_passthru(struct scsi_device *dev, int cmd, void *arg) +{ + IOCTL32_Command_struct __user *arg32 = + (IOCTL32_Command_struct __user *) arg; + IOCTL_Command_struct arg64; + IOCTL_Command_struct __user *p = compat_alloc_user_space(sizeof(arg64)); + int err; + u32 cp; + + err = 0; + err |= copy_from_user(&arg64.LUN_info, &arg32->LUN_info, + sizeof(arg64.LUN_info)); + err |= copy_from_user(&arg64.Request, &arg32->Request, + sizeof(arg64.Request)); + err |= copy_from_user(&arg64.error_info, &arg32->error_info, + sizeof(arg64.error_info)); + err |= get_user(arg64.buf_size, &arg32->buf_size); + err |= get_user(cp, &arg32->buf); + arg64.buf = compat_ptr(cp); + err |= copy_to_user(p, &arg64, sizeof(arg64)); + + if (err) + return -EFAULT; + + err = do_ioctl(dev, CCISS_PASSTHRU, (void *)p); + if (err) + return err; + err |= copy_in_user(&arg32->error_info, &p->error_info, + sizeof(arg32->error_info)); + if (err) + return -EFAULT; + return err; +} + +static int hpsa_ioctl32_big_passthru(struct scsi_device *dev, + int cmd, void *arg) +{ + BIG_IOCTL32_Command_struct __user *arg32 = + (BIG_IOCTL32_Command_struct __user *) arg; + BIG_IOCTL_Command_struct arg64; + BIG_IOCTL_Command_struct __user *p = + compat_alloc_user_space(sizeof(arg64)); + int err; + u32 cp; + + err = 0; + err |= copy_from_user(&arg64.LUN_info, &arg32->LUN_info, + sizeof(arg64.LUN_info)); + err |= copy_from_user(&arg64.Request, &arg32->Request, + sizeof(arg64.Request)); + err |= copy_from_user(&arg64.error_info, &arg32->error_info, + sizeof(arg64.error_info)); + err |= get_user(arg64.buf_size, &arg32->buf_size); + err |= get_user(arg64.malloc_size, &arg32->malloc_size); + err |= get_user(cp, &arg32->buf); + arg64.buf = compat_ptr(cp); + err |= copy_to_user(p, &arg64, sizeof(arg64)); + + if (err) + return -EFAULT; + + err = do_ioctl(dev, CCISS_BIG_PASSTHRU, (void *)p); + if (err) + return err; + err |= copy_in_user(&arg32->error_info, &p->error_info, + sizeof(arg32->error_info)); + if (err) + return -EFAULT; + return err; +} +#endif + +static int hpsa_getpciinfo_ioctl(struct ctlr_info *h, void __user *argp) +{ + struct hpsa_pci_info pciinfo; + + if (!argp) + return -EINVAL; + pciinfo.domain = pci_domain_nr(h->pdev->bus); + pciinfo.bus = h->pdev->bus->number; + pciinfo.dev_fn = h->pdev->devfn; + pciinfo.board_id = h->board_id; + if (copy_to_user(argp, &pciinfo, sizeof(pciinfo))) + return -EFAULT; + return 0; +} + +static int hpsa_getdrivver_ioctl(struct ctlr_info *h, void __user *argp) +{ + DriverVer_type DriverVer; + unsigned char vmaj, vmin, vsubmin; + int rc; + + rc = sscanf(HPSA_DRIVER_VERSION, "%hhu.%hhu.%hhu", + &vmaj, &vmin, &vsubmin); + if (rc != 3) { + dev_info(&h->pdev->dev, "driver version string '%s' " + "unrecognized.", HPSA_DRIVER_VERSION); + vmaj = 0; + vmin = 0; + vsubmin = 0; + } + DriverVer = (vmaj << 16) | (vmin << 8) | vsubmin; + if (!argp) + return -EINVAL; + if (copy_to_user(argp, &DriverVer, sizeof(DriverVer_type))) + return -EFAULT; + return 0; +} + +static int hpsa_passthru_ioctl(struct ctlr_info *h, void __user *argp) +{ + IOCTL_Command_struct iocommand; + struct CommandList *c; + char *buff = NULL; + union u64bit temp64; + + if (!argp) + return -EINVAL; + if (!capable(CAP_SYS_RAWIO)) + return -EPERM; + if (copy_from_user(&iocommand, argp, sizeof(iocommand))) + return -EFAULT; + if ((iocommand.buf_size < 1) && + (iocommand.Request.Type.Direction != XFER_NONE)) { + return -EINVAL; + } + if (iocommand.buf_size > 0) { + buff = kmalloc(iocommand.buf_size, GFP_KERNEL); + if (buff == NULL) + return -EFAULT; + } + if (iocommand.Request.Type.Direction == XFER_WRITE) { + /* Copy the data into the buffer we created */ + if (copy_from_user(buff, iocommand.buf, iocommand.buf_size)) { + kfree(buff); + return -EFAULT; + } + } else + memset(buff, 0, iocommand.buf_size); + c = cmd_special_alloc(h); + if (c == NULL) { + kfree(buff); + return -ENOMEM; + } + /* Fill in the command type */ + c->cmd_type = CMD_IOCTL_PEND; + /* Fill in Command Header */ + c->Header.ReplyQueue = 0; /* unused in simple mode */ + if (iocommand.buf_size > 0) { /* buffer to fill */ + c->Header.SGList = 1; + c->Header.SGTotal = 1; + } else { /* no buffers to fill */ + c->Header.SGList = 0; + c->Header.SGTotal = 0; + } + memcpy(&c->Header.LUN, &iocommand.LUN_info, sizeof(c->Header.LUN)); + /* use the kernel address the cmd block for tag */ + c->Header.Tag.lower = c->busaddr; + + /* Fill in Request block */ + memcpy(&c->Request, &iocommand.Request, + sizeof(c->Request)); + + /* Fill in the scatter gather information */ + if (iocommand.buf_size > 0) { + temp64.val = pci_map_single(h->pdev, buff, + iocommand.buf_size, PCI_DMA_BIDIRECTIONAL); + c->SG[0].Addr.lower = temp64.val32.lower; + c->SG[0].Addr.upper = temp64.val32.upper; + c->SG[0].Len = iocommand.buf_size; + c->SG[0].Ext = 0; /* we are not chaining*/ + } + hpsa_scsi_do_simple_cmd_core(h, c); + hpsa_pci_unmap(h->pdev, c, 1, PCI_DMA_BIDIRECTIONAL); + check_ioctl_unit_attention(h, c); + + /* Copy the error information out */ + memcpy(&iocommand.error_info, c->err_info, + sizeof(iocommand.error_info)); + if (copy_to_user(argp, &iocommand, sizeof(iocommand))) { + kfree(buff); + cmd_special_free(h, c); + return -EFAULT; + } + + if (iocommand.Request.Type.Direction == XFER_READ) { + /* Copy the data out of the buffer we created */ + if (copy_to_user(iocommand.buf, buff, iocommand.buf_size)) { + kfree(buff); + cmd_special_free(h, c); + return -EFAULT; + } + } + kfree(buff); + cmd_special_free(h, c); + return 0; +} + +static int hpsa_big_passthru_ioctl(struct ctlr_info *h, void __user *argp) +{ + BIG_IOCTL_Command_struct *ioc; + struct CommandList *c; + unsigned char **buff = NULL; + int *buff_size = NULL; + union u64bit temp64; + BYTE sg_used = 0; + int status = 0; + int i; + __u32 left; + __u32 sz; + BYTE __user *data_ptr; + + if (!argp) + return -EINVAL; + if (!capable(CAP_SYS_RAWIO)) + return -EPERM; + ioc = (BIG_IOCTL_Command_struct *) + kmalloc(sizeof(*ioc), GFP_KERNEL); + if (!ioc) { + status = -ENOMEM; + goto cleanup1; + } + if (copy_from_user(ioc, argp, sizeof(*ioc))) { + status = -EFAULT; + goto cleanup1; + } + if ((ioc->buf_size < 1) && + (ioc->Request.Type.Direction != XFER_NONE)) { + status = -EINVAL; + goto cleanup1; + } + /* Check kmalloc limits using all SGs */ + if (ioc->malloc_size > MAX_KMALLOC_SIZE) { + status = -EINVAL; + goto cleanup1; + } + if (ioc->buf_size > ioc->malloc_size * MAXSGENTRIES) { + status = -EINVAL; + goto cleanup1; + } + buff = kzalloc(MAXSGENTRIES * sizeof(char *), GFP_KERNEL); + if (!buff) { + status = -ENOMEM; + goto cleanup1; + } + buff_size = kmalloc(MAXSGENTRIES * sizeof(int), GFP_KERNEL); + if (!buff_size) { + status = -ENOMEM; + goto cleanup1; + } + left = ioc->buf_size; + data_ptr = ioc->buf; + while (left) { + sz = (left > ioc->malloc_size) ? ioc->malloc_size : left; + buff_size[sg_used] = sz; + buff[sg_used] = kmalloc(sz, GFP_KERNEL); + if (buff[sg_used] == NULL) { + status = -ENOMEM; + goto cleanup1; + } + if (ioc->Request.Type.Direction == XFER_WRITE) { + if (copy_from_user(buff[sg_used], data_ptr, sz)) { + status = -ENOMEM; + goto cleanup1; + } + } else + memset(buff[sg_used], 0, sz); + left -= sz; + data_ptr += sz; + sg_used++; + } + c = cmd_special_alloc(h); + if (c == NULL) { + status = -ENOMEM; + goto cleanup1; + } + c->cmd_type = CMD_IOCTL_PEND; + c->Header.ReplyQueue = 0; + + if (ioc->buf_size > 0) { + c->Header.SGList = sg_used; + c->Header.SGTotal = sg_used; + } else { + c->Header.SGList = 0; + c->Header.SGTotal = 0; + } + memcpy(&c->Header.LUN, &ioc->LUN_info, sizeof(c->Header.LUN)); + c->Header.Tag.lower = c->busaddr; + memcpy(&c->Request, &ioc->Request, sizeof(c->Request)); + if (ioc->buf_size > 0) { + int i; + for (i = 0; i < sg_used; i++) { + temp64.val = pci_map_single(h->pdev, buff[i], + buff_size[i], PCI_DMA_BIDIRECTIONAL); + c->SG[i].Addr.lower = temp64.val32.lower; + c->SG[i].Addr.upper = temp64.val32.upper; + c->SG[i].Len = buff_size[i]; + /* we are not chaining */ + c->SG[i].Ext = 0; + } + } + hpsa_scsi_do_simple_cmd_core(h, c); + hpsa_pci_unmap(h->pdev, c, sg_used, PCI_DMA_BIDIRECTIONAL); + check_ioctl_unit_attention(h, c); + /* Copy the error information out */ + memcpy(&ioc->error_info, c->err_info, sizeof(ioc->error_info)); + if (copy_to_user(argp, ioc, sizeof(*ioc))) { + cmd_special_free(h, c); + status = -EFAULT; + goto cleanup1; + } + if (ioc->Request.Type.Direction == XFER_READ) { + /* Copy the data out of the buffer we created */ + BYTE __user *ptr = ioc->buf; + for (i = 0; i < sg_used; i++) { + if (copy_to_user(ptr, buff[i], buff_size[i])) { + cmd_special_free(h, c); + status = -EFAULT; + goto cleanup1; + } + ptr += buff_size[i]; + } + } + cmd_special_free(h, c); + status = 0; +cleanup1: + if (buff) { + for (i = 0; i < sg_used; i++) + kfree(buff[i]); + kfree(buff); + } + kfree(buff_size); + kfree(ioc); + return status; +} + +static void check_ioctl_unit_attention(struct ctlr_info *h, + struct CommandList *c) +{ + if (c->err_info->CommandStatus == CMD_TARGET_STATUS && + c->err_info->ScsiStatus != SAM_STAT_CHECK_CONDITION) + (void) check_for_unit_attention(h, c); +} +/* + * ioctl + */ +static int hpsa_ioctl(struct scsi_device *dev, int cmd, void *arg) +{ + struct ctlr_info *h; + void __user *argp = (void __user *)arg; + + h = sdev_to_hba(dev); + + switch (cmd) { + case CCISS_DEREGDISK: + case CCISS_REGNEWDISK: + case CCISS_REGNEWD: + hpsa_update_scsi_devices(h, dev->host->host_no); + return 0; + case CCISS_GETPCIINFO: + return hpsa_getpciinfo_ioctl(h, argp); + case CCISS_GETDRIVVER: + return hpsa_getdrivver_ioctl(h, argp); + case CCISS_PASSTHRU: + return hpsa_passthru_ioctl(h, argp); + case CCISS_BIG_PASSTHRU: + return hpsa_big_passthru_ioctl(h, argp); + default: + return -ENOTTY; + } +} + +static void fill_cmd(struct CommandList *c, __u8 cmd, struct ctlr_info *h, + void *buff, size_t size, __u8 page_code, unsigned char *scsi3addr, + int cmd_type) +{ + int pci_dir = XFER_NONE; + + c->cmd_type = CMD_IOCTL_PEND; + c->Header.ReplyQueue = 0; + if (buff != NULL && size > 0) { + c->Header.SGList = 1; + c->Header.SGTotal = 1; + } else { + c->Header.SGList = 0; + c->Header.SGTotal = 0; + } + c->Header.Tag.lower = c->busaddr; + memcpy(c->Header.LUN.LunAddrBytes, scsi3addr, 8); + + c->Request.Type.Type = cmd_type; + if (cmd_type == TYPE_CMD) { + switch (cmd) { + case HPSA_INQUIRY: + /* are we trying to read a vital product page */ + if (page_code != 0) { + c->Request.CDB[1] = 0x01; + c->Request.CDB[2] = page_code; + } + c->Request.CDBLen = 6; + c->Request.Type.Attribute = ATTR_SIMPLE; + c->Request.Type.Direction = XFER_READ; + c->Request.Timeout = 0; + c->Request.CDB[0] = HPSA_INQUIRY; + c->Request.CDB[4] = size & 0xFF; + break; + case HPSA_REPORT_LOG: + case HPSA_REPORT_PHYS: + /* Talking to controller so It's a physical command + mode = 00 target = 0. Nothing to write. + */ + c->Request.CDBLen = 12; + c->Request.Type.Attribute = ATTR_SIMPLE; + c->Request.Type.Direction = XFER_READ; + c->Request.Timeout = 0; + c->Request.CDB[0] = cmd; + c->Request.CDB[6] = (size >> 24) & 0xFF; /* MSB */ + c->Request.CDB[7] = (size >> 16) & 0xFF; + c->Request.CDB[8] = (size >> 8) & 0xFF; + c->Request.CDB[9] = size & 0xFF; + break; + + case HPSA_READ_CAPACITY: + c->Request.CDBLen = 10; + c->Request.Type.Attribute = ATTR_SIMPLE; + c->Request.Type.Direction = XFER_READ; + c->Request.Timeout = 0; + c->Request.CDB[0] = cmd; + break; + case HPSA_CACHE_FLUSH: + c->Request.CDBLen = 12; + c->Request.Type.Attribute = ATTR_SIMPLE; + c->Request.Type.Direction = XFER_WRITE; + c->Request.Timeout = 0; + c->Request.CDB[0] = BMIC_WRITE; + c->Request.CDB[6] = BMIC_CACHE_FLUSH; + break; + case TEST_UNIT_READY: + c->Request.CDBLen = 6; + c->Request.Type.Attribute = ATTR_SIMPLE; + c->Request.Type.Direction = XFER_NONE; + c->Request.Timeout = 0; + break; + default: + dev_warn(&h->pdev->dev, "unknown command 0x%c\n", cmd); + BUG(); + return; + } + } else if (cmd_type == TYPE_MSG) { + switch (cmd) { + + case HPSA_DEVICE_RESET_MSG: + c->Request.CDBLen = 16; + c->Request.Type.Type = 1; /* It is a MSG not a CMD */ + c->Request.Type.Attribute = ATTR_SIMPLE; + c->Request.Type.Direction = XFER_NONE; + c->Request.Timeout = 0; /* Don't time out */ + c->Request.CDB[0] = 0x01; /* RESET_MSG is 0x01 */ + c->Request.CDB[1] = 0x03; /* Reset target above */ + /* If bytes 4-7 are zero, it means reset the */ + /* LunID device */ + c->Request.CDB[4] = 0x00; + c->Request.CDB[5] = 0x00; + c->Request.CDB[6] = 0x00; + c->Request.CDB[7] = 0x00; + break; + + default: + dev_warn(&h->pdev->dev, "unknown message type %d\n", + cmd); + BUG(); + } + } else { + dev_warn(&h->pdev->dev, "unknown command type %d\n", cmd_type); + BUG(); + } + + switch (c->Request.Type.Direction) { + case XFER_READ: + pci_dir = PCI_DMA_FROMDEVICE; + break; + case XFER_WRITE: + pci_dir = PCI_DMA_TODEVICE; + break; + case XFER_NONE: + pci_dir = PCI_DMA_NONE; + break; + default: + pci_dir = PCI_DMA_BIDIRECTIONAL; + } + + hpsa_map_one(h->pdev, c, buff, size, pci_dir); + + return; +} + +/* + * Map (physical) PCI mem into (virtual) kernel space + */ +static void __iomem *remap_pci_mem(ulong base, ulong size) +{ + ulong page_base = ((ulong) base) & PAGE_MASK; + ulong page_offs = ((ulong) base) - page_base; + void __iomem *page_remapped = ioremap(page_base, page_offs + size); + + return page_remapped ? (page_remapped + page_offs) : NULL; +} + +/* Takes cmds off the submission queue and sends them to the hardware, + * then puts them on the queue of cmds waiting for completion. + */ +static void start_io(struct ctlr_info *h) +{ + struct CommandList *c; + + while (!hlist_empty(&h->reqQ)) { + c = hlist_entry(h->reqQ.first, struct CommandList, list); + /* can't do anything if fifo is full */ + if ((h->access.fifo_full(h))) { + dev_warn(&h->pdev->dev, "fifo full\n"); + break; + } + + /* Get the first entry from the Request Q */ + removeQ(c); + h->Qdepth--; + + /* Tell the controller execute command */ + h->access.submit_command(h, c); + + /* Put job onto the completed Q */ + addQ(&h->cmpQ, c); + } +} + +static inline unsigned long get_next_completion(struct ctlr_info *h) +{ + return h->access.command_completed(h); +} + +static inline int interrupt_pending(struct ctlr_info *h) +{ + return h->access.intr_pending(h); +} + +static inline long interrupt_not_for_us(struct ctlr_info *h) +{ + return ((h->access.intr_pending(h) == 0) || + (h->interrupts_enabled == 0)); +} + +static inline int bad_tag(struct ctlr_info *h, __u32 tag_index, + __u32 raw_tag) +{ + if (unlikely(tag_index >= h->nr_cmds)) { + dev_warn(&h->pdev->dev, "bad tag 0x%08x ignored.\n", raw_tag); + return 1; + } + return 0; +} + +static inline void finish_cmd(struct CommandList *c, __u32 raw_tag) +{ + removeQ(c); + if (likely(c->cmd_type == CMD_SCSI)) + complete_scsi_command(c, 0, raw_tag); + else if (c->cmd_type == CMD_IOCTL_PEND) + complete(c->waiting); +} + +static irqreturn_t do_hpsa_intr(int irq, void *dev_id) +{ + struct ctlr_info *h = dev_id; + struct CommandList *c; + unsigned long flags; + __u32 raw_tag, tag, tag_index; + struct hlist_node *tmp; + + if (interrupt_not_for_us(h)) + return IRQ_NONE; + spin_lock_irqsave(&h->lock, flags); + while (interrupt_pending(h)) { + while ((raw_tag = get_next_completion(h)) != FIFO_EMPTY) { + if (likely(HPSA_TAG_CONTAINS_INDEX(raw_tag))) { + tag_index = HPSA_TAG_TO_INDEX(raw_tag); + if (bad_tag(h, tag_index, raw_tag)) + return IRQ_HANDLED; + c = h->cmd_pool + tag_index; + finish_cmd(c, raw_tag); + continue; + } + tag = HPSA_TAG_DISCARD_ERROR_BITS(raw_tag); + c = NULL; + hlist_for_each_entry(c, tmp, &h->cmpQ, list) { + if (c->busaddr == tag) { + finish_cmd(c, raw_tag); + break; + } + } + } + } + spin_unlock_irqrestore(&h->lock, flags); + return IRQ_HANDLED; +} + +/* Send a message CDB to the firmware. */ +static __devinit int hpsa_message(struct pci_dev *pdev, unsigned char opcode, + unsigned char type) +{ + struct Command { + struct CommandListHeader CommandHeader; + struct RequestBlock Request; + struct ErrDescriptor ErrorDescriptor; + }; + struct Command *cmd; + static const size_t cmd_sz = sizeof(*cmd) + + sizeof(cmd->ErrorDescriptor); + dma_addr_t paddr64; + uint32_t paddr32, tag; + void __iomem *vaddr; + int i, err; + + vaddr = pci_ioremap_bar(pdev, 0); + if (vaddr == NULL) + return -ENOMEM; + + /* The Inbound Post Queue only accepts 32-bit physical addresses for the + * CCISS commands, so they must be allocated from the lower 4GiB of + * memory. + */ + err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); + if (err) { + iounmap(vaddr); + return -ENOMEM; + } + + cmd = pci_alloc_consistent(pdev, cmd_sz, &paddr64); + if (cmd == NULL) { + iounmap(vaddr); + return -ENOMEM; + } + + /* This must fit, because of the 32-bit consistent DMA mask. Also, + * although there's no guarantee, we assume that the address is at + * least 4-byte aligned (most likely, it's page-aligned). + */ + paddr32 = paddr64; + + cmd->CommandHeader.ReplyQueue = 0; + cmd->CommandHeader.SGList = 0; + cmd->CommandHeader.SGTotal = 0; + cmd->CommandHeader.Tag.lower = paddr32; + cmd->CommandHeader.Tag.upper = 0; + memset(&cmd->CommandHeader.LUN.LunAddrBytes, 0, 8); + + cmd->Request.CDBLen = 16; + cmd->Request.Type.Type = TYPE_MSG; + cmd->Request.Type.Attribute = ATTR_HEADOFQUEUE; + cmd->Request.Type.Direction = XFER_NONE; + cmd->Request.Timeout = 0; /* Don't time out */ + cmd->Request.CDB[0] = opcode; + cmd->Request.CDB[1] = type; + memset(&cmd->Request.CDB[2], 0, 14); /* rest of the CDB is reserved */ + cmd->ErrorDescriptor.Addr.lower = paddr32 + sizeof(*cmd); + cmd->ErrorDescriptor.Addr.upper = 0; + cmd->ErrorDescriptor.Len = sizeof(struct ErrorInfo); + + writel(paddr32, vaddr + SA5_REQUEST_PORT_OFFSET); + + for (i = 0; i < HPSA_MSG_SEND_RETRY_LIMIT; i++) { + tag = readl(vaddr + SA5_REPLY_PORT_OFFSET); + if (HPSA_TAG_DISCARD_ERROR_BITS(tag) == paddr32) + break; + msleep(HPSA_MSG_SEND_RETRY_INTERVAL_MSECS); + } + + iounmap(vaddr); + + /* we leak the DMA buffer here ... no choice since the controller could + * still complete the command. + */ + if (i == HPSA_MSG_SEND_RETRY_LIMIT) { + dev_err(&pdev->dev, "controller message %02x:%02x timed out\n", + opcode, type); + return -ETIMEDOUT; + } + + pci_free_consistent(pdev, cmd_sz, cmd, paddr64); + + if (tag & HPSA_ERROR_BIT) { + dev_err(&pdev->dev, "controller message %02x:%02x failed\n", + opcode, type); + return -EIO; + } + + dev_info(&pdev->dev, "controller message %02x:%02x succeeded\n", + opcode, type); + return 0; +} + +#define hpsa_soft_reset_controller(p) hpsa_message(p, 1, 0) +#define hpsa_noop(p) hpsa_message(p, 3, 0) + +static __devinit int hpsa_reset_msi(struct pci_dev *pdev) +{ +/* the #defines are stolen from drivers/pci/msi.h. */ +#define msi_control_reg(base) (base + PCI_MSI_FLAGS) +#define PCI_MSIX_FLAGS_ENABLE (1 << 15) + + int pos; + u16 control = 0; + + pos = pci_find_capability(pdev, PCI_CAP_ID_MSI); + if (pos) { + pci_read_config_word(pdev, msi_control_reg(pos), &control); + if (control & PCI_MSI_FLAGS_ENABLE) { + dev_info(&pdev->dev, "resetting MSI\n"); + pci_write_config_word(pdev, msi_control_reg(pos), + control & ~PCI_MSI_FLAGS_ENABLE); + } + } + + pos = pci_find_capability(pdev, PCI_CAP_ID_MSIX); + if (pos) { + pci_read_config_word(pdev, msi_control_reg(pos), &control); + if (control & PCI_MSIX_FLAGS_ENABLE) { + dev_info(&pdev->dev, "resetting MSI-X\n"); + pci_write_config_word(pdev, msi_control_reg(pos), + control & ~PCI_MSIX_FLAGS_ENABLE); + } + } + + return 0; +} + +/* This does a hard reset of the controller using PCI power management + * states. + */ +static __devinit int hpsa_hard_reset_controller(struct pci_dev *pdev) +{ + u16 pmcsr, saved_config_space[32]; + int i, pos; + + dev_info(&pdev->dev, "using PCI PM to reset controller\n"); + + /* This is very nearly the same thing as + * + * pci_save_state(pci_dev); + * pci_set_power_state(pci_dev, PCI_D3hot); + * pci_set_power_state(pci_dev, PCI_D0); + * pci_restore_state(pci_dev); + * + * but we can't use these nice canned kernel routines on + * kexec, because they also check the MSI/MSI-X state in PCI + * configuration space and do the wrong thing when it is + * set/cleared. Also, the pci_save/restore_state functions + * violate the ordering requirements for restoring the + * configuration space from the CCISS document (see the + * comment below). So we roll our own .... + */ + + for (i = 0; i < 32; i++) + pci_read_config_word(pdev, 2*i, &saved_config_space[i]); + + pos = pci_find_capability(pdev, PCI_CAP_ID_PM); + if (pos == 0) { + dev_err(&pdev->dev, + "hpsa_reset_controller: PCI PM not supported\n"); + return -ENODEV; + } + + /* Quoting from the Open CISS Specification: "The Power + * Management Control/Status Register (CSR) controls the power + * state of the device. The normal operating state is D0, + * CSR=00h. The software off state is D3, CSR=03h. To reset + * the controller, place the interface device in D3 then to + * D0, this causes a secondary PCI reset which will reset the + * controller." + */ + + /* enter the D3hot power management state */ + pci_read_config_word(pdev, pos + PCI_PM_CTRL, &pmcsr); + pmcsr &= ~PCI_PM_CTRL_STATE_MASK; + pmcsr |= PCI_D3hot; + pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr); + + msleep(500); + + /* enter the D0 power management state */ + pmcsr &= ~PCI_PM_CTRL_STATE_MASK; + pmcsr |= PCI_D0; + pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr); + + msleep(500); + + /* Restore the PCI configuration space. The Open CISS + * Specification says, "Restore the PCI Configuration + * Registers, offsets 00h through 60h. It is important to + * restore the command register, 16-bits at offset 04h, + * last. Do not restore the configuration status register, + * 16-bits at offset 06h." Note that the offset is 2*i. + */ + for (i = 0; i < 32; i++) { + if (i == 2 || i == 3) + continue; + pci_write_config_word(pdev, 2*i, saved_config_space[i]); + } + wmb(); + pci_write_config_word(pdev, 4, saved_config_space[2]); + + return 0; +} + +/* + * We cannot read the structure directly, for portability we must use + * the io functions. + * This is for debug only. + */ +#ifdef HPSA_DEBUG +static void print_cfg_table(struct device *dev, struct CfgTable *tb) +{ + int i; + char temp_name[17]; + + dev_info(dev, "Controller Configuration information\n"); + dev_info(dev, "------------------------------------\n"); + for (i = 0; i < 4; i++) + temp_name[i] = readb(&(tb->Signature[i])); + temp_name[4] = '\0'; + dev_info(dev, " Signature = %s\n", temp_name); + dev_info(dev, " Spec Number = %d\n", readl(&(tb->SpecValence))); + dev_info(dev, " Transport methods supported = 0x%x\n", + readl(&(tb->TransportSupport))); + dev_info(dev, " Transport methods active = 0x%x\n", + readl(&(tb->TransportActive))); + dev_info(dev, " Requested transport Method = 0x%x\n", + readl(&(tb->HostWrite.TransportRequest))); + dev_info(dev, " Coalesce Interrupt Delay = 0x%x\n", + readl(&(tb->HostWrite.CoalIntDelay))); + dev_info(dev, " Coalesce Interrupt Count = 0x%x\n", + readl(&(tb->HostWrite.CoalIntCount))); + dev_info(dev, " Max outstanding commands = 0x%d\n", + readl(&(tb->CmdsOutMax))); + dev_info(dev, " Bus Types = 0x%x\n", readl(&(tb->BusTypes))); + for (i = 0; i < 16; i++) + temp_name[i] = readb(&(tb->ServerName[i])); + temp_name[16] = '\0'; + dev_info(dev, " Server Name = %s\n", temp_name); + dev_info(dev, " Heartbeat Counter = 0x%x\n\n\n", + readl(&(tb->HeartBeat))); +} +#endif /* HPSA_DEBUG */ + +static int find_PCI_BAR_index(struct pci_dev *pdev, unsigned long pci_bar_addr) +{ + int i, offset, mem_type, bar_type; + + if (pci_bar_addr == PCI_BASE_ADDRESS_0) /* looking for BAR zero? */ + return 0; + offset = 0; + for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { + bar_type = pci_resource_flags(pdev, i) & PCI_BASE_ADDRESS_SPACE; + if (bar_type == PCI_BASE_ADDRESS_SPACE_IO) + offset += 4; + else { + mem_type = pci_resource_flags(pdev, i) & + PCI_BASE_ADDRESS_MEM_TYPE_MASK; + switch (mem_type) { + case PCI_BASE_ADDRESS_MEM_TYPE_32: + case PCI_BASE_ADDRESS_MEM_TYPE_1M: + offset += 4; /* 32 bit */ + break; + case PCI_BASE_ADDRESS_MEM_TYPE_64: + offset += 8; + break; + default: /* reserved in PCI 2.2 */ + dev_warn(&pdev->dev, + "base address is invalid\n"); + return -1; + break; + } + } + if (offset == pci_bar_addr - PCI_BASE_ADDRESS_0) + return i + 1; + } + return -1; +} + +/* If MSI/MSI-X is supported by the kernel we will try to enable it on + * controllers that are capable. If not, we use IO-APIC mode. + */ + +static void __devinit hpsa_interrupt_mode(struct ctlr_info *h, + struct pci_dev *pdev, __u32 board_id) +{ +#ifdef CONFIG_PCI_MSI + int err; + struct msix_entry hpsa_msix_entries[4] = { {0, 0}, {0, 1}, + {0, 2}, {0, 3} + }; + + /* Some boards advertise MSI but don't really support it */ + if ((board_id == 0x40700E11) || + (board_id == 0x40800E11) || + (board_id == 0x40820E11) || (board_id == 0x40830E11)) + goto default_int_mode; + if (pci_find_capability(pdev, PCI_CAP_ID_MSIX)) { + dev_info(&pdev->dev, "MSIX\n"); + err = pci_enable_msix(pdev, hpsa_msix_entries, 4); + if (!err) { + h->intr[0] = hpsa_msix_entries[0].vector; + h->intr[1] = hpsa_msix_entries[1].vector; + h->intr[2] = hpsa_msix_entries[2].vector; + h->intr[3] = hpsa_msix_entries[3].vector; + h->msix_vector = 1; + return; + } + if (err > 0) { + dev_warn(&pdev->dev, "only %d MSI-X vectors " + "available\n", err); + goto default_int_mode; + } else { + dev_warn(&pdev->dev, "MSI-X init failed %d\n", + err); + goto default_int_mode; + } + } + if (pci_find_capability(pdev, PCI_CAP_ID_MSI)) { + dev_info(&pdev->dev, "MSI\n"); + if (!pci_enable_msi(pdev)) + h->msi_vector = 1; + else + dev_warn(&pdev->dev, "MSI init failed\n"); + } +default_int_mode: +#endif /* CONFIG_PCI_MSI */ + /* if we get here we're going to use the default interrupt mode */ + h->intr[SIMPLE_MODE_INT] = pdev->irq; + return; +} + +static int hpsa_pci_init(struct ctlr_info *h, struct pci_dev *pdev) +{ + ushort subsystem_vendor_id, subsystem_device_id, command; + __u32 board_id, scratchpad = 0; + __u64 cfg_offset; + __u32 cfg_base_addr; + __u64 cfg_base_addr_index; + int i, prod_index, err; + + subsystem_vendor_id = pdev->subsystem_vendor; + subsystem_device_id = pdev->subsystem_device; + board_id = (((__u32) (subsystem_device_id << 16) & 0xffff0000) | + subsystem_vendor_id); + + for (i = 0; i < ARRAY_SIZE(products); i++) + if (board_id == products[i].board_id) + break; + + prod_index = i; + + if (prod_index == ARRAY_SIZE(products)) { + prod_index--; + if (subsystem_vendor_id != PCI_VENDOR_ID_HP || + !hpsa_allow_any) { + dev_warn(&pdev->dev, "unrecognized board ID:" + " 0x%08lx, ignoring.\n", + (unsigned long) board_id); + return -ENODEV; + } + } + /* check to see if controller has been disabled + * BEFORE trying to enable it + */ + (void)pci_read_config_word(pdev, PCI_COMMAND, &command); + if (!(command & 0x02)) { + dev_warn(&pdev->dev, "controller appears to be disabled\n"); + return -ENODEV; + } + + err = pci_enable_device(pdev); + if (err) { + dev_warn(&pdev->dev, "unable to enable PCI device\n"); + return err; + } + + err = pci_request_regions(pdev, "hpsa"); + if (err) { + dev_err(&pdev->dev, "cannot obtain PCI resources, aborting\n"); + return err; + } + + /* If the kernel supports MSI/MSI-X we will try to enable that, + * else we use the IO-APIC interrupt assigned to us by system ROM. + */ + hpsa_interrupt_mode(h, pdev, board_id); + + /* find the memory BAR */ + for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { + if (pci_resource_flags(pdev, i) & IORESOURCE_MEM) + break; + } + if (i == DEVICE_COUNT_RESOURCE) { + dev_warn(&pdev->dev, "no memory BAR found\n"); + err = -ENODEV; + goto err_out_free_res; + } + + h->paddr = pci_resource_start(pdev, i); /* addressing mode bits + * already removed + */ + + h->vaddr = remap_pci_mem(h->paddr, 0x250); + + /* Wait for the board to become ready. */ + for (i = 0; i < HPSA_BOARD_READY_ITERATIONS; i++) { + scratchpad = readl(h->vaddr + SA5_SCRATCHPAD_OFFSET); + if (scratchpad == HPSA_FIRMWARE_READY) + break; + msleep(HPSA_BOARD_READY_POLL_INTERVAL_MSECS); + } + if (scratchpad != HPSA_FIRMWARE_READY) { + dev_warn(&pdev->dev, "board not ready, timed out.\n"); + err = -ENODEV; + goto err_out_free_res; + } + + /* get the address index number */ + cfg_base_addr = readl(h->vaddr + SA5_CTCFG_OFFSET); + cfg_base_addr &= (__u32) 0x0000ffff; + cfg_base_addr_index = find_PCI_BAR_index(pdev, cfg_base_addr); + if (cfg_base_addr_index == -1) { + dev_warn(&pdev->dev, "cannot find cfg_base_addr_index\n"); + err = -ENODEV; + goto err_out_free_res; + } + + cfg_offset = readl(h->vaddr + SA5_CTMEM_OFFSET); + h->cfgtable = remap_pci_mem(pci_resource_start(pdev, + cfg_base_addr_index) + cfg_offset, + sizeof(h->cfgtable)); + h->board_id = board_id; + + /* Query controller for max supported commands: */ + h->max_commands = readl(&(h->cfgtable->CmdsOutMax)); + + h->product_name = products[prod_index].product_name; + h->access = *(products[prod_index].access); + /* Allow room for some ioctls */ + h->nr_cmds = h->max_commands - 4; + + if ((readb(&h->cfgtable->Signature[0]) != 'C') || + (readb(&h->cfgtable->Signature[1]) != 'I') || + (readb(&h->cfgtable->Signature[2]) != 'S') || + (readb(&h->cfgtable->Signature[3]) != 'S')) { + dev_warn(&pdev->dev, "not a valid CISS config table\n"); + err = -ENODEV; + goto err_out_free_res; + } +#ifdef CONFIG_X86 + { + /* Need to enable prefetch in the SCSI core for 6400 in x86 */ + __u32 prefetch; + prefetch = readl(&(h->cfgtable->SCSI_Prefetch)); + prefetch |= 0x100; + writel(prefetch, &(h->cfgtable->SCSI_Prefetch)); + } +#endif + + /* Disabling DMA prefetch for the P600 + * An ASIC bug may result in a prefetch beyond + * physical memory. + */ + if (board_id == 0x3225103C) { + __u32 dma_prefetch; + dma_prefetch = readl(h->vaddr + I2O_DMA1_CFG); + dma_prefetch |= 0x8000; + writel(dma_prefetch, h->vaddr + I2O_DMA1_CFG); + } + + h->max_commands = readl(&(h->cfgtable->CmdsOutMax)); + /* Update the field, and then ring the doorbell */ + writel(CFGTBL_Trans_Simple, &(h->cfgtable->HostWrite.TransportRequest)); + writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL); + + /* under certain very rare conditions, this can take awhile. + * (e.g.: hot replace a failed 144GB drive in a RAID 5 set right + * as we enter this code.) + */ + for (i = 0; i < MAX_CONFIG_WAIT; i++) { + if (!(readl(h->vaddr + SA5_DOORBELL) & CFGTBL_ChangeReq)) + break; + /* delay and try again */ + msleep(10); + } + +#ifdef HPSA_DEBUG + print_cfg_table(&pdev->dev, h->cfgtable); +#endif /* HPSA_DEBUG */ + + if (!(readl(&(h->cfgtable->TransportActive)) & CFGTBL_Trans_Simple)) { + dev_warn(&pdev->dev, "unable to get board into simple mode\n"); + err = -ENODEV; + goto err_out_free_res; + } + return 0; + +err_out_free_res: + /* + * Deliberately omit pci_disable_device(): it does something nasty to + * Smart Array controllers that pci_enable_device does not undo + */ + pci_release_regions(pdev); + return err; +} + +static int __devinit hpsa_init_one(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + int i; + int dac; + struct ctlr_info *h; + + if (number_of_controllers == 0) + printk(KERN_INFO DRIVER_NAME "\n"); + if (reset_devices) { + /* Reset the controller with a PCI power-cycle */ + if (hpsa_hard_reset_controller(pdev) || hpsa_reset_msi(pdev)) + return -ENODEV; + + /* Some devices (notably the HP Smart Array 5i Controller) + need a little pause here */ + msleep(HPSA_POST_RESET_PAUSE_MSECS); + + /* Now try to get the controller to respond to a no-op */ + for (i = 0; i < HPSA_POST_RESET_NOOP_RETRIES; i++) { + if (hpsa_noop(pdev) == 0) + break; + else + dev_warn(&pdev->dev, "no-op failed%s\n", + (i < 11 ? "; re-trying" : "")); + } + } + + BUILD_BUG_ON(sizeof(struct CommandList) % 8); + h = kzalloc(sizeof(*h), GFP_KERNEL); + if (!h) + return -1; + + h->busy_initializing = 1; + INIT_HLIST_HEAD(&h->cmpQ); + INIT_HLIST_HEAD(&h->reqQ); + mutex_init(&h->busy_shutting_down); + init_completion(&h->scan_wait); + if (hpsa_pci_init(h, pdev) != 0) + goto clean1; + + sprintf(h->devname, "hpsa%d", number_of_controllers); + h->ctlr = number_of_controllers; + number_of_controllers++; + h->pdev = pdev; + + /* configure PCI DMA stuff */ + if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) + dac = 1; + else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) + dac = 0; + else { + dev_err(&pdev->dev, "no suitable DMA available\n"); + goto clean1; + } + + /* make sure the board interrupts are off */ + h->access.set_intr_mask(h, HPSA_INTR_OFF); + if (request_irq(h->intr[SIMPLE_MODE_INT], do_hpsa_intr, + IRQF_DISABLED | IRQF_SHARED, h->devname, h)) { + dev_err(&pdev->dev, "unable to get irq %d for %s\n", + h->intr[SIMPLE_MODE_INT], h->devname); + goto clean2; + } + + dev_info(&pdev->dev, "%s: <0x%x> at PCI %s IRQ %d%s using DAC\n", + h->devname, pdev->device, pci_name(pdev), + h->intr[SIMPLE_MODE_INT], dac ? "" : " not"); + + h->cmd_pool_bits = + kmalloc(((h->nr_cmds + BITS_PER_LONG - + 1) / BITS_PER_LONG) * sizeof(unsigned long), GFP_KERNEL); + h->cmd_pool = pci_alloc_consistent(h->pdev, + h->nr_cmds * sizeof(*h->cmd_pool), + &(h->cmd_pool_dhandle)); + h->errinfo_pool = pci_alloc_consistent(h->pdev, + h->nr_cmds * sizeof(*h->errinfo_pool), + &(h->errinfo_pool_dhandle)); + if ((h->cmd_pool_bits == NULL) + || (h->cmd_pool == NULL) + || (h->errinfo_pool == NULL)) { + dev_err(&pdev->dev, "out of memory"); + goto clean4; + } + spin_lock_init(&h->lock); + + pci_set_drvdata(pdev, h); + memset(h->cmd_pool_bits, 0, + ((h->nr_cmds + BITS_PER_LONG - + 1) / BITS_PER_LONG) * sizeof(unsigned long)); + + hpsa_scsi_setup(h); + + /* Turn the interrupts on so we can service requests */ + h->access.set_intr_mask(h, HPSA_INTR_ON); + + hpsa_register_scsi(h); /* hook ourselves into SCSI subsystem */ + h->busy_initializing = 0; + return 1; + +clean4: + kfree(h->cmd_pool_bits); + if (h->cmd_pool) + pci_free_consistent(h->pdev, + h->nr_cmds * sizeof(struct CommandList), + h->cmd_pool, h->cmd_pool_dhandle); + if (h->errinfo_pool) + pci_free_consistent(h->pdev, + h->nr_cmds * sizeof(struct ErrorInfo), + h->errinfo_pool, + h->errinfo_pool_dhandle); + free_irq(h->intr[SIMPLE_MODE_INT], h); +clean2: +clean1: + h->busy_initializing = 0; + kfree(h); + return -1; +} + +static void hpsa_flush_cache(struct ctlr_info *h) +{ + char *flush_buf; + struct CommandList *c; + + flush_buf = kzalloc(4, GFP_KERNEL); + if (!flush_buf) + return; + + c = cmd_special_alloc(h); + if (!c) { + dev_warn(&h->pdev->dev, "cmd_special_alloc returned NULL!\n"); + goto out_of_memory; + } + fill_cmd(c, HPSA_CACHE_FLUSH, h, flush_buf, 4, 0, + RAID_CTLR_LUNID, TYPE_CMD); + hpsa_scsi_do_simple_cmd_with_retry(h, c, PCI_DMA_TODEVICE); + if (c->err_info->CommandStatus != 0) + dev_warn(&h->pdev->dev, + "error flushing cache on controller\n"); + cmd_special_free(h, c); +out_of_memory: + kfree(flush_buf); +} + +static void hpsa_shutdown(struct pci_dev *pdev) +{ + struct ctlr_info *h; + + h = pci_get_drvdata(pdev); + /* Turn board interrupts off and send the flush cache command + * sendcmd will turn off interrupt, and send the flush... + * To write all data in the battery backed cache to disks + */ + hpsa_flush_cache(h); + h->access.set_intr_mask(h, HPSA_INTR_OFF); + free_irq(h->intr[2], h); +#ifdef CONFIG_PCI_MSI + if (h->msix_vector) + pci_disable_msix(h->pdev); + else if (h->msi_vector) + pci_disable_msi(h->pdev); +#endif /* CONFIG_PCI_MSI */ +} + +static void __devexit hpsa_remove_one(struct pci_dev *pdev) +{ + struct ctlr_info *h; + + if (pci_get_drvdata(pdev) == NULL) { + dev_err(&pdev->dev, "unable to remove device \n"); + return; + } + h = pci_get_drvdata(pdev); + mutex_lock(&h->busy_shutting_down); + remove_from_scan_list(h); + hpsa_unregister_scsi(h); /* unhook from SCSI subsystem */ + hpsa_shutdown(pdev); + iounmap(h->vaddr); + pci_free_consistent(h->pdev, + h->nr_cmds * sizeof(struct CommandList), + h->cmd_pool, h->cmd_pool_dhandle); + pci_free_consistent(h->pdev, + h->nr_cmds * sizeof(struct ErrorInfo), + h->errinfo_pool, h->errinfo_pool_dhandle); + kfree(h->cmd_pool_bits); + /* + * Deliberately omit pci_disable_device(): it does something nasty to + * Smart Array controllers that pci_enable_device does not undo + */ + pci_release_regions(pdev); + pci_set_drvdata(pdev, NULL); + mutex_unlock(&h->busy_shutting_down); + kfree(h); +} + +static int hpsa_suspend(__attribute__((unused)) struct pci_dev *pdev, + __attribute__((unused)) pm_message_t state) +{ + return -ENOSYS; +} + +static int hpsa_resume(__attribute__((unused)) struct pci_dev *pdev) +{ + return -ENOSYS; +} + +static struct pci_driver hpsa_pci_driver = { + .name = "hpsa", + .probe = hpsa_init_one, + .remove = __devexit_p(hpsa_remove_one), + .id_table = hpsa_pci_device_id, /* id_table */ + .shutdown = hpsa_shutdown, + .suspend = hpsa_suspend, + .resume = hpsa_resume, +}; + +/* + * This is it. Register the PCI driver information for the cards we control + * the OS will call our registered routines when it finds one of our cards. + */ +static int __init hpsa_init(void) +{ + int err; + /* Start the scan thread */ + hpsa_scan_thread = kthread_run(hpsa_scan_func, NULL, "hpsa_scan"); + if (IS_ERR(hpsa_scan_thread)) { + err = PTR_ERR(hpsa_scan_thread); + return -ENODEV; + } + err = pci_register_driver(&hpsa_pci_driver); + if (err) + kthread_stop(hpsa_scan_thread); + return err; +} + +static void __exit hpsa_cleanup(void) +{ + pci_unregister_driver(&hpsa_pci_driver); + kthread_stop(hpsa_scan_thread); +} + +module_init(hpsa_init); +module_exit(hpsa_cleanup); diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h new file mode 100644 index 0000000..6bd1949 --- /dev/null +++ b/drivers/scsi/hpsa.h @@ -0,0 +1,273 @@ +/* + * Disk Array driver for HP Smart Array SAS controllers + * Copyright 2000, 2009 Hewlett-Packard Development Company, L.P. + * + * 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, GOOD TITLE or + * NON INFRINGEMENT. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Questions/Comments/Bugfixes to iss_storagedev@hp.com + * + */ +#ifndef HPSA_H +#define HPSA_H + +#include + +#define IO_OK 0 +#define IO_ERROR 1 + +struct ctlr_info; + +struct access_method { + void (*submit_command)(struct ctlr_info *h, + struct CommandList *c); + void (*set_intr_mask)(struct ctlr_info *h, unsigned long val); + unsigned long (*fifo_full)(struct ctlr_info *h); + unsigned long (*intr_pending)(struct ctlr_info *h); + unsigned long (*command_completed)(struct ctlr_info *h); +}; + +struct hpsa_scsi_dev_t { + int devtype; + int bus, target, lun; /* as presented to the OS */ + unsigned char scsi3addr[8]; /* as presented to the HW */ +#define RAID_CTLR_LUNID "\0\0\0\0\0\0\0\0" + unsigned char device_id[16]; /* from inquiry pg. 0x83 */ + unsigned char vendor[8]; /* bytes 8-15 of inquiry data */ + unsigned char model[16]; /* bytes 16-31 of inquiry data */ + unsigned char revision[4]; /* bytes 32-35 of inquiry data */ + unsigned char raid_level; /* from inquiry page 0xC1 */ +}; + +struct ctlr_info { + int ctlr; + char devname[8]; + char *product_name; + char firm_ver[4]; /* Firmware version */ + struct pci_dev *pdev; + __u32 board_id; + void __iomem *vaddr; + unsigned long paddr; + int nr_cmds; /* Number of commands allowed on this controller */ + struct CfgTable __iomem *cfgtable; + int interrupts_enabled; + int major; + int max_commands; + int commands_outstanding; + int max_outstanding; /* Debug */ + int usage_count; /* number of opens all all minor devices */ +# define DOORBELL_INT 0 +# define PERF_MODE_INT 1 +# define SIMPLE_MODE_INT 2 +# define MEMQ_MODE_INT 3 + unsigned int intr[4]; + unsigned int msix_vector; + unsigned int msi_vector; + struct access_method access; + + /* queue and queue Info */ + struct hlist_head reqQ; + struct hlist_head cmpQ; + unsigned int Qdepth; + unsigned int maxQsinceinit; + unsigned int maxSG; + spinlock_t lock; + + /* pointers to command and error info pool */ + struct CommandList *cmd_pool; + dma_addr_t cmd_pool_dhandle; + struct ErrorInfo *errinfo_pool; + dma_addr_t errinfo_pool_dhandle; + unsigned long *cmd_pool_bits; + int nr_allocs; + int nr_frees; + int busy_initializing; + int busy_scanning; + struct mutex busy_shutting_down; + struct list_head scan_list; + struct completion scan_wait; + + struct Scsi_Host *scsi_host; + spinlock_t devlock; /* to protect hba[ctlr]->dev[]; */ + int ndevices; /* number of used elements in .dev[] array. */ +#define HPSA_MAX_SCSI_DEVS_PER_HBA 256 + struct hpsa_scsi_dev_t *dev[HPSA_MAX_SCSI_DEVS_PER_HBA]; +}; +#define HPSA_ABORT_MSG 0 +#define HPSA_DEVICE_RESET_MSG 1 +#define HPSA_BUS_RESET_MSG 2 +#define HPSA_HOST_RESET_MSG 3 +#define HPSA_MSG_SEND_RETRY_LIMIT 10 +#define HPSA_MSG_SEND_RETRY_INTERVAL_MSECS 1000 + +/* Maximum time in seconds driver will wait for command completions + * when polling before giving up. + */ +#define HPSA_MAX_POLL_TIME_SECS (20) + +/* During SCSI error recovery, HPSA_TUR_RETRY_LIMIT defines + * how many times to retry TEST UNIT READY on a device + * while waiting for it to become ready before giving up. + * HPSA_MAX_WAIT_INTERVAL_SECS is the max wait interval + * between sending TURs while waiting for a device + * to become ready. + */ +#define HPSA_TUR_RETRY_LIMIT (20) +#define HPSA_MAX_WAIT_INTERVAL_SECS (30) + +/* HPSA_BOARD_READY_WAIT_SECS is how long to wait for a board + * to become ready, in seconds, before giving up on it. + * HPSA_BOARD_READY_POLL_INTERVAL_MSECS * is how long to wait + * between polling the board to see if it is ready, in + * milliseconds. HPSA_BOARD_READY_POLL_INTERVAL and + * HPSA_BOARD_READY_ITERATIONS are derived from those. + */ +#define HPSA_BOARD_READY_WAIT_SECS (120) +#define HPSA_BOARD_READY_POLL_INTERVAL_MSECS (100) +#define HPSA_BOARD_READY_POLL_INTERVAL \ + ((HPSA_BOARD_READY_POLL_INTERVAL_MSECS * HZ) / 1000) +#define HPSA_BOARD_READY_ITERATIONS \ + ((HPSA_BOARD_READY_WAIT_SECS * 1000) / \ + HPSA_BOARD_READY_POLL_INTERVAL_MSECS) +#define HPSA_POST_RESET_PAUSE_MSECS (3000) +#define HPSA_POST_RESET_NOOP_RETRIES (12) + +/* Defining the diffent access_menthods */ +/* + * Memory mapped FIFO interface (SMART 53xx cards) + */ +#define SA5_DOORBELL 0x20 +#define SA5_REQUEST_PORT_OFFSET 0x40 +#define SA5_REPLY_INTR_MASK_OFFSET 0x34 +#define SA5_REPLY_PORT_OFFSET 0x44 +#define SA5_INTR_STATUS 0x30 +#define SA5_SCRATCHPAD_OFFSET 0xB0 + +#define SA5_CTCFG_OFFSET 0xB4 +#define SA5_CTMEM_OFFSET 0xB8 + +#define SA5_INTR_OFF 0x08 +#define SA5B_INTR_OFF 0x04 +#define SA5_INTR_PENDING 0x08 +#define SA5B_INTR_PENDING 0x04 +#define FIFO_EMPTY 0xffffffff +#define HPSA_FIRMWARE_READY 0xffff0000 /* value in scratchpad register */ + +#define HPSA_ERROR_BIT 0x02 +#define HPSA_TAG_CONTAINS_INDEX(tag) ((tag) & 0x04) +#define HPSA_TAG_TO_INDEX(tag) ((tag) >> 3) +#define HPSA_TAG_DISCARD_ERROR_BITS(tag) ((tag) & ~3) + +#define HPSA_INTR_ON 1 +#define HPSA_INTR_OFF 0 +/* + Send the command to the hardware +*/ +static void SA5_submit_command(struct ctlr_info *h, + struct CommandList *c) +{ +#ifdef HPSA_DEBUG + printk(KERN_WARNING "hpsa: Sending %x - down to controller\n", + c->busaddr); +#endif /* HPSA_DEBUG */ + writel(c->busaddr, h->vaddr + SA5_REQUEST_PORT_OFFSET); + h->commands_outstanding++; + if (h->commands_outstanding > h->max_outstanding) + h->max_outstanding = h->commands_outstanding; +} + +/* + * This card is the opposite of the other cards. + * 0 turns interrupts on... + * 0x08 turns them off... + */ +static void SA5_intr_mask(struct ctlr_info *h, unsigned long val) +{ + if (val) { /* Turn interrupts on */ + h->interrupts_enabled = 1; + writel(0, h->vaddr + SA5_REPLY_INTR_MASK_OFFSET); + } else { /* Turn them off */ + h->interrupts_enabled = 0; + writel(SA5_INTR_OFF, + h->vaddr + SA5_REPLY_INTR_MASK_OFFSET); + } +} +/* + * Returns true if fifo is full. + * + */ +static unsigned long SA5_fifo_full(struct ctlr_info *h) +{ + if (h->commands_outstanding >= h->max_commands) + return 1; + else + return 0; + +} +/* + * returns value read from hardware. + * returns FIFO_EMPTY if there is nothing to read + */ +static unsigned long SA5_completed(struct ctlr_info *h) +{ + unsigned long register_value + = readl(h->vaddr + SA5_REPLY_PORT_OFFSET); + + if (register_value != FIFO_EMPTY) + h->commands_outstanding--; + +#ifdef HPSA_DEBUG + if (register_value != FIFO_EMPTY) + printk(KERN_INFO "hpsa: Read %lx back from board\n", + register_value); + else + printk(KERN_INFO "hpsa: FIFO Empty read\n"); +#endif + + return register_value; +} +/* + * Returns true if an interrupt is pending.. + */ +static unsigned long SA5_intr_pending(struct ctlr_info *h) +{ + unsigned long register_value = + readl(h->vaddr + SA5_INTR_STATUS); +#ifdef HPSA_DEBUG + printk(KERN_INFO "hpsa: intr_pending %lx\n", register_value); +#endif /* HPSA_DEBUG */ + if (register_value & SA5_INTR_PENDING) + return 1; + return 0 ; +} + + +static struct access_method SA5_access = { + SA5_submit_command, + SA5_intr_mask, + SA5_fifo_full, + SA5_intr_pending, + SA5_completed, +}; + +struct board_type { + __u32 board_id; + char *product_name; + struct access_method *access; +}; + + +/* end of old hpsa_scsi.h file */ + +#endif /* HPSA_H */ + diff --git a/drivers/scsi/hpsa_cmd.h b/drivers/scsi/hpsa_cmd.h new file mode 100644 index 0000000..12d7138 --- /dev/null +++ b/drivers/scsi/hpsa_cmd.h @@ -0,0 +1,326 @@ +/* + * Disk Array driver for HP Smart Array SAS controllers + * Copyright 2000, 2009 Hewlett-Packard Development Company, L.P. + * + * 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, GOOD TITLE or + * NON INFRINGEMENT. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Questions/Comments/Bugfixes to iss_storagedev@hp.com + * + */ +#ifndef HPSA_CMD_H +#define HPSA_CMD_H + +/* general boundary defintions */ +#define SENSEINFOBYTES 32 /* may vary between hbas */ +#define MAXSGENTRIES 31 +#define MAXREPLYQS 256 + +/* Command Status value */ +#define CMD_SUCCESS 0x0000 +#define CMD_TARGET_STATUS 0x0001 +#define CMD_DATA_UNDERRUN 0x0002 +#define CMD_DATA_OVERRUN 0x0003 +#define CMD_INVALID 0x0004 +#define CMD_PROTOCOL_ERR 0x0005 +#define CMD_HARDWARE_ERR 0x0006 +#define CMD_CONNECTION_LOST 0x0007 +#define CMD_ABORTED 0x0008 +#define CMD_ABORT_FAILED 0x0009 +#define CMD_UNSOLICITED_ABORT 0x000A +#define CMD_TIMEOUT 0x000B +#define CMD_UNABORTABLE 0x000C + +/* Unit Attentions ASC's as defined for the MSA2012sa */ +#define POWER_OR_RESET 0x29 +#define STATE_CHANGED 0x2a +#define UNIT_ATTENTION_CLEARED 0x2f +#define LUN_FAILED 0x3e +#define REPORT_LUNS_CHANGED 0x3f + +/* Unit Attentions ASCQ's as defined for the MSA2012sa */ + + /* These ASCQ's defined for ASC = POWER_OR_RESET */ +#define POWER_ON_RESET 0x00 +#define POWER_ON_REBOOT 0x01 +#define SCSI_BUS_RESET 0x02 +#define MSA_TARGET_RESET 0x03 +#define CONTROLLER_FAILOVER 0x04 +#define TRANSCEIVER_SE 0x05 +#define TRANSCEIVER_LVD 0x06 + + /* These ASCQ's defined for ASC = STATE_CHANGED */ +#define RESERVATION_PREEMPTED 0x03 +#define ASYM_ACCESS_CHANGED 0x06 +#define LUN_CAPACITY_CHANGED 0x09 + +/* transfer direction */ +#define XFER_NONE 0x00 +#define XFER_WRITE 0x01 +#define XFER_READ 0x02 +#define XFER_RSVD 0x03 + +/* task attribute */ +#define ATTR_UNTAGGED 0x00 +#define ATTR_SIMPLE 0x04 +#define ATTR_HEADOFQUEUE 0x05 +#define ATTR_ORDERED 0x06 +#define ATTR_ACA 0x07 + +/* cdb type */ +#define TYPE_CMD 0x00 +#define TYPE_MSG 0x01 + +/* config space register offsets */ +#define CFG_VENDORID 0x00 +#define CFG_DEVICEID 0x02 +#define CFG_I2OBAR 0x10 +#define CFG_MEM1BAR 0x14 + +/* i2o space register offsets */ +#define I2O_IBDB_SET 0x20 +#define I2O_IBDB_CLEAR 0x70 +#define I2O_INT_STATUS 0x30 +#define I2O_INT_MASK 0x34 +#define I2O_IBPOST_Q 0x40 +#define I2O_OBPOST_Q 0x44 +#define I2O_DMA1_CFG 0x214 + +/* Configuration Table */ +#define CFGTBL_ChangeReq 0x00000001l +#define CFGTBL_AccCmds 0x00000001l + +#define CFGTBL_Trans_Simple 0x00000002l + +#define CFGTBL_BusType_Ultra2 0x00000001l +#define CFGTBL_BusType_Ultra3 0x00000002l +#define CFGTBL_BusType_Fibre1G 0x00000100l +#define CFGTBL_BusType_Fibre2G 0x00000200l +struct vals32 { + __u32 lower; + __u32 upper; +}; + +union u64bit { + struct vals32 val32; + __u64 val; +}; + +/* FIXME this is a per controller value (barf!) */ +#define HPSA_MAX_TARGETS_PER_CTLR 16 +#define HPSA_MAX_LUN 256 +#define HPSA_MAX_PHYS_LUN 1024 + +/* SCSI-3 Commands */ +#pragma pack(1) + +#define HPSA_INQUIRY 0x12 +struct InquiryData { + __u8 data_byte[36]; +}; + +#define HPSA_REPORT_LOG 0xc2 /* Report Logical LUNs */ +#define HPSA_REPORT_PHYS 0xc3 /* Report Physical LUNs */ +struct ReportLUNdata { + __u8 LUNListLength[4]; + __u32 reserved; + __u8 LUN[HPSA_MAX_LUN][8]; +}; + +struct ReportExtendedLUNdata { + __u8 LUNListLength[4]; + __u8 extended_response_flag; + __u8 reserved[3]; + __u8 LUN[HPSA_MAX_LUN][24]; +}; + +struct SenseSubsystem_info { + __u8 reserved[36]; + __u8 portname[8]; + __u8 reserved1[1108]; +}; + +#define HPSA_READ_CAPACITY 0x25 /* Read Capacity */ +struct ReadCapdata { + __u8 total_size[4]; /* Total size in blocks */ + __u8 block_size[4]; /* Size of blocks in bytes */ +}; + +#if 0 +/* 12 byte commands not implemented in firmware yet. */ +#define HPSA_READ 0xa8 +#define HPSA_WRITE 0xaa +#endif + +#define HPSA_READ 0x28 /* Read(10) */ +#define HPSA_WRITE 0x2a /* Write(10) */ + +/* BMIC commands */ +#define BMIC_READ 0x26 +#define BMIC_WRITE 0x27 +#define BMIC_CACHE_FLUSH 0xc2 +#define HPSA_CACHE_FLUSH 0x01 /* C2 was already being used by HPSA */ + +/* Command List Structure */ +union SCSI3Addr { + struct { + __u8 Dev; + __u8 Bus:6; + __u8 Mode:2; /* b00 */ + } PeripDev; + struct { + __u8 DevLSB; + __u8 DevMSB:6; + __u8 Mode:2; /* b01 */ + } LogDev; + struct { + __u8 Dev:5; + __u8 Bus:3; + __u8 Targ:6; + __u8 Mode:2; /* b10 */ + } LogUnit; +}; + +struct PhysDevAddr { + __u32 TargetId:24; + __u32 Bus:6; + __u32 Mode:2; + /* 2 level target device addr */ + union SCSI3Addr Target[2]; +}; + +struct LogDevAddr { + __u32 VolId:30; + __u32 Mode:2; + __u8 reserved[4]; +}; + +union LUNAddr { + __u8 LunAddrBytes[8]; + union SCSI3Addr SCSI3Lun[4]; + struct PhysDevAddr PhysDev; + struct LogDevAddr LogDev; +}; + +struct CommandListHeader { + __u8 ReplyQueue; + __u8 SGList; + __u16 SGTotal; + struct vals32 Tag; + union LUNAddr LUN; +}; + +struct RequestBlock { + __u8 CDBLen; + struct { + __u8 Type:3; + __u8 Attribute:3; + __u8 Direction:2; + } Type; + __u16 Timeout; + __u8 CDB[16]; +}; + +struct ErrDescriptor { + struct vals32 Addr; + __u32 Len; +}; + +struct SGDescriptor { + struct vals32 Addr; + __u32 Len; + __u32 Ext; +}; + +union MoreErrInfo { + struct { + __u8 Reserved[3]; + __u8 Type; + __u32 ErrorInfo; + } Common_Info; + struct { + __u8 Reserved[2]; + __u8 offense_size; /* size of offending entry */ + __u8 offense_num; /* byte # of offense 0-base */ + __u32 offense_value; + } Invalid_Cmd; +}; +struct ErrorInfo { + __u8 ScsiStatus; + __u8 SenseLen; + __u16 CommandStatus; + __u32 ResidualCnt; + union MoreErrInfo MoreErrInfo; + __u8 SenseInfo[SENSEINFOBYTES]; +}; +/* Command types */ +#define CMD_IOCTL_PEND 0x01 +#define CMD_SCSI 0x03 + +struct ctlr_info; /* defined in hpsa.h */ +/* The size of this structure needs to be divisible by 8 + * od on all architectures, because the controller uses 2 + * lower bits of the address, and the driver uses 1 lower + * bit (3 bits total.) + */ +struct CommandList { + struct CommandListHeader Header; + struct RequestBlock Request; + struct ErrDescriptor ErrDesc; + struct SGDescriptor SG[MAXSGENTRIES]; + /* information associated with the command */ + __u32 busaddr; /* physical addr of this record */ + struct ErrorInfo *err_info; /* pointer to the allocated mem */ + struct ctlr_info *h; + int cmd_type; + long cmdindex; + struct hlist_node list; + struct CommandList *prev; + struct CommandList *next; + struct request *rq; + struct completion *waiting; + int retry_count; + void *scsi_cmd; +}; + +/* Configuration Table Structure */ +struct HostWrite { + __u32 TransportRequest; + __u32 Reserved; + __u32 CoalIntDelay; + __u32 CoalIntCount; +}; + +struct CfgTable { + __u8 Signature[4]; + __u32 SpecValence; + __u32 TransportSupport; + __u32 TransportActive; + struct HostWrite HostWrite; + __u32 CmdsOutMax; + __u32 BusTypes; + __u32 Reserved; + __u8 ServerName[16]; + __u32 HeartBeat; + __u32 SCSI_Prefetch; +}; + +struct hpsa_pci_info { + unsigned char bus; + unsigned char dev_fn; + unsigned short domain; + __u32 board_id; +}; + +#pragma pack() +#endif /* HPSA_CMD_H */ -- cgit v0.10.2 From 9e79e12554d651f586ff2364e69a8e9cd5e9dbcb Mon Sep 17 00:00:00 2001 From: jack wang Date: Mon, 7 Dec 2009 17:22:36 +0800 Subject: [SCSI] pm8001: Fix for sata io circular lock dependency. This patch fix for sata IO circular lock dependency. When we call task_done for SATA IO, we have got pm8001_ha->lock ,and in sas_ata_task_done, it will get (dev->sata_dev.ap->lock. then cause circular lock dependency .So we should drop pm8001_ha->lock when we call task_done for SATA task. Signed-off-by: Jack Wang Signed-off-by: Lindar Liu Signed-off-by: James Bottomley diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c index a3de306..68695b7 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.c +++ b/drivers/scsi/pm8001/pm8001_hwi.c @@ -1901,7 +1901,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) { struct sas_task *t; struct pm8001_ccb_info *ccb; - unsigned long flags; + unsigned long flags = 0; u32 param; u32 status; u32 tag; @@ -2040,7 +2040,9 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) ts->stat = SAS_QUEUE_FULL; pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); mb();/*in order to force CPU ordering*/ + spin_unlock_irqrestore(&pm8001_ha->lock, flags); t->task_done(t); + spin_lock_irqsave(&pm8001_ha->lock, flags); return; } break; @@ -2058,7 +2060,9 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) ts->stat = SAS_QUEUE_FULL; pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); mb();/*ditto*/ + spin_unlock_irqrestore(&pm8001_ha->lock, flags); t->task_done(t); + spin_lock_irqsave(&pm8001_ha->lock, flags); return; } break; @@ -2084,7 +2088,9 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) ts->stat = SAS_QUEUE_FULL; pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); mb();/* ditto*/ + spin_unlock_irqrestore(&pm8001_ha->lock, flags); t->task_done(t); + spin_lock_irqsave(&pm8001_ha->lock, flags); return; } break; @@ -2149,7 +2155,9 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) ts->stat = SAS_QUEUE_FULL; pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); mb();/*ditto*/ + spin_unlock_irqrestore(&pm8001_ha->lock, flags); t->task_done(t); + spin_lock_irqsave(&pm8001_ha->lock, flags); return; } break; @@ -2171,7 +2179,9 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) ts->stat = SAS_QUEUE_FULL; pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); mb();/*ditto*/ + spin_unlock_irqrestore(&pm8001_ha->lock, flags); t->task_done(t); + spin_lock_irqsave(&pm8001_ha->lock, flags); return; } break; @@ -2200,11 +2210,20 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) " resp 0x%x stat 0x%x but aborted by upper layer!\n", t, status, ts->resp, ts->stat)); pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); - } else { + } else if (t->uldd_task) { spin_unlock_irqrestore(&t->task_state_lock, flags); pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); mb();/* ditto */ + spin_unlock_irqrestore(&pm8001_ha->lock, flags); + t->task_done(t); + spin_lock_irqsave(&pm8001_ha->lock, flags); + } else if (!t->uldd_task) { + spin_unlock_irqrestore(&t->task_state_lock, flags); + pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); + mb();/*ditto*/ + spin_unlock_irqrestore(&pm8001_ha->lock, flags); t->task_done(t); + spin_lock_irqsave(&pm8001_ha->lock, flags); } } @@ -2212,7 +2231,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb) { struct sas_task *t; - unsigned long flags; + unsigned long flags = 0; struct task_status_struct *ts; struct pm8001_ccb_info *ccb; struct pm8001_device *pm8001_dev; @@ -2292,7 +2311,9 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb) ts->stat = SAS_QUEUE_FULL; pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); mb();/*ditto*/ + spin_unlock_irqrestore(&pm8001_ha->lock, flags); t->task_done(t); + spin_lock_irqsave(&pm8001_ha->lock, flags); return; } break; @@ -2401,11 +2422,20 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb) " resp 0x%x stat 0x%x but aborted by upper layer!\n", t, event, ts->resp, ts->stat)); pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); - } else { + } else if (t->uldd_task) { spin_unlock_irqrestore(&t->task_state_lock, flags); pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); - mb();/* in order to force CPU ordering */ + mb();/* ditto */ + spin_unlock_irqrestore(&pm8001_ha->lock, flags); + t->task_done(t); + spin_lock_irqsave(&pm8001_ha->lock, flags); + } else if (!t->uldd_task) { + spin_unlock_irqrestore(&t->task_state_lock, flags); + pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); + mb();/*ditto*/ + spin_unlock_irqrestore(&pm8001_ha->lock, flags); t->task_done(t); + spin_lock_irqsave(&pm8001_ha->lock, flags); } } -- cgit v0.10.2 From 1cc943ae5003e4612a73119cb6fb637a45c2714d Mon Sep 17 00:00:00 2001 From: jack wang Date: Mon, 7 Dec 2009 17:22:42 +0800 Subject: [SCSI] pm8001: enhance error handle for IO patch Enhance error handle for IO patch, when the port is down, fast return phy down for task. Signed-off-by: Jack Wang Signed-off-by: James Bottomley diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c index 68695b7..3a121fb 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.c +++ b/drivers/scsi/pm8001/pm8001_hwi.c @@ -2906,13 +2906,17 @@ hw_event_sas_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) le32_to_cpu(pPayload->lr_evt_status_phyid_portid); u8 link_rate = (u8)((lr_evt_status_phyid_portid & 0xF0000000) >> 28); + u8 port_id = (u8)(lr_evt_status_phyid_portid & 0x0000000F); u8 phy_id = (u8)((lr_evt_status_phyid_portid & 0x000000F0) >> 4); + u32 npip_portstate = le32_to_cpu(pPayload->npip_portstate); + u8 portstate = (u8)(npip_portstate & 0x0000000F); + struct pm8001_port *port = &pm8001_ha->port[port_id]; struct sas_ha_struct *sas_ha = pm8001_ha->sas; struct pm8001_phy *phy = &pm8001_ha->phy[phy_id]; unsigned long flags; u8 deviceType = pPayload->sas_identify.dev_type; - + port->port_state = portstate; PM8001_MSG_DBG(pm8001_ha, pm8001_printk("HW_EVENT_SAS_PHY_UP \n")); @@ -2925,16 +2929,19 @@ hw_event_sas_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) PM8001_MSG_DBG(pm8001_ha, pm8001_printk("end device.\n")); pm8001_chip_phy_ctl_req(pm8001_ha, phy_id, PHY_NOTIFY_ENABLE_SPINUP); + port->port_attached = 1; get_lrate_mode(phy, link_rate); break; case SAS_EDGE_EXPANDER_DEVICE: PM8001_MSG_DBG(pm8001_ha, pm8001_printk("expander device.\n")); + port->port_attached = 1; get_lrate_mode(phy, link_rate); break; case SAS_FANOUT_EXPANDER_DEVICE: PM8001_MSG_DBG(pm8001_ha, pm8001_printk("fanout expander device.\n")); + port->port_attached = 1; get_lrate_mode(phy, link_rate); break; default: @@ -2976,11 +2983,17 @@ hw_event_sata_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) le32_to_cpu(pPayload->lr_evt_status_phyid_portid); u8 link_rate = (u8)((lr_evt_status_phyid_portid & 0xF0000000) >> 28); + u8 port_id = (u8)(lr_evt_status_phyid_portid & 0x0000000F); u8 phy_id = (u8)((lr_evt_status_phyid_portid & 0x000000F0) >> 4); + u32 npip_portstate = le32_to_cpu(pPayload->npip_portstate); + u8 portstate = (u8)(npip_portstate & 0x0000000F); + struct pm8001_port *port = &pm8001_ha->port[port_id]; struct sas_ha_struct *sas_ha = pm8001_ha->sas; struct pm8001_phy *phy = &pm8001_ha->phy[phy_id]; unsigned long flags; + port->port_state = portstate; + port->port_attached = 1; get_lrate_mode(phy, link_rate); phy->phy_type |= PORT_TYPE_SATA; phy->phy_attached = 1; @@ -3014,7 +3027,13 @@ hw_event_phy_down(struct pm8001_hba_info *pm8001_ha, void *piomb) (u8)((lr_evt_status_phyid_portid & 0x000000F0) >> 4); u32 npip_portstate = le32_to_cpu(pPayload->npip_portstate); u8 portstate = (u8)(npip_portstate & 0x0000000F); - + struct pm8001_port *port = &pm8001_ha->port[port_id]; + struct pm8001_phy *phy = &pm8001_ha->phy[phy_id]; + port->port_state = portstate; + phy->phy_type = 0; + phy->identify.device_type = 0; + phy->phy_attached = 0; + memset(&phy->dev_sas_addr, 0, SAS_ADDR_SIZE); switch (portstate) { case PORT_VALID: break; @@ -3023,26 +3042,30 @@ hw_event_phy_down(struct pm8001_hba_info *pm8001_ha, void *piomb) pm8001_printk(" PortInvalid portID %d \n", port_id)); PM8001_MSG_DBG(pm8001_ha, pm8001_printk(" Last phy Down and port invalid\n")); + port->port_attached = 0; pm8001_hw_event_ack_req(pm8001_ha, 0, HW_EVENT_PHY_DOWN, port_id, phy_id, 0, 0); break; case PORT_IN_RESET: PM8001_MSG_DBG(pm8001_ha, - pm8001_printk(" PortInReset portID %d \n", port_id)); + pm8001_printk(" Port In Reset portID %d \n", port_id)); break; case PORT_NOT_ESTABLISHED: PM8001_MSG_DBG(pm8001_ha, pm8001_printk(" phy Down and PORT_NOT_ESTABLISHED\n")); + port->port_attached = 0; break; case PORT_LOSTCOMM: PM8001_MSG_DBG(pm8001_ha, pm8001_printk(" phy Down and PORT_LOSTCOMM\n")); PM8001_MSG_DBG(pm8001_ha, pm8001_printk(" Last phy Down and port invalid\n")); + port->port_attached = 0; pm8001_hw_event_ack_req(pm8001_ha, 0, HW_EVENT_PHY_DOWN, port_id, phy_id, 0, 0); break; default: + port->port_attached = 0; PM8001_MSG_DBG(pm8001_ha, pm8001_printk(" phy Down and(default) = %x\n", portstate)); diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c index 42ebe72..fb6379a 100644 --- a/drivers/scsi/pm8001/pm8001_init.c +++ b/drivers/scsi/pm8001/pm8001_init.c @@ -200,8 +200,13 @@ static int __devinit pm8001_alloc(struct pm8001_hba_info *pm8001_ha) { int i; spin_lock_init(&pm8001_ha->lock); - for (i = 0; i < pm8001_ha->chip->n_phy; i++) + for (i = 0; i < pm8001_ha->chip->n_phy; i++) { pm8001_phy_init(pm8001_ha, i); + pm8001_ha->port[i].wide_port_phymap = 0; + pm8001_ha->port[i].port_attached = 0; + pm8001_ha->port[i].port_state = 0; + INIT_LIST_HEAD(&pm8001_ha->port[i].list); + } pm8001_ha->tags = kzalloc(PM8001_MAX_CCB, GFP_KERNEL); if (!pm8001_ha->tags) diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c index 1f767a0..49721c8 100644 --- a/drivers/scsi/pm8001/pm8001_sas.c +++ b/drivers/scsi/pm8001/pm8001_sas.c @@ -329,6 +329,23 @@ int pm8001_slave_configure(struct scsi_device *sdev) } return 0; } + /* Find the local port id that's attached to this device */ +static int sas_find_local_port_id(struct domain_device *dev) +{ + struct domain_device *pdev = dev->parent; + + /* Directly attached device */ + if (!pdev) + return dev->port->id; + while (pdev) { + struct domain_device *pdev_p = pdev->parent; + if (!pdev_p) + return pdev->port->id; + pdev = pdev->parent; + } + return 0; +} + /** * pm8001_task_exec - queue the task(ssp, smp && ata) to the hardware. * @task: the task to be execute. @@ -346,11 +363,12 @@ static int pm8001_task_exec(struct sas_task *task, const int num, struct domain_device *dev = task->dev; struct pm8001_hba_info *pm8001_ha; struct pm8001_device *pm8001_dev; + struct pm8001_port *port = NULL; struct sas_task *t = task; struct pm8001_ccb_info *ccb; u32 tag = 0xdeadbeef, rc, n_elem = 0; u32 n = num; - unsigned long flags = 0; + unsigned long flags = 0, flags_libsas = 0; if (!dev->port) { struct task_status_struct *tsm = &t->task_status; @@ -379,6 +397,35 @@ static int pm8001_task_exec(struct sas_task *task, const int num, rc = SAS_PHY_DOWN; goto out_done; } + port = &pm8001_ha->port[sas_find_local_port_id(dev)]; + if (!port->port_attached) { + if (sas_protocol_ata(t->task_proto)) { + struct task_status_struct *ts = &t->task_status; + ts->resp = SAS_TASK_UNDELIVERED; + ts->stat = SAS_PHY_DOWN; + + spin_unlock_irqrestore(&pm8001_ha->lock, flags); + spin_unlock_irqrestore(dev->sata_dev.ap->lock, + flags_libsas); + t->task_done(t); + spin_lock_irqsave(dev->sata_dev.ap->lock, + flags_libsas); + spin_lock_irqsave(&pm8001_ha->lock, flags); + if (n > 1) + t = list_entry(t->list.next, + struct sas_task, list); + continue; + } else { + struct task_status_struct *ts = &t->task_status; + ts->resp = SAS_TASK_UNDELIVERED; + ts->stat = SAS_PHY_DOWN; + t->task_done(t); + if (n > 1) + t = list_entry(t->list.next, + struct sas_task, list); + continue; + } + } rc = pm8001_tag_alloc(pm8001_ha, &tag); if (rc) goto err_out; diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h index 30f2ede..c44a115 100644 --- a/drivers/scsi/pm8001/pm8001_sas.h +++ b/drivers/scsi/pm8001/pm8001_sas.h @@ -164,6 +164,10 @@ struct pm8001_chip_info { struct pm8001_port { struct asd_sas_port sas_port; + u8 port_attached; + u8 wide_port_phymap; + u8 port_state; + struct list_head list; }; struct pm8001_phy { -- cgit v0.10.2 From afc5ca9ddc6c223dbea8a2f8816a88b21a0883b5 Mon Sep 17 00:00:00 2001 From: jack wang Date: Mon, 7 Dec 2009 17:22:47 +0800 Subject: [SCSI] pm8001: fix endian issues with SAS address Signed-off-by: Jack Wang Signed-off-by: James Bottomley diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c index 3a121fb..b4426b5 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.c +++ b/drivers/scsi/pm8001/pm8001_hwi.c @@ -3823,7 +3823,8 @@ static int pm8001_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha, u32 opc = OPC_INB_SSPINIIOSTART; memset(&ssp_cmd, 0, sizeof(ssp_cmd)); memcpy(ssp_cmd.ssp_iu.lun, task->ssp_task.LUN, 8); - ssp_cmd.dir_m_tlr = data_dir_flags[task->data_dir] << 8 | 0x0;/*0 for + ssp_cmd.dir_m_tlr = + cpu_to_le32(data_dir_flags[task->data_dir] << 8 | 0x0);/*0 for SAS 1.1 compatible TLR*/ ssp_cmd.data_len = cpu_to_le32(task->total_xfer_len); ssp_cmd.device_id = cpu_to_le32(pm8001_dev->device_id); @@ -3894,7 +3895,7 @@ static int pm8001_chip_sata_req(struct pm8001_hba_info *pm8001_ha, } } if (task->ata_task.use_ncq && pm8001_get_ncq_tag(task, &hdr_tag)) - ncg_tag = cpu_to_le32(hdr_tag); + ncg_tag = hdr_tag; dir = data_dir_flags[task->data_dir] << 8; sata_cmd.tag = cpu_to_le32(tag); sata_cmd.device_id = cpu_to_le32(pm8001_ha_dev->device_id); @@ -4039,7 +4040,7 @@ static int pm8001_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha, ((stp_sspsmp_sata & 0x03) * 0x10000000)); payload.firstburstsize_ITNexustimeout = cpu_to_le32(ITNT | (firstBurstSize * 0x10000)); - memcpy(&payload.sas_addr_hi, pm8001_dev->sas_device->sas_addr, + memcpy(payload.sas_addr, pm8001_dev->sas_device->sas_addr, SAS_ADDR_SIZE); rc = mpi_build_cmd(pm8001_ha, circularQ, opc, &payload); return rc; diff --git a/drivers/scsi/pm8001/pm8001_hwi.h b/drivers/scsi/pm8001/pm8001_hwi.h index 96e4daa..833a520 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.h +++ b/drivers/scsi/pm8001/pm8001_hwi.h @@ -242,8 +242,7 @@ struct reg_dev_req { __le32 phyid_portid; __le32 dtype_dlr_retry; __le32 firstburstsize_ITNexustimeout; - u32 sas_addr_hi; - u32 sas_addr_low; + u8 sas_addr[SAS_ADDR_SIZE]; __le32 upper_device_id; u32 reserved[8]; } __attribute__((packed, aligned(4))); -- cgit v0.10.2 From 0330dba36127768a2e2df2eabb902b5530102871 Mon Sep 17 00:00:00 2001 From: jack wang Date: Mon, 7 Dec 2009 17:46:22 +0800 Subject: [SCSI] pm8001: set SSC down-spreading only to get less errors on some 6G device. Signed-off-by: Jack Wang Signed-off-by: James Bottomley diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c index b4426b5..6e1bdd8 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.c +++ b/drivers/scsi/pm8001/pm8001_hwi.c @@ -373,10 +373,7 @@ static int bar4_shift(struct pm8001_hba_info *pm8001_ha, u32 shiftValue) static void __devinit mpi_set_phys_g3_with_ssc(struct pm8001_hba_info *pm8001_ha, u32 SSCbit) { - u32 offset; - u32 value; - u32 i, j; - u32 bit_cnt; + u32 value, offset, i; #define SAS2_SETTINGS_LOCAL_PHY_0_3_SHIFT_ADDR 0x00030000 #define SAS2_SETTINGS_LOCAL_PHY_4_7_SHIFT_ADDR 0x00040000 @@ -392,55 +389,35 @@ mpi_set_phys_g3_with_ssc(struct pm8001_hba_info *pm8001_ha, u32 SSCbit) */ if (-1 == bar4_shift(pm8001_ha, SAS2_SETTINGS_LOCAL_PHY_0_3_SHIFT_ADDR)) return; - /* set SSC bit of PHY 0 - 3 */ + for (i = 0; i < 4; i++) { offset = SAS2_SETTINGS_LOCAL_PHY_0_3_OFFSET + 0x4000 * i; - value = pm8001_cr32(pm8001_ha, 2, offset); - if (SSCbit) { - value |= 0x00000001 << PHY_G3_WITH_SSC_BIT_SHIFT; - value &= ~(0x00000001 << PHY_G3_WITHOUT_SSC_BIT_SHIFT); - } else { - value |= 0x00000001 << PHY_G3_WITHOUT_SSC_BIT_SHIFT; - value &= ~(0x00000001 << PHY_G3_WITH_SSC_BIT_SHIFT); - } - bit_cnt = 0; - for (j = 0; j < 31; j++) - if ((value >> j) & 0x00000001) - bit_cnt++; - if (bit_cnt % 2) - value &= ~(0x00000001 << SNW3_PHY_CAPABILITIES_PARITY); - else - value |= 0x00000001 << SNW3_PHY_CAPABILITIES_PARITY; - - pm8001_cw32(pm8001_ha, 2, offset, value); + pm8001_cw32(pm8001_ha, 2, offset, 0x80001501); } - /* shift membase 3 for SAS2_SETTINGS_LOCAL_PHY 4 - 7 */ if (-1 == bar4_shift(pm8001_ha, SAS2_SETTINGS_LOCAL_PHY_4_7_SHIFT_ADDR)) return; - - /* set SSC bit of PHY 4 - 7 */ for (i = 4; i < 8; i++) { offset = SAS2_SETTINGS_LOCAL_PHY_4_7_OFFSET + 0x4000 * (i-4); - value = pm8001_cr32(pm8001_ha, 2, offset); - if (SSCbit) { - value |= 0x00000001 << PHY_G3_WITH_SSC_BIT_SHIFT; - value &= ~(0x00000001 << PHY_G3_WITHOUT_SSC_BIT_SHIFT); - } else { - value |= 0x00000001 << PHY_G3_WITHOUT_SSC_BIT_SHIFT; - value &= ~(0x00000001 << PHY_G3_WITH_SSC_BIT_SHIFT); - } - bit_cnt = 0; - for (j = 0; j < 31; j++) - if ((value >> j) & 0x00000001) - bit_cnt++; - if (bit_cnt % 2) - value &= ~(0x00000001 << SNW3_PHY_CAPABILITIES_PARITY); - else - value |= 0x00000001 << SNW3_PHY_CAPABILITIES_PARITY; - - pm8001_cw32(pm8001_ha, 2, offset, value); + pm8001_cw32(pm8001_ha, 2, offset, 0x80001501); } + /************************************************************* + Change the SSC upspreading value to 0x0 so that upspreading is disabled. + Device MABC SMOD0 Controls + Address: (via MEMBASE-III): + Using shifted destination address 0x0_0000: with Offset 0xD8 + + 31:28 R/W Reserved Do not change + 27:24 R/W SAS_SMOD_SPRDUP 0000 + 23:20 R/W SAS_SMOD_SPRDDN 0000 + 19:0 R/W Reserved Do not change + Upon power-up this register will read as 0x8990c016, + and I would like you to change the SAS_SMOD_SPRDUP bits to 0b0000 + so that the written value will be 0x8090c016. + This will ensure only down-spreading SSC is enabled on the SPC. + *************************************************************/ + value = pm8001_cr32(pm8001_ha, 2, 0xd8); + pm8001_cw32(pm8001_ha, 2, 0xd8, 0x8000C016); /*set the shifted destination address to 0x0 to avoid error operation */ bar4_shift(pm8001_ha, 0x0); -- cgit v0.10.2 From f01f4e6a1cb343fc75dc580ec9203d9719f78f95 Mon Sep 17 00:00:00 2001 From: jack wang Date: Mon, 7 Dec 2009 17:22:55 +0800 Subject: [SCSI] pm8001:fix potential NULL pointer dereference Signed-off-by: Jack Wang Signed-off-by: James Bottomley diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c index 49721c8..487f78f 100644 --- a/drivers/scsi/pm8001/pm8001_sas.c +++ b/drivers/scsi/pm8001/pm8001_sas.c @@ -616,11 +616,11 @@ static int pm8001_dev_found_notify(struct domain_device *dev) spin_lock_irqsave(&pm8001_ha->lock, flags); pm8001_device = pm8001_alloc_dev(pm8001_ha); - pm8001_device->sas_device = dev; if (!pm8001_device) { res = -1; goto found_out; } + pm8001_device->sas_device = dev; dev->lldd_dev = pm8001_device; pm8001_device->dev_type = dev->dev_type; pm8001_device->dcompletion = &completion; -- cgit v0.10.2 From a61b8699c764cccf85ccbf489e1772b2950ba4c6 Mon Sep 17 00:00:00 2001 From: jack wang Date: Mon, 7 Dec 2009 17:22:59 +0800 Subject: [SCSI] pm8001: bit set pm8001_ha->flags Signed-off-by: Jack Wang Signed-off-by: James Bottomley diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c index 487f78f..c86f921 100644 --- a/drivers/scsi/pm8001/pm8001_sas.c +++ b/drivers/scsi/pm8001/pm8001_sas.c @@ -656,7 +656,7 @@ static int pm8001_dev_found_notify(struct domain_device *dev) wait_for_completion(&completion); if (dev->dev_type == SAS_END_DEV) msleep(50); - pm8001_ha->flags = PM8001F_RUN_TIME ; + pm8001_ha->flags |= PM8001F_RUN_TIME ; return 0; found_out: spin_unlock_irqrestore(&pm8001_ha->lock, flags); -- cgit v0.10.2 From 8257ec80ba5b333dedf3395acf90055075aeba94 Mon Sep 17 00:00:00 2001 From: jack wang Date: Mon, 7 Dec 2009 17:23:05 +0800 Subject: [SCSI] pm8001: do not reset local sata as it will not be found if reset Signed-off-by: Jack Wang Signed-off-by: James Bottomley diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c index c86f921..e3d4f38 100644 --- a/drivers/scsi/pm8001/pm8001_sas.c +++ b/drivers/scsi/pm8001/pm8001_sas.c @@ -944,6 +944,8 @@ int pm8001_I_T_nexus_reset(struct domain_device *dev) if (dev_is_sata(dev)) { DECLARE_COMPLETION_ONSTACK(completion_setstate); + if (scsi_is_sas_phy_local(phy)) + return 0; rc = sas_phy_reset(phy, 1); msleep(2000); rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev , -- cgit v0.10.2 From 7c8356d969e203a8f2f740a9a80d4944eb8cf1d1 Mon Sep 17 00:00:00 2001 From: jack wang Date: Mon, 7 Dec 2009 17:23:08 +0800 Subject: [SCSI] pm8001: enable read HBA SAS address from VPD Signed-off-by: Jack Wang Signed-off-by: James Bottomley diff --git a/drivers/scsi/pm8001/pm8001_ctl.h b/drivers/scsi/pm8001/pm8001_ctl.h index 22644de..63ad4aa 100644 --- a/drivers/scsi/pm8001/pm8001_ctl.h +++ b/drivers/scsi/pm8001/pm8001_ctl.h @@ -45,16 +45,6 @@ #define HEADER_LEN 28 #define SIZE_OFFSET 16 -struct pm8001_ioctl_payload { - u32 signature; - u16 major_function; - u16 minor_function; - u16 length; - u16 status; - u16 offset; - u16 id; - u8 func_specific[1]; -}; #define FLASH_OK 0x000000 #define FAIL_OPEN_BIOS_FILE 0x000100 diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c index fb6379a..c2f1032 100644 --- a/drivers/scsi/pm8001/pm8001_init.c +++ b/drivers/scsi/pm8001/pm8001_init.c @@ -516,19 +516,23 @@ static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha) u8 i; #ifdef PM8001_READ_VPD DECLARE_COMPLETION_ONSTACK(completion); + struct pm8001_ioctl_payload payload; pm8001_ha->nvmd_completion = &completion; - PM8001_CHIP_DISP->get_nvmd_req(pm8001_ha, 0, 0); + payload.minor_function = 0; + payload.length = 128; + payload.func_specific = kzalloc(128, GFP_KERNEL); + PM8001_CHIP_DISP->get_nvmd_req(pm8001_ha, &payload); wait_for_completion(&completion); for (i = 0; i < pm8001_ha->chip->n_phy; i++) { memcpy(&pm8001_ha->phy[i].dev_sas_addr, pm8001_ha->sas_addr, SAS_ADDR_SIZE); PM8001_INIT_DBG(pm8001_ha, - pm8001_printk("phy %d sas_addr = %x \n", i, - (u64)pm8001_ha->phy[i].dev_sas_addr)); + pm8001_printk("phy %d sas_addr = %016llx \n", i, + pm8001_ha->phy[i].dev_sas_addr)); } #else for (i = 0; i < pm8001_ha->chip->n_phy; i++) { - pm8001_ha->phy[i].dev_sas_addr = 0x500e004010000004ULL; + pm8001_ha->phy[i].dev_sas_addr = 0x50010c600047f9d0ULL; pm8001_ha->phy[i].dev_sas_addr = cpu_to_be64((u64) (*(u64 *)&pm8001_ha->phy[i].dev_sas_addr)); diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h index c44a115..599601e 100644 --- a/drivers/scsi/pm8001/pm8001_sas.h +++ b/drivers/scsi/pm8001/pm8001_sas.h @@ -100,6 +100,7 @@ do { \ #define PM8001_USE_TASKLET #define PM8001_USE_MSIX +#define PM8001_READ_VPD #define DEV_IS_EXPANDER(type) ((type == EDGE_DEV) || (type == FANOUT_DEV)) @@ -111,7 +112,22 @@ extern const struct pm8001_dispatch pm8001_8001_dispatch; struct pm8001_hba_info; struct pm8001_ccb_info; struct pm8001_device; -struct pm8001_tmf_task; +/* define task management IU */ +struct pm8001_tmf_task { + u8 tmf; + u32 tag_of_task_to_be_managed; +}; +struct pm8001_ioctl_payload { + u32 signature; + u16 major_function; + u16 minor_function; + u16 length; + u16 status; + u16 offset; + u16 id; + u8 *func_specific; +}; + struct pm8001_dispatch { char *name; int (*chip_init)(struct pm8001_hba_info *pm8001_ha); @@ -390,11 +406,7 @@ struct pm8001_fw_image_header { __be32 startup_entry; } __attribute__((packed, aligned(4))); -/* define task management IU */ -struct pm8001_tmf_task { - u8 tmf; - u32 tag_of_task_to_be_managed; -}; + /** * FW Flash Update status values */ -- cgit v0.10.2 From 83e7332941e3e2621502aadb0e5c8a3b11fd1197 Mon Sep 17 00:00:00 2001 From: jack wang Date: Mon, 7 Dec 2009 17:23:11 +0800 Subject: [SCSI] pm8001: misc code cleanup Add more data to printk's, add some spaces around arithmetic ops and improve comments. Signed-off-by: Jack Wang Signed-off-by: James Bottomley diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c index 6e1bdd8..9b44c6f 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.c +++ b/drivers/scsi/pm8001/pm8001_hwi.c @@ -2895,7 +2895,8 @@ hw_event_sas_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) u8 deviceType = pPayload->sas_identify.dev_type; port->port_state = portstate; PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("HW_EVENT_SAS_PHY_UP \n")); + pm8001_printk("HW_EVENT_SAS_PHY_UP port id = %d, phy id = %d\n", + port_id, phy_id)); switch (deviceType) { case SAS_PHY_UNUSED: @@ -2969,6 +2970,9 @@ hw_event_sata_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) struct sas_ha_struct *sas_ha = pm8001_ha->sas; struct pm8001_phy *phy = &pm8001_ha->phy[phy_id]; unsigned long flags; + PM8001_MSG_DBG(pm8001_ha, + pm8001_printk("HW_EVENT_SATA_PHY_UP port id = %d," + " phy id = %d\n", port_id, phy_id)); port->port_state = portstate; port->port_attached = 1; get_lrate_mode(phy, link_rate); @@ -4058,7 +4062,7 @@ static int pm8001_chip_phy_ctl_req(struct pm8001_hba_info *pm8001_ha, struct inbound_queue_table *circularQ; int ret; u32 opc = OPC_INB_LOCAL_PHY_CONTROL; - memset((u8 *)&payload, 0, sizeof(payload)); + memset(&payload, 0, sizeof(payload)); circularQ = &pm8001_ha->inbnd_q_tbl[0]; payload.tag = 1; payload.phyop_phyid = diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c index e3d4f38..7f9c83a 100644 --- a/drivers/scsi/pm8001/pm8001_sas.c +++ b/drivers/scsi/pm8001/pm8001_sas.c @@ -819,7 +819,7 @@ pm8001_exec_internal_task_abort(struct pm8001_hba_info *pm8001_ha, task->task_done = pm8001_task_done; task->timer.data = (unsigned long)task; task->timer.function = pm8001_tmf_timedout; - task->timer.expires = jiffies + PM8001_TASK_TIMEOUT*HZ; + task->timer.expires = jiffies + PM8001_TASK_TIMEOUT * HZ; add_timer(&task->timer); res = pm8001_tag_alloc(pm8001_ha, &ccb_tag); diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h index 599601e..8e38ca8 100644 --- a/drivers/scsi/pm8001/pm8001_sas.h +++ b/drivers/scsi/pm8001/pm8001_sas.h @@ -59,11 +59,11 @@ #define DRV_NAME "pm8001" #define DRV_VERSION "0.1.36" -#define PM8001_FAIL_LOGGING 0x01 /* libsas EH function logging */ +#define PM8001_FAIL_LOGGING 0x01 /* Error message logging */ #define PM8001_INIT_LOGGING 0x02 /* driver init logging */ #define PM8001_DISC_LOGGING 0x04 /* discovery layer logging */ #define PM8001_IO_LOGGING 0x08 /* I/O path logging */ -#define PM8001_EH_LOGGING 0x10 /* Error message logging */ +#define PM8001_EH_LOGGING 0x10 /* libsas EH function logging*/ #define PM8001_IOCTL_LOGGING 0x20 /* IOCTL message logging */ #define PM8001_MSG_LOGGING 0x40 /* misc message logging */ #define pm8001_printk(format, arg...) printk(KERN_INFO "%s %d:" format,\ -- cgit v0.10.2 From b22b97c15eed893a6768aad2f596706c56bf194e Mon Sep 17 00:00:00 2001 From: Mark Ware Date: Thu, 10 Dec 2009 22:14:34 +1100 Subject: powerpc/cpm2_pic: Allow correct flow_types for port C interrupts Port C interrupts can be either falling edge, or either edge. Other external interrupts are either falling edge or active low. Tested on a custom 8280 based board. Signed-off-by: Mark Ware Acked-by: Anton Vorontsov Acked-by: Scott Wood Signed-off-by: Kumar Gala diff --git a/arch/powerpc/sysdev/cpm2_pic.c b/arch/powerpc/sysdev/cpm2_pic.c index 971483f..1709ac5 100644 --- a/arch/powerpc/sysdev/cpm2_pic.c +++ b/arch/powerpc/sysdev/cpm2_pic.c @@ -143,13 +143,23 @@ static int cpm2_set_irq_type(unsigned int virq, unsigned int flow_type) struct irq_desc *desc = irq_to_desc(virq); unsigned int vold, vnew, edibit; - if (flow_type == IRQ_TYPE_NONE) - flow_type = IRQ_TYPE_LEVEL_LOW; - - if (flow_type & IRQ_TYPE_EDGE_RISING) { - printk(KERN_ERR "CPM2 PIC: sense type 0x%x not supported\n", - flow_type); - return -EINVAL; + /* Port C interrupts are either IRQ_TYPE_EDGE_FALLING or + * IRQ_TYPE_EDGE_BOTH (default). All others are IRQ_TYPE_EDGE_FALLING + * or IRQ_TYPE_LEVEL_LOW (default) + */ + if (src >= CPM2_IRQ_PORTC15 && src <= CPM2_IRQ_PORTC0) { + if (flow_type == IRQ_TYPE_NONE) + flow_type = IRQ_TYPE_EDGE_BOTH; + + if (flow_type != IRQ_TYPE_EDGE_BOTH && + flow_type != IRQ_TYPE_EDGE_FALLING) + goto err_sense; + } else { + if (flow_type == IRQ_TYPE_NONE) + flow_type = IRQ_TYPE_LEVEL_LOW; + + if (flow_type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_LEVEL_HIGH)) + goto err_sense; } desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL); @@ -181,6 +191,10 @@ static int cpm2_set_irq_type(unsigned int virq, unsigned int flow_type) if (vold != vnew) out_be32(&cpm2_intctl->ic_siexr, vnew); return 0; + +err_sense: + pr_err("CPM2 PIC: sense type 0x%x not supported\n", flow_type); + return -EINVAL; } static struct irq_chip cpm2_pic = { -- cgit v0.10.2 From 14d8c9f3c09e7fd7b9af80904289fe204f5b93c6 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 10 Dec 2009 00:53:17 +0000 Subject: signal: Fix racy access to __task_cred in kill_pid_info_as_uid() kill_pid_info_as_uid() accesses __task_cred() without being in a RCU read side critical section. tasklist_lock is not protecting that when CONFIG_TREE_PREEMPT_RCU=y. Convert the whole tasklist_lock section to rcu and use lock_task_sighand to prevent the exit race. Signed-off-by: Thomas Gleixner LKML-Reference: <20091210004703.232302055@linutronix.de> Acked-by: Oleg Nesterov diff --git a/kernel/signal.c b/kernel/signal.c index 6b982f2..7331656 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1175,11 +1175,12 @@ int kill_pid_info_as_uid(int sig, struct siginfo *info, struct pid *pid, int ret = -EINVAL; struct task_struct *p; const struct cred *pcred; + unsigned long flags; if (!valid_signal(sig)) return ret; - read_lock(&tasklist_lock); + rcu_read_lock(); p = pid_task(pid, PIDTYPE_PID); if (!p) { ret = -ESRCH; @@ -1196,14 +1197,16 @@ int kill_pid_info_as_uid(int sig, struct siginfo *info, struct pid *pid, ret = security_task_kill(p, info, sig, secid); if (ret) goto out_unlock; - if (sig && p->sighand) { - unsigned long flags; - spin_lock_irqsave(&p->sighand->siglock, flags); - ret = __send_signal(sig, info, p, 1, 0); - spin_unlock_irqrestore(&p->sighand->siglock, flags); + + if (sig) { + if (lock_task_sighand(p, &flags)) { + ret = __send_signal(sig, info, p, 1, 0); + unlock_task_sighand(p, &flags); + } else + ret = -ESRCH; } out_unlock: - read_unlock(&tasklist_lock); + rcu_read_unlock(); return ret; } EXPORT_SYMBOL_GPL(kill_pid_info_as_uid); -- cgit v0.10.2 From 7cf7db8df0b78076eafa4ead47559344ca7b7a43 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 10 Dec 2009 00:53:21 +0000 Subject: signals: Fix more rcu assumptions 1) Remove the misleading comment in __sigqueue_alloc() which claims that holding a spinlock is equivalent to rcu_read_lock(). 2) Add a rcu_read_lock/unlock around the __task_cred() access in __sigqueue_alloc() This needs to be revisited to remove the remaining users of read_lock(&tasklist_lock) but that's outside the scope of this patch. Signed-off-by: Thomas Gleixner LKML-Reference: <20091210004703.269843657@linutronix.de> diff --git a/kernel/signal.c b/kernel/signal.c index 7331656..f67545f 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -218,13 +218,13 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_t flags, int override_rlimi struct user_struct *user; /* - * We won't get problems with the target's UID changing under us - * because changing it requires RCU be used, and if t != current, the - * caller must be holding the RCU readlock (by way of a spinlock) and - * we use RCU protection here + * Protect access to @t credentials. This can go away when all + * callers hold rcu read lock. */ + rcu_read_lock(); user = get_uid(__task_cred(t)->user); atomic_inc(&user->sigpending); + rcu_read_unlock(); if (override_rlimit || atomic_read(&user->sigpending) <= -- cgit v0.10.2 From d4581a239a40319205762b76c01eb6363f277efa Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 10 Dec 2009 00:52:51 +0000 Subject: sys: Fix missing rcu protection for __task_cred() access commit c69e8d9 (CRED: Use RCU to access another task's creds and to release a task's own creds) added non rcu_read_lock() protected access to task creds of the target task in set_prio_one(). The comment above the function says: * - the caller must hold the RCU read lock The calling code in sys_setpriority does read_lock(&tasklist_lock) but not rcu_read_lock(). This works only when CONFIG_TREE_PREEMPT_RCU=n. With CONFIG_TREE_PREEMPT_RCU=y the rcu_callbacks can run in the tick interrupt when they see no read side critical section. There is another instance of __task_cred() in sys_setpriority() itself which is equally unprotected. Wrap the whole code section into a rcu read side critical section to fix this quick and dirty. Will be revisited in course of the read_lock(&tasklist_lock) -> rcu crusade. Oleg noted further: This also fixes another bug here. find_task_by_vpid() is not safe without rcu_read_lock(). I do not mean it is not safe to use the result, just find_pid_ns() by itself is not safe. Usually tasklist gives enough protection, but if copy_process() fails it calls free_pid() lockless and does call_rcu(delayed_put_pid(). This means, without rcu lock find_pid_ns() can't scan the hash table safely. Signed-off-by: Thomas Gleixner LKML-Reference: <20091210004703.029784964@linutronix.de> Acked-by: Paul E. McKenney diff --git a/kernel/sys.c b/kernel/sys.c index 9968c5f..bc1dc61 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -163,6 +163,7 @@ SYSCALL_DEFINE3(setpriority, int, which, int, who, int, niceval) if (niceval > 19) niceval = 19; + rcu_read_lock(); read_lock(&tasklist_lock); switch (which) { case PRIO_PROCESS: @@ -200,6 +201,7 @@ SYSCALL_DEFINE3(setpriority, int, which, int, who, int, niceval) } out_unlock: read_unlock(&tasklist_lock); + rcu_read_unlock(); out: return error; } -- cgit v0.10.2 From f25c525c1412675d2b23d5d88660fb5c9f3a5341 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Thu, 10 Dec 2009 21:00:53 +0300 Subject: powerpc/83xx/suspend: Clear deep_sleeping after devices resume Currently 83xx PMC driver clears deep_sleeping variable very early, before devices are resumed. This makes fsl_deep_sleep() unusable in drivers' resume() callback. Sure, drivers can store fsl_deep_sleep() value on suspend and use the stored value on resume. But a better solution is to postpone clearing the deep_sleeping variable, i.e. move it into finish() callback. Signed-off-by: Anton Vorontsov Acked-by: Scott Wood Signed-off-by: Kumar Gala diff --git a/arch/powerpc/platforms/83xx/suspend.c b/arch/powerpc/platforms/83xx/suspend.c index d306f07..b0c2619 100644 --- a/arch/powerpc/platforms/83xx/suspend.c +++ b/arch/powerpc/platforms/83xx/suspend.c @@ -194,7 +194,7 @@ out: return ret; } -static void mpc83xx_suspend_finish(void) +static void mpc83xx_suspend_end(void) { deep_sleeping = 0; } @@ -278,7 +278,7 @@ static struct platform_suspend_ops mpc83xx_suspend_ops = { .valid = mpc83xx_suspend_valid, .begin = mpc83xx_suspend_begin, .enter = mpc83xx_suspend_enter, - .finish = mpc83xx_suspend_finish, + .end = mpc83xx_suspend_end, }; static int pmc_probe(struct of_device *ofdev, -- cgit v0.10.2 From 87faaabb09d0802d54ff863a16ca821d7c669cb6 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Thu, 10 Dec 2009 21:00:56 +0300 Subject: powerpc/83xx/suspend: Save and restore SICRL, SICRH and SCCR We need to save SICRL, SICRH and SCCR registers on suspend, and restore them on resume. Otherwise, we lose IO and clocks setup on MPC8315E-RDB boards when ULPI USB PHY is used (non-POR setup). Signed-off-by: Anton Vorontsov Acked-by: Scott Wood Signed-off-by: Kumar Gala diff --git a/arch/powerpc/platforms/83xx/suspend.c b/arch/powerpc/platforms/83xx/suspend.c index b0c2619..4380534 100644 --- a/arch/powerpc/platforms/83xx/suspend.c +++ b/arch/powerpc/platforms/83xx/suspend.c @@ -32,6 +32,7 @@ #define PMCCR1_NEXT_STATE 0x0C /* Next state for power management */ #define PMCCR1_NEXT_STATE_SHIFT 2 #define PMCCR1_CURR_STATE 0x03 /* Current state for power management*/ +#define IMMR_SYSCR_OFFSET 0x100 #define IMMR_RCW_OFFSET 0x900 #define RCW_PCI_HOST 0x80000000 @@ -78,6 +79,22 @@ struct mpc83xx_clock { u32 sccr; }; +struct mpc83xx_syscr { + __be32 sgprl; + __be32 sgprh; + __be32 spridr; + __be32 :32; + __be32 spcr; + __be32 sicrl; + __be32 sicrh; +}; + +struct mpc83xx_saved { + u32 sicrl; + u32 sicrh; + u32 sccr; +}; + struct pmc_type { int has_deep_sleep; }; @@ -87,6 +104,8 @@ static int has_deep_sleep, deep_sleeping; static int pmc_irq; static struct mpc83xx_pmc __iomem *pmc_regs; static struct mpc83xx_clock __iomem *clock_regs; +static struct mpc83xx_syscr __iomem *syscr_regs; +static struct mpc83xx_saved saved_regs; static int is_pci_agent, wake_from_pci; static phys_addr_t immrbase; static int pci_pm_state; @@ -137,6 +156,20 @@ static irqreturn_t pmc_irq_handler(int irq, void *dev_id) return ret; } +static void mpc83xx_suspend_restore_regs(void) +{ + out_be32(&syscr_regs->sicrl, saved_regs.sicrl); + out_be32(&syscr_regs->sicrh, saved_regs.sicrh); + out_be32(&clock_regs->sccr, saved_regs.sccr); +} + +static void mpc83xx_suspend_save_regs(void) +{ + saved_regs.sicrl = in_be32(&syscr_regs->sicrl); + saved_regs.sicrh = in_be32(&syscr_regs->sicrh); + saved_regs.sccr = in_be32(&clock_regs->sccr); +} + static int mpc83xx_suspend_enter(suspend_state_t state) { int ret = -EAGAIN; @@ -166,6 +199,8 @@ static int mpc83xx_suspend_enter(suspend_state_t state) */ if (deep_sleeping) { + mpc83xx_suspend_save_regs(); + out_be32(&pmc_regs->mask, PMCER_ALL); out_be32(&pmc_regs->config1, @@ -179,6 +214,8 @@ static int mpc83xx_suspend_enter(suspend_state_t state) in_be32(&pmc_regs->config1) & ~PMCCR1_POWER_OFF); out_be32(&pmc_regs->mask, PMCER_PMCI); + + mpc83xx_suspend_restore_regs(); } else { out_be32(&pmc_regs->mask, PMCER_PMCI); @@ -333,12 +370,23 @@ static int pmc_probe(struct of_device *ofdev, goto out_pmc; } + if (has_deep_sleep) { + syscr_regs = ioremap(immrbase + IMMR_SYSCR_OFFSET, + sizeof(*syscr_regs)); + if (!syscr_regs) { + ret = -ENOMEM; + goto out_syscr; + } + } + if (is_pci_agent) mpc83xx_set_agent(); suspend_set_ops(&mpc83xx_suspend_ops); return 0; +out_syscr: + iounmap(clock_regs); out_pmc: iounmap(pmc_regs); out: -- cgit v0.10.2 From 1cad2c874162d84bf7b2d31344a08b9cb724d138 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Thu, 10 Dec 2009 21:01:03 +0300 Subject: powerpc/83xx: Add power management support for MPC8315E-RDB boards - Add nodes for PMC and GTM controllers. GTM4 can be used as a wakeup source; - Add fsl,magic-packet properties to eTSEC nodes, i.e. wake-on-lan support. Unlike MPC8313 processors, MPC8315 can resume from deep sleep upon magic packet reception. Signed-off-by: Anton Vorontsov Acked-by: Scott Wood Signed-off-by: Kumar Gala diff --git a/arch/powerpc/boot/dts/mpc8315erdb.dts b/arch/powerpc/boot/dts/mpc8315erdb.dts index 32e10f5..8a3a4f3 100644 --- a/arch/powerpc/boot/dts/mpc8315erdb.dts +++ b/arch/powerpc/boot/dts/mpc8315erdb.dts @@ -204,6 +204,7 @@ interrupt-parent = <&ipic>; tbi-handle = <&tbi0>; phy-handle = < &phy0 >; + fsl,magic-packet; mdio@520 { #address-cells = <1>; @@ -246,6 +247,7 @@ interrupt-parent = <&ipic>; tbi-handle = <&tbi1>; phy-handle = < &phy1 >; + fsl,magic-packet; mdio@520 { #address-cells = <1>; @@ -309,6 +311,22 @@ interrupt-parent = <&ipic>; }; + gtm1: timer@500 { + compatible = "fsl,mpc8315-gtm", "fsl,gtm"; + reg = <0x500 0x100>; + interrupts = <90 8 78 8 84 8 72 8>; + interrupt-parent = <&ipic>; + clock-frequency = <133333333>; + }; + + timer@600 { + compatible = "fsl,mpc8315-gtm", "fsl,gtm"; + reg = <0x600 0x100>; + interrupts = <91 8 79 8 85 8 73 8>; + interrupt-parent = <&ipic>; + clock-frequency = <133333333>; + }; + /* IPIC * interrupts cell = * sense values match linux IORESOURCE_IRQ_* defines: @@ -337,6 +355,15 @@ 0x59 0x8>; interrupt-parent = < &ipic >; }; + + pmc: power@b00 { + compatible = "fsl,mpc8315-pmc", "fsl,mpc8313-pmc", + "fsl,mpc8349-pmc"; + reg = <0xb00 0x100 0xa00 0x100>; + interrupts = <80 8>; + interrupt-parent = <&ipic>; + fsl,mpc8313-wakeup-timer = <>m1>; + }; }; pci0: pci@e0008500 { -- cgit v0.10.2 From 78331aded913d76c7ff996a1a0747d54b057460b Mon Sep 17 00:00:00 2001 From: Peter Korsgaard Date: Tue, 1 Dec 2009 21:48:13 +0100 Subject: powerpc/gpio: support gpio_to_irq() gpiolib returns -ENXIO if struct gpio_chip::to_irq isn't set, so it's safe to always call. Signed-off-by: Peter Korsgaard Signed-off-by: Kumar Gala diff --git a/arch/powerpc/include/asm/gpio.h b/arch/powerpc/include/asm/gpio.h index ea04632..38762ed 100644 --- a/arch/powerpc/include/asm/gpio.h +++ b/arch/powerpc/include/asm/gpio.h @@ -38,12 +38,9 @@ static inline int gpio_cansleep(unsigned int gpio) return __gpio_cansleep(gpio); } -/* - * Not implemented, yet. - */ static inline int gpio_to_irq(unsigned int gpio) { - return -ENOSYS; + return __gpio_to_irq(gpio); } static inline int irq_to_gpio(unsigned int irq) -- cgit v0.10.2 From c1a676dfa2fa25fb9ec77c92ebe3ff580648b6ac Mon Sep 17 00:00:00 2001 From: Felix Radensky Date: Wed, 12 Aug 2009 08:57:39 +0300 Subject: powerpc/85xx: Workaround MPC8572/MPC8536 GPIO 1 errata. On MPC8572 and MPC8536 the status of GPIO pins configured as output cannot be determined by reading GPDAT register. Workaround by reading the status of input pins from GPDAT and the status of output pins from a shadow register. Signed-off-by: Felix Radensky Signed-off-by: Kumar Gala diff --git a/arch/powerpc/sysdev/mpc8xxx_gpio.c b/arch/powerpc/sysdev/mpc8xxx_gpio.c index 103eace..ee1c0e1 100644 --- a/arch/powerpc/sysdev/mpc8xxx_gpio.c +++ b/arch/powerpc/sysdev/mpc8xxx_gpio.c @@ -54,6 +54,22 @@ static void mpc8xxx_gpio_save_regs(struct of_mm_gpio_chip *mm) mpc8xxx_gc->data = in_be32(mm->regs + GPIO_DAT); } +/* Workaround GPIO 1 errata on MPC8572/MPC8536. The status of GPIOs + * defined as output cannot be determined by reading GPDAT register, + * so we use shadow data register instead. The status of input pins + * is determined by reading GPDAT register. + */ +static int mpc8572_gpio_get(struct gpio_chip *gc, unsigned int gpio) +{ + u32 val; + struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); + struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm); + + val = in_be32(mm->regs + GPIO_DAT) & ~in_be32(mm->regs + GPIO_DIR); + + return (val | mpc8xxx_gc->data) & mpc8xxx_gpio2mask(gpio); +} + static int mpc8xxx_gpio_get(struct gpio_chip *gc, unsigned int gpio) { struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); @@ -136,7 +152,10 @@ static void __init mpc8xxx_add_controller(struct device_node *np) gc->ngpio = MPC8XXX_GPIO_PINS; gc->direction_input = mpc8xxx_gpio_dir_in; gc->direction_output = mpc8xxx_gpio_dir_out; - gc->get = mpc8xxx_gpio_get; + if (of_device_is_compatible(np, "fsl,mpc8572-gpio")) + gc->get = mpc8572_gpio_get; + else + gc->get = mpc8xxx_gpio_get; gc->set = mpc8xxx_gpio_set; ret = of_mm_gpiochip_add(np, mm_gc); -- cgit v0.10.2 From 1cb9f9b086f818eb9543ed759382de7b95c67f87 Mon Sep 17 00:00:00 2001 From: Simon Guinot Date: Wed, 9 Dec 2009 01:43:49 +0100 Subject: [ARM] Kirkwood: Add LaCie Network Space v2 support Signed-off-by: Simon Guinot Signed-off-by: Nicolas Pitre diff --git a/arch/arm/mach-kirkwood/Kconfig b/arch/arm/mach-kirkwood/Kconfig index 8bf09ae..f6c6196 100644 --- a/arch/arm/mach-kirkwood/Kconfig +++ b/arch/arm/mach-kirkwood/Kconfig @@ -52,6 +52,12 @@ config MACH_OPENRD_BASE Say 'Y' here if you want your kernel to support the Marvell OpenRD Base Board. +config MACH_NETSPACE_V2 + bool "LaCie Network Space v2 NAS Board" + help + Say 'Y' here if you want your kernel to support the + LaCie Network Space v2 NAS. + endmenu endif diff --git a/arch/arm/mach-kirkwood/Makefile b/arch/arm/mach-kirkwood/Makefile index 9f2f67b..d4d7f53 100644 --- a/arch/arm/mach-kirkwood/Makefile +++ b/arch/arm/mach-kirkwood/Makefile @@ -8,5 +8,6 @@ obj-$(CONFIG_MACH_SHEEVAPLUG) += sheevaplug-setup.o obj-$(CONFIG_MACH_TS219) += ts219-setup.o tsx1x-common.o obj-$(CONFIG_MACH_TS41X) += ts41x-setup.o tsx1x-common.o obj-$(CONFIG_MACH_OPENRD_BASE) += openrd_base-setup.o +obj-$(CONFIG_MACH_NETSPACE_V2) += netspace_v2-setup.o obj-$(CONFIG_CPU_IDLE) += cpuidle.o diff --git a/arch/arm/mach-kirkwood/netspace_v2-setup.c b/arch/arm/mach-kirkwood/netspace_v2-setup.c new file mode 100644 index 0000000..9a06406 --- /dev/null +++ b/arch/arm/mach-kirkwood/netspace_v2-setup.c @@ -0,0 +1,325 @@ +/* + * arch/arm/mach-kirkwood/netspace_v2-setup.c + * + * LaCie Network Space v2 board setup + * + * Copyright (C) 2009 Simon Guinot + * Copyright (C) 2009 Benoît Canet + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "mpp.h" + +/***************************************************************************** + * 512KB SPI Flash on Boot Device (MACRONIX MX25L4005) + ****************************************************************************/ + +static struct mtd_partition netspace_v2_flash_parts[] = { + { + .name = "u-boot", + .size = MTDPART_SIZ_FULL, + .offset = 0, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, +}; + +static const struct flash_platform_data netspace_v2_flash = { + .type = "mx25l4005a", + .name = "spi_flash", + .parts = netspace_v2_flash_parts, + .nr_parts = ARRAY_SIZE(netspace_v2_flash_parts), +}; + +static struct spi_board_info __initdata netspace_v2_spi_slave_info[] = { + { + .modalias = "m25p80", + .platform_data = &netspace_v2_flash, + .irq = -1, + .max_speed_hz = 20000000, + .bus_num = 0, + .chip_select = 0, + }, +}; + +/***************************************************************************** + * Ethernet + ****************************************************************************/ + +static struct mv643xx_eth_platform_data netspace_v2_ge00_data = { + .phy_addr = MV643XX_ETH_PHY_ADDR(8), +}; + +/***************************************************************************** + * I2C devices + ****************************************************************************/ + +static struct at24_platform_data at24c04 = { + .byte_len = SZ_4K / 8, + .page_size = 16, +}; + +/* + * i2c addr | chip | description + * 0x50 | HT24LC04 | eeprom (512B) + */ + +static struct i2c_board_info __initdata netspace_v2_i2c_info[] = { + { + I2C_BOARD_INFO("24c04", 0x50), + .platform_data = &at24c04, + } +}; + +/***************************************************************************** + * SATA + ****************************************************************************/ + +static struct mv_sata_platform_data netspace_v2_sata_data = { + .n_ports = 2, +}; + +#define NETSPACE_V2_GPIO_SATA0_POWER 16 +#define NETSPACE_V2_GPIO_SATA1_POWER 17 + +static void __init netspace_v2_sata_power_init(void) +{ + int err; + + err = gpio_request(NETSPACE_V2_GPIO_SATA0_POWER, "SATA0 power"); + if (err == 0) { + err = gpio_direction_output(NETSPACE_V2_GPIO_SATA0_POWER, 1); + if (err) + gpio_free(NETSPACE_V2_GPIO_SATA0_POWER); + } + if (err) + pr_err("netspace_v2: failed to setup SATA0 power\n"); +} + +/***************************************************************************** + * GPIO keys + ****************************************************************************/ + +#define NETSPACE_V2_PUSH_BUTTON 32 + +static struct gpio_keys_button netspace_v2_buttons[] = { + [0] = { + .code = KEY_POWER, + .gpio = NETSPACE_V2_PUSH_BUTTON, + .desc = "Power push button", + .active_low = 0, + }, +}; + +static struct gpio_keys_platform_data netspace_v2_button_data = { + .buttons = netspace_v2_buttons, + .nbuttons = ARRAY_SIZE(netspace_v2_buttons), +}; + +static struct platform_device netspace_v2_gpio_buttons = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &netspace_v2_button_data, + }, +}; + +/***************************************************************************** + * GPIO LEDs + ****************************************************************************/ + +/* + * The blue front LED is wired to a CPLD and can blink in relation with the + * SATA activity. + * + * The following array detail the different LED registers and the combination + * of their possible values: + * + * cmd_led | slow_led | /SATA active | LED state + * | | | + * 1 | 0 | x | off + * - | 1 | x | on + * 0 | 0 | 1 | on + * 0 | 0 | 0 | blink (rate 300ms) + */ + +#define NETSPACE_V2_GPIO_RED_LED 12 +#define NETSPACE_V2_GPIO_BLUE_LED_SLOW 29 +#define NETSPACE_V2_GPIO_BLUE_LED_CMD 30 + + +static struct gpio_led netspace_v2_gpio_led_pins[] = { + { + .name = "ns_v2:red:fail", + .gpio = NETSPACE_V2_GPIO_RED_LED, + }, +}; + +static struct gpio_led_platform_data netspace_v2_gpio_leds_data = { + .num_leds = ARRAY_SIZE(netspace_v2_gpio_led_pins), + .leds = netspace_v2_gpio_led_pins, +}; + +static struct platform_device netspace_v2_gpio_leds = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &netspace_v2_gpio_leds_data, + }, +}; + +static void __init netspace_v2_gpio_leds_init(void) +{ + platform_device_register(&netspace_v2_gpio_leds); + + /* + * Configure the front blue LED to blink in relation with the SATA + * activity. + */ + if (gpio_request(NETSPACE_V2_GPIO_BLUE_LED_SLOW, + "SATA blue LED slow") != 0) + return; + if (gpio_direction_output(NETSPACE_V2_GPIO_BLUE_LED_SLOW, 0) != 0) + goto err_free_1; + if (gpio_request(NETSPACE_V2_GPIO_BLUE_LED_CMD, + "SATA blue LED command") != 0) + goto err_free_1; + if (gpio_direction_output(NETSPACE_V2_GPIO_BLUE_LED_CMD, 0) != 0) + goto err_free_2; + + return; + +err_free_2: + gpio_free(NETSPACE_V2_GPIO_BLUE_LED_CMD); +err_free_1: + gpio_free(NETSPACE_V2_GPIO_BLUE_LED_SLOW); + pr_err("netspace_v2: failed to configure SATA blue LED\n"); +} + +/***************************************************************************** + * Timer + ****************************************************************************/ + +static void netspace_v2_timer_init(void) +{ + kirkwood_tclk = 166666667; + orion_time_init(IRQ_KIRKWOOD_BRIDGE, kirkwood_tclk); +} + +struct sys_timer netspace_v2_timer = { + .init = netspace_v2_timer_init, +}; + +/***************************************************************************** + * General Setup + ****************************************************************************/ + +static unsigned int netspace_v2_mpp_config[] __initdata = { + MPP0_SPI_SCn, + MPP1_SPI_MOSI, + MPP2_SPI_SCK, + MPP3_SPI_MISO, + MPP4_NF_IO6, + MPP5_NF_IO7, + MPP6_SYSRST_OUTn, + MPP8_TW_SDA, + MPP9_TW_SCK, + MPP10_UART0_TXD, + MPP11_UART0_RXD, + MPP12_GPO, /* Red led */ + MPP14_GPIO, /* USB fuse */ + MPP16_GPIO, /* SATA 0 power */ + MPP18_NF_IO0, + MPP19_NF_IO1, + MPP20_SATA1_ACTn, + MPP21_SATA0_ACTn, + MPP24_GPIO, /* USB mode select */ + MPP25_GPIO, /* Fan rotation fail */ + MPP26_GPIO, /* USB device vbus */ + MPP28_GPIO, /* USB enable host vbus */ + MPP29_GPIO, /* Blue led (slow register) */ + MPP30_GPIO, /* Blue led (command register) */ + MPP31_GPIO, /* Board power off */ + MPP32_GPIO, /* Power button (0 = Released, 1 = Pushed) */ + 0 +}; + +#define NETSPACE_V2_GPIO_POWER_OFF 31 + +static void netspace_v2_power_off(void) +{ + gpio_set_value(NETSPACE_V2_GPIO_POWER_OFF, 1); +} + +static void __init netspace_v2_init(void) +{ + /* + * Basic setup. Needs to be called early. + */ + kirkwood_init(); + kirkwood_mpp_conf(netspace_v2_mpp_config); + + netspace_v2_sata_power_init(); + + kirkwood_ehci_init(); + kirkwood_ge00_init(&netspace_v2_ge00_data); + kirkwood_sata_init(&netspace_v2_sata_data); + kirkwood_uart0_init(); + spi_register_board_info(netspace_v2_spi_slave_info, + ARRAY_SIZE(netspace_v2_spi_slave_info)); + kirkwood_spi_init(); + kirkwood_i2c_init(); + i2c_register_board_info(0, netspace_v2_i2c_info, + ARRAY_SIZE(netspace_v2_i2c_info)); + + netspace_v2_gpio_leds_init(); + platform_device_register(&netspace_v2_gpio_buttons); + + if (gpio_request(NETSPACE_V2_GPIO_POWER_OFF, "power-off") == 0 && + gpio_direction_output(NETSPACE_V2_GPIO_POWER_OFF, 0) == 0) + pm_power_off = netspace_v2_power_off; + else + pr_err("netspace_v2: failed to configure power-off GPIO\n"); +} + +MACHINE_START(NETSPACE_V2, "LaCie Network Space v2") + .phys_io = KIRKWOOD_REGS_PHYS_BASE, + .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .init_machine = netspace_v2_init, + .map_io = kirkwood_map_io, + .init_irq = kirkwood_init_irq, + .timer = &netspace_v2_timer, +MACHINE_END -- cgit v0.10.2 From bb6eddf7676e1c1f3e637aa93c5224488d99036f Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 10 Dec 2009 15:35:10 +0100 Subject: clockevents: Prevent clockevent_devices list corruption on cpu hotplug Xiaotian Feng triggered a list corruption in the clock events list on CPU hotplug and debugged the root cause. If a CPU registers more than one per cpu clock event device, then only the active clock event device is removed on CPU_DEAD. The unused devices are kept in the clock events device list. On CPU up the clock event devices are registered again, which means that we list_add an already enqueued list_head. That results in list corruption. Resolve this by removing all devices which are associated to the dead CPU on CPU_DEAD. Reported-by: Xiaotian Feng Signed-off-by: Thomas Gleixner Tested-by: Xiaotian Feng Cc: stable@kernel.org diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c index 20a8920..91db2e3 100644 --- a/kernel/time/clockevents.c +++ b/kernel/time/clockevents.c @@ -238,8 +238,9 @@ void clockevents_exchange_device(struct clock_event_device *old, */ void clockevents_notify(unsigned long reason, void *arg) { - struct list_head *node, *tmp; + struct clock_event_device *dev, *tmp; unsigned long flags; + int cpu; spin_lock_irqsave(&clockevents_lock, flags); clockevents_do_notify(reason, arg); @@ -250,8 +251,19 @@ void clockevents_notify(unsigned long reason, void *arg) * Unregister the clock event devices which were * released from the users in the notify chain. */ - list_for_each_safe(node, tmp, &clockevents_released) - list_del(node); + list_for_each_entry_safe(dev, tmp, &clockevents_released, list) + list_del(&dev->list); + /* + * Now check whether the CPU has left unused per cpu devices + */ + cpu = *((int *)arg); + list_for_each_entry_safe(dev, tmp, &clockevent_devices, list) { + if (cpumask_test_cpu(cpu, dev->cpumask) && + cpumask_weight(dev->cpumask) == 1) { + BUG_ON(dev->mode != CLOCK_EVT_MODE_UNUSED); + list_del(&dev->list); + } + } break; default: break; -- cgit v0.10.2 From 070bae1fb03bbf6a19a18722464a984eb3ddf55e Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Fri, 11 Dec 2009 03:39:53 +0000 Subject: powerpc/44x: Extend Katmai dts for ADMA and RAID56 support Add nodes for PPC440SPe DMA, I2O, XOR engines and Memory Queue module which are used in the updated PPC440SPe ADMA driver. Also extend plb ranges property to specify address ranges for DMA0/1 and I2O engines. Signed-off-by: Yuri Tikhonov Signed-off-by: Anatolij Gustschin Signed-off-by: Josh Boyer diff --git a/arch/powerpc/boot/dts/katmai.dts b/arch/powerpc/boot/dts/katmai.dts index 51eb6ed..8f345de9 100644 --- a/arch/powerpc/boot/dts/katmai.dts +++ b/arch/powerpc/boot/dts/katmai.dts @@ -108,12 +108,19 @@ dcr-reg = <0x00c 0x002>; }; + MQ0: mq { + compatible = "ibm,mq-440spe"; + dcr-reg = <0x040 0x020>; + }; + plb { compatible = "ibm,plb-440spe", "ibm,plb-440gp", "ibm,plb4"; #address-cells = <2>; #size-cells = <1>; /* addr-child addr-parent size */ - ranges = <0x4 0xe0000000 0x4 0xe0000000 0x20000000 + ranges = <0x4 0x00100000 0x4 0x00100000 0x00001000 + 0x4 0x00200000 0x4 0x00200000 0x00000400 + 0x4 0xe0000000 0x4 0xe0000000 0x20000000 0xc 0x00000000 0xc 0x00000000 0x20000000 0xd 0x00000000 0xd 0x00000000 0x80000000 0xd 0x80000000 0xd 0x80000000 0x80000000 @@ -400,6 +407,49 @@ 0x0 0x0 0x0 0x3 &UIC3 0xa 0x4 /* swizzled int C */ 0x0 0x0 0x0 0x4 &UIC3 0xb 0x4 /* swizzled int D */>; }; + + I2O: i2o@400100000 { + compatible = "ibm,i2o-440spe"; + reg = <0x00000004 0x00100000 0x100>; + dcr-reg = <0x060 0x020>; + }; + + DMA0: dma0@400100100 { + compatible = "ibm,dma-440spe"; + cell-index = <0>; + reg = <0x00000004 0x00100100 0x100>; + dcr-reg = <0x060 0x020>; + interrupt-parent = <&DMA0>; + interrupts = <0 1>; + #interrupt-cells = <1>; + #address-cells = <0>; + #size-cells = <0>; + interrupt-map = < + 0 &UIC0 0x14 4 + 1 &UIC1 0x16 4>; + }; + + DMA1: dma1@400100200 { + compatible = "ibm,dma-440spe"; + cell-index = <1>; + reg = <0x00000004 0x00100200 0x100>; + dcr-reg = <0x060 0x020>; + interrupt-parent = <&DMA1>; + interrupts = <0 1>; + #interrupt-cells = <1>; + #address-cells = <0>; + #size-cells = <0>; + interrupt-map = < + 0 &UIC0 0x16 4 + 1 &UIC1 0x16 4>; + }; + + xor-accel@400200000 { + compatible = "amcc,xor-accelerator"; + reg = <0x00000004 0x00200000 0x400>; + interrupt-parent = <&UIC1>; + interrupts = <0x1f 4>; + }; }; chosen { -- cgit v0.10.2 From a18cb387e5c29be5c95cded5b5a55110bb930f5c Mon Sep 17 00:00:00 2001 From: Sean MacLennan Date: Tue, 8 Dec 2009 19:04:37 +0000 Subject: powerpc/44x: Increase warp SD buffer Newer revs of the FPGA have a larger SD buffer. Signed-off-by: Sean MacLennan Signed-off-by: Josh Boyer diff --git a/arch/powerpc/boot/dts/warp.dts b/arch/powerpc/boot/dts/warp.dts index 31605ee..e576ee8 100644 --- a/arch/powerpc/boot/dts/warp.dts +++ b/arch/powerpc/boot/dts/warp.dts @@ -146,7 +146,7 @@ fpga@2,4000 { compatible = "pika,fpga-sd"; - reg = <0x00000002 0x00004000 0x00000A00>; + reg = <0x00000002 0x00004000 0x00004000>; }; nor@0,0 { -- cgit v0.10.2 From 23e707dd9b0b26215d801c59e87feed1c218a0f9 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 11 Dec 2009 15:38:46 -0800 Subject: Staging: batman: fix debug Kconfig option The debug batman option needs to depend on the correct config option. Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/batman-adv/Kconfig b/drivers/staging/batman-adv/Kconfig index b9742e7..7632f57 100644 --- a/drivers/staging/batman-adv/Kconfig +++ b/drivers/staging/batman-adv/Kconfig @@ -15,7 +15,7 @@ config BATMAN_ADV config BATMAN_DEBUG bool "B.A.T.M.A.N. debugging" - depends on BATMAN != n + depends on BATMAN_ADV != n help This is an option for use by developers; most people should -- cgit v0.10.2 From 4a2ff67c88211026afcbdbc190c13f705dae1b59 Mon Sep 17 00:00:00 2001 From: Michael Tokarev Date: Tue, 13 Oct 2009 22:22:46 +0200 Subject: kbuild: fix bzImage build for x86 As has been discussed previously (and Sam has been CC'ed), the fix is still incorrect. It replaces "echo -ne" with "/bin/echo -ne", but neither of the two are guaranteed to support the necessary arguments and necessary (hexadecimal) escape sequences. What should be used here is printf(1). The trivial patch below (on top of these kbuild changes) fixes this issue. Signed-Off-By: Michael Tokarev Signed-off-by: Sam Ravnborg Signed-off-by: Michal Marek diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index ffdafb2..d9f0cb8 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -208,7 +208,7 @@ cmd_gzip = (cat $(filter-out FORCE,$^) | gzip -f -9 > $@) || \ # Bzip2 and LZMA do not include size in file... so we have to fake that; # append the size as a 32-bit littleendian number as gzip does. -size_append = /bin/echo -ne $(shell \ +size_append = printf $(shell \ dec_size=0; \ for F in $1; do \ fsize=$$(stat -c "%s" $$F); \ -- cgit v0.10.2 From 24a675e8b86bef077e549a5ea2c6936989be4815 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 17 Oct 2009 21:14:18 +0200 Subject: kbuild: search arch/$ARCH/include before include/ The namespace used in arch/$ARCH/include is different from what is used in include/ except for the include/asm directory. This patch gives the arch/$ARCH/include/asm directory priority over include/asm. When we add asm-offsets.h to arch/$ARCH/include/asm/ this patch makes sure we pick up the arch specific version and not the one we have in include/asm. The situation with an asm-offsets.h file located in both include/asm _and_ arch/$ARCH/include/asm will happen when we move more files over to include/generated. This happens because in some cases it is not practical to rename all users so we simply add a file in arch/$ARCH/include/asm that includes the generated version. This is the solution we use for asm-offsets.h as an example. Signed-off-by: Sam Ravnborg Cc: Stephen Rothwell Signed-off-by: Michal Marek diff --git a/Makefile b/Makefile index 33d4732..0771178 100644 --- a/Makefile +++ b/Makefile @@ -334,9 +334,8 @@ CFLAGS_GCOV = -fprofile-arcs -ftest-coverage # Use LINUXINCLUDE when you must reference the include/ directory. # Needed to be compatible with the O= option -LINUXINCLUDE := -Iinclude \ +LINUXINCLUDE := -I$(srctree)/arch/$(hdr-arch)/include -Iinclude \ $(if $(KBUILD_SRC),-Iinclude2 -I$(srctree)/include) \ - -I$(srctree)/arch/$(hdr-arch)/include \ -include include/linux/autoconf.h KBUILD_CPPFLAGS := -D__KERNEL__ -- cgit v0.10.2 From 9367858dd08caf4e6ebd511abd2fca0a2d87b648 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 17 Oct 2009 21:33:34 +0200 Subject: dontdiff: add generated We move more and more stuff to include/generated - so lets ignore the content for users of plain diff. Signed-off-by: Sam Ravnborg Signed-off-by: Michal Marek diff --git a/Documentation/dontdiff b/Documentation/dontdiff index e151b2a..3ad6ace 100644 --- a/Documentation/dontdiff +++ b/Documentation/dontdiff @@ -103,6 +103,7 @@ gconf gen-devlist gen_crc32table gen_init_cpio +generated genheaders genksyms *_gray256.c -- cgit v0.10.2 From 01fc0ac198eabcbf460e1ed058860a935b6c2c9a Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sun, 19 Apr 2009 21:57:19 +0200 Subject: kbuild: move bounds.h to include/generated Signed-off-by: Sam Ravnborg Cc: Al Viro Signed-off-by: Michal Marek diff --git a/.gitignore b/.gitignore index 946c7ec..36d9cd6 100644 --- a/.gitignore +++ b/.gitignore @@ -52,7 +52,6 @@ include/linux/autoconf.h include/linux/compile.h include/linux/version.h include/linux/utsrelease.h -include/linux/bounds.h include/generated # stgit generated dirs diff --git a/Kbuild b/Kbuild index f056b4f..1165d7a 100644 --- a/Kbuild +++ b/Kbuild @@ -8,7 +8,7 @@ ##### # 1) Generate bounds.h -bounds-file := include/linux/bounds.h +bounds-file := include/generated/bounds.h always := $(bounds-file) targets := $(bounds-file) kernel/bounds.s diff --git a/Makefile b/Makefile index 0771178..b58e931 100644 --- a/Makefile +++ b/Makefile @@ -1197,7 +1197,7 @@ MRPROPER_DIRS += include/config include2 usr/include include/generated MRPROPER_FILES += .config .config.old include/asm .version .old_version \ include/linux/autoconf.h include/linux/version.h \ include/linux/utsrelease.h \ - include/linux/bounds.h include/asm*/asm-offsets.h \ + include/asm*/asm-offsets.h \ Module.symvers Module.markers tags TAGS cscope* # clean - Delete most, but leave enough to build external modules diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 6f75617..30fe668 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h index 6b202b1..ef36725 100644 --- a/include/linux/page-flags.h +++ b/include/linux/page-flags.h @@ -8,7 +8,7 @@ #include #ifndef __GENERATING_BOUNDS_H #include -#include +#include #endif /* !__GENERATING_BOUNDS_H */ /* diff --git a/kernel/bounds.c b/kernel/bounds.c index 3c53013..98a51f2 100644 --- a/kernel/bounds.c +++ b/kernel/bounds.c @@ -12,7 +12,7 @@ void foo(void) { - /* The enum constants to put into include/linux/bounds.h */ + /* The enum constants to put into include/generated/bounds.h */ DEFINE(NR_PAGEFLAGS, __NR_PAGEFLAGS); DEFINE(MAX_NR_ZONES, __MAX_NR_ZONES); /* End of constants */ -- cgit v0.10.2 From 559df2e0210352f83926d178c40c51142292a18c Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sun, 19 Apr 2009 22:35:10 +0200 Subject: kbuild: move asm-offsets.h to include/generated The simplest method was to add an extra asm-offsets.h file in arch/$ARCH/include/asm that references the generated file. We can now migrate the architectures one-by-one to reference the generated file direct - and when done we can delete the temporary arch/$ARCH/include/asm/asm-offsets.h file. Signed-off-by: Sam Ravnborg Cc: Al Viro Signed-off-by: Michal Marek diff --git a/.gitignore b/.gitignore index 36d9cd6..3582f422 100644 --- a/.gitignore +++ b/.gitignore @@ -46,7 +46,6 @@ Module.symvers # Generated include files # include/asm -include/asm-*/asm-offsets.h include/config include/linux/autoconf.h include/linux/compile.h diff --git a/Kbuild b/Kbuild index 1165d7a..e3737ad 100644 --- a/Kbuild +++ b/Kbuild @@ -43,7 +43,7 @@ $(obj)/$(bounds-file): kernel/bounds.s Kbuild # 2) Generate asm-offsets.h # -offsets-file := include/asm/asm-offsets.h +offsets-file := include/generated/asm-offsets.h always += $(offsets-file) targets += $(offsets-file) diff --git a/Makefile b/Makefile index b58e931..eb43b9f 100644 --- a/Makefile +++ b/Makefile @@ -1197,7 +1197,6 @@ MRPROPER_DIRS += include/config include2 usr/include include/generated MRPROPER_FILES += .config .config.old include/asm .version .old_version \ include/linux/autoconf.h include/linux/version.h \ include/linux/utsrelease.h \ - include/asm*/asm-offsets.h \ Module.symvers Module.markers tags TAGS cscope* # clean - Delete most, but leave enough to build external modules diff --git a/arch/alpha/include/asm/asm-offsets.h b/arch/alpha/include/asm/asm-offsets.h new file mode 100644 index 0000000..d370ee3 --- /dev/null +++ b/arch/alpha/include/asm/asm-offsets.h @@ -0,0 +1 @@ +#include diff --git a/arch/arm/include/asm/asm-offsets.h b/arch/arm/include/asm/asm-offsets.h new file mode 100644 index 0000000..d370ee3 --- /dev/null +++ b/arch/arm/include/asm/asm-offsets.h @@ -0,0 +1 @@ +#include diff --git a/arch/avr32/include/asm/asm-offsets.h b/arch/avr32/include/asm/asm-offsets.h new file mode 100644 index 0000000..d370ee3 --- /dev/null +++ b/arch/avr32/include/asm/asm-offsets.h @@ -0,0 +1 @@ +#include diff --git a/arch/blackfin/include/asm/asm-offsets.h b/arch/blackfin/include/asm/asm-offsets.h new file mode 100644 index 0000000..d370ee3 --- /dev/null +++ b/arch/blackfin/include/asm/asm-offsets.h @@ -0,0 +1 @@ +#include diff --git a/arch/cris/include/asm/asm-offsets.h b/arch/cris/include/asm/asm-offsets.h new file mode 100644 index 0000000..d370ee3 --- /dev/null +++ b/arch/cris/include/asm/asm-offsets.h @@ -0,0 +1 @@ +#include diff --git a/arch/frv/include/asm/asm-offsets.h b/arch/frv/include/asm/asm-offsets.h new file mode 100644 index 0000000..d370ee3 --- /dev/null +++ b/arch/frv/include/asm/asm-offsets.h @@ -0,0 +1 @@ +#include diff --git a/arch/h8300/include/asm/asm-offsets.h b/arch/h8300/include/asm/asm-offsets.h new file mode 100644 index 0000000..d370ee3 --- /dev/null +++ b/arch/h8300/include/asm/asm-offsets.h @@ -0,0 +1 @@ +#include diff --git a/arch/ia64/include/asm/asm-offsets.h b/arch/ia64/include/asm/asm-offsets.h new file mode 100644 index 0000000..d370ee3 --- /dev/null +++ b/arch/ia64/include/asm/asm-offsets.h @@ -0,0 +1 @@ +#include diff --git a/arch/m68k/include/asm/asm-offsets.h b/arch/m68k/include/asm/asm-offsets.h new file mode 100644 index 0000000..d370ee3 --- /dev/null +++ b/arch/m68k/include/asm/asm-offsets.h @@ -0,0 +1 @@ +#include diff --git a/arch/microblaze/include/asm/asm-offsets.h b/arch/microblaze/include/asm/asm-offsets.h new file mode 100644 index 0000000..d370ee3 --- /dev/null +++ b/arch/microblaze/include/asm/asm-offsets.h @@ -0,0 +1 @@ +#include diff --git a/arch/mips/include/asm/asm-offsets.h b/arch/mips/include/asm/asm-offsets.h new file mode 100644 index 0000000..d370ee3 --- /dev/null +++ b/arch/mips/include/asm/asm-offsets.h @@ -0,0 +1 @@ +#include diff --git a/arch/mn10300/include/asm/asm-offsets.h b/arch/mn10300/include/asm/asm-offsets.h new file mode 100644 index 0000000..d370ee3 --- /dev/null +++ b/arch/mn10300/include/asm/asm-offsets.h @@ -0,0 +1 @@ +#include diff --git a/arch/parisc/include/asm/asm-offsets.h b/arch/parisc/include/asm/asm-offsets.h new file mode 100644 index 0000000..d370ee3 --- /dev/null +++ b/arch/parisc/include/asm/asm-offsets.h @@ -0,0 +1 @@ +#include diff --git a/arch/powerpc/include/asm/asm-offsets.h b/arch/powerpc/include/asm/asm-offsets.h new file mode 100644 index 0000000..d370ee3 --- /dev/null +++ b/arch/powerpc/include/asm/asm-offsets.h @@ -0,0 +1 @@ +#include diff --git a/arch/s390/include/asm/asm-offsets.h b/arch/s390/include/asm/asm-offsets.h new file mode 100644 index 0000000..d370ee3 --- /dev/null +++ b/arch/s390/include/asm/asm-offsets.h @@ -0,0 +1 @@ +#include diff --git a/arch/sh/include/asm/asm-offsets.h b/arch/sh/include/asm/asm-offsets.h new file mode 100644 index 0000000..d370ee3 --- /dev/null +++ b/arch/sh/include/asm/asm-offsets.h @@ -0,0 +1 @@ +#include diff --git a/arch/sparc/include/asm/asm-offsets.h b/arch/sparc/include/asm/asm-offsets.h new file mode 100644 index 0000000..d370ee3 --- /dev/null +++ b/arch/sparc/include/asm/asm-offsets.h @@ -0,0 +1 @@ +#include diff --git a/arch/um/Makefile b/arch/um/Makefile index fc633db..fab8121 100644 --- a/arch/um/Makefile +++ b/arch/um/Makefile @@ -149,6 +149,6 @@ $(SHARED_HEADERS)/user_constants.h: $(ARCH_DIR)/sys-$(SUBARCH)/user-offsets.s $(SHARED_HEADERS)/kern_constants.h: $(Q)mkdir -p $(dir $@) - $(Q)echo '#include "../../../../include/asm/asm-offsets.h"' >$@ + $(Q)echo '#include "../../../../include/generated/asm-offsets.h"' >$@ export SUBARCH USER_CFLAGS CFLAGS_NO_HARDENING OS HEADER_ARCH DEV_NULL_PATH diff --git a/arch/um/include/asm/asm-offsets.h b/arch/um/include/asm/asm-offsets.h new file mode 100644 index 0000000..d370ee3 --- /dev/null +++ b/arch/um/include/asm/asm-offsets.h @@ -0,0 +1 @@ +#include diff --git a/arch/x86/include/asm/asm-offsets.h b/arch/x86/include/asm/asm-offsets.h new file mode 100644 index 0000000..d370ee3 --- /dev/null +++ b/arch/x86/include/asm/asm-offsets.h @@ -0,0 +1 @@ +#include diff --git a/arch/xtensa/include/asm/asm-offsets.h b/arch/xtensa/include/asm/asm-offsets.h new file mode 100644 index 0000000..d370ee3 --- /dev/null +++ b/arch/xtensa/include/asm/asm-offsets.h @@ -0,0 +1 @@ +#include -- cgit v0.10.2 From 4929d29c0dffd5fdc2df987254366c2e25c392d4 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Mon, 20 Apr 2009 19:35:54 +0200 Subject: ia64: move nr-irqs.h to include/generated Avoid generating files in the now deprecated asm-ia64 dir Simplified the logic in the Makefile when editing stuff in the area Signed-off-by: Sam Ravnborg Cc: Al Viro Cc: Tony Luck Cc: Fenghua Yu Signed-off-by: Michal Marek diff --git a/arch/ia64/Makefile b/arch/ia64/Makefile index e7cbaa0..475e272 100644 --- a/arch/ia64/Makefile +++ b/arch/ia64/Makefile @@ -103,4 +103,4 @@ archprepare: make_nr_irqs_h FORCE PHONY += make_nr_irqs_h FORCE make_nr_irqs_h: FORCE - $(Q)$(MAKE) $(build)=arch/ia64/kernel include/asm-ia64/nr-irqs.h + $(Q)$(MAKE) $(build)=arch/ia64/kernel include/generated/nr-irqs.h diff --git a/arch/ia64/include/asm/irq.h b/arch/ia64/include/asm/irq.h index 5282546..91b920fd 100644 --- a/arch/ia64/include/asm/irq.h +++ b/arch/ia64/include/asm/irq.h @@ -13,7 +13,7 @@ #include #include -#include +#include static __inline__ int irq_canonicalize (int irq) diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile index 6b7edca..2a75e93 100644 --- a/arch/ia64/kernel/Makefile +++ b/arch/ia64/kernel/Makefile @@ -81,17 +81,14 @@ define cmd_nr_irqs endef # We use internal kbuild rules to avoid the "is up to date" message from make -arch/$(SRCARCH)/kernel/nr-irqs.s: $(srctree)/arch/$(SRCARCH)/kernel/nr-irqs.c \ - $(wildcard $(srctree)/include/asm-ia64/*/irq.h) +arch/$(SRCARCH)/kernel/nr-irqs.s: arch/$(SRCARCH)/kernel/nr-irqs.c $(Q)mkdir -p $(dir $@) $(call if_changed_dep,cc_s_c) -include/asm-ia64/nr-irqs.h: arch/$(SRCARCH)/kernel/nr-irqs.s +include/generated/nr-irqs.h: arch/$(SRCARCH)/kernel/nr-irqs.s $(Q)mkdir -p $(dir $@) $(call cmd,nr_irqs) -clean-files += $(objtree)/include/asm-ia64/nr-irqs.h - # # native ivt.S, entry.S and fsys.S # -- cgit v0.10.2 From 66206536fe56e889a8bd86ab5742fc76c78c5b4a Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Mon, 20 Apr 2009 19:59:58 +0200 Subject: arm: move mach-types to include/generated Simplified arch/arm/Makefile by dropping the maketools target It was undocumented and not needed Signed-off-by: Sam Ravnborg Cc: Al Viro Cc: Russell King Signed-off-by: Michal Marek diff --git a/arch/arm/Makefile b/arch/arm/Makefile index fa0cdab..e9da084 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -242,15 +242,8 @@ all: $(KBUILD_IMAGE) boot := arch/arm/boot -# Update machine arch and proc symlinks if something which affects -# them changed. We use .arch to indicate when they were updated -# last, otherwise make uses the target directory mtime. - -archprepare: maketools - -PHONY += maketools FORCE -maketools: include/linux/version.h FORCE - $(Q)$(MAKE) $(build)=arch/arm/tools include/asm-arm/mach-types.h +archprepare: + $(Q)$(MAKE) $(build)=arch/arm/tools include/generated/mach-types.h # Convert bzImage to zImage bzImage: zImage @@ -261,9 +254,6 @@ zImage Image xipImage bootpImage uImage: vmlinux zinstall install: vmlinux $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@ -CLEAN_FILES += include/asm-arm/mach-types.h \ - include/asm-arm/arch include/asm-arm/.arch - # We use MRPROPER_FILES and CLEAN_FILES now archclean: $(Q)$(MAKE) $(clean)=$(boot) diff --git a/arch/arm/include/asm/mach-types.h b/arch/arm/include/asm/mach-types.h new file mode 100644 index 0000000..948178c --- /dev/null +++ b/arch/arm/include/asm/mach-types.h @@ -0,0 +1 @@ +#include diff --git a/arch/arm/tools/Makefile b/arch/arm/tools/Makefile index 1dbaa29..635cb18 100644 --- a/arch/arm/tools/Makefile +++ b/arch/arm/tools/Makefile @@ -4,7 +4,7 @@ # Copyright (C) 2001 Russell King # -include/asm-arm/mach-types.h: $(src)/gen-mach-types $(src)/mach-types +include/generated/mach-types.h: $(src)/gen-mach-types $(src)/mach-types @echo ' Generating $@' @mkdir -p $(dir $@) $(Q)$(AWK) -f $^ > $@ || { rm -f $@; /bin/false; } diff --git a/arch/arm/tools/gen-mach-types b/arch/arm/tools/gen-mach-types index ce319ef..04fef71 100644 --- a/arch/arm/tools/gen-mach-types +++ b/arch/arm/tools/gen-mach-types @@ -1,6 +1,6 @@ #!/bin/awk # -# Awk script to generate include/asm-arm/mach-types.h +# Awk script to generate include/generated/mach-types.h # BEGIN { nr = 0 } /^#/ { next } -- cgit v0.10.2 From 3252b11fc4790d046b93f300c898df2f7cd7c176 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 17 Oct 2009 22:20:22 +0200 Subject: sh: move machtypes.h to include/generated Signed-off-by: Sam Ravnborg Cc: Paul Mundt Cc: Al Viro Signed-off-by: Michal Marek diff --git a/arch/sh/Makefile b/arch/sh/Makefile index ac17c5a..db91925 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile @@ -205,10 +205,7 @@ libs-$(CONFIG_SUPERH64) := arch/sh/lib64/ $(libs-y) BOOT_TARGETS = uImage uImage.bz2 uImage.gz uImage.lzma uImage.srec uImage.bin \ zImage vmlinux.srec romImage -PHONY += maketools $(BOOT_TARGETS) FORCE - -maketools: include/linux/version.h FORCE - $(Q)$(MAKE) $(build)=arch/sh/tools include/asm-sh/machtypes.h +PHONY += $(BOOT_TARGETS) all: $(KBUILD_IMAGE) @@ -217,7 +214,8 @@ $(BOOT_TARGETS): vmlinux compressed: zImage -archprepare: maketools +archprepare: + $(Q)$(MAKE) $(build)=arch/sh/tools include/generated/machtypes.h archclean: $(Q)$(MAKE) $(clean)=$(boot) @@ -234,5 +232,3 @@ define archhelp @echo ' uImage.bz2 - Kernel-only image for U-Boot (bzip2)' @echo ' uImage.lzma - Kernel-only image for U-Boot (lzma)' endef - -CLEAN_FILES += include/asm-sh/machtypes.h diff --git a/arch/sh/drivers/pci/fixups-rts7751r2d.c b/arch/sh/drivers/pci/fixups-rts7751r2d.c index 052b354..7898f14 100644 --- a/arch/sh/drivers/pci/fixups-rts7751r2d.c +++ b/arch/sh/drivers/pci/fixups-rts7751r2d.c @@ -15,7 +15,7 @@ #include #include #include "pci-sh4.h" -#include +#include #define PCIMCR_MRSET_OFF 0xBFFFFFFF #define PCIMCR_RFSH_OFF 0xFFFFFFFB diff --git a/arch/sh/include/asm/.gitignore b/arch/sh/include/asm/.gitignore deleted file mode 100644 index 378db77..0000000 --- a/arch/sh/include/asm/.gitignore +++ /dev/null @@ -1 +0,0 @@ -machtypes.h diff --git a/arch/sh/include/asm/machvec.h b/arch/sh/include/asm/machvec.h index 84dd377..9c30955 100644 --- a/arch/sh/include/asm/machvec.h +++ b/arch/sh/include/asm/machvec.h @@ -12,7 +12,7 @@ #include #include -#include +#include struct sh_machine_vector { void (*mv_setup)(char **cmdline_p); diff --git a/arch/sh/tools/Makefile b/arch/sh/tools/Makefile index 567516b..558a56b 100644 --- a/arch/sh/tools/Makefile +++ b/arch/sh/tools/Makefile @@ -10,7 +10,7 @@ # Shamelessly cloned from ARM. # -include/asm-sh/machtypes.h: $(src)/gen-mach-types $(src)/mach-types +include/generated/machtypes.h: $(src)/gen-mach-types $(src)/mach-types @echo ' Generating $@' - $(Q)if [ ! -d include/asm-sh ]; then mkdir -p include/asm-sh; fi + $(Q)mkdir -p $(dir $@) $(Q)$(AWK) -f $^ > $@ || { rm -f $@; /bin/false; } diff --git a/arch/sh/tools/gen-mach-types b/arch/sh/tools/gen-mach-types index 65161e3..f5ff7c5 100644 --- a/arch/sh/tools/gen-mach-types +++ b/arch/sh/tools/gen-mach-types @@ -1,6 +1,6 @@ #!/bin/awk # -# Awk script to generate include/asm-sh/machtypes.h +# Awk script to generate include/generated/machtypes.h # Heavily based on arch/arm/tools/gen-mach-types # BEGIN { nr = 0 } -- cgit v0.10.2 From 96f13045b6cb0c562bf3ffd3844871811e677e63 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 17 Oct 2009 22:33:27 +0200 Subject: kbuild: drop include2/ used for O=... builds There is no longer any use of the include2/ directory. The generated files has moved to include/generated. Drop all references to said directory. Signed-off-by: Sam Ravnborg Signed-off-by: Michal Marek diff --git a/Makefile b/Makefile index eb43b9f..b9d747e 100644 --- a/Makefile +++ b/Makefile @@ -335,7 +335,7 @@ CFLAGS_GCOV = -fprofile-arcs -ftest-coverage # Use LINUXINCLUDE when you must reference the include/ directory. # Needed to be compatible with the O= option LINUXINCLUDE := -I$(srctree)/arch/$(hdr-arch)/include -Iinclude \ - $(if $(KBUILD_SRC),-Iinclude2 -I$(srctree)/include) \ + $(if $(KBUILD_SRC), -I$(srctree)/include) \ -include include/linux/autoconf.h KBUILD_CPPFLAGS := -D__KERNEL__ @@ -954,7 +954,6 @@ PHONY += prepare archprepare prepare0 prepare1 prepare2 prepare3 # prepare3 is used to check if we are building in a separate output directory, # and if so do: # 1) Check that make has not been executed in the kernel src $(srctree) -# 2) Create the include2 directory, used for the second asm symlink prepare3: include/config/kernel.release ifneq ($(KBUILD_SRC),) @$(kecho) ' Using $(srctree) as source for kernel' @@ -963,10 +962,6 @@ ifneq ($(KBUILD_SRC),) echo " in the '$(srctree)' directory.";\ /bin/false; \ fi; - $(Q)if [ ! -d include2 ]; then \ - mkdir -p include2; \ - ln -fsn $(srctree)/include/asm-$(SRCARCH) include2/asm; \ - fi endif # prepare2 creates a makefile if using a separate output directory @@ -1193,7 +1188,7 @@ CLEAN_FILES += vmlinux System.map \ .tmp_kallsyms* .tmp_version .tmp_vmlinux* .tmp_System.map # Directories & files removed with 'make mrproper' -MRPROPER_DIRS += include/config include2 usr/include include/generated +MRPROPER_DIRS += include/config usr/include include/generated MRPROPER_FILES += .config .config.old include/asm .version .old_version \ include/linux/autoconf.h include/linux/version.h \ include/linux/utsrelease.h \ diff --git a/arch/powerpc/platforms/cell/spufs/Makefile b/arch/powerpc/platforms/cell/spufs/Makefile index b93f877..b9d5d67 100644 --- a/arch/powerpc/platforms/cell/spufs/Makefile +++ b/arch/powerpc/platforms/cell/spufs/Makefile @@ -13,10 +13,8 @@ SPU_CC := $(SPU_CROSS)gcc SPU_AS := $(SPU_CROSS)gcc SPU_LD := $(SPU_CROSS)ld SPU_OBJCOPY := $(SPU_CROSS)objcopy -SPU_CFLAGS := -O2 -Wall -I$(srctree)/include \ - -I$(objtree)/include2 -D__KERNEL__ -SPU_AFLAGS := -c -D__ASSEMBLY__ -I$(srctree)/include \ - -I$(objtree)/include2 -D__KERNEL__ +SPU_CFLAGS := -O2 -Wall -I$(srctree)/include -D__KERNEL__ +SPU_AFLAGS := -c -D__ASSEMBLY__ -I$(srctree)/include -D__KERNEL__ SPU_LDFLAGS := -N -Ttext=0x0 $(obj)/switch.o: $(obj)/spu_save_dump.h $(obj)/spu_restore_dump.h -- cgit v0.10.2 From c95fa08a3e17c3f2983c4cbf409f5c9ae47b7dec Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 17 Oct 2009 22:47:31 +0200 Subject: kbuild: do not check for include/asm-$ARCH No architectures uses include/asm-$ARCH now. So drop check for location of include files Signed-off-by: Sam Ravnborg Signed-off-by: Michal Marek diff --git a/Makefile b/Makefile index b9d747e..924c62e 100644 --- a/Makefile +++ b/Makefile @@ -1070,11 +1070,6 @@ firmware_install: FORCE export INSTALL_HDR_PATH = $(objtree)/usr hdr-inst := -rR -f $(srctree)/scripts/Makefile.headersinst obj -# Find out where the Kbuild file is located to support -# arch/$(ARCH)/include/asm -hdr-dir = $(strip \ - $(if $(wildcard $(srctree)/arch/$(hdr-arch)/include/asm/Kbuild), \ - arch/$(hdr-arch)/include/asm, include/asm-$(hdr-arch))) # If we do an all arch process set dst to asm-$(hdr-arch) hdr-dst = $(if $(KBUILD_HEADERS), dst=include/asm-$(hdr-arch), dst=include/asm) @@ -1089,10 +1084,10 @@ headers_install_all: PHONY += headers_install headers_install: __headers - $(if $(wildcard $(srctree)/$(hdr-dir)/Kbuild),, \ + $(if $(wildcard $(srctree)/arch/$(hdr-arch)/include/asm/Kbuild),, \ $(error Headers not exportable for the $(SRCARCH) architecture)) $(Q)$(MAKE) $(hdr-inst)=include - $(Q)$(MAKE) $(hdr-inst)=$(hdr-dir) $(hdr-dst) + $(Q)$(MAKE) $(hdr-inst)=arch/$(hdr-arch)/include/asm $(hdr-dst) PHONY += headers_check_all headers_check_all: headers_install_all @@ -1101,7 +1096,7 @@ headers_check_all: headers_install_all PHONY += headers_check headers_check: headers_install $(Q)$(MAKE) $(hdr-inst)=include HDRCHECK=1 - $(Q)$(MAKE) $(hdr-inst)=$(hdr-dir) $(hdr-dst) HDRCHECK=1 + $(Q)$(MAKE) $(hdr-inst)=arch/$(hdr-arch)/include/asm $(hdr-dst) HDRCHECK=1 # --------------------------------------------------------------------------- # Modules diff --git a/scripts/headers.sh b/scripts/headers.sh index 0308ecc..1ddcdd3 100755 --- a/scripts/headers.sh +++ b/scripts/headers.sh @@ -8,8 +8,6 @@ do_command() { if [ -f ${srctree}/arch/$2/include/asm/Kbuild ]; then make ARCH=$2 KBUILD_HEADERS=$1 headers_$1 - elif [ -f ${srctree}/include/asm-$2/Kbuild ]; then - make ARCH=$2 KBUILD_HEADERS=$1 headers_$1 else printf "Ignoring arch: %s\n" ${arch} fi -- cgit v0.10.2 From f7f16b7799ed68654850ab340ef812895aebcf4c Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sun, 18 Oct 2009 00:00:43 +0200 Subject: kbuild: drop include/asm We no longer use this directory for generated files and all architectures has moved their header files so no symlink tricks are needed either. Drop the symlink and drop the ARCH check. If we really need to check that the SRCARCH has not changed when we build a kernel we can add this check back - but then we will find a more convenient way to store the info. Signed-off-by: Sam Ravnborg Signed-off-by: Michal Marek diff --git a/.gitignore b/.gitignore index 3582f422..e074c1c 100644 --- a/.gitignore +++ b/.gitignore @@ -45,7 +45,6 @@ Module.symvers # # Generated include files # -include/asm include/config include/linux/autoconf.h include/linux/compile.h diff --git a/Makefile b/Makefile index 924c62e..86b66cf 100644 --- a/Makefile +++ b/Makefile @@ -968,7 +968,7 @@ endif prepare2: prepare3 outputmakefile prepare1: prepare2 include/linux/version.h include/linux/utsrelease.h \ - include/asm include/config/auto.conf + include/config/auto.conf $(cmd_crmodverdir) archprepare: prepare1 scripts_basic @@ -980,42 +980,6 @@ prepare0: archprepare FORCE # All the preparing.. prepare: prepare0 -# The asm symlink changes when $(ARCH) changes. -# Detect this and ask user to run make mrproper -# If asm is a stale symlink (point to dir that does not exist) remove it -define check-symlink - set -e; \ - if [ -L include/asm ]; then \ - asmlink=`readlink include/asm | cut -d '-' -f 2`; \ - if [ "$$asmlink" != "$(SRCARCH)" ]; then \ - echo "ERROR: the symlink $@ points to asm-$$asmlink but asm-$(SRCARCH) was expected"; \ - echo " set ARCH or save .config and run 'make mrproper' to fix it"; \ - exit 1; \ - fi; \ - test -e $$asmlink || rm include/asm; \ - elif [ -d include/asm ]; then \ - echo "ERROR: $@ is a directory but a symlink was expected";\ - exit 1; \ - fi -endef - -# We create the target directory of the symlink if it does -# not exist so the test in check-symlink works and we have a -# directory for generated filesas used by some architectures. -define create-symlink - if [ ! -L include/asm ]; then \ - $(kecho) ' SYMLINK $@ -> include/asm-$(SRCARCH)'; \ - if [ ! -d include/asm-$(SRCARCH) ]; then \ - mkdir -p include/asm-$(SRCARCH); \ - fi; \ - ln -fsn asm-$(SRCARCH) $@; \ - fi -endef - -include/asm: FORCE - $(Q)$(check-symlink) - $(Q)$(create-symlink) - # Generate some files # --------------------------------------------------------------------------- @@ -1184,7 +1148,7 @@ CLEAN_FILES += vmlinux System.map \ # Directories & files removed with 'make mrproper' MRPROPER_DIRS += include/config usr/include include/generated -MRPROPER_FILES += .config .config.old include/asm .version .old_version \ +MRPROPER_FILES += .config .config.old .version .old_version \ include/linux/autoconf.h include/linux/version.h \ include/linux/utsrelease.h \ Module.symvers Module.markers tags TAGS cscope* -- cgit v0.10.2 From 92045954058671fdd0ccf031ca06611ce1d929d1 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sun, 18 Oct 2009 00:36:47 +0200 Subject: kbuild: move compile.h to include/generated Signed-off-by: Sam Ravnborg Signed-off-by: Michal Marek diff --git a/.gitignore b/.gitignore index e074c1c..c06b4c9 100644 --- a/.gitignore +++ b/.gitignore @@ -47,7 +47,6 @@ Module.symvers # include/config include/linux/autoconf.h -include/linux/compile.h include/linux/version.h include/linux/utsrelease.h include/generated diff --git a/arch/x86/boot/version.c b/arch/x86/boot/version.c index 2723d9b..4d88763 100644 --- a/arch/x86/boot/version.c +++ b/arch/x86/boot/version.c @@ -14,7 +14,7 @@ #include "boot.h" #include -#include +#include const char kernel_version[] = UTS_RELEASE " (" LINUX_COMPILE_BY "@" LINUX_COMPILE_HOST ") " diff --git a/init/Makefile b/init/Makefile index 4a243df..0bf677a 100644 --- a/init/Makefile +++ b/init/Makefile @@ -15,12 +15,8 @@ mounts-$(CONFIG_BLK_DEV_RAM) += do_mounts_rd.o mounts-$(CONFIG_BLK_DEV_INITRD) += do_mounts_initrd.o mounts-$(CONFIG_BLK_DEV_MD) += do_mounts_md.o -# files to be removed upon make clean -clean-files := ../include/linux/compile.h - # dependencies on generated files need to be listed explicitly - -$(obj)/version.o: include/linux/compile.h +$(obj)/version.o: include/generated/compile.h # compile.h changes depending on hostname, generation number, etc, # so we regenerate it always. @@ -30,7 +26,7 @@ $(obj)/version.o: include/linux/compile.h chk_compile.h = : quiet_chk_compile.h = echo ' CHK $@' silent_chk_compile.h = : -include/linux/compile.h: FORCE +include/generated/compile.h: FORCE @$($(quiet)chk_compile.h) $(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkcompile_h $@ \ "$(UTS_MACHINE)" "$(CONFIG_SMP)" "$(CONFIG_PREEMPT)" "$(CC) $(KBUILD_CFLAGS)" diff --git a/init/version.c b/init/version.c index 52a8b98..82328aa 100644 --- a/init/version.c +++ b/init/version.c @@ -6,7 +6,7 @@ * May be freely distributed as part of Linux. */ -#include +#include #include #include #include -- cgit v0.10.2 From 98b8788ae91694499d1995035625bea16a4db0c4 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sun, 18 Oct 2009 00:39:40 +0200 Subject: drop explicit include of autoconf.h kbuild.h forces include of autoconf.h on the commandline using -include - so we do not need to include the file explicit. Signed-off-by: Sam Ravnborg Signed-off-by: Michal Marek diff --git a/arch/cris/arch-v32/kernel/head.S b/arch/cris/arch-v32/kernel/head.S index 3db478e..76266f8 100644 --- a/arch/cris/arch-v32/kernel/head.S +++ b/arch/cris/arch-v32/kernel/head.S @@ -10,7 +10,6 @@ * The macros found in mmu_defs_asm.h uses the ## concatenation operator, so * -traditional must not be used when assembling this file. */ -#include #include #include #include diff --git a/arch/cris/kernel/asm-offsets.c b/arch/cris/kernel/asm-offsets.c index ddd6fbb..dd7b8e9 100644 --- a/arch/cris/kernel/asm-offsets.c +++ b/arch/cris/kernel/asm-offsets.c @@ -1,6 +1,5 @@ #include #include -#include /* * Generate definitions needed by assembly language modules. diff --git a/arch/cris/kernel/vmlinux.lds.S b/arch/cris/kernel/vmlinux.lds.S index bbfda67..d49d17d2 100644 --- a/arch/cris/kernel/vmlinux.lds.S +++ b/arch/cris/kernel/vmlinux.lds.S @@ -8,7 +8,6 @@ * the kernel has booted. */ -#include #include #include diff --git a/arch/ia64/kvm/asm-offsets.c b/arch/ia64/kvm/asm-offsets.c index 0c3564a..9324c87 100644 --- a/arch/ia64/kvm/asm-offsets.c +++ b/arch/ia64/kvm/asm-offsets.c @@ -22,7 +22,6 @@ * */ -#include #include #include diff --git a/drivers/accessibility/braille/braille_console.c b/drivers/accessibility/braille/braille_console.c index d672cfe..cb423f5 100644 --- a/drivers/accessibility/braille/braille_console.c +++ b/drivers/accessibility/braille/braille_console.c @@ -21,7 +21,6 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include #include #include #include diff --git a/drivers/hid/hid-lg.h b/drivers/hid/hid-lg.h index 27ae750..bf31592 100644 --- a/drivers/hid/hid-lg.h +++ b/drivers/hid/hid-lg.h @@ -1,8 +1,6 @@ #ifndef __HID_LG_H #define __HID_LG_H -#include - #ifdef CONFIG_LOGITECH_FF int lgff_init(struct hid_device *hdev); #else diff --git a/drivers/platform/x86/compal-laptop.c b/drivers/platform/x86/compal-laptop.c index 11003bb..1a387e7 100644 --- a/drivers/platform/x86/compal-laptop.c +++ b/drivers/platform/x86/compal-laptop.c @@ -51,7 +51,6 @@ #include #include #include -#include #define COMPAL_DRIVER_VERSION "0.2.6" diff --git a/drivers/staging/iio/ring_sw.h b/drivers/staging/iio/ring_sw.h index f0b86f0..fd677f0 100644 --- a/drivers/staging/iio/ring_sw.h +++ b/drivers/staging/iio/ring_sw.h @@ -29,7 +29,6 @@ * driver requests - some may support multiple options */ -#include #include "iio.h" #include "ring_generic.h" diff --git a/include/linux/mmdebug.h b/include/linux/mmdebug.h index 8a55098..ee24ef8 100644 --- a/include/linux/mmdebug.h +++ b/include/linux/mmdebug.h @@ -1,8 +1,6 @@ #ifndef LINUX_MM_DEBUG_H #define LINUX_MM_DEBUG_H 1 -#include - #ifdef CONFIG_DEBUG_VM #define VM_BUG_ON(cond) BUG_ON(cond) #else -- cgit v0.10.2 From 264a26838056fc2d759f58bec2e720e01fcb1bdb Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sun, 18 Oct 2009 00:49:24 +0200 Subject: kbuild: move autoconf.h to include/generated Signed-off-by: Sam Ravnborg Signed-off-by: Michal Marek diff --git a/.gitignore b/.gitignore index c06b4c9..c6c19ea 100644 --- a/.gitignore +++ b/.gitignore @@ -46,7 +46,6 @@ Module.symvers # Generated include files # include/config -include/linux/autoconf.h include/linux/version.h include/linux/utsrelease.h include/generated diff --git a/Documentation/kbuild/kconfig.txt b/Documentation/kbuild/kconfig.txt index 849b5e5..ab8dc35 100644 --- a/Documentation/kbuild/kconfig.txt +++ b/Documentation/kbuild/kconfig.txt @@ -106,7 +106,8 @@ This environment variable can be set to specify the path & name of the KCONFIG_AUTOHEADER -------------------------------------------------- This environment variable can be set to specify the path & name of the -"autoconf.h" (header) file. Its default value is "include/linux/autoconf.h". +"autoconf.h" (header) file. +Its default value is "include/generated/autoconf.h". ====================================================================== diff --git a/Makefile b/Makefile index 86b66cf..3bdd932 100644 --- a/Makefile +++ b/Makefile @@ -336,7 +336,7 @@ CFLAGS_GCOV = -fprofile-arcs -ftest-coverage # Needed to be compatible with the O= option LINUXINCLUDE := -I$(srctree)/arch/$(hdr-arch)/include -Iinclude \ $(if $(KBUILD_SRC), -I$(srctree)/include) \ - -include include/linux/autoconf.h + -include include/generated/autoconf.h KBUILD_CPPFLAGS := -D__KERNEL__ @@ -492,17 +492,18 @@ $(KCONFIG_CONFIG) include/config/auto.conf.cmd: ; # if auto.conf.cmd is missing then we are probably in a cleaned tree so # we execute the config step to be sure to catch updated Kconfig files include/config/auto.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd + $(Q)mkdir -p include/generated $(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig else -# external modules needs include/linux/autoconf.h and include/config/auto.conf +# external modules needs include/generated/autoconf.h and include/config/auto.conf # but do not care if they are up-to-date. Use auto.conf to trigger the test PHONY += include/config/auto.conf include/config/auto.conf: - $(Q)test -e include/linux/autoconf.h -a -e $@ || ( \ + $(Q)test -e include/generated/autoconf.h -a -e $@ || ( \ echo; \ echo " ERROR: Kernel configuration is invalid."; \ - echo " include/linux/autoconf.h or $@ are missing."; \ + echo " include/generated/autoconf.h or $@ are missing.";\ echo " Run 'make oldconfig && make prepare' on kernel src to fix it."; \ echo; \ /bin/false) @@ -1149,7 +1150,7 @@ CLEAN_FILES += vmlinux System.map \ # Directories & files removed with 'make mrproper' MRPROPER_DIRS += include/config usr/include include/generated MRPROPER_FILES += .config .config.old .version .old_version \ - include/linux/autoconf.h include/linux/version.h \ + include/linux/version.h \ include/linux/utsrelease.h \ Module.symvers Module.markers tags TAGS cscope* diff --git a/arch/m68k/kernel/head.S b/arch/m68k/kernel/head.S index 86edb5f..ef54128 100644 --- a/arch/m68k/kernel/head.S +++ b/arch/m68k/kernel/head.S @@ -196,7 +196,7 @@ * for them and trying to understand what they mean. * * CONFIG_xxx: These are the obvious machine configuration defines created - * during configuration. These are defined in include/linux/autoconf.h. + * during configuration. These are defined in autoconf.h. * * CONSOLE: There is support for head.S console in this file. This * console can talk to a Mac frame buffer, but could easily be extrapolated diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c index 6bf21f8..ea26b23 100644 --- a/scripts/basic/fixdep.c +++ b/scripts/basic/fixdep.c @@ -16,15 +16,15 @@ * tells make when to remake a file. * * To use this list as-is however has the drawback that virtually - * every file in the kernel includes . + * every file in the kernel includes autoconf.h. * - * If the user re-runs make *config, linux/autoconf.h will be + * If the user re-runs make *config, autoconf.h will be * regenerated. make notices that and will rebuild every file which * includes autoconf.h, i.e. basically all files. This is extremely * annoying if the user just changed CONFIG_HIS_DRIVER from n to m. * * So we play the same trick that "mkdep" played before. We replace - * the dependency on linux/autoconf.h by a dependency on every config + * the dependency on autoconf.h by a dependency on every config * option which is mentioned in any of the listed prequisites. * * kconfig populates a tree in include/config/ with an empty file @@ -73,7 +73,7 @@ * cmd_ = * * and then basically copies the ..d file to stdout, in the - * process filtering out the dependency on linux/autoconf.h and adding + * process filtering out the dependency on autoconf.h and adding * dependencies on include/config/my/option.h for every * CONFIG_MY_OPTION encountered in any of the prequisites. * @@ -324,7 +324,7 @@ static void parse_dep_file(void *map, size_t len) p++; } memcpy(s, m, p-m); s[p-m] = 0; - if (strrcmp(s, "include/linux/autoconf.h") && + if (strrcmp(s, "include/generated/autoconf.h") && strrcmp(s, "arch/um/include/uml-config.h") && strrcmp(s, ".ver")) { printf(" %s \\\n", s); diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index b55e72f..797a741 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -776,7 +776,7 @@ int conf_write_autoconf(void) name = getenv("KCONFIG_AUTOHEADER"); if (!name) - name = "include/linux/autoconf.h"; + name = "include/generated/autoconf.h"; if (rename(".tmpconfig.h", name)) return 1; name = conf_get_autoconfig_name(); diff --git a/scripts/mkcompile_h b/scripts/mkcompile_h index bce3d0f..23dbad8 100755 --- a/scripts/mkcompile_h +++ b/scripts/mkcompile_h @@ -14,7 +14,7 @@ vecho() { [ "${quiet}" = "silent_" ] || echo "$@" ; } # So "sudo make install" won't change the "compiled by " # do "compiled by root" -if [ -r $TARGET -a ! -O include/linux/autoconf.h ]; then +if [ -r $TARGET -a ! -O include/generated/autoconf.h ]; then vecho " SKIPPED $TARGET" exit 0 fi -- cgit v0.10.2 From 273b281fa22c293963ee3e6eec418f5dda2dbc83 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sun, 18 Oct 2009 00:52:28 +0200 Subject: kbuild: move utsrelease.h to include/generated Fix up all users of utsrelease.h Signed-off-by: Sam Ravnborg Signed-off-by: Michal Marek diff --git a/.gitignore b/.gitignore index c6c19ea..002d530 100644 --- a/.gitignore +++ b/.gitignore @@ -47,7 +47,6 @@ Module.symvers # include/config include/linux/version.h -include/linux/utsrelease.h include/generated # stgit generated dirs diff --git a/Makefile b/Makefile index 3bdd932..860224d 100644 --- a/Makefile +++ b/Makefile @@ -968,7 +968,7 @@ endif # prepare2 creates a makefile if using a separate output directory prepare2: prepare3 outputmakefile -prepare1: prepare2 include/linux/version.h include/linux/utsrelease.h \ +prepare1: prepare2 include/linux/version.h include/generated/utsrelease.h \ include/config/auto.conf $(cmd_crmodverdir) @@ -1005,7 +1005,7 @@ endef include/linux/version.h: $(srctree)/Makefile FORCE $(call filechk,version.h) -include/linux/utsrelease.h: include/config/kernel.release FORCE +include/generated/utsrelease.h: include/config/kernel.release FORCE $(call filechk,utsrelease.h) PHONY += headerdep @@ -1151,7 +1151,6 @@ CLEAN_FILES += vmlinux System.map \ MRPROPER_DIRS += include/config usr/include include/generated MRPROPER_FILES += .config .config.old .version .old_version \ include/linux/version.h \ - include/linux/utsrelease.h \ Module.symvers Module.markers tags TAGS cscope* # clean - Delete most, but leave enough to build external modules diff --git a/arch/alpha/boot/bootp.c b/arch/alpha/boot/bootp.c index 3af21c7..3c8d1b2 100644 --- a/arch/alpha/boot/bootp.c +++ b/arch/alpha/boot/bootp.c @@ -9,7 +9,7 @@ */ #include #include -#include +#include #include #include diff --git a/arch/alpha/boot/bootpz.c b/arch/alpha/boot/bootpz.c index 1036b51..ade3f12 100644 --- a/arch/alpha/boot/bootpz.c +++ b/arch/alpha/boot/bootpz.c @@ -11,7 +11,7 @@ */ #include #include -#include +#include #include #include diff --git a/arch/alpha/boot/main.c b/arch/alpha/boot/main.c index 89f3be0..644b7db 100644 --- a/arch/alpha/boot/main.c +++ b/arch/alpha/boot/main.c @@ -7,7 +7,7 @@ */ #include #include -#include +#include #include #include diff --git a/arch/frv/kernel/setup.c b/arch/frv/kernel/setup.c index 55e4fab..75cf7f4 100644 --- a/arch/frv/kernel/setup.c +++ b/arch/frv/kernel/setup.c @@ -10,7 +10,7 @@ * 2 of the License, or (at your option) any later version. */ -#include +#include #include #include #include diff --git a/arch/powerpc/platforms/52xx/efika.c b/arch/powerpc/platforms/52xx/efika.c index bcc69e1..45c0cb9 100644 --- a/arch/powerpc/platforms/52xx/efika.c +++ b/arch/powerpc/platforms/52xx/efika.c @@ -10,7 +10,7 @@ */ #include -#include +#include #include #include #include diff --git a/arch/powerpc/platforms/amigaone/setup.c b/arch/powerpc/platforms/amigaone/setup.c index 9290a7a..fb4eb0d 100644 --- a/arch/powerpc/platforms/amigaone/setup.c +++ b/arch/powerpc/platforms/amigaone/setup.c @@ -14,7 +14,7 @@ #include #include -#include +#include #include #include diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c index cd4ad9a..0a6f5ab 100644 --- a/arch/powerpc/platforms/chrp/setup.c +++ b/arch/powerpc/platforms/chrp/setup.c @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/powerpc/platforms/powermac/bootx_init.c b/arch/powerpc/platforms/powermac/bootx_init.c index cf66091..9dd789a 100644 --- a/arch/powerpc/platforms/powermac/bootx_init.c +++ b/arch/powerpc/platforms/powermac/bootx_init.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S index b31cc54..93e689f4 100644 --- a/arch/x86/boot/header.S +++ b/arch/x86/boot/header.S @@ -16,7 +16,7 @@ */ #include -#include +#include #include #include #include diff --git a/arch/x86/boot/version.c b/arch/x86/boot/version.c index 4d88763..2b15aa4 100644 --- a/arch/x86/boot/version.c +++ b/arch/x86/boot/version.c @@ -13,7 +13,7 @@ */ #include "boot.h" -#include +#include #include const char kernel_version[] = diff --git a/drivers/staging/panel/panel.c b/drivers/staging/panel/panel.c index 4ce399b..f98a524 100644 --- a/drivers/staging/panel/panel.c +++ b/drivers/staging/panel/panel.c @@ -55,7 +55,7 @@ #include #include #include -#include +#include #include #include diff --git a/include/linux/vermagic.h b/include/linux/vermagic.h index 79b9837..cf97b5b 100644 --- a/include/linux/vermagic.h +++ b/include/linux/vermagic.h @@ -1,4 +1,4 @@ -#include +#include #include /* Simply sanity version stamp for modules. */ diff --git a/init/version.c b/init/version.c index 82328aa..adff586 100644 --- a/init/version.c +++ b/init/version.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #ifndef CONFIG_KALLSYMS diff --git a/kernel/kexec.c b/kernel/kexec.c index f336e21..83f54e2 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 88bd9ae..bfb1b64 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -12,7 +12,7 @@ * Copyright (C) 2004 William Lee Irwin III */ #include -#include +#include #include #include #include -- cgit v0.10.2 From 7a77080dbec28ab2bceb422398601dcc53c142ad Mon Sep 17 00:00:00 2001 From: Jie Zhang Date: Thu, 12 Nov 2009 17:59:56 +0800 Subject: net: add net_tstamp.h to headers_install include/linux/net_tstamp.h is userspace API for hardware time stamping of network packets. It should be exported to userspace. Signed-off-by: Jie Zhang Signed-off-by: Barry Song Signed-off-by: Patrick Ohly Signed-off-by: Michal Marek diff --git a/include/linux/Kbuild b/include/linux/Kbuild index f72914d..756f831 100644 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild @@ -118,6 +118,7 @@ header-y += mtio.h header-y += ncp_no.h header-y += neighbour.h header-y += net_dropmon.h +header-y += net_tstamp.h header-y += netfilter_arp.h header-y += netrom.h header-y += nfs2.h -- cgit v0.10.2 From 8723eaeff59a5146326288392f08be4c894fdad7 Mon Sep 17 00:00:00 2001 From: Wenji Huang Date: Thu, 19 Nov 2009 08:44:32 +0800 Subject: Kbuild: clean up marker Drop Module.markers from cleaning list since marker is removed. Signed-off-by: Wenji Huang Signed-off-by: Michal Marek diff --git a/Makefile b/Makefile index 860224d..96b32e5 100644 --- a/Makefile +++ b/Makefile @@ -1151,7 +1151,7 @@ CLEAN_FILES += vmlinux System.map \ MRPROPER_DIRS += include/config usr/include include/generated MRPROPER_FILES += .config .config.old .version .old_version \ include/linux/version.h \ - Module.symvers Module.markers tags TAGS cscope* + Module.symvers tags TAGS cscope* # clean - Delete most, but leave enough to build external modules # @@ -1170,7 +1170,7 @@ clean: archclean $(clean-dirs) \( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \ -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \ -o -name '*.symtypes' -o -name 'modules.order' \ - -o -name 'Module.markers' -o -name '.tmp_*.o.*' \ + -o -name '.tmp_*.o.*' \ -o -name '*.gcno' \) -type f -print | xargs rm -f # mrproper - Delete all generated files, including .config @@ -1368,7 +1368,6 @@ $(clean-dirs): clean: rm-dirs := $(MODVERDIR) clean: rm-files := $(KBUILD_EXTMOD)/Module.symvers \ - $(KBUILD_EXTMOD)/Module.markers \ $(KBUILD_EXTMOD)/modules.order clean: $(clean-dirs) $(call cmd,rmdirs) -- cgit v0.10.2 From 91d161857ce9672bd2a8cd99ff712a67186e2e76 Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Tue, 24 Nov 2009 09:11:37 -0600 Subject: scripts/package: tar-pkg: use tar --owner=root Use the --owner= and --group= options to make sure the entries in the built tar file are owned by root. Without this change, a careless sysadmin using the tar-pkg target can easily end up installing a kernel that is writable by the unprivileged user account used to build the kernel. Test that these options are understood before using them so that non-GNU versions of tar can still be used if the operator is appropriately cautious. Signed-off-by: Jonathan Nieder Signed-off-by: Michal Marek diff --git a/scripts/package/buildtar b/scripts/package/buildtar index b1fd48d..51b2aa0 100644 --- a/scripts/package/buildtar +++ b/scripts/package/buildtar @@ -101,7 +101,11 @@ esac # ( cd "${tmpdir}" - tar cf - . | ${compress} > "${tarball}${file_ext}" + opts= + if tar --owner=root --group=root --help >/dev/null 2>&1; then + opts="--owner=root --group=root" + fi + tar cf - . $opts | ${compress} > "${tarball}${file_ext}" ) echo "Tarball successfully created in ${tarball}${file_ext}" -- cgit v0.10.2 From 05ba4488a51edde95df3f89987fdcdbca7c3cebb Mon Sep 17 00:00:00 2001 From: Jonathan Nieder Date: Tue, 24 Nov 2009 09:14:41 -0600 Subject: scripts/package: add KBUILD_PKG_ROOTCMD variable Let the deb-pkg target acquire (fake) root privileges before running commands that need them. Without such privileges, deb-pkg errors out because chown fails. The new KBUILD_PKG_ROOTCMD variable, if defined, is used as a command to run other commands with possibly fake elevated privileges. Since this is not needed for the tar-pkg and rpm-pkg targets, it is only used by deb-pkg. If it is not defined, the behavior is as before, and the user will have to rerun make as root. In other words, as a shortcut, instead of running 'make oldconfig && make && fakeroot -u make deb-pkg', one can use the single command 'make oldconfig deb-pkg KBUILD_PKG_ROOTCMD="fakeroot -u"'. Suggested-by: Ryan Anderson Signed-off-by: Jonathan Nieder Signed-off-by: Michal Marek diff --git a/scripts/package/Makefile b/scripts/package/Makefile index f67cc88..5c0b43a 100644 --- a/scripts/package/Makefile +++ b/scripts/package/Makefile @@ -79,7 +79,8 @@ clean-files += $(objtree)/binkernel.spec # --------------------------------------------------------------------------- deb-pkg: FORCE $(MAKE) KBUILD_SRC= - $(CONFIG_SHELL) $(srctree)/scripts/package/builddeb + $(KBUILD_PKG_ROOTCMD) $(CONFIG_SHELL) \ + $(srctree)/scripts/package/builddeb clean-dirs += $(objtree)/debian/ -- cgit v0.10.2 From db1d18657c96cc675596077cb60ef50fbe1947f8 Mon Sep 17 00:00:00 2001 From: Jonathan Nieder Date: Tue, 24 Nov 2009 09:21:56 -0600 Subject: scripts/package: deb-pkg: use fakeroot if available Running "make deb-pkg" requires setting KBUILD_PKG_ROOTCMD or becoming root oneself or it errors out. Unless already running as root or KBUILD_PKG_ROOTCMD is already set, use fakeroot as a good default. With this patch applied, you can run "make oldconfig deb-pkg" as an ordinary user to build a binary package for an updated kernel tree and it should just work. fakeroot is too zealous by default in treating files as owned by root. Its wrapped stat() sets st_uid and st_gid to 0 for all files, which causes Git to go on a wild goose chase if CONFIG_LOCALVERSION_AUTO is set, checking if any file's content has changed along with its stat information. Avoid this by telling fakeroot to use the actual owner and group for preexisting files, by passing it the -u option. Signed-off-by: Jonathan Nieder Signed-off-by: Michal Marek diff --git a/scripts/package/Makefile b/scripts/package/Makefile index 5c0b43a..62fcc3a 100644 --- a/scripts/package/Makefile +++ b/scripts/package/Makefile @@ -77,10 +77,27 @@ clean-files += $(objtree)/binkernel.spec # Deb target # --------------------------------------------------------------------------- +quiet_cmd_builddeb = BUILDDEB + cmd_builddeb = set -e; \ + test `id -u` = 0 || \ + test -n "$(KBUILD_PKG_ROOTCMD)" || { \ + which fakeroot >/dev/null 2>&1 && \ + KBUILD_PKG_ROOTCMD="fakeroot -u"; \ + } || { \ + echo; \ + echo "builddeb must be run as root (or using fakeroot)."; \ + echo "KBUILD_PKG_ROOTCMD is unset and fakeroot not found."; \ + echo "Try setting KBUILD_PKG_ROOTCMD to a command to acquire"; \ + echo "root privileges (e.g., 'fakeroot -u' or 'sudo')."; \ + false; \ + } && \ + \ + $$KBUILD_PKG_ROOTCMD $(CONFIG_SHELL) \ + $(srctree)/scripts/package/builddeb + deb-pkg: FORCE $(MAKE) KBUILD_SRC= - $(KBUILD_PKG_ROOTCMD) $(CONFIG_SHELL) \ - $(srctree)/scripts/package/builddeb + $(call cmd,builddeb) clean-dirs += $(objtree)/debian/ -- cgit v0.10.2 From 32197c7ffb06b1319850f8fdfa1a49d32a63b79b Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Wed, 25 Nov 2009 15:14:49 +0100 Subject: kbuild: create include/generated in silentoldconfig The toplevel Makefile creates the directory if it runs silentoldconfig automatically, but if run manually, it fails: $ make mrproper $ make defconfig && make silentoldconfig *** Default configuration is based on 'x86_64_defconfig' # # configuration written to .config # scripts/kconfig/conf -s arch/x86/Kconfig *** Error during update of the kernel configuration. ... Move the mkdir command to the silentoldconfig target to make it work. Signed-off-by: Michal Marek diff --git a/Makefile b/Makefile index 96b32e5..aa608c2 100644 --- a/Makefile +++ b/Makefile @@ -492,7 +492,6 @@ $(KCONFIG_CONFIG) include/config/auto.conf.cmd: ; # if auto.conf.cmd is missing then we are probably in a cleaned tree so # we execute the config step to be sure to catch updated Kconfig files include/config/auto.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd - $(Q)mkdir -p include/generated $(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig else # external modules needs include/generated/autoconf.h and include/config/auto.conf diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 80599e3..999e8a7 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -27,6 +27,7 @@ oldconfig: $(obj)/conf $< -o $(Kconfig) silentoldconfig: $(obj)/conf + $(Q)mkdir -p include/generated $< -s $(Kconfig) localmodconfig: $(obj)/streamline_config.pl $(obj)/conf -- cgit v0.10.2 From eb8f844c0a41c4529a7d06b7801296eca9ae67aa Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 26 Nov 2009 13:34:12 +0100 Subject: kbuild: specify absolute paths for cscope Cscope doesn't hadle relative paths when cscope.out is not in $PWD. Use absolute paths when generating cscope.files, which seems to be the recommended way to generate cscope.out, anyway (at least according to cscope.sf.net). The speed and size differences are minimal, the only drawback is that the database needs to be regenerated if the source directory is moved. [mmarek: fixed for O= builds, modified changelog] Signed-off-by: Daniel Vetter Signed-off-by: Michal Marek diff --git a/scripts/tags.sh b/scripts/tags.sh index d52f7a0..1a0c44d 100755 --- a/scripts/tags.sh +++ b/scripts/tags.sh @@ -89,7 +89,13 @@ all_defconfigs() docscope() { - (echo \-k; echo \-q; all_sources) > cscope.files + # always use absolute paths for cscope, as recommended by cscope + # upstream + case "$tree" in + /*) ;; + *) tree=$PWD/$tree ;; + esac + (cd /; echo \-k; echo \-q; all_sources) > cscope.files cscope -b -f cscope.out } -- cgit v0.10.2 From d8379ab1dde371f13d7fdddf05346840a82c2b61 Mon Sep 17 00:00:00 2001 From: Tony Finch Date: Fri, 27 Nov 2009 15:50:30 +0000 Subject: unifdef: update to upstream revision 1.190 Fix handling of input files (e.g. with no newline at EOF) that could make unifdef get into an unexpected state and call abort(). The new -B option compresses blank lines around a deleted section so that blank lines around "paragraphs" of code don't get doubled. The evaluator can now handle macros with arguments, and unbracketed arguments to the "defined" operator. Add myself to MAINTAINERS for unifdef. Signed-off-by: Tony Finch Acked-by: Sam Ravnborg Signed-off-by: Michal Marek diff --git a/MAINTAINERS b/MAINTAINERS index d58fa70..94381ed 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5407,6 +5407,12 @@ F: drivers/uwb/* F: include/linux/uwb.h F: include/linux/uwb/ +UNIFDEF +M: Tony Finch +W: http://dotat.at/prog/unifdef +S: Maintained +F: scripts/unifdef.c + UNIFORM CDROM DRIVER M: Jens Axboe W: http://www.kernel.dk diff --git a/scripts/unifdef.c b/scripts/unifdef.c index 30d459f..44d3978 100644 --- a/scripts/unifdef.c +++ b/scripts/unifdef.c @@ -1,13 +1,5 @@ /* - * Copyright (c) 2002 - 2005 Tony Finch . All rights reserved. - * - * This code is derived from software contributed to Berkeley by Dave Yost. - * It was rewritten to support ANSI C by Tony Finch. The original version of - * unifdef carried the following copyright notice. None of its code remains - * in this version (though some of the names remain). - * - * Copyright (c) 1985, 1993 - * The Regents of the University of California. All rights reserved. + * Copyright (c) 2002 - 2009 Tony Finch * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -31,23 +23,20 @@ * SUCH DAMAGE. */ -#include +/* + * This code was derived from software contributed to Berkeley by Dave Yost. + * It was rewritten to support ANSI C by Tony Finch. The original version + * of unifdef carried the 4-clause BSD copyright licence. None of its code + * remains in this version (though some of the names remain) so it now + * carries a more liberal licence. + * + * The latest version is available from http://dotat.at/prog/unifdef + */ -#ifndef lint -#if 0 -static const char copyright[] = -"@(#) Copyright (c) 1985, 1993\n\ - The Regents of the University of California. All rights reserved.\n"; -#endif -#ifdef __IDSTRING -__IDSTRING(Berkeley, "@(#)unifdef.c 8.1 (Berkeley) 6/6/93"); -__IDSTRING(NetBSD, "$NetBSD: unifdef.c,v 1.8 2000/07/03 02:51:36 matt Exp $"); -__IDSTRING(dotat, "$dotat: things/unifdef.c,v 1.171 2005/03/08 12:38:48 fanf2 Exp $"); -#endif -#endif /* not lint */ -#ifdef __FBSDID -__FBSDID("$FreeBSD: /repoman/r/ncvs/src/usr.bin/unifdef/unifdef.c,v 1.20 2005/05/21 09:55:09 ru Exp $"); -#endif +static const char * const copyright[] = { + "@(#) Copyright (c) 2002 - 2009 Tony Finch \n", + "$dotat: unifdef/unifdef.c,v 1.190 2009/11/27 17:21:26 fanf2 Exp $", +}; /* * unifdef - remove ifdef'ed lines @@ -72,8 +61,6 @@ __FBSDID("$FreeBSD: /repoman/r/ncvs/src/usr.bin/unifdef/unifdef.c,v 1.20 2005/05 #include #include -size_t strlcpy(char *dst, const char *src, size_t siz); - /* types of input lines: */ typedef enum { LT_TRUEI, /* a true #if with ignore flag */ @@ -90,6 +77,7 @@ typedef enum { LT_DODGY_LAST = LT_DODGY + LT_ENDIF, LT_PLAIN, /* ordinary line */ LT_EOF, /* end of file */ + LT_ERROR, /* unevaluable #if */ LT_COUNT } Linetype; @@ -100,7 +88,7 @@ static char const * const linetype_name[] = { "DODGY IF", "DODGY TRUE", "DODGY FALSE", "DODGY ELIF", "DODGY ELTRUE", "DODGY ELFALSE", "DODGY ELSE", "DODGY ENDIF", - "PLAIN", "EOF" + "PLAIN", "EOF", "ERROR" }; /* state of #if processing */ @@ -168,11 +156,13 @@ static char const * const linestate_name[] = { * Globals. */ +static bool compblank; /* -B: compress blank lines */ +static bool lnblank; /* -b: blank deleted lines */ static bool complement; /* -c: do the complement */ static bool debugging; /* -d: debugging reports */ static bool iocccok; /* -e: fewer IOCCC errors */ +static bool strictlogic; /* -K: keep ambiguous #ifs */ static bool killconsts; /* -k: eval constant #ifs */ -static bool lnblank; /* -l: blank deleted lines */ static bool lnnum; /* -n: add #line directives */ static bool symlist; /* -s: output symbol list */ static bool text; /* -t: this is a text file */ @@ -196,7 +186,9 @@ static bool ignoring[MAXDEPTH]; /* ignore comments state */ static int stifline[MAXDEPTH]; /* start of current #if */ static int depth; /* current #if nesting */ static int delcount; /* count of deleted lines */ -static bool keepthis; /* don't delete constant #if */ +static unsigned blankcount; /* count of blank lines */ +static unsigned blankmax; /* maximum recent blankcount */ +static bool constexpr; /* constant #if expression */ static int exitstat; /* program exit status */ @@ -206,13 +198,14 @@ static void done(void); static void error(const char *); static int findsym(const char *); static void flushline(bool); -static Linetype get_line(void); +static Linetype parseline(void); static Linetype ifeval(const char **); static void ignoreoff(void); static void ignoreon(void); static void keywordedit(const char *); static void nest(void); static void process(void); +static const char *skipargs(const char *); static const char *skipcomment(const char *); static const char *skipsym(const char *); static void state(Ifstate); @@ -220,7 +213,7 @@ static int strlcmp(const char *, const char *, size_t); static void unnest(void); static void usage(void); -#define endsym(c) (!isalpha((unsigned char)c) && !isdigit((unsigned char)c) && c != '_') +#define endsym(c) (!isalnum((unsigned char)c) && c != '_') /* * The main program. @@ -230,7 +223,7 @@ main(int argc, char *argv[]) { int opt; - while ((opt = getopt(argc, argv, "i:D:U:I:cdeklnst")) != -1) + while ((opt = getopt(argc, argv, "i:D:U:I:BbcdeKklnst")) != -1) switch (opt) { case 'i': /* treat stuff controlled by these symbols as text */ /* @@ -255,6 +248,13 @@ main(int argc, char *argv[]) case 'I': /* no-op for compatibility with cpp */ break; + case 'B': /* compress blank lines around removed section */ + compblank = true; + break; + case 'b': /* blank deleted lines instead of omitting them */ + case 'l': /* backwards compatibility */ + lnblank = true; + break; case 'c': /* treat -D as -U and vice versa */ complement = true; break; @@ -264,12 +264,12 @@ main(int argc, char *argv[]) case 'e': /* fewer errors from dodgy lines */ iocccok = true; break; + case 'K': /* keep ambiguous #ifs */ + strictlogic = true; + break; case 'k': /* process constant #ifs */ killconsts = true; break; - case 'l': /* blank deleted lines instead of omitting them */ - lnblank = true; - break; case 'n': /* add #line directive after deleted lines */ lnnum = true; break; @@ -284,6 +284,8 @@ main(int argc, char *argv[]) } argc -= optind; argv += optind; + if (compblank && lnblank) + errx(2, "-B and -b are mutually exclusive"); if (argc > 1) { errx(2, "can only do one file"); } else if (argc == 1 && strcmp(*argv, "-") != 0) { @@ -302,7 +304,7 @@ main(int argc, char *argv[]) static void usage(void) { - fprintf(stderr, "usage: unifdef [-cdeklnst] [-Ipath]" + fprintf(stderr, "usage: unifdef [-BbcdeKknst] [-Ipath]" " [-Dsym[=val]] [-Usym] [-iDsym[=val]] [-iUsym] ... [file]\n"); exit(2); } @@ -383,46 +385,46 @@ static state_fn * const trans_table[IS_COUNT][LT_COUNT] = { /* IS_OUTSIDE */ { Itrue, Ifalse,Fpass, Ftrue, Ffalse,Eelif, Eelif, Eelif, Eelse, Eendif, Oiffy, Oiffy, Fpass, Oif, Oif, Eelif, Eelif, Eelif, Eelse, Eendif, - print, done }, + print, done, abort }, /* IS_FALSE_PREFIX */ { Idrop, Idrop, Fdrop, Fdrop, Fdrop, Mpass, Strue, Sfalse,Selse, Dendif, Idrop, Idrop, Fdrop, Fdrop, Fdrop, Mpass, Eioccc,Eioccc,Eioccc,Eioccc, - drop, Eeof }, + drop, Eeof, abort }, /* IS_TRUE_PREFIX */ { Itrue, Ifalse,Fpass, Ftrue, Ffalse,Dfalse,Dfalse,Dfalse,Delse, Dendif, Oiffy, Oiffy, Fpass, Oif, Oif, Eioccc,Eioccc,Eioccc,Eioccc,Eioccc, - print, Eeof }, + print, Eeof, abort }, /* IS_PASS_MIDDLE */ { Itrue, Ifalse,Fpass, Ftrue, Ffalse,Pelif, Mtrue, Delif, Pelse, Pendif, Oiffy, Oiffy, Fpass, Oif, Oif, Pelif, Oelif, Oelif, Pelse, Pendif, - print, Eeof }, + print, Eeof, abort }, /* IS_FALSE_MIDDLE */ { Idrop, Idrop, Fdrop, Fdrop, Fdrop, Pelif, Mtrue, Delif, Pelse, Pendif, Idrop, Idrop, Fdrop, Fdrop, Fdrop, Eioccc,Eioccc,Eioccc,Eioccc,Eioccc, - drop, Eeof }, + drop, Eeof, abort }, /* IS_TRUE_MIDDLE */ { Itrue, Ifalse,Fpass, Ftrue, Ffalse,Melif, Melif, Melif, Melse, Pendif, Oiffy, Oiffy, Fpass, Oif, Oif, Eioccc,Eioccc,Eioccc,Eioccc,Pendif, - print, Eeof }, + print, Eeof, abort }, /* IS_PASS_ELSE */ { Itrue, Ifalse,Fpass, Ftrue, Ffalse,Eelif, Eelif, Eelif, Eelse, Pendif, Oiffy, Oiffy, Fpass, Oif, Oif, Eelif, Eelif, Eelif, Eelse, Pendif, - print, Eeof }, + print, Eeof, abort }, /* IS_FALSE_ELSE */ { Idrop, Idrop, Fdrop, Fdrop, Fdrop, Eelif, Eelif, Eelif, Eelse, Dendif, Idrop, Idrop, Fdrop, Fdrop, Fdrop, Eelif, Eelif, Eelif, Eelse, Eioccc, - drop, Eeof }, + drop, Eeof, abort }, /* IS_TRUE_ELSE */ { Itrue, Ifalse,Fpass, Ftrue, Ffalse,Eelif, Eelif, Eelif, Eelse, Dendif, Oiffy, Oiffy, Fpass, Oif, Oif, Eelif, Eelif, Eelif, Eelse, Eioccc, - print, Eeof }, + print, Eeof, abort }, /* IS_FALSE_TRAILER */ { Idrop, Idrop, Fdrop, Fdrop, Fdrop, Dfalse,Dfalse,Dfalse,Delse, Dendif, Idrop, Idrop, Fdrop, Fdrop, Fdrop, Dfalse,Dfalse,Dfalse,Delse, Eioccc, - drop, Eeof } + drop, Eeof, abort } /*TRUEI FALSEI IF TRUE FALSE ELIF ELTRUE ELFALSE ELSE ENDIF TRUEI FALSEI IF TRUE FALSE ELIF ELTRUE ELFALSE ELSE ENDIF (DODGY) - PLAIN EOF */ + PLAIN EOF ERROR */ }; /* @@ -463,9 +465,11 @@ keywordedit(const char *replacement) static void nest(void) { - depth += 1; - if (depth >= MAXDEPTH) + if (depth > MAXDEPTH-1) + abort(); /* bug */ + if (depth == MAXDEPTH-1) error("Too many levels of nesting"); + depth += 1; stifline[depth] = linenum; } static void @@ -490,15 +494,23 @@ flushline(bool keep) if (symlist) return; if (keep ^ complement) { - if (lnnum && delcount > 0) - printf("#line %d\n", linenum); - fputs(tline, stdout); - delcount = 0; + bool blankline = tline[strspn(tline, " \t\n")] == '\0'; + if (blankline && compblank && blankcount != blankmax) { + delcount += 1; + blankcount += 1; + } else { + if (lnnum && delcount > 0) + printf("#line %d\n", linenum); + fputs(tline, stdout); + delcount = 0; + blankmax = blankcount = blankline ? blankcount + 1 : 0; + } } else { if (lnblank) putc('\n', stdout); exitstat = 1; delcount += 1; + blankcount = 0; } } @@ -510,9 +522,12 @@ process(void) { Linetype lineval; + /* When compressing blank lines, act as if the file + is preceded by a large number of blank lines. */ + blankmax = blankcount = 1000; for (;;) { linenum++; - lineval = get_line(); + lineval = parseline(); trans_table[ifstate[depth]][lineval](); debug("process %s -> %s depth %d", linetype_name[lineval], @@ -526,7 +541,7 @@ process(void) * help from skipcomment(). */ static Linetype -get_line(void) +parseline(void) { const char *cp; int cursym; @@ -595,9 +610,21 @@ get_line(void) if (incomment) linestate = LS_DIRTY; } - /* skipcomment should have changed the state */ - if (linestate == LS_HASH) - abort(); /* bug */ + /* skipcomment normally changes the state, except + if the last line of the file lacks a newline, or + if there is too much whitespace in a directive */ + if (linestate == LS_HASH) { + size_t len = cp - tline; + if (fgets(tline + len, MAXLINE - len, input) == NULL) { + /* append the missing newline */ + tline[len+0] = '\n'; + tline[len+1] = '\0'; + cp++; + linestate = LS_START; + } else { + linestate = LS_DIRTY; + } + } } if (linestate == LS_DIRTY) { while (*cp != '\0') @@ -610,17 +637,40 @@ get_line(void) /* * These are the binary operators that are supported by the expression - * evaluator. Note that if support for division is added then we also - * need short-circuiting booleans because of divide-by-zero. + * evaluator. */ -static int op_lt(int a, int b) { return (a < b); } -static int op_gt(int a, int b) { return (a > b); } -static int op_le(int a, int b) { return (a <= b); } -static int op_ge(int a, int b) { return (a >= b); } -static int op_eq(int a, int b) { return (a == b); } -static int op_ne(int a, int b) { return (a != b); } -static int op_or(int a, int b) { return (a || b); } -static int op_and(int a, int b) { return (a && b); } +static Linetype op_strict(int *p, int v, Linetype at, Linetype bt) { + if(at == LT_IF || bt == LT_IF) return (LT_IF); + return (*p = v, v ? LT_TRUE : LT_FALSE); +} +static Linetype op_lt(int *p, Linetype at, int a, Linetype bt, int b) { + return op_strict(p, a < b, at, bt); +} +static Linetype op_gt(int *p, Linetype at, int a, Linetype bt, int b) { + return op_strict(p, a > b, at, bt); +} +static Linetype op_le(int *p, Linetype at, int a, Linetype bt, int b) { + return op_strict(p, a <= b, at, bt); +} +static Linetype op_ge(int *p, Linetype at, int a, Linetype bt, int b) { + return op_strict(p, a >= b, at, bt); +} +static Linetype op_eq(int *p, Linetype at, int a, Linetype bt, int b) { + return op_strict(p, a == b, at, bt); +} +static Linetype op_ne(int *p, Linetype at, int a, Linetype bt, int b) { + return op_strict(p, a != b, at, bt); +} +static Linetype op_or(int *p, Linetype at, int a, Linetype bt, int b) { + if (!strictlogic && (at == LT_TRUE || bt == LT_TRUE)) + return (*p = 1, LT_TRUE); + return op_strict(p, a || b, at, bt); +} +static Linetype op_and(int *p, Linetype at, int a, Linetype bt, int b) { + if (!strictlogic && (at == LT_FALSE || bt == LT_FALSE)) + return (*p = 0, LT_FALSE); + return op_strict(p, a && b, at, bt); +} /* * An evaluation function takes three arguments, as follows: (1) a pointer to @@ -629,8 +679,8 @@ static int op_and(int a, int b) { return (a && b); } * value of the expression; and (3) a pointer to a char* that points to the * expression to be evaluated and that is updated to the end of the expression * when evaluation is complete. The function returns LT_FALSE if the value of - * the expression is zero, LT_TRUE if it is non-zero, or LT_IF if the - * expression could not be evaluated. + * the expression is zero, LT_TRUE if it is non-zero, LT_IF if the expression + * depends on an unknown symbol, or LT_ERROR if there is a parse failure. */ struct ops; @@ -649,7 +699,7 @@ static const struct ops { eval_fn *inner; struct op { const char *str; - int (*fn)(int, int); + Linetype (*fn)(int *, Linetype, int, Linetype, int); } op[5]; } eval_ops[] = { { eval_table, { { "||", op_or } } }, @@ -664,8 +714,8 @@ static const struct ops { /* * Function for evaluating the innermost parts of expressions, - * viz. !expr (expr) defined(symbol) symbol number - * We reset the keepthis flag when we find a non-constant subexpression. + * viz. !expr (expr) number defined(symbol) symbol + * We reset the constexpr flag in the last two cases. */ static Linetype eval_unary(const struct ops *ops, int *valp, const char **cpp) @@ -673,68 +723,83 @@ eval_unary(const struct ops *ops, int *valp, const char **cpp) const char *cp; char *ep; int sym; + bool defparen; + Linetype lt; cp = skipcomment(*cpp); if (*cp == '!') { debug("eval%d !", ops - eval_ops); cp++; - if (eval_unary(ops, valp, &cp) == LT_IF) { - *cpp = cp; - return (LT_IF); + lt = eval_unary(ops, valp, &cp); + if (lt == LT_ERROR) + return (LT_ERROR); + if (lt != LT_IF) { + *valp = !*valp; + lt = *valp ? LT_TRUE : LT_FALSE; } - *valp = !*valp; } else if (*cp == '(') { cp++; debug("eval%d (", ops - eval_ops); - if (eval_table(eval_ops, valp, &cp) == LT_IF) - return (LT_IF); + lt = eval_table(eval_ops, valp, &cp); + if (lt == LT_ERROR) + return (LT_ERROR); cp = skipcomment(cp); if (*cp++ != ')') - return (LT_IF); + return (LT_ERROR); } else if (isdigit((unsigned char)*cp)) { debug("eval%d number", ops - eval_ops); *valp = strtol(cp, &ep, 0); + if (ep == cp) + return (LT_ERROR); + lt = *valp ? LT_TRUE : LT_FALSE; cp = skipsym(cp); } else if (strncmp(cp, "defined", 7) == 0 && endsym(cp[7])) { cp = skipcomment(cp+7); debug("eval%d defined", ops - eval_ops); - if (*cp++ != '(') - return (LT_IF); - cp = skipcomment(cp); + if (*cp == '(') { + cp = skipcomment(cp+1); + defparen = true; + } else { + defparen = false; + } sym = findsym(cp); - cp = skipsym(cp); - cp = skipcomment(cp); - if (*cp++ != ')') - return (LT_IF); - if (sym >= 0) + if (sym < 0) { + lt = LT_IF; + } else { *valp = (value[sym] != NULL); - else { - *cpp = cp; - return (LT_IF); + lt = *valp ? LT_TRUE : LT_FALSE; } - keepthis = false; + cp = skipsym(cp); + cp = skipcomment(cp); + if (defparen && *cp++ != ')') + return (LT_ERROR); + constexpr = false; } else if (!endsym(*cp)) { debug("eval%d symbol", ops - eval_ops); sym = findsym(cp); - if (sym < 0) - return (LT_IF); - if (value[sym] == NULL) + cp = skipsym(cp); + if (sym < 0) { + lt = LT_IF; + cp = skipargs(cp); + } else if (value[sym] == NULL) { *valp = 0; - else { + lt = LT_FALSE; + } else { *valp = strtol(value[sym], &ep, 0); if (*ep != '\0' || ep == value[sym]) - return (LT_IF); + return (LT_ERROR); + lt = *valp ? LT_TRUE : LT_FALSE; + cp = skipargs(cp); } - cp = skipsym(cp); - keepthis = false; + constexpr = false; } else { debug("eval%d bad expr", ops - eval_ops); - return (LT_IF); + return (LT_ERROR); } *cpp = cp; debug("eval%d = %d", ops - eval_ops, *valp); - return (*valp ? LT_TRUE : LT_FALSE); + return (lt); } /* @@ -746,11 +811,13 @@ eval_table(const struct ops *ops, int *valp, const char **cpp) const struct op *op; const char *cp; int val; - Linetype lhs, rhs; + Linetype lt, rt; debug("eval%d", ops - eval_ops); cp = *cpp; - lhs = ops->inner(ops+1, valp, &cp); + lt = ops->inner(ops+1, valp, &cp); + if (lt == LT_ERROR) + return (LT_ERROR); for (;;) { cp = skipcomment(cp); for (op = ops->op; op->str != NULL; op++) @@ -760,32 +827,16 @@ eval_table(const struct ops *ops, int *valp, const char **cpp) break; cp += strlen(op->str); debug("eval%d %s", ops - eval_ops, op->str); - rhs = ops->inner(ops+1, &val, &cp); - if (op->fn == op_and && (lhs == LT_FALSE || rhs == LT_FALSE)) { - debug("eval%d: and always false", ops - eval_ops); - if (lhs == LT_IF) - *valp = val; - lhs = LT_FALSE; - continue; - } - if (op->fn == op_or && (lhs == LT_TRUE || rhs == LT_TRUE)) { - debug("eval%d: or always true", ops - eval_ops); - if (lhs == LT_IF) - *valp = val; - lhs = LT_TRUE; - continue; - } - if (rhs == LT_IF) - lhs = LT_IF; - if (lhs != LT_IF) - *valp = op->fn(*valp, val); + rt = ops->inner(ops+1, &val, &cp); + if (rt == LT_ERROR) + return (LT_ERROR); + lt = op->fn(valp, lt, *valp, rt, val); } *cpp = cp; debug("eval%d = %d", ops - eval_ops, *valp); - if (lhs != LT_IF) - lhs = (*valp ? LT_TRUE : LT_FALSE); - return lhs; + debug("eval%d lt = %s", ops - eval_ops, linetype_name[lt]); + return (lt); } /* @@ -796,17 +847,14 @@ eval_table(const struct ops *ops, int *valp, const char **cpp) static Linetype ifeval(const char **cpp) { - const char *cp = *cpp; int ret; - int val; + int val = 0; debug("eval %s", *cpp); - keepthis = killconsts ? false : true; - ret = eval_table(eval_ops, &val, &cp); - if (ret != LT_IF) - *cpp = cp; + constexpr = killconsts ? false : true; + ret = eval_table(eval_ops, &val, cpp); debug("eval = %d", val); - return (keepthis ? LT_IF : ret); + return (constexpr ? LT_IF : ret == LT_ERROR ? LT_IF : ret); } /* @@ -918,6 +966,31 @@ skipcomment(const char *cp) } /* + * Skip macro arguments. + */ +static const char * +skipargs(const char *cp) +{ + const char *ocp = cp; + int level = 0; + cp = skipcomment(cp); + if (*cp != '(') + return (cp); + do { + if (*cp == '(') + level++; + if (*cp == ')') + level--; + cp = skipcomment(cp+1); + } while (level != 0 && *cp != '\0'); + if (level == 0) + return (cp); + else + /* Rewind and re-detect the syntax error later. */ + return (ocp); +} + +/* * Skip over an identifier. */ static const char * @@ -929,7 +1002,7 @@ skipsym(const char *cp) } /* - * Look for the symbol in the symbol table. If is is found, we return + * Look for the symbol in the symbol table. If it is found, we return * the symbol table index, else we return -1. */ static int -- cgit v0.10.2 From 75f0d92b6a11736429940bdd58f9c141abee8865 Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Fri, 4 Dec 2009 20:46:17 +0000 Subject: score: add asm/asm-offsets.h wrapper A recent kbuild patch moved asm-offsets.h to include/generated. Provide a wrapper header as for other architectures. Signed-off-by: Michal Marek diff --git a/arch/score/include/asm/asm-offsets.h b/arch/score/include/asm/asm-offsets.h new file mode 100644 index 0000000..d370ee3 --- /dev/null +++ b/arch/score/include/asm/asm-offsets.h @@ -0,0 +1 @@ +#include -- cgit v0.10.2 From 6299fee7b84ac7b4429b4e2787b99470a89cd5f5 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Sat, 5 Dec 2009 20:20:50 +0000 Subject: genksyms: properly consider EXPORT_UNUSED_SYMBOL{,_GPL}() Despite being unused these should also get a CRC calculated. Primarily I view this as a consistency thing. But I also think this is one of the reasons why __crc_* need to be weak (which I think should be avoided, and hence we should have the goal to eliminate this so that failure to calculate a proper CRC for a symbol causes the build to fail). Signed-off-by: Jan Beulich Cc: Anibal Monsalve Salazar Cc: Steven Rostedt Cc: Sam Ravnborg Signed-off-by: Andrew Morton Signed-off-by: Michal Marek diff --git a/scripts/genksyms/keywords.c_shipped b/scripts/genksyms/keywords.c_shipped index 287467a..8060e06 100644 --- a/scripts/genksyms/keywords.c_shipped +++ b/scripts/genksyms/keywords.c_shipped @@ -1,4 +1,4 @@ -/* ANSI-C code produced by gperf version 3.0.3 */ +/* ANSI-C code produced by gperf version 3.0.4 */ /* Command-line: gperf -L ANSI-C -a -C -E -g -H is_reserved_hash -k '1,3,$' -N is_reserved_word -p -t scripts/genksyms/keywords.gperf */ #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ @@ -34,7 +34,7 @@ struct resword; static const struct resword *is_reserved_word(register const char *str, register unsigned int len); #line 5 "scripts/genksyms/keywords.gperf" struct resword { const char *name; int token; }; -/* maximum key range = 62, duplicates = 0 */ +/* maximum key range = 64, duplicates = 0 */ #ifdef __GNUC__ __inline @@ -48,39 +48,39 @@ is_reserved_hash (register const char *str, register unsigned int len) { static const unsigned char asso_values[] = { - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 5, - 65, 65, 65, 65, 65, 65, 35, 65, 65, 65, - 0, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 0, 65, 0, 65, 5, - 20, 15, 10, 30, 65, 15, 65, 65, 20, 0, - 10, 35, 20, 65, 10, 5, 0, 10, 5, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65 + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 0, + 67, 67, 67, 67, 67, 67, 15, 67, 67, 67, + 0, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 0, 67, 0, 67, 5, + 25, 20, 15, 30, 67, 15, 67, 67, 10, 0, + 10, 40, 20, 67, 10, 5, 0, 10, 15, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67 }; return len + asso_values[(unsigned char)str[2]] + asso_values[(unsigned char)str[0]] + asso_values[(unsigned char)str[len - 1]]; } #ifdef __GNUC__ __inline -#ifdef __GNUC_STDC_INLINE__ +#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__ __attribute__ ((__gnu_inline__)) #endif #endif @@ -89,116 +89,119 @@ is_reserved_word (register const char *str, register unsigned int len) { enum { - TOTAL_KEYWORDS = 43, + TOTAL_KEYWORDS = 45, MIN_WORD_LENGTH = 3, MAX_WORD_LENGTH = 24, MIN_HASH_VALUE = 3, - MAX_HASH_VALUE = 64 + MAX_HASH_VALUE = 66 }; static const struct resword wordlist[] = { {""}, {""}, {""}, -#line 28 "scripts/genksyms/keywords.gperf" +#line 30 "scripts/genksyms/keywords.gperf" {"asm", ASM_KEYW}, {""}, -#line 10 "scripts/genksyms/keywords.gperf" +#line 12 "scripts/genksyms/keywords.gperf" {"__asm", ASM_KEYW}, {""}, -#line 11 "scripts/genksyms/keywords.gperf" +#line 13 "scripts/genksyms/keywords.gperf" {"__asm__", ASM_KEYW}, {""}, {""}, -#line 54 "scripts/genksyms/keywords.gperf" +#line 56 "scripts/genksyms/keywords.gperf" {"__typeof__", TYPEOF_KEYW}, {""}, -#line 14 "scripts/genksyms/keywords.gperf" +#line 16 "scripts/genksyms/keywords.gperf" {"__const", CONST_KEYW}, -#line 13 "scripts/genksyms/keywords.gperf" - {"__attribute__", ATTRIBUTE_KEYW}, #line 15 "scripts/genksyms/keywords.gperf" + {"__attribute__", ATTRIBUTE_KEYW}, +#line 17 "scripts/genksyms/keywords.gperf" {"__const__", CONST_KEYW}, -#line 20 "scripts/genksyms/keywords.gperf" +#line 22 "scripts/genksyms/keywords.gperf" {"__signed__", SIGNED_KEYW}, -#line 46 "scripts/genksyms/keywords.gperf" +#line 48 "scripts/genksyms/keywords.gperf" {"static", STATIC_KEYW}, -#line 22 "scripts/genksyms/keywords.gperf" - {"__volatile__", VOLATILE_KEYW}, -#line 41 "scripts/genksyms/keywords.gperf" + {""}, +#line 43 "scripts/genksyms/keywords.gperf" {"int", INT_KEYW}, -#line 34 "scripts/genksyms/keywords.gperf" +#line 36 "scripts/genksyms/keywords.gperf" {"char", CHAR_KEYW}, -#line 35 "scripts/genksyms/keywords.gperf" +#line 37 "scripts/genksyms/keywords.gperf" {"const", CONST_KEYW}, -#line 47 "scripts/genksyms/keywords.gperf" +#line 49 "scripts/genksyms/keywords.gperf" {"struct", STRUCT_KEYW}, -#line 26 "scripts/genksyms/keywords.gperf" +#line 28 "scripts/genksyms/keywords.gperf" {"__restrict__", RESTRICT_KEYW}, -#line 27 "scripts/genksyms/keywords.gperf" +#line 29 "scripts/genksyms/keywords.gperf" {"restrict", RESTRICT_KEYW}, -#line 25 "scripts/genksyms/keywords.gperf" - {"_restrict", RESTRICT_KEYW}, -#line 18 "scripts/genksyms/keywords.gperf" +#line 9 "scripts/genksyms/keywords.gperf" + {"EXPORT_SYMBOL_GPL_FUTURE", EXPORT_SYMBOL_KEYW}, +#line 20 "scripts/genksyms/keywords.gperf" {"__inline__", INLINE_KEYW}, -#line 12 "scripts/genksyms/keywords.gperf" - {"__attribute", ATTRIBUTE_KEYW}, {""}, -#line 16 "scripts/genksyms/keywords.gperf" +#line 24 "scripts/genksyms/keywords.gperf" + {"__volatile__", VOLATILE_KEYW}, +#line 7 "scripts/genksyms/keywords.gperf" + {"EXPORT_SYMBOL", EXPORT_SYMBOL_KEYW}, +#line 27 "scripts/genksyms/keywords.gperf" + {"_restrict", RESTRICT_KEYW}, + {""}, +#line 14 "scripts/genksyms/keywords.gperf" + {"__attribute", ATTRIBUTE_KEYW}, +#line 8 "scripts/genksyms/keywords.gperf" + {"EXPORT_SYMBOL_GPL", EXPORT_SYMBOL_KEYW}, +#line 18 "scripts/genksyms/keywords.gperf" {"__extension__", EXTENSION_KEYW}, -#line 37 "scripts/genksyms/keywords.gperf" +#line 39 "scripts/genksyms/keywords.gperf" {"enum", ENUM_KEYW}, -#line 21 "scripts/genksyms/keywords.gperf" - {"__volatile", VOLATILE_KEYW}, -#line 38 "scripts/genksyms/keywords.gperf" +#line 10 "scripts/genksyms/keywords.gperf" + {"EXPORT_UNUSED_SYMBOL", EXPORT_SYMBOL_KEYW}, +#line 40 "scripts/genksyms/keywords.gperf" {"extern", EXTERN_KEYW}, {""}, -#line 19 "scripts/genksyms/keywords.gperf" +#line 21 "scripts/genksyms/keywords.gperf" {"__signed", SIGNED_KEYW}, -#line 9 "scripts/genksyms/keywords.gperf" - {"EXPORT_SYMBOL_GPL_FUTURE", EXPORT_SYMBOL_KEYW}, - {""}, -#line 53 "scripts/genksyms/keywords.gperf" +#line 11 "scripts/genksyms/keywords.gperf" + {"EXPORT_UNUSED_SYMBOL_GPL", EXPORT_SYMBOL_KEYW}, +#line 51 "scripts/genksyms/keywords.gperf" + {"union", UNION_KEYW}, +#line 55 "scripts/genksyms/keywords.gperf" {"typeof", TYPEOF_KEYW}, -#line 48 "scripts/genksyms/keywords.gperf" +#line 50 "scripts/genksyms/keywords.gperf" {"typedef", TYPEDEF_KEYW}, -#line 17 "scripts/genksyms/keywords.gperf" +#line 19 "scripts/genksyms/keywords.gperf" {"__inline", INLINE_KEYW}, -#line 33 "scripts/genksyms/keywords.gperf" +#line 35 "scripts/genksyms/keywords.gperf" {"auto", AUTO_KEYW}, -#line 49 "scripts/genksyms/keywords.gperf" - {"union", UNION_KEYW}, - {""}, {""}, -#line 50 "scripts/genksyms/keywords.gperf" - {"unsigned", UNSIGNED_KEYW}, -#line 51 "scripts/genksyms/keywords.gperf" - {"void", VOID_KEYW}, -#line 44 "scripts/genksyms/keywords.gperf" - {"short", SHORT_KEYW}, +#line 23 "scripts/genksyms/keywords.gperf" + {"__volatile", VOLATILE_KEYW}, {""}, {""}, #line 52 "scripts/genksyms/keywords.gperf" - {"volatile", VOLATILE_KEYW}, - {""}, -#line 39 "scripts/genksyms/keywords.gperf" - {"float", FLOAT_KEYW}, -#line 36 "scripts/genksyms/keywords.gperf" - {"double", DOUBLE_KEYW}, + {"unsigned", UNSIGNED_KEYW}, {""}, -#line 7 "scripts/genksyms/keywords.gperf" - {"EXPORT_SYMBOL", EXPORT_SYMBOL_KEYW}, - {""}, {""}, -#line 40 "scripts/genksyms/keywords.gperf" +#line 46 "scripts/genksyms/keywords.gperf" + {"short", SHORT_KEYW}, +#line 42 "scripts/genksyms/keywords.gperf" {"inline", INLINE_KEYW}, -#line 8 "scripts/genksyms/keywords.gperf" - {"EXPORT_SYMBOL_GPL", EXPORT_SYMBOL_KEYW}, -#line 43 "scripts/genksyms/keywords.gperf" - {"register", REGISTER_KEYW}, {""}, -#line 24 "scripts/genksyms/keywords.gperf" +#line 54 "scripts/genksyms/keywords.gperf" + {"volatile", VOLATILE_KEYW}, +#line 44 "scripts/genksyms/keywords.gperf" + {"long", LONG_KEYW}, +#line 26 "scripts/genksyms/keywords.gperf" {"_Bool", BOOL_KEYW}, -#line 45 "scripts/genksyms/keywords.gperf" - {"signed", SIGNED_KEYW}, {""}, {""}, -#line 42 "scripts/genksyms/keywords.gperf" - {"long", LONG_KEYW} +#line 45 "scripts/genksyms/keywords.gperf" + {"register", REGISTER_KEYW}, +#line 53 "scripts/genksyms/keywords.gperf" + {"void", VOID_KEYW}, +#line 41 "scripts/genksyms/keywords.gperf" + {"float", FLOAT_KEYW}, +#line 38 "scripts/genksyms/keywords.gperf" + {"double", DOUBLE_KEYW}, + {""}, {""}, {""}, {""}, +#line 47 "scripts/genksyms/keywords.gperf" + {"signed", SIGNED_KEYW} }; if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) diff --git a/scripts/genksyms/keywords.gperf b/scripts/genksyms/keywords.gperf index 8fe977a..e6349ac 100644 --- a/scripts/genksyms/keywords.gperf +++ b/scripts/genksyms/keywords.gperf @@ -7,6 +7,8 @@ struct resword { const char *name; int token; } EXPORT_SYMBOL, EXPORT_SYMBOL_KEYW EXPORT_SYMBOL_GPL, EXPORT_SYMBOL_KEYW EXPORT_SYMBOL_GPL_FUTURE, EXPORT_SYMBOL_KEYW +EXPORT_UNUSED_SYMBOL, EXPORT_SYMBOL_KEYW +EXPORT_UNUSED_SYMBOL_GPL, EXPORT_SYMBOL_KEYW __asm, ASM_KEYW __asm__, ASM_KEYW __attribute, ATTRIBUTE_KEYW -- cgit v0.10.2 From bc081dd6e9f622c73334dc465359168543ccaabf Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Mon, 7 Dec 2009 16:38:33 +0100 Subject: kbuild: generate modules.builtin To make it easier for module-init-tools and scripts like mkinitrd to distinguish builtin and missing modules, install a modules.builtin file listing all builtin modules. This is done by generating an additional config file (tristate.conf) with tristate options set to uppercase 'Y' or 'M'. If we source that config file, the builtin modules appear in obj-Y. Signed-off-by: Michal Marek diff --git a/.gitignore b/.gitignore index 002d530..fb2190c 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,7 @@ *.lst *.symtypes *.order +modules.builtin *.elf *.bin *.gz diff --git a/Documentation/kbuild/kbuild.txt b/Documentation/kbuild/kbuild.txt index bb3bf38..6f8c1ca 100644 --- a/Documentation/kbuild/kbuild.txt +++ b/Documentation/kbuild/kbuild.txt @@ -1,3 +1,17 @@ +Output files + +modules.order +-------------------------------------------------- +This file records the order in which modules appear in Makefiles. This +is used by modprobe to deterministically resolve aliases that match +multiple modules. + +modules.builtin +-------------------------------------------------- +This file lists all modules that are built into the kernel. This is used +by modprobe to not fail when trying to load something builtin. + + Environment variables KCPPFLAGS diff --git a/Documentation/kbuild/kconfig.txt b/Documentation/kbuild/kconfig.txt index ab8dc35..49efae7 100644 --- a/Documentation/kbuild/kconfig.txt +++ b/Documentation/kbuild/kconfig.txt @@ -103,6 +103,11 @@ KCONFIG_AUTOCONFIG This environment variable can be set to specify the path & name of the "auto.conf" file. Its default value is "include/config/auto.conf". +KCONFIG_TRISTATE +-------------------------------------------------- +This environment variable can be set to specify the path & name of the +"tristate.conf" file. Its default value is "include/config/tristate.conf". + KCONFIG_AUTOHEADER -------------------------------------------------- This environment variable can be set to specify the path & name of the diff --git a/Makefile b/Makefile index aa608c2..391fcb3 100644 --- a/Makefile +++ b/Makefile @@ -464,7 +464,7 @@ ifeq ($(KBUILD_EXTMOD),) # Carefully list dependencies so we do not try to build scripts twice # in parallel PHONY += scripts -scripts: scripts_basic include/config/auto.conf +scripts: scripts_basic include/config/auto.conf include/config/tristate.conf $(Q)$(MAKE) $(build)=$(@) # Objects we will link into vmlinux / subdirs we need to visit @@ -491,7 +491,7 @@ $(KCONFIG_CONFIG) include/config/auto.conf.cmd: ; # with it and forgot to run make oldconfig. # if auto.conf.cmd is missing then we are probably in a cleaned tree so # we execute the config step to be sure to catch updated Kconfig files -include/config/auto.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd +include/config/%.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd $(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig else # external modules needs include/generated/autoconf.h and include/config/auto.conf @@ -876,6 +876,9 @@ $(sort $(vmlinux-init) $(vmlinux-main)) $(vmlinux-lds): $(vmlinux-dirs) ; PHONY += $(vmlinux-dirs) $(vmlinux-dirs): prepare scripts $(Q)$(MAKE) $(build)=$@ +ifdef CONFIG_MODULES + $(Q)$(MAKE) $(modbuiltin)=$@ +endif # Build the kernel release string # @@ -1080,6 +1083,7 @@ all: modules PHONY += modules modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux) $(Q)$(AWK) '!x[$$0]++' $(vmlinux-dirs:%=$(objtree)/%/modules.order) > $(objtree)/modules.order + $(Q)$(AWK) '!x[$$0]++' $(vmlinux-dirs:%=$(objtree)/%/modules.builtin) > $(objtree)/modules.builtin @$(kecho) ' Building modules, stage 2.'; $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.fwinst obj=firmware __fw_modbuild @@ -1109,6 +1113,7 @@ _modinst_: ln -s $(objtree) $(MODLIB)/build ; \ fi @cp -f $(objtree)/modules.order $(MODLIB)/ + @cp -f $(objtree)/modules.builtin $(MODLIB)/ $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modinst # This depmod is only for convenience to give the initial @@ -1169,7 +1174,7 @@ clean: archclean $(clean-dirs) \( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \ -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \ -o -name '*.symtypes' -o -name 'modules.order' \ - -o -name '.tmp_*.o.*' \ + -o modules.order -o -name '.tmp_*.o.*' \ -o -name '*.gcno' \) -type f -print | xargs rm -f # mrproper - Delete all generated files, including .config @@ -1367,7 +1372,8 @@ $(clean-dirs): clean: rm-dirs := $(MODVERDIR) clean: rm-files := $(KBUILD_EXTMOD)/Module.symvers \ - $(KBUILD_EXTMOD)/modules.order + $(KBUILD_EXTMOD)/modules.order \ + $(KBUILD_EXTMOD)/modules.builtin clean: $(clean-dirs) $(call cmd,rmdirs) $(call cmd,rmfiles) diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index c67e73e..ed2773e 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include @@ -149,6 +149,12 @@ ld-option = $(call try-run,\ # $(Q)$(MAKE) $(build)=dir build := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj +### +# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.modbuiltin obj= +# Usage: +# $(Q)$(MAKE) $(modbuiltin)=dir +modbuiltin := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.modbuiltin obj + # Prefix -I with $(srctree) if it is not an absolute path. # skip if -I has no parameter addtree = $(if $(patsubst -I%,%,$(1)), \ diff --git a/scripts/Makefile.modbuiltin b/scripts/Makefile.modbuiltin new file mode 100644 index 0000000..102a276 --- /dev/null +++ b/scripts/Makefile.modbuiltin @@ -0,0 +1,55 @@ +# ========================================================================== +# Generating modules.builtin +# ========================================================================== + +src := $(obj) + +PHONY := __modbuiltin +__modbuiltin: + +-include include/config/auto.conf +# tristate.conf sets tristate variables to uppercase 'Y' or 'M' +# That way, we get the list of built-in modules in obj-Y +-include include/config/tristate.conf + +include scripts/Kbuild.include + +# The filename Kbuild has precedence over Makefile +kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src)) +kbuild-file := $(if $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile) +include $(kbuild-file) + +include scripts/Makefile.lib +__subdir-Y := $(patsubst %/,%,$(filter %/, $(obj-Y))) +subdir-Y += $(__subdir-Y) +subdir-ym := $(sort $(subdir-y) $(subdir-Y) $(subdir-m)) +subdir-ym := $(addprefix $(obj)/,$(subdir-ym)) +obj-Y := $(addprefix $(obj)/,$(obj-Y)) + +modbuiltin-subdirs := $(patsubst %,%/modules.builtin, $(subdir-ym)) +modbuiltin-mods := $(filter %.ko, $(obj-Y:.o=.ko)) +modbuiltin-target := $(obj)/modules.builtin + +__modbuiltin: $(modbuiltin-target) $(subdir-ym) + @: + +$(modbuiltin-target): $(subdir-ym) FORCE + $(Q)(for m in $(modbuiltin-mods); do echo kernel/$$m; done; \ + cat /dev/null $(modbuiltin-subdirs)) > $@ + +PHONY += FORCE + +FORCE: + +# Descending +# --------------------------------------------------------------------------- + +PHONY += $(subdir-ym) +$(subdir-ym): + $(Q)$(MAKE) $(modbuiltin)=$@ + + +# Declare the contents of the .PHONY variable as phony. We keep that +# information in a variable se we can use it in if_changed and friends. + +.PHONY: $(PHONY) diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 797a741..c4dec80 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -677,7 +677,7 @@ int conf_write_autoconf(void) struct symbol *sym; const char *str; const char *name; - FILE *out, *out_h; + FILE *out, *tristate, *out_h; time_t now; int i, l; @@ -692,9 +692,16 @@ int conf_write_autoconf(void) if (!out) return 1; + tristate = fopen(".tmpconfig_tristate", "w"); + if (!tristate) { + fclose(out); + return 1; + } + out_h = fopen(".tmpconfig.h", "w"); if (!out_h) { fclose(out); + fclose(tristate); return 1; } @@ -707,6 +714,9 @@ int conf_write_autoconf(void) "# %s" "#\n", sym_get_string_value(sym), ctime(&now)); + fprintf(tristate, "#\n" + "# Automatically generated - do not edit\n" + "\n"); fprintf(out_h, "/*\n" " * Automatically generated C config: don't edit\n" " * Linux kernel version: %s\n" @@ -727,10 +737,14 @@ int conf_write_autoconf(void) break; case mod: fprintf(out, "CONFIG_%s=m\n", sym->name); + fprintf(tristate, "CONFIG_%s=M\n", sym->name); fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name); break; case yes: fprintf(out, "CONFIG_%s=y\n", sym->name); + if (sym->type == S_TRISTATE) + fprintf(tristate, "CONFIG_%s=Y\n", + sym->name); fprintf(out_h, "#define CONFIG_%s 1\n", sym->name); break; } @@ -772,6 +786,7 @@ int conf_write_autoconf(void) } } fclose(out); + fclose(tristate); fclose(out_h); name = getenv("KCONFIG_AUTOHEADER"); @@ -779,6 +794,11 @@ int conf_write_autoconf(void) name = "include/generated/autoconf.h"; if (rename(".tmpconfig.h", name)) return 1; + name = getenv("KCONFIG_TRISTATE"); + if (!name) + name = "include/config/tristate.conf"; + if (rename(".tmpconfig_tristate", name)) + return 1; name = conf_get_autoconfig_name(); /* * This must be the last step, kbuild has a dependency on auto.conf -- cgit v0.10.2 From d9bdcc72ecf055f97ed736a6c0309bd41baf10a7 Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Tue, 8 Dec 2009 16:03:10 +0100 Subject: kbuild: fix make clean after mismerge Fix typo / thinko in commit bc081dd. Signed-off-by: Michal Marek diff --git a/Makefile b/Makefile index 391fcb3..8491b21 100644 --- a/Makefile +++ b/Makefile @@ -1174,7 +1174,7 @@ clean: archclean $(clean-dirs) \( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \ -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \ -o -name '*.symtypes' -o -name 'modules.order' \ - -o modules.order -o -name '.tmp_*.o.*' \ + -o -name modules.builtin -o -name '.tmp_*.o.*' \ -o -name '*.gcno' \) -type f -print | xargs rm -f # mrproper - Delete all generated files, including .config -- cgit v0.10.2 From 6d87fea4dd7152df4a4605a3846c3bf10f869e0c Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 9 Dec 2009 06:55:19 -0500 Subject: gen_init_cpio: fixed fwrite warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On compilers with security warnings enabled by default, we get: usr/gen_init_cpio.c: In function ‘cpio_mkfile’: usr/gen_init_cpio.c:357: warning: ignoring return value of ‘fwrite’, declared with attribute warn_unused_result So check the return value and handle errors accordingly. Signed-off-by: Mike Frysinger Signed-off-by: Michal Marek diff --git a/usr/gen_init_cpio.c b/usr/gen_init_cpio.c index 83b3dde..b2b3c2d 100644 --- a/usr/gen_init_cpio.c +++ b/usr/gen_init_cpio.c @@ -354,7 +354,10 @@ static int cpio_mkfile(const char *name, const char *location, push_pad(); if (size) { - fwrite(filebuf, size, 1, stdout); + if (fwrite(filebuf, size, 1, stdout) != 1) { + fprintf(stderr, "writing filebuf failed\n"); + goto error; + } offset += size; push_pad(); } -- cgit v0.10.2 From 46e75f66677f5094bb51e91f9473128c4e907c7d Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Mon, 7 Dec 2009 19:56:42 +1100 Subject: net: fix for utsrelease.h moving to generated Signed-off-by: Stephen Rothwell Signed-off-by: Michal Marek diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 675b7df..27ca859 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -63,7 +63,7 @@ #ifndef __iwl_core_h__ #define __iwl_core_h__ -#include +#include /************************ * forward declarations * -- cgit v0.10.2 From 5543c72e2bbb30e5ba5938b18ec26617b8b3fb04 Mon Sep 17 00:00:00 2001 From: Abhijeet Joglekar Date: Thu, 10 Dec 2009 09:59:20 -0800 Subject: [SCSI] libfc: remote port gets stuck in restart state without really restarting We ran into a scenario where a remote port goes into RESTART state, but never gets added to scsi transport. The running vmcore showed the following: a) Port was in RESTART state b) rdata->event was STOP c) no work gets scheduled for the remote work to fc_rport_work After this point, shut/no-shut of the remote port did not cause the port to get re-discovered. The port would move betwen DELETE and RESTART states, but the event would always be STOP, no work would get scheduled to fc_rport_work and the port would not get added to scsi_transport. The problem is that rdata->event is not set to NONE after a port is restarted. After this point, no more work gets scheduled for the remote port since new work is scheduled only if rdata->event is non-NONE. So, the event and state keep changing, but fc_rport_work does not get scheduled to actually handle the event. Here's a transition of states that explains the above observation: ) Port is first in READY State, event is NONE 2) RSCN on shut, port goes to DELETED, event is stop 3) Before fc_rport_work runs, RSCN on no-shut, port goes to RESTART, event is still STOP 4) fc_rport_work gets scheduled, removes the port from transport, sees state as RESTART, begins the PLOGI state machine, event remains as STOP (event NOT changed to NONE, this is the bug) 5) Plogi state machine completes, port state goes to READY, event goes to READY, but no work is scheduled since event was STOP (non-NONE) before. Fc_rport_work is not scheduled, port remains in READY state, but is not added to transport. Things are broken at this point. Libfc rport is ready, but no transport rport created. 6) now a shut causes port state to change to DELETE, event to change to STOP, no work gets scheduled 7) no-shut causes port state to change to RESTART, event remains at STOP, no work gets scheduled (6) and (7) now get repeated everytime we do shut/no-shut. No way to get out of this state. Fcc reset does not help too. Only way to get out is to load/unload module. Fix is to set rdata->event to NONE while processing the STOP/LOGO/FAILED events, inside the discovery and rport locks. Signed-off-by: Abhijeet Joglekar Signed-off-by: Robert Love Signed-off-by: James Bottomley diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c index 35ca0e7..0230052 100644 --- a/drivers/scsi/libfc/fc_rport.c +++ b/drivers/scsi/libfc/fc_rport.c @@ -310,6 +310,7 @@ static void fc_rport_work(struct work_struct *work) restart = 1; else list_del(&rdata->peers); + rdata->event = RPORT_EV_NONE; mutex_unlock(&rdata->rp_mutex); mutex_unlock(&lport->disc.disc_mutex); } -- cgit v0.10.2 From c1ecb90a66c5afc7cc5c9349f9c3714eef4a5cfb Mon Sep 17 00:00:00 2001 From: Chris Leech Date: Thu, 10 Dec 2009 09:59:26 -0800 Subject: [SCSI] libfc: reduce hold time on SCSI host lock Introduce a new lock to protect the list of fc_fcp_pkt structs in libfc instead of using the host lock. This reduces the contention of this heavily used lock, and I see up to a 25% performance gain in CPU bound small I/O tests when scaling out across multiple quad-core CPUs. The big win is in removing the host lock from the completion path completely, as it does not need to be held around the call to scsi_done. Signed-off-by: Chris Leech Signed-off-by: Robert Love Signed-off-by: James Bottomley diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c index c4b58d0..881d5df 100644 --- a/drivers/scsi/libfc/fc_fcp.c +++ b/drivers/scsi/libfc/fc_fcp.c @@ -68,18 +68,20 @@ struct kmem_cache *scsi_pkt_cachep; /** * struct fc_fcp_internal - FCP layer internal data - * @scsi_pkt_pool: Memory pool to draw FCP packets from + * @scsi_pkt_pool: Memory pool to draw FCP packets from + * @scsi_queue_lock: Protects the scsi_pkt_queue * @scsi_pkt_queue: Current FCP packets * @last_can_queue_ramp_down_time: ramp down time * @last_can_queue_ramp_up_time: ramp up time * @max_can_queue: max can_queue size */ struct fc_fcp_internal { - mempool_t *scsi_pkt_pool; - struct list_head scsi_pkt_queue; - unsigned long last_can_queue_ramp_down_time; - unsigned long last_can_queue_ramp_up_time; - int max_can_queue; + mempool_t *scsi_pkt_pool; + spinlock_t scsi_queue_lock; + struct list_head scsi_pkt_queue; + unsigned long last_can_queue_ramp_down_time; + unsigned long last_can_queue_ramp_up_time; + int max_can_queue; }; #define fc_get_scsi_internal(x) ((struct fc_fcp_internal *)(x)->scsi_priv) @@ -410,12 +412,14 @@ static inline struct fc_frame *fc_fcp_frame_alloc(struct fc_lport *lport, unsigned long flags; fp = fc_frame_alloc(lport, len); - if (!fp) { - spin_lock_irqsave(lport->host->host_lock, flags); - fc_fcp_can_queue_ramp_down(lport); - spin_unlock_irqrestore(lport->host->host_lock, flags); - } - return fp; + if (likely(fp)) + return fp; + + /* error case */ + spin_lock_irqsave(lport->host->host_lock, flags); + fc_fcp_can_queue_ramp_down(lport); + spin_unlock_irqrestore(lport->host->host_lock, flags); + return NULL; } /** @@ -990,7 +994,7 @@ static void fc_fcp_cleanup_each_cmd(struct fc_lport *lport, unsigned int id, struct scsi_cmnd *sc_cmd; unsigned long flags; - spin_lock_irqsave(lport->host->host_lock, flags); + spin_lock_irqsave(&si->scsi_queue_lock, flags); restart: list_for_each_entry(fsp, &si->scsi_pkt_queue, list) { sc_cmd = fsp->cmd; @@ -1001,7 +1005,7 @@ restart: continue; fc_fcp_pkt_hold(fsp); - spin_unlock_irqrestore(lport->host->host_lock, flags); + spin_unlock_irqrestore(&si->scsi_queue_lock, flags); if (!fc_fcp_lock_pkt(fsp)) { fc_fcp_cleanup_cmd(fsp, error); @@ -1010,14 +1014,14 @@ restart: } fc_fcp_pkt_release(fsp); - spin_lock_irqsave(lport->host->host_lock, flags); + spin_lock_irqsave(&si->scsi_queue_lock, flags); /* * while we dropped the lock multiple pkts could * have been released, so we have to start over. */ goto restart; } - spin_unlock_irqrestore(lport->host->host_lock, flags); + spin_unlock_irqrestore(&si->scsi_queue_lock, flags); } /** @@ -1035,11 +1039,12 @@ static void fc_fcp_abort_io(struct fc_lport *lport) * @fsp: The FCP packet to send * * Return: Zero for success and -1 for failure - * Locks: Called with the host lock and irqs disabled. + * Locks: Called without locks held */ static int fc_fcp_pkt_send(struct fc_lport *lport, struct fc_fcp_pkt *fsp) { struct fc_fcp_internal *si = fc_get_scsi_internal(lport); + unsigned long flags; int rc; fsp->cmd->SCp.ptr = (char *)fsp; @@ -1049,13 +1054,16 @@ static int fc_fcp_pkt_send(struct fc_lport *lport, struct fc_fcp_pkt *fsp) int_to_scsilun(fsp->cmd->device->lun, (struct scsi_lun *)fsp->cdb_cmd.fc_lun); memcpy(fsp->cdb_cmd.fc_cdb, fsp->cmd->cmnd, fsp->cmd->cmd_len); - list_add_tail(&fsp->list, &si->scsi_pkt_queue); - spin_unlock_irq(lport->host->host_lock); + spin_lock_irqsave(&si->scsi_queue_lock, flags); + list_add_tail(&fsp->list, &si->scsi_pkt_queue); + spin_unlock_irqrestore(&si->scsi_queue_lock, flags); rc = lport->tt.fcp_cmd_send(lport, fsp, fc_fcp_recv); - spin_lock_irq(lport->host->host_lock); - if (rc) + if (unlikely(rc)) { + spin_lock_irqsave(&si->scsi_queue_lock, flags); list_del(&fsp->list); + spin_unlock_irqrestore(&si->scsi_queue_lock, flags); + } return rc; } @@ -1752,6 +1760,7 @@ int fc_queuecommand(struct scsi_cmnd *sc_cmd, void (*done)(struct scsi_cmnd *)) struct fcoe_dev_stats *stats; lport = shost_priv(sc_cmd->device->host); + spin_unlock_irq(lport->host->host_lock); rval = fc_remote_port_chkready(rport); if (rval) { @@ -1834,6 +1843,7 @@ int fc_queuecommand(struct scsi_cmnd *sc_cmd, void (*done)(struct scsi_cmnd *)) rc = SCSI_MLQUEUE_HOST_BUSY; } out: + spin_lock_irq(lport->host->host_lock); return rc; } EXPORT_SYMBOL(fc_queuecommand); @@ -1864,11 +1874,8 @@ static void fc_io_compl(struct fc_fcp_pkt *fsp) lport = fsp->lp; si = fc_get_scsi_internal(lport); - spin_lock_irqsave(lport->host->host_lock, flags); - if (!fsp->cmd) { - spin_unlock_irqrestore(lport->host->host_lock, flags); + if (!fsp->cmd) return; - } /* * if can_queue ramp down is done then try can_queue ramp up @@ -1880,10 +1887,8 @@ static void fc_io_compl(struct fc_fcp_pkt *fsp) sc_cmd = fsp->cmd; fsp->cmd = NULL; - if (!sc_cmd->SCp.ptr) { - spin_unlock_irqrestore(lport->host->host_lock, flags); + if (!sc_cmd->SCp.ptr) return; - } CMD_SCSI_STATUS(sc_cmd) = fsp->cdb_status; switch (fsp->status_code) { @@ -1945,10 +1950,11 @@ static void fc_io_compl(struct fc_fcp_pkt *fsp) break; } + spin_lock_irqsave(&si->scsi_queue_lock, flags); list_del(&fsp->list); + spin_unlock_irqrestore(&si->scsi_queue_lock, flags); sc_cmd->SCp.ptr = NULL; sc_cmd->scsi_done(sc_cmd); - spin_unlock_irqrestore(lport->host->host_lock, flags); /* release ref from initial allocation in queue command */ fc_fcp_pkt_release(fsp); @@ -2216,6 +2222,7 @@ int fc_fcp_init(struct fc_lport *lport) lport->scsi_priv = si; si->max_can_queue = lport->host->can_queue; INIT_LIST_HEAD(&si->scsi_pkt_queue); + spin_lock_init(&si->scsi_queue_lock); si->scsi_pkt_pool = mempool_create_slab_pool(2, scsi_pkt_cachep); if (!si->scsi_pkt_pool) { -- cgit v0.10.2 From 55a66d3c1e57f7e3e554d6ec8011e840f3802f20 Mon Sep 17 00:00:00 2001 From: Vasu Dev Date: Thu, 10 Dec 2009 09:59:31 -0800 Subject: [SCSI] fcoe, libfc: adds enable/disable for fcoe interface This is to allow fcoemon util to enable or disable a fcoe interface according to DCB link state change. Adds sysfs module param enable and disable for this and also updates existing other module param description to be consistent and more accurate since older description had double "fcoe" word with less meaningful netdev reference to user space. Adds code to ignore redundant fc_lport_enter_reset handling for a already disabled fcoe interface by checking LPORT_ST_DISABLED or LPORT_ST_LOGO states, this also prevents lport state transition on link flap on a disabled interface. Above changes required lport state transition to get out of disabled or logo state on call to fc_fabric_login. Signed-off-by: Vasu Dev Signed-off-by: Robert Love Signed-off-by: James Bottomley diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index 9b6aebb..e3896fc 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c @@ -101,6 +101,8 @@ static int fcoe_cpu_callback(struct notifier_block *, unsigned long, void *); static int fcoe_create(const char *, struct kernel_param *); static int fcoe_destroy(const char *, struct kernel_param *); +static int fcoe_enable(const char *, struct kernel_param *); +static int fcoe_disable(const char *, struct kernel_param *); static struct fc_seq *fcoe_elsct_send(struct fc_lport *, u32 did, struct fc_frame *, @@ -115,10 +117,16 @@ static void fcoe_get_lesb(struct fc_lport *, struct fc_els_lesb *); module_param_call(create, fcoe_create, NULL, NULL, S_IWUSR); __MODULE_PARM_TYPE(create, "string"); -MODULE_PARM_DESC(create, "Create fcoe fcoe using net device passed in."); +MODULE_PARM_DESC(create, " Creates fcoe instance on a ethernet interface"); module_param_call(destroy, fcoe_destroy, NULL, NULL, S_IWUSR); __MODULE_PARM_TYPE(destroy, "string"); -MODULE_PARM_DESC(destroy, "Destroy fcoe fcoe"); +MODULE_PARM_DESC(destroy, " Destroys fcoe instance on a ethernet interface"); +module_param_call(enable, fcoe_enable, NULL, NULL, S_IWUSR); +__MODULE_PARM_TYPE(enable, "string"); +MODULE_PARM_DESC(enable, " Enables fcoe on a ethernet interface."); +module_param_call(disable, fcoe_disable, NULL, NULL, S_IWUSR); +__MODULE_PARM_TYPE(disable, "string"); +MODULE_PARM_DESC(disable, " Disables fcoe on a ethernet interface."); /* notification function for packets from net device */ static struct notifier_block fcoe_notifier = { @@ -1859,6 +1867,104 @@ static struct net_device *fcoe_if_to_netdev(const char *buffer) } /** + * fcoe_disable() - Disables a FCoE interface + * @buffer: The name of the Ethernet interface to be disabled + * @kp: The associated kernel parameter + * + * Called from sysfs. + * + * Returns: 0 for success + */ +static int fcoe_disable(const char *buffer, struct kernel_param *kp) +{ + struct fcoe_interface *fcoe; + struct net_device *netdev; + int rc = 0; + + mutex_lock(&fcoe_config_mutex); +#ifdef CONFIG_FCOE_MODULE + /* + * Make sure the module has been initialized, and is not about to be + * removed. Module paramter sysfs files are writable before the + * module_init function is called and after module_exit. + */ + if (THIS_MODULE->state != MODULE_STATE_LIVE) { + rc = -ENODEV; + goto out_nodev; + } +#endif + + netdev = fcoe_if_to_netdev(buffer); + if (!netdev) { + rc = -ENODEV; + goto out_nodev; + } + + rtnl_lock(); + fcoe = fcoe_hostlist_lookup_port(netdev); + rtnl_unlock(); + + if (fcoe) + fc_fabric_logoff(fcoe->ctlr.lp); + else + rc = -ENODEV; + + dev_put(netdev); +out_nodev: + mutex_unlock(&fcoe_config_mutex); + return rc; +} + +/** + * fcoe_enable() - Enables a FCoE interface + * @buffer: The name of the Ethernet interface to be enabled + * @kp: The associated kernel parameter + * + * Called from sysfs. + * + * Returns: 0 for success + */ +static int fcoe_enable(const char *buffer, struct kernel_param *kp) +{ + struct fcoe_interface *fcoe; + struct net_device *netdev; + int rc = 0; + + mutex_lock(&fcoe_config_mutex); +#ifdef CONFIG_FCOE_MODULE + /* + * Make sure the module has been initialized, and is not about to be + * removed. Module paramter sysfs files are writable before the + * module_init function is called and after module_exit. + */ + if (THIS_MODULE->state != MODULE_STATE_LIVE) { + rc = -ENODEV; + goto out_nodev; + } +#endif + + netdev = fcoe_if_to_netdev(buffer); + if (!netdev) { + rc = -ENODEV; + goto out_nodev; + } + + rtnl_lock(); + fcoe = fcoe_hostlist_lookup_port(netdev); + rtnl_unlock(); + + if (fcoe) + rc = fc_fabric_login(fcoe->ctlr.lp); + else + rc = -ENODEV; + + dev_put(netdev); +out_nodev: + mutex_unlock(&fcoe_config_mutex); + return rc; +} + +/** * fcoe_destroy() - Destroy a FCoE interface * @buffer: The name of the Ethernet interface to be destroyed * @kp: The associated kernel parameter diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c index 74338c8..0b16502 100644 --- a/drivers/scsi/libfc/fc_lport.c +++ b/drivers/scsi/libfc/fc_lport.c @@ -537,7 +537,9 @@ int fc_fabric_login(struct fc_lport *lport) int rc = -1; mutex_lock(&lport->lp_mutex); - if (lport->state == LPORT_ST_DISABLED) { + if (lport->state == LPORT_ST_DISABLED || + lport->state == LPORT_ST_LOGO) { + fc_lport_state_enter(lport, LPORT_ST_RESET); fc_lport_enter_reset(lport); rc = 0; } @@ -967,6 +969,9 @@ static void fc_lport_enter_reset(struct fc_lport *lport) FC_LPORT_DBG(lport, "Entered RESET state from %s state\n", fc_lport_state(lport)); + if (lport->state == LPORT_ST_DISABLED || lport->state == LPORT_ST_LOGO) + return; + if (lport->vport) { if (lport->link_up) fc_vport_set_state(lport->vport, FC_VPORT_INITIALIZING); -- cgit v0.10.2 From 53ca353594a254e6bd45ccf2d405aa31bcbb7091 Mon Sep 17 00:00:00 2001 From: adam radford Date: Thu, 10 Dec 2009 11:53:31 -0800 Subject: [SCSI] 3w-9xxx fix bug in sgl loading This small patch fixes a bug in the 3w-9xxx driver where it would load an invalid sgl address in the ioctl path even if request length was zero. Signed-off-by: Adam Radford Signed-off-by: James Bottomley diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c index 3bf7592..84d3bba 100644 --- a/drivers/scsi/3w-9xxx.c +++ b/drivers/scsi/3w-9xxx.c @@ -76,6 +76,7 @@ Fix bug in twa_get_param() on 4GB+. Use pci_resource_len() for ioremap(). 2.26.02.012 - Add power management support. + 2.26.02.013 - Fix bug in twa_load_sgl(). */ #include @@ -100,7 +101,7 @@ #include "3w-9xxx.h" /* Globals */ -#define TW_DRIVER_VERSION "2.26.02.012" +#define TW_DRIVER_VERSION "2.26.02.013" static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT]; static unsigned int twa_device_extension_count; static int twa_major = -1; @@ -1382,10 +1383,12 @@ static void twa_load_sgl(TW_Device_Extension *tw_dev, TW_Command_Full *full_comm newcommand = &full_command_packet->command.newcommand; newcommand->request_id__lunl = cpu_to_le16(TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->request_id__lunl), request_id)); - newcommand->sg_list[0].address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1); - newcommand->sg_list[0].length = cpu_to_le32(length); + if (length) { + newcommand->sg_list[0].address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1); + newcommand->sg_list[0].length = cpu_to_le32(length); + } newcommand->sgl_entries__lunh = - cpu_to_le16(TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->sgl_entries__lunh), 1)); + cpu_to_le16(TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->sgl_entries__lunh), length ? 1 : 0)); } else { oldcommand = &full_command_packet->command.oldcommand; oldcommand->request_id = request_id; -- cgit v0.10.2 From 7539a3b3d1f892dd97eaf094134d7de55c13befe Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 13 Dec 2009 00:07:30 +0100 Subject: sched: Make wakeup side and atomic variants of completion API irq safe Alan Stern noticed that all the wakeup side (and atomic) variants of the completion APIs should be irq safe, but the newly introduced completion_done() and try_wait_for_completion() aren't. The use of the irq unsafe variants in IRQ contexts can cause crashes/hangs. Fix the problem by making them use spin_lock_irqsave() and spin_lock_irqrestore(). Reported-by: Alan Stern Signed-off-by: Rafael J. Wysocki Cc: Linus Torvalds Cc: Zhang Rui Cc: pm list Cc: Peter Zijlstra Cc: David Chinner Cc: Lachlan McIlroy LKML-Reference: <200912130007.30541.rjw@sisk.pl> Signed-off-by: Ingo Molnar diff --git a/kernel/sched.c b/kernel/sched.c index ff39cad..8b3532f 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -5908,14 +5908,15 @@ EXPORT_SYMBOL(wait_for_completion_killable); */ bool try_wait_for_completion(struct completion *x) { + unsigned long flags; int ret = 1; - spin_lock_irq(&x->wait.lock); + spin_lock_irqsave(&x->wait.lock, flags); if (!x->done) ret = 0; else x->done--; - spin_unlock_irq(&x->wait.lock); + spin_unlock_irqrestore(&x->wait.lock, flags); return ret; } EXPORT_SYMBOL(try_wait_for_completion); @@ -5930,12 +5931,13 @@ EXPORT_SYMBOL(try_wait_for_completion); */ bool completion_done(struct completion *x) { + unsigned long flags; int ret = 1; - spin_lock_irq(&x->wait.lock); + spin_lock_irqsave(&x->wait.lock, flags); if (!x->done) ret = 0; - spin_unlock_irq(&x->wait.lock); + spin_unlock_irqrestore(&x->wait.lock, flags); return ret; } EXPORT_SYMBOL(completion_done); -- cgit v0.10.2 From 663997d417330a59a566452f52cfa04c8ffd190b Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sat, 12 Dec 2009 13:57:27 -0800 Subject: sched: Use pr_fmt() and pr_() - Convert printk(KERN_ to pr_ (not KERN_DEBUG) - Add #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - Coalesce long format strings - Add missing \n to "ERROR: !SD_LOAD_BALANCE domain has parent" Signed-off-by: Joe Perches Cc: Peter Zijlstra LKML-Reference: <1260655047.2637.7.camel@Joe-Laptop.home> Signed-off-by: Ingo Molnar diff --git a/kernel/sched.c b/kernel/sched.c index 8b3532f..258c73c 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -26,6 +26,8 @@ * Thomas Gleixner, Mike Kravetz */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -5337,8 +5339,8 @@ static noinline void __schedule_bug(struct task_struct *prev) { struct pt_regs *regs = get_irq_regs(); - printk(KERN_ERR "BUG: scheduling while atomic: %s/%d/0x%08x\n", - prev->comm, prev->pid, preempt_count()); + pr_err("BUG: scheduling while atomic: %s/%d/0x%08x\n", + prev->comm, prev->pid, preempt_count()); debug_show_held_locks(prev); print_modules(); @@ -6906,23 +6908,23 @@ void sched_show_task(struct task_struct *p) unsigned state; state = p->state ? __ffs(p->state) + 1 : 0; - printk(KERN_INFO "%-13.13s %c", p->comm, + pr_info("%-13.13s %c", p->comm, state < sizeof(stat_nam) - 1 ? stat_nam[state] : '?'); #if BITS_PER_LONG == 32 if (state == TASK_RUNNING) - printk(KERN_CONT " running "); + pr_cont(" running "); else - printk(KERN_CONT " %08lx ", thread_saved_pc(p)); + pr_cont(" %08lx ", thread_saved_pc(p)); #else if (state == TASK_RUNNING) - printk(KERN_CONT " running task "); + pr_cont(" running task "); else - printk(KERN_CONT " %016lx ", thread_saved_pc(p)); + pr_cont(" %016lx ", thread_saved_pc(p)); #endif #ifdef CONFIG_DEBUG_STACK_USAGE free = stack_not_used(p); #endif - printk(KERN_CONT "%5lu %5d %6d 0x%08lx\n", free, + pr_cont("%5lu %5d %6d 0x%08lx\n", free, task_pid_nr(p), task_pid_nr(p->real_parent), (unsigned long)task_thread_info(p)->flags); @@ -6934,11 +6936,9 @@ void show_state_filter(unsigned long state_filter) struct task_struct *g, *p; #if BITS_PER_LONG == 32 - printk(KERN_INFO - " task PC stack pid father\n"); + pr_info(" task PC stack pid father\n"); #else - printk(KERN_INFO - " task PC stack pid father\n"); + pr_info(" task PC stack pid father\n"); #endif read_lock(&tasklist_lock); do_each_thread(g, p) { @@ -7296,9 +7296,8 @@ again: * leave kernel. */ if (p->mm && printk_ratelimit()) { - printk(KERN_INFO "process %d (%s) no " - "longer affine to cpu%d\n", - task_pid_nr(p), p->comm, dead_cpu); + pr_info("process %d (%s) no longer affine to cpu%d\n", + task_pid_nr(p), p->comm, dead_cpu); } } @@ -7805,48 +7804,44 @@ static int sched_domain_debug_one(struct sched_domain *sd, int cpu, int level, printk(KERN_DEBUG "%*s domain %d: ", level, "", level); if (!(sd->flags & SD_LOAD_BALANCE)) { - printk("does not load-balance\n"); + pr_cont("does not load-balance\n"); if (sd->parent) - printk(KERN_ERR "ERROR: !SD_LOAD_BALANCE domain" - " has parent"); + pr_err("ERROR: !SD_LOAD_BALANCE domain has parent\n"); return -1; } - printk(KERN_CONT "span %s level %s\n", str, sd->name); + pr_cont("span %s level %s\n", str, sd->name); if (!cpumask_test_cpu(cpu, sched_domain_span(sd))) { - printk(KERN_ERR "ERROR: domain->span does not contain " - "CPU%d\n", cpu); + pr_err("ERROR: domain->span does not contain CPU%d\n", cpu); } if (!cpumask_test_cpu(cpu, sched_group_cpus(group))) { - printk(KERN_ERR "ERROR: domain->groups does not contain" - " CPU%d\n", cpu); + pr_err("ERROR: domain->groups does not contain CPU%d\n", cpu); } printk(KERN_DEBUG "%*s groups:", level + 1, ""); do { if (!group) { - printk("\n"); - printk(KERN_ERR "ERROR: group is NULL\n"); + pr_cont("\n"); + pr_err("ERROR: group is NULL\n"); break; } if (!group->cpu_power) { - printk(KERN_CONT "\n"); - printk(KERN_ERR "ERROR: domain->cpu_power not " - "set\n"); + pr_cont("\n"); + pr_err("ERROR: domain->cpu_power not set\n"); break; } if (!cpumask_weight(sched_group_cpus(group))) { - printk(KERN_CONT "\n"); - printk(KERN_ERR "ERROR: empty group\n"); + pr_cont("\n"); + pr_err("ERROR: empty group\n"); break; } if (cpumask_intersects(groupmask, sched_group_cpus(group))) { - printk(KERN_CONT "\n"); - printk(KERN_ERR "ERROR: repeated CPUs\n"); + pr_cont("\n"); + pr_err("ERROR: repeated CPUs\n"); break; } @@ -7854,23 +7849,21 @@ static int sched_domain_debug_one(struct sched_domain *sd, int cpu, int level, cpulist_scnprintf(str, sizeof(str), sched_group_cpus(group)); - printk(KERN_CONT " %s", str); + pr_cont(" %s", str); if (group->cpu_power != SCHED_LOAD_SCALE) { - printk(KERN_CONT " (cpu_power = %d)", - group->cpu_power); + pr_cont(" (cpu_power = %d)", group->cpu_power); } group = group->next; } while (group != sd->groups); - printk(KERN_CONT "\n"); + pr_cont("\n"); if (!cpumask_equal(sched_domain_span(sd), groupmask)) - printk(KERN_ERR "ERROR: groups don't span domain->span\n"); + pr_err("ERROR: groups don't span domain->span\n"); if (sd->parent && !cpumask_subset(groupmask, sched_domain_span(sd->parent))) - printk(KERN_ERR "ERROR: parent span is not a superset " - "of domain->span\n"); + pr_err("ERROR: parent span is not a superset of domain->span\n"); return 0; } @@ -8426,8 +8419,7 @@ static int build_numa_sched_groups(struct s_data *d, sg = kmalloc_node(sizeof(struct sched_group) + cpumask_size(), GFP_KERNEL, num); if (!sg) { - printk(KERN_WARNING "Can not alloc domain group for node %d\n", - num); + pr_warning("Can not alloc domain group for node %d\n", num); return -ENOMEM; } d->sched_group_nodes[num] = sg; @@ -8456,8 +8448,8 @@ static int build_numa_sched_groups(struct s_data *d, sg = kmalloc_node(sizeof(struct sched_group) + cpumask_size(), GFP_KERNEL, num); if (!sg) { - printk(KERN_WARNING - "Can not alloc domain group for node %d\n", j); + pr_warning("Can not alloc domain group for node %d\n", + j); return -ENOMEM; } sg->cpu_power = 0; @@ -8685,7 +8677,7 @@ static enum s_alloc __visit_domain_allocation_hell(struct s_data *d, d->sched_group_nodes = kcalloc(nr_node_ids, sizeof(struct sched_group *), GFP_KERNEL); if (!d->sched_group_nodes) { - printk(KERN_WARNING "Can not alloc sched group node list\n"); + pr_warning("Can not alloc sched group node list\n"); return sa_notcovered; } sched_group_nodes_bycpu[cpumask_first(cpu_map)] = d->sched_group_nodes; @@ -8702,7 +8694,7 @@ static enum s_alloc __visit_domain_allocation_hell(struct s_data *d, return sa_send_covered; d->rd = alloc_rootdomain(); if (!d->rd) { - printk(KERN_WARNING "Cannot alloc root domain\n"); + pr_warning("Cannot alloc root domain\n"); return sa_tmpmask; } return sa_rootdomain; @@ -9684,13 +9676,11 @@ void __might_sleep(char *file, int line, int preempt_offset) return; prev_jiffy = jiffies; - printk(KERN_ERR - "BUG: sleeping function called from invalid context at %s:%d\n", - file, line); - printk(KERN_ERR - "in_atomic(): %d, irqs_disabled(): %d, pid: %d, name: %s\n", - in_atomic(), irqs_disabled(), - current->pid, current->comm); + pr_err("BUG: sleeping function called from invalid context at %s:%d\n", + file, line); + pr_err("in_atomic(): %d, irqs_disabled(): %d, pid: %d, name: %s\n", + in_atomic(), irqs_disabled(), + current->pid, current->comm); debug_show_held_locks(current); if (irqs_disabled()) diff --git a/kernel/sched_idletask.c b/kernel/sched_idletask.c index 33d5384..b810e22 100644 --- a/kernel/sched_idletask.c +++ b/kernel/sched_idletask.c @@ -35,7 +35,7 @@ static void dequeue_task_idle(struct rq *rq, struct task_struct *p, int sleep) { spin_unlock_irq(&rq->lock); - printk(KERN_ERR "bad: scheduling from the idle thread!\n"); + pr_err("bad: scheduling from the idle thread!\n"); dump_stack(); spin_lock_irq(&rq->lock); } -- cgit v0.10.2 From 500f5a0bf5f0624dae34307010e240ec090e4cde Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Sun, 13 Dec 2009 22:48:54 +0100 Subject: reiserfs: Fix possible recursive lock While allocating the bitmap using vmalloc, we hold the reiserfs lock, which makes lockdep later reporting a possible deadlock as we may swap out pages to allocate memory and then take the reiserfs lock recursively: inconsistent {RECLAIM_FS-ON-W} -> {IN-RECLAIM_FS-W} usage. kswapd0/312 [HC0[0]:SC0[0]:HE1:SE1] takes: (&REISERFS_SB(s)->lock){+.+.?.}, at: [] reiserfs_write_lock+0x28/0x40 {RECLAIM_FS-ON-W} state was registered at: [] mark_held_locks+0x62/0x90 [] lockdep_trace_alloc+0x9a/0xc0 [] kmem_cache_alloc+0x26/0xf0 [] __get_vm_area_node+0x6c/0xf0 [] __vmalloc_node+0x7e/0xa0 [] vmalloc+0x2b/0x30 [] reiserfs_init_bitmap_cache+0x39/0x70 [] reiserfs_fill_super+0x2e8/0xb90 [] get_sb_bdev+0x145/0x180 [] get_super_block+0x21/0x30 [] vfs_kern_mount+0x40/0xd0 [] do_kern_mount+0x39/0xd0 [] do_mount+0x2c7/0x6b0 [] sys_mount+0x66/0xa0 [] mount_block_root+0xc4/0x245 [] mount_root+0x59/0x5f [] prepare_namespace+0x111/0x14b [] kernel_init+0xcf/0xdb [] kernel_thread_helper+0x7/0x1c This is actually fine for two reasons: we call vmalloc at mount time then it's not in the swapping out path. Also the reiserfs lock can be acquired recursively, but since its implementation depends on a mutex, it's hard and not necessary worth it to teach that to lockdep. The lock is useless at mount time anyway, at least until we replay the journal. But let's remove it from this path later as this needs more thinking and is a sensible change. For now we can just relax the lock around vmalloc, Reported-by: Alexander Beregalov Signed-off-by: Frederic Weisbecker Cc: Chris Mason Cc: Ingo Molnar Cc: Thomas Gleixner diff --git a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c index 6854957..65c8727 100644 --- a/fs/reiserfs/bitmap.c +++ b/fs/reiserfs/bitmap.c @@ -1277,7 +1277,10 @@ int reiserfs_init_bitmap_cache(struct super_block *sb) struct reiserfs_bitmap_info *bitmap; unsigned int bmap_nr = reiserfs_bmap_count(sb); + /* Avoid lock recursion in fault case */ + reiserfs_write_unlock(sb); bitmap = vmalloc(sizeof(*bitmap) * bmap_nr); + reiserfs_write_lock(sb); if (bitmap == NULL) return -ENOMEM; -- cgit v0.10.2 From cb1c2e51c5a72f093b5af384b11d2f1c2abd6c13 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Sun, 13 Dec 2009 23:32:06 +0100 Subject: reiserfs: Fix reiserfs lock and journal lock inversion dependency When we were using the bkl, we didn't care about dependencies against other locks, but the mutex conversion created new ones, which is why we have reiserfs_mutex_lock_safe(), which unlocks the reiserfs lock before acquiring another mutex. But this trick actually fails if we have acquired the reiserfs lock recursively, as we try to unlock it to acquire the new mutex without inverted dependency, but we eventually only decrease its depth. This happens in the case of a nested inode creation/deletion. Say we have no space left on the device, we create an inode and tak the lock but fail to create its entry, then we release the inode using iput(), which calls reiserfs_delete_inode() that takes the reiserfs lock recursively. The path eventually ends up in journal_begin() where we try to take the journal safely but we fail because of the reiserfs lock recursion: [ INFO: possible circular locking dependency detected ] 2.6.32-06486-g053fe57 #2 ------------------------------------------------------- vi/23454 is trying to acquire lock: (&journal->j_mutex){+.+...}, at: [] do_journal_begin_r+0x64/0x2f0 but task is already holding lock: (&REISERFS_SB(s)->lock){+.+.+.}, at: [] reiserfs_write_lock+0x28/0x40 which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #1 (&REISERFS_SB(s)->lock){+.+.+.}: [] validate_chain+0xa23/0xf70 [] __lock_acquire+0x4e5/0xa70 [] lock_acquire+0x7a/0xa0 [] mutex_lock_nested+0x5f/0x2b0 [] reiserfs_write_lock+0x28/0x40 [] do_journal_begin_r+0x6b/0x2f0 [] journal_begin+0x7f/0x120 [] reiserfs_remount+0x212/0x4d0 [] do_remount_sb+0x67/0x140 [] do_mount+0x436/0x6b0 [] sys_mount+0x66/0xa0 [] sysenter_do_call+0x12/0x36 -> #0 (&journal->j_mutex){+.+...}: [] validate_chain+0xf68/0xf70 [] __lock_acquire+0x4e5/0xa70 [] lock_acquire+0x7a/0xa0 [] mutex_lock_nested+0x5f/0x2b0 [] do_journal_begin_r+0x64/0x2f0 [] journal_begin+0x7f/0x120 [] reiserfs_delete_inode+0x9f/0x140 [] generic_delete_inode+0x9c/0x150 [] generic_drop_inode+0x3d/0x60 [] iput+0x47/0x50 [] reiserfs_create+0x16c/0x1c0 [] vfs_create+0xc1/0x130 [] do_filp_open+0x81c/0x920 [] do_sys_open+0x4f/0x110 [] sys_open+0x29/0x40 [] sysenter_do_call+0x12/0x36 other info that might help us debug this: 2 locks held by vi/23454: #0: (&sb->s_type->i_mutex_key#5){+.+.+.}, at: [] do_filp_open+0x27e/0x920 #1: (&REISERFS_SB(s)->lock){+.+.+.}, at: [] reiserfs_write_lock+0x28/0x40 stack backtrace: Pid: 23454, comm: vi Not tainted 2.6.32-06486-g053fe57 #2 Call Trace: [] ? printk+0x18/0x1e [] print_circular_bug+0xc0/0xd0 [] validate_chain+0xf68/0xf70 [] ? trace_hardirqs_off+0xb/0x10 [] __lock_acquire+0x4e5/0xa70 [] lock_acquire+0x7a/0xa0 [] ? do_journal_begin_r+0x64/0x2f0 [] mutex_lock_nested+0x5f/0x2b0 [] ? do_journal_begin_r+0x64/0x2f0 [] ? do_journal_begin_r+0x64/0x2f0 [] ? delete_one_xattr+0x0/0x1c0 [] do_journal_begin_r+0x64/0x2f0 [] journal_begin+0x7f/0x120 [] ? reiserfs_delete_xattrs+0x15/0x50 [] reiserfs_delete_inode+0x9f/0x140 [] ? generic_delete_inode+0x5f/0x150 [] ? reiserfs_delete_inode+0x0/0x140 [] generic_delete_inode+0x9c/0x150 [] generic_drop_inode+0x3d/0x60 [] iput+0x47/0x50 [] reiserfs_create+0x16c/0x1c0 [] ? inode_permission+0x7d/0xa0 [] vfs_create+0xc1/0x130 [] ? reiserfs_create+0x0/0x1c0 [] do_filp_open+0x81c/0x920 [] ? trace_hardirqs_off+0xb/0x10 [] ? _spin_unlock+0x1d/0x20 [] ? alloc_fd+0xba/0xf0 [] do_sys_open+0x4f/0x110 [] sys_open+0x29/0x40 [] sysenter_do_call+0x12/0x36 To fix this, use reiserfs_lock_once() from reiserfs_delete_inode() which prevents from adding reiserfs lock recursion. Reported-by: Alexander Beregalov Signed-off-by: Frederic Weisbecker Cc: Chris Mason Cc: Ingo Molnar Cc: Thomas Gleixner diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 3a28e77..bd615df 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c @@ -31,11 +31,12 @@ void reiserfs_delete_inode(struct inode *inode) JOURNAL_PER_BALANCE_CNT * 2 + 2 * REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb); struct reiserfs_transaction_handle th; + int depth; int err; truncate_inode_pages(&inode->i_data, 0); - reiserfs_write_lock(inode->i_sb); + depth = reiserfs_write_lock_once(inode->i_sb); /* The = 0 happens when we abort creating a new inode for some reason like lack of space.. */ if (!(inode->i_state & I_NEW) && INODE_PKEY(inode)->k_objectid != 0) { /* also handles bad_inode case */ @@ -74,7 +75,7 @@ void reiserfs_delete_inode(struct inode *inode) out: clear_inode(inode); /* note this must go after the journal_end to prevent deadlock */ inode->i_blocks = 0; - reiserfs_write_unlock(inode->i_sb); + reiserfs_write_unlock_once(inode->i_sb, depth); } static void _make_cpu_key(struct cpu_key *key, int version, __u32 dirid, -- cgit v0.10.2 From 0eb948dd7f7c3cec37440c16a6c738c8e75efcda Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 19 Nov 2009 11:12:15 +0000 Subject: ARM: cache-l2x0: avoid taking spinlock for every iteration Taking the spinlock for every iteration is very expensive; instead, batch iterations up into 4K blocks, releasing and reacquiring the spinlock between each block. Signed-off-by: Russell King Acked-by: Catalin Marinas diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c index b480f1d..c1b7bff 100644 --- a/arch/arm/mm/cache-l2x0.c +++ b/arch/arm/mm/cache-l2x0.c @@ -31,14 +31,10 @@ static DEFINE_SPINLOCK(l2x0_lock); static inline void sync_writel(unsigned long val, unsigned long reg, unsigned long complete_mask) { - unsigned long flags; - - spin_lock_irqsave(&l2x0_lock, flags); writel(val, l2x0_base + reg); /* wait for the operation to complete */ while (readl(l2x0_base + reg) & complete_mask) ; - spin_unlock_irqrestore(&l2x0_lock, flags); } static inline void cache_sync(void) @@ -48,15 +44,20 @@ static inline void cache_sync(void) static inline void l2x0_inv_all(void) { + unsigned long flags; + /* invalidate all ways */ + spin_lock_irqsave(&l2x0_lock, flags); sync_writel(0xff, L2X0_INV_WAY, 0xff); cache_sync(); + spin_unlock_irqrestore(&l2x0_lock, flags); } static void l2x0_inv_range(unsigned long start, unsigned long end) { - unsigned long addr; + unsigned long flags; + spin_lock_irqsave(&l2x0_lock, flags); if (start & (CACHE_LINE_SIZE - 1)) { start &= ~(CACHE_LINE_SIZE - 1); sync_writel(start, L2X0_CLEAN_INV_LINE_PA, 1); @@ -68,29 +69,67 @@ static void l2x0_inv_range(unsigned long start, unsigned long end) sync_writel(end, L2X0_CLEAN_INV_LINE_PA, 1); } - for (addr = start; addr < end; addr += CACHE_LINE_SIZE) - sync_writel(addr, L2X0_INV_LINE_PA, 1); + while (start < end) { + unsigned long blk_end = start + min(end - start, 4096UL); + + while (start < blk_end) { + sync_writel(start, L2X0_INV_LINE_PA, 1); + start += CACHE_LINE_SIZE; + } + + if (blk_end < end) { + spin_unlock_irqrestore(&l2x0_lock, flags); + spin_lock_irqsave(&l2x0_lock, flags); + } + } cache_sync(); + spin_unlock_irqrestore(&l2x0_lock, flags); } static void l2x0_clean_range(unsigned long start, unsigned long end) { - unsigned long addr; + unsigned long flags; + spin_lock_irqsave(&l2x0_lock, flags); start &= ~(CACHE_LINE_SIZE - 1); - for (addr = start; addr < end; addr += CACHE_LINE_SIZE) - sync_writel(addr, L2X0_CLEAN_LINE_PA, 1); + while (start < end) { + unsigned long blk_end = start + min(end - start, 4096UL); + + while (start < blk_end) { + sync_writel(start, L2X0_CLEAN_LINE_PA, 1); + start += CACHE_LINE_SIZE; + } + + if (blk_end < end) { + spin_unlock_irqrestore(&l2x0_lock, flags); + spin_lock_irqsave(&l2x0_lock, flags); + } + } cache_sync(); + spin_unlock_irqrestore(&l2x0_lock, flags); } static void l2x0_flush_range(unsigned long start, unsigned long end) { - unsigned long addr; + unsigned long flags; + spin_lock_irqsave(&l2x0_lock, flags); start &= ~(CACHE_LINE_SIZE - 1); - for (addr = start; addr < end; addr += CACHE_LINE_SIZE) - sync_writel(addr, L2X0_CLEAN_INV_LINE_PA, 1); + while (start < end) { + unsigned long blk_end = start + min(end - start, 4096UL); + + while (start < blk_end) { + sync_writel(start, L2X0_CLEAN_INV_LINE_PA, 1); + start += CACHE_LINE_SIZE; + } + + if (blk_end < end) { + spin_unlock_irqrestore(&l2x0_lock, flags); + spin_lock_irqsave(&l2x0_lock, flags); + } + } cache_sync(); + spin_unlock_irqrestore(&l2x0_lock, flags); } void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask) -- cgit v0.10.2 From 3d1074349b22c9653e746282564136c87668c2b8 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 19 Nov 2009 11:41:09 +0000 Subject: ARM: cache-l2x0: make better use of background cache handling There's no point having the hardware support background operations if we issue a cache operation, and then wait for it to complete before calculating the address of the next operation. We gain no advantage in the cache controller stalling the bus until completion. What we should be doing is using the 'wait' time productively by calculating the address of the next operation, and only then waiting for the previous operation to complete. This means that cache operations can occur in parallel with the CPU calculating the next address. Signed-off-by: Russell King Acked-by: Catalin Marinas diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c index c1b7bff..ec85dda 100644 --- a/arch/arm/mm/cache-l2x0.c +++ b/arch/arm/mm/cache-l2x0.c @@ -28,18 +28,18 @@ static void __iomem *l2x0_base; static DEFINE_SPINLOCK(l2x0_lock); -static inline void sync_writel(unsigned long val, unsigned long reg, - unsigned long complete_mask) +static inline void cache_wait(void __iomem *reg, unsigned long mask) { - writel(val, l2x0_base + reg); /* wait for the operation to complete */ - while (readl(l2x0_base + reg) & complete_mask) + while (readl(reg) & mask) ; } static inline void cache_sync(void) { - sync_writel(0, L2X0_CACHE_SYNC, 1); + void __iomem *base = l2x0_base; + writel(0, base + L2X0_CACHE_SYNC); + cache_wait(base + L2X0_CACHE_SYNC, 1); } static inline void l2x0_inv_all(void) @@ -48,32 +48,37 @@ static inline void l2x0_inv_all(void) /* invalidate all ways */ spin_lock_irqsave(&l2x0_lock, flags); - sync_writel(0xff, L2X0_INV_WAY, 0xff); + writel(0xff, l2x0_base + L2X0_INV_WAY); + cache_wait(l2x0_base + L2X0_INV_WAY, 0xff); cache_sync(); spin_unlock_irqrestore(&l2x0_lock, flags); } static void l2x0_inv_range(unsigned long start, unsigned long end) { + void __iomem *base = l2x0_base; unsigned long flags; spin_lock_irqsave(&l2x0_lock, flags); if (start & (CACHE_LINE_SIZE - 1)) { start &= ~(CACHE_LINE_SIZE - 1); - sync_writel(start, L2X0_CLEAN_INV_LINE_PA, 1); + cache_wait(base + L2X0_CLEAN_INV_LINE_PA, 1); + writel(start, base + L2X0_CLEAN_INV_LINE_PA); start += CACHE_LINE_SIZE; } if (end & (CACHE_LINE_SIZE - 1)) { end &= ~(CACHE_LINE_SIZE - 1); - sync_writel(end, L2X0_CLEAN_INV_LINE_PA, 1); + cache_wait(base + L2X0_CLEAN_INV_LINE_PA, 1); + writel(end, base + L2X0_CLEAN_INV_LINE_PA); } while (start < end) { unsigned long blk_end = start + min(end - start, 4096UL); while (start < blk_end) { - sync_writel(start, L2X0_INV_LINE_PA, 1); + cache_wait(base + L2X0_INV_LINE_PA, 1); + writel(start, base + L2X0_INV_LINE_PA); start += CACHE_LINE_SIZE; } @@ -82,12 +87,14 @@ static void l2x0_inv_range(unsigned long start, unsigned long end) spin_lock_irqsave(&l2x0_lock, flags); } } + cache_wait(base + L2X0_INV_LINE_PA, 1); cache_sync(); spin_unlock_irqrestore(&l2x0_lock, flags); } static void l2x0_clean_range(unsigned long start, unsigned long end) { + void __iomem *base = l2x0_base; unsigned long flags; spin_lock_irqsave(&l2x0_lock, flags); @@ -96,7 +103,8 @@ static void l2x0_clean_range(unsigned long start, unsigned long end) unsigned long blk_end = start + min(end - start, 4096UL); while (start < blk_end) { - sync_writel(start, L2X0_CLEAN_LINE_PA, 1); + cache_wait(base + L2X0_CLEAN_LINE_PA, 1); + writel(start, base + L2X0_CLEAN_LINE_PA); start += CACHE_LINE_SIZE; } @@ -105,12 +113,14 @@ static void l2x0_clean_range(unsigned long start, unsigned long end) spin_lock_irqsave(&l2x0_lock, flags); } } + cache_wait(base + L2X0_CLEAN_LINE_PA, 1); cache_sync(); spin_unlock_irqrestore(&l2x0_lock, flags); } static void l2x0_flush_range(unsigned long start, unsigned long end) { + void __iomem *base = l2x0_base; unsigned long flags; spin_lock_irqsave(&l2x0_lock, flags); @@ -119,7 +129,8 @@ static void l2x0_flush_range(unsigned long start, unsigned long end) unsigned long blk_end = start + min(end - start, 4096UL); while (start < blk_end) { - sync_writel(start, L2X0_CLEAN_INV_LINE_PA, 1); + cache_wait(base + L2X0_CLEAN_INV_LINE_PA, 1); + writel(start, base + L2X0_CLEAN_INV_LINE_PA); start += CACHE_LINE_SIZE; } @@ -128,6 +139,7 @@ static void l2x0_flush_range(unsigned long start, unsigned long end) spin_lock_irqsave(&l2x0_lock, flags); } } + cache_wait(base + L2X0_CLEAN_INV_LINE_PA, 1); cache_sync(); spin_unlock_irqrestore(&l2x0_lock, flags); } -- cgit v0.10.2 From 149feb00d7c3f4f06896b245533c957b54e3e052 Mon Sep 17 00:00:00 2001 From: Huang Weiyi Date: Mon, 14 Dec 2009 09:24:20 -0500 Subject: ext4: remove unused #include Remove unused #include ('s) in fs/ext4/block_validity.c fs/ext4/mballoc.h Signed-off-by: Huang Weiyi Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/block_validity.c b/fs/ext4/block_validity.c index 4df8621..a60ab9a 100644 --- a/fs/ext4/block_validity.c +++ b/fs/ext4/block_validity.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include "ext4.h" diff --git a/fs/ext4/mballoc.h b/fs/ext4/mballoc.h index 0ca8110..436521c 100644 --- a/fs/ext4/mballoc.h +++ b/fs/ext4/mballoc.h @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include "ext4_jbd2.h" -- cgit v0.10.2 From ccaf5f05b218e5eb41e2f5cdfd26b18dce4a0218 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Fri, 11 Dec 2009 02:21:57 +0100 Subject: ARM: 5848/1: kill flush_ioremap_region() There is not enough users to warrant its existence, and it is actually an obstacle to progress with the new DMA API which cannot cover this case properly. To keep backward compatibility, let's perform the necessary custom cache maintenance locally in the only driver affected. Signed-off-by: Nicolas Pitre Signed-off-by: Russell King diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h index 73eceb8..3db7acd 100644 --- a/arch/arm/include/asm/cacheflush.h +++ b/arch/arm/include/asm/cacheflush.h @@ -465,13 +465,6 @@ static inline void flush_kernel_dcache_page(struct page *page) */ #define flush_icache_page(vma,page) do { } while (0) -static inline void flush_ioremap_region(unsigned long phys, void __iomem *virt, - unsigned offset, size_t size) -{ - const void *start = (void __force *)virt + offset; - dmac_inv_range(start, start + size); -} - /* * flush_cache_vmap() is used when creating mappings (eg, via vmap, * vmalloc, ioremap etc) in kernel space for pages. On non-VIPT diff --git a/arch/arm/mm/proc-syms.c b/arch/arm/mm/proc-syms.c index ac5c800..f604aa8 100644 --- a/arch/arm/mm/proc-syms.c +++ b/arch/arm/mm/proc-syms.c @@ -28,7 +28,6 @@ EXPORT_SYMBOL(__cpuc_flush_user_all); EXPORT_SYMBOL(__cpuc_flush_user_range); EXPORT_SYMBOL(__cpuc_coherent_kern_range); EXPORT_SYMBOL(__cpuc_flush_dcache_page); -EXPORT_SYMBOL(dmac_inv_range); /* because of flush_ioremap_region() */ #else EXPORT_SYMBOL(cpu_cache); #endif diff --git a/drivers/mtd/maps/pxa2xx-flash.c b/drivers/mtd/maps/pxa2xx-flash.c index 74fa075..b13f641 100644 --- a/drivers/mtd/maps/pxa2xx-flash.c +++ b/drivers/mtd/maps/pxa2xx-flash.c @@ -20,14 +20,23 @@ #include #include -#include #include +#define CACHELINESIZE 32 + static void pxa2xx_map_inval_cache(struct map_info *map, unsigned long from, ssize_t len) { - flush_ioremap_region(map->phys, map->cached, from, len); + unsigned long start = (unsigned long)map->cached + from; + unsigned long end = start + len; + + start &= ~(CACHELINESIZE - 1); + while (start < end) { + /* invalidate D cache line */ + asm volatile ("mcr p15, 0, %0, c7, c6, 1" : : "r" (start)); + start += CACHELINESIZE; + } } struct pxa2xx_flash_info { -- cgit v0.10.2 From 2c9b9c8490b60428fa2d1c64042f7c7caed93940 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 26 Nov 2009 12:56:21 +0000 Subject: ARM: add size argument to __cpuc_flush_dcache_page ... and rename the function since it no longer operates on just pages. Signed-off-by: Russell King diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h index 3db7acd..730aefc 100644 --- a/arch/arm/include/asm/cacheflush.h +++ b/arch/arm/include/asm/cacheflush.h @@ -211,7 +211,7 @@ struct cpu_cache_fns { void (*coherent_kern_range)(unsigned long, unsigned long); void (*coherent_user_range)(unsigned long, unsigned long); - void (*flush_kern_dcache_page)(void *); + void (*flush_kern_dcache_area)(void *, size_t); void (*dma_inv_range)(const void *, const void *); void (*dma_clean_range)(const void *, const void *); @@ -236,7 +236,7 @@ extern struct cpu_cache_fns cpu_cache; #define __cpuc_flush_user_range cpu_cache.flush_user_range #define __cpuc_coherent_kern_range cpu_cache.coherent_kern_range #define __cpuc_coherent_user_range cpu_cache.coherent_user_range -#define __cpuc_flush_dcache_page cpu_cache.flush_kern_dcache_page +#define __cpuc_flush_dcache_area cpu_cache.flush_kern_dcache_area /* * These are private to the dma-mapping API. Do not use directly. @@ -255,14 +255,14 @@ extern struct cpu_cache_fns cpu_cache; #define __cpuc_flush_user_range __glue(_CACHE,_flush_user_cache_range) #define __cpuc_coherent_kern_range __glue(_CACHE,_coherent_kern_range) #define __cpuc_coherent_user_range __glue(_CACHE,_coherent_user_range) -#define __cpuc_flush_dcache_page __glue(_CACHE,_flush_kern_dcache_page) +#define __cpuc_flush_dcache_area __glue(_CACHE,_flush_kern_dcache_area) extern void __cpuc_flush_kern_all(void); extern void __cpuc_flush_user_all(void); extern void __cpuc_flush_user_range(unsigned long, unsigned long, unsigned int); extern void __cpuc_coherent_kern_range(unsigned long, unsigned long); extern void __cpuc_coherent_user_range(unsigned long, unsigned long); -extern void __cpuc_flush_dcache_page(void *); +extern void __cpuc_flush_dcache_area(void *, size_t); /* * These are private to the dma-mapping API. Do not use directly. @@ -448,7 +448,7 @@ static inline void flush_kernel_dcache_page(struct page *page) { /* highmem pages are always flushed upon kunmap already */ if ((cache_is_vivt() || cache_is_vipt_aliasing()) && !PageHighMem(page)) - __cpuc_flush_dcache_page(page_address(page)); + __cpuc_flush_dcache_area(page_address(page), PAGE_SIZE); } #define flush_dcache_mmap_lock(mapping) \ diff --git a/arch/arm/mm/cache-fa.S b/arch/arm/mm/cache-fa.S index b63a8f7..a89444a 100644 --- a/arch/arm/mm/cache-fa.S +++ b/arch/arm/mm/cache-fa.S @@ -127,15 +127,16 @@ ENTRY(fa_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_page(kaddr) + * flush_kern_dcache_area(void *addr, size_t size) * * Ensure that the data held in the page kaddr is written back * to the page in question. * - * - kaddr - kernel address (guaranteed to be page aligned) + * - addr - kernel address + * - size - size of region */ -ENTRY(fa_flush_kern_dcache_page) - add r1, r0, #PAGE_SZ +ENTRY(fa_flush_kern_dcache_area) + add r1, r0, r1 1: mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line add r0, r0, #CACHE_DLINESIZE cmp r0, r1 @@ -213,7 +214,7 @@ ENTRY(fa_cache_fns) .long fa_flush_user_cache_range .long fa_coherent_kern_range .long fa_coherent_user_range - .long fa_flush_kern_dcache_page + .long fa_flush_kern_dcache_area .long fa_dma_inv_range .long fa_dma_clean_range .long fa_dma_flush_range diff --git a/arch/arm/mm/cache-v3.S b/arch/arm/mm/cache-v3.S index 8a4abeb..2a48273 100644 --- a/arch/arm/mm/cache-v3.S +++ b/arch/arm/mm/cache-v3.S @@ -72,14 +72,15 @@ ENTRY(v3_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_page(void *page) + * flush_kern_dcache_area(void *page, size_t size) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - addr - page aligned address + * - addr - kernel address + * - size - region size */ -ENTRY(v3_flush_kern_dcache_page) +ENTRY(v3_flush_kern_dcache_area) /* FALLTHROUGH */ /* @@ -129,7 +130,7 @@ ENTRY(v3_cache_fns) .long v3_flush_user_cache_range .long v3_coherent_kern_range .long v3_coherent_user_range - .long v3_flush_kern_dcache_page + .long v3_flush_kern_dcache_area .long v3_dma_inv_range .long v3_dma_clean_range .long v3_dma_flush_range diff --git a/arch/arm/mm/cache-v4.S b/arch/arm/mm/cache-v4.S index 3668611..5c7da3e 100644 --- a/arch/arm/mm/cache-v4.S +++ b/arch/arm/mm/cache-v4.S @@ -82,14 +82,15 @@ ENTRY(v4_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_page(void *page) + * flush_kern_dcache_area(void *addr, size_t size) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - addr - page aligned address + * - addr - kernel address + * - size - region size */ -ENTRY(v4_flush_kern_dcache_page) +ENTRY(v4_flush_kern_dcache_area) /* FALLTHROUGH */ /* @@ -141,7 +142,7 @@ ENTRY(v4_cache_fns) .long v4_flush_user_cache_range .long v4_coherent_kern_range .long v4_coherent_user_range - .long v4_flush_kern_dcache_page + .long v4_flush_kern_dcache_area .long v4_dma_inv_range .long v4_dma_clean_range .long v4_dma_flush_range diff --git a/arch/arm/mm/cache-v4wb.S b/arch/arm/mm/cache-v4wb.S index 2ebc1b3..3dbedf1e 100644 --- a/arch/arm/mm/cache-v4wb.S +++ b/arch/arm/mm/cache-v4wb.S @@ -114,15 +114,16 @@ ENTRY(v4wb_flush_user_cache_range) mov pc, lr /* - * flush_kern_dcache_page(void *page) + * flush_kern_dcache_area(void *addr, size_t size) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - addr - page aligned address + * - addr - kernel address + * - size - region size */ -ENTRY(v4wb_flush_kern_dcache_page) - add r1, r0, #PAGE_SZ +ENTRY(v4wb_flush_kern_dcache_area) + add r1, r0, r1 /* fall through */ /* @@ -224,7 +225,7 @@ ENTRY(v4wb_cache_fns) .long v4wb_flush_user_cache_range .long v4wb_coherent_kern_range .long v4wb_coherent_user_range - .long v4wb_flush_kern_dcache_page + .long v4wb_flush_kern_dcache_area .long v4wb_dma_inv_range .long v4wb_dma_clean_range .long v4wb_dma_flush_range diff --git a/arch/arm/mm/cache-v4wt.S b/arch/arm/mm/cache-v4wt.S index c54fa2c..b3b7410 100644 --- a/arch/arm/mm/cache-v4wt.S +++ b/arch/arm/mm/cache-v4wt.S @@ -117,17 +117,18 @@ ENTRY(v4wt_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_page(void *page) + * flush_kern_dcache_area(void *addr, size_t size) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - addr - page aligned address + * - addr - kernel address + * - size - region size */ -ENTRY(v4wt_flush_kern_dcache_page) +ENTRY(v4wt_flush_kern_dcache_area) mov r2, #0 mcr p15, 0, r2, c7, c5, 0 @ invalidate I cache - add r1, r0, #PAGE_SZ + add r1, r0, r1 /* fallthrough */ /* @@ -180,7 +181,7 @@ ENTRY(v4wt_cache_fns) .long v4wt_flush_user_cache_range .long v4wt_coherent_kern_range .long v4wt_coherent_user_range - .long v4wt_flush_kern_dcache_page + .long v4wt_flush_kern_dcache_area .long v4wt_dma_inv_range .long v4wt_dma_clean_range .long v4wt_dma_flush_range diff --git a/arch/arm/mm/cache-v6.S b/arch/arm/mm/cache-v6.S index 295e25d..4ba0a24 100644 --- a/arch/arm/mm/cache-v6.S +++ b/arch/arm/mm/cache-v6.S @@ -159,15 +159,16 @@ ENDPROC(v6_coherent_user_range) ENDPROC(v6_coherent_kern_range) /* - * v6_flush_kern_dcache_page(kaddr) + * v6_flush_kern_dcache_area(void *addr, size_t size) * * Ensure that the data held in the page kaddr is written back * to the page in question. * - * - kaddr - kernel address (guaranteed to be page aligned) + * - addr - kernel address + * - size - region size */ -ENTRY(v6_flush_kern_dcache_page) - add r1, r0, #PAGE_SZ +ENTRY(v6_flush_kern_dcache_area) + add r1, r0, r1 1: #ifdef HARVARD_CACHE mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line @@ -271,7 +272,7 @@ ENTRY(v6_cache_fns) .long v6_flush_user_cache_range .long v6_coherent_kern_range .long v6_coherent_user_range - .long v6_flush_kern_dcache_page + .long v6_flush_kern_dcache_area .long v6_dma_inv_range .long v6_dma_clean_range .long v6_dma_flush_range diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S index e1bd975..9073db8 100644 --- a/arch/arm/mm/cache-v7.S +++ b/arch/arm/mm/cache-v7.S @@ -186,16 +186,17 @@ ENDPROC(v7_coherent_kern_range) ENDPROC(v7_coherent_user_range) /* - * v7_flush_kern_dcache_page(kaddr) + * v7_flush_kern_dcache_area(void *addr, size_t size) * * Ensure that the data held in the page kaddr is written back * to the page in question. * - * - kaddr - kernel address (guaranteed to be page aligned) + * - addr - kernel address + * - size - region size */ -ENTRY(v7_flush_kern_dcache_page) +ENTRY(v7_flush_kern_dcache_area) dcache_line_size r2, r3 - add r1, r0, #PAGE_SZ + add r1, r0, r1 1: mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line / unified line add r0, r0, r2 @@ -203,7 +204,7 @@ ENTRY(v7_flush_kern_dcache_page) blo 1b dsb mov pc, lr -ENDPROC(v7_flush_kern_dcache_page) +ENDPROC(v7_flush_kern_dcache_area) /* * v7_dma_inv_range(start,end) @@ -279,7 +280,7 @@ ENTRY(v7_cache_fns) .long v7_flush_user_cache_range .long v7_coherent_kern_range .long v7_coherent_user_range - .long v7_flush_kern_dcache_page + .long v7_flush_kern_dcache_area .long v7_dma_inv_range .long v7_dma_clean_range .long v7_dma_flush_range diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c index 329594e..6f3a4b7 100644 --- a/arch/arm/mm/flush.c +++ b/arch/arm/mm/flush.c @@ -131,7 +131,7 @@ void __flush_dcache_page(struct address_space *mapping, struct page *page) */ if (addr) #endif - __cpuc_flush_dcache_page(addr); + __cpuc_flush_dcache_area(addr, PAGE_SIZE); /* * If this is a page cache page, and we have an aliasing VIPT cache, @@ -258,5 +258,5 @@ void __flush_anon_page(struct vm_area_struct *vma, struct page *page, unsigned l * in this mapping of the page. FIXME: this is overkill * since we actually ask for a write-back and invalidate. */ - __cpuc_flush_dcache_page(page_address(page)); + __cpuc_flush_dcache_area(page_address(page), PAGE_SIZE); } diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c index 30f82fb..2be1ec7 100644 --- a/arch/arm/mm/highmem.c +++ b/arch/arm/mm/highmem.c @@ -79,7 +79,7 @@ void kunmap_atomic(void *kvaddr, enum km_type type) unsigned int idx = type + KM_TYPE_NR * smp_processor_id(); if (kvaddr >= (void *)FIXADDR_START) { - __cpuc_flush_dcache_page((void *)vaddr); + __cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE); #ifdef CONFIG_DEBUG_HIGHMEM BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx)); set_pte_ext(TOP_PTE(vaddr), __pte(0), 0); diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c index 900811c..374a831 100644 --- a/arch/arm/mm/nommu.c +++ b/arch/arm/mm/nommu.c @@ -61,7 +61,7 @@ void setup_mm_for_reboot(char mode) void flush_dcache_page(struct page *page) { - __cpuc_flush_dcache_page(page_address(page)); + __cpuc_flush_dcache_area(page_address(page), PAGE_SIZE); } EXPORT_SYMBOL(flush_dcache_page); diff --git a/arch/arm/mm/proc-arm1020.S b/arch/arm/mm/proc-arm1020.S index d9fb4b9..8012e24 100644 --- a/arch/arm/mm/proc-arm1020.S +++ b/arch/arm/mm/proc-arm1020.S @@ -231,17 +231,18 @@ ENTRY(arm1020_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_page(void *page) + * flush_kern_dcache_area(void *addr, size_t size) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - page - page aligned address + * - addr - kernel address + * - size - region size */ -ENTRY(arm1020_flush_kern_dcache_page) +ENTRY(arm1020_flush_kern_dcache_area) mov ip, #0 #ifndef CONFIG_CPU_DCACHE_DISABLE - add r1, r0, #PAGE_SZ + add r1, r0, r1 1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry mcr p15, 0, ip, c7, c10, 4 @ drain WB add r0, r0, #CACHE_DLINESIZE @@ -335,7 +336,7 @@ ENTRY(arm1020_cache_fns) .long arm1020_flush_user_cache_range .long arm1020_coherent_kern_range .long arm1020_coherent_user_range - .long arm1020_flush_kern_dcache_page + .long arm1020_flush_kern_dcache_area .long arm1020_dma_inv_range .long arm1020_dma_clean_range .long arm1020_dma_flush_range diff --git a/arch/arm/mm/proc-arm1020e.S b/arch/arm/mm/proc-arm1020e.S index 7453b75..41fe25d 100644 --- a/arch/arm/mm/proc-arm1020e.S +++ b/arch/arm/mm/proc-arm1020e.S @@ -225,17 +225,18 @@ ENTRY(arm1020e_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_page(void *page) + * flush_kern_dcache_area(void *addr, size_t size) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - page - page aligned address + * - addr - kernel address + * - size - region size */ -ENTRY(arm1020e_flush_kern_dcache_page) +ENTRY(arm1020e_flush_kern_dcache_area) mov ip, #0 #ifndef CONFIG_CPU_DCACHE_DISABLE - add r1, r0, #PAGE_SZ + add r1, r0, r1 1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry add r0, r0, #CACHE_DLINESIZE cmp r0, r1 @@ -321,7 +322,7 @@ ENTRY(arm1020e_cache_fns) .long arm1020e_flush_user_cache_range .long arm1020e_coherent_kern_range .long arm1020e_coherent_user_range - .long arm1020e_flush_kern_dcache_page + .long arm1020e_flush_kern_dcache_area .long arm1020e_dma_inv_range .long arm1020e_dma_clean_range .long arm1020e_dma_flush_range diff --git a/arch/arm/mm/proc-arm1022.S b/arch/arm/mm/proc-arm1022.S index 8eb72d7..20a5b1b 100644 --- a/arch/arm/mm/proc-arm1022.S +++ b/arch/arm/mm/proc-arm1022.S @@ -214,17 +214,18 @@ ENTRY(arm1022_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_page(void *page) + * flush_kern_dcache_area(void *addr, size_t size) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - page - page aligned address + * - addr - kernel address + * - size - region size */ -ENTRY(arm1022_flush_kern_dcache_page) +ENTRY(arm1022_flush_kern_dcache_area) mov ip, #0 #ifndef CONFIG_CPU_DCACHE_DISABLE - add r1, r0, #PAGE_SZ + add r1, r0, r1 1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry add r0, r0, #CACHE_DLINESIZE cmp r0, r1 @@ -310,7 +311,7 @@ ENTRY(arm1022_cache_fns) .long arm1022_flush_user_cache_range .long arm1022_coherent_kern_range .long arm1022_coherent_user_range - .long arm1022_flush_kern_dcache_page + .long arm1022_flush_kern_dcache_area .long arm1022_dma_inv_range .long arm1022_dma_clean_range .long arm1022_dma_flush_range diff --git a/arch/arm/mm/proc-arm1026.S b/arch/arm/mm/proc-arm1026.S index 3b59f0d..96aedb1 100644 --- a/arch/arm/mm/proc-arm1026.S +++ b/arch/arm/mm/proc-arm1026.S @@ -208,17 +208,18 @@ ENTRY(arm1026_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_page(void *page) + * flush_kern_dcache_area(void *addr, size_t size) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - page - page aligned address + * - addr - kernel address + * - size - region size */ -ENTRY(arm1026_flush_kern_dcache_page) +ENTRY(arm1026_flush_kern_dcache_area) mov ip, #0 #ifndef CONFIG_CPU_DCACHE_DISABLE - add r1, r0, #PAGE_SZ + add r1, r0, r1 1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry add r0, r0, #CACHE_DLINESIZE cmp r0, r1 @@ -304,7 +305,7 @@ ENTRY(arm1026_cache_fns) .long arm1026_flush_user_cache_range .long arm1026_coherent_kern_range .long arm1026_coherent_user_range - .long arm1026_flush_kern_dcache_page + .long arm1026_flush_kern_dcache_area .long arm1026_dma_inv_range .long arm1026_dma_clean_range .long arm1026_dma_flush_range diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S index 2b7c197..471669e 100644 --- a/arch/arm/mm/proc-arm920.S +++ b/arch/arm/mm/proc-arm920.S @@ -207,15 +207,16 @@ ENTRY(arm920_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_page(void *page) + * flush_kern_dcache_area(void *addr, size_t size) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - addr - page aligned address + * - addr - kernel address + * - size - region size */ -ENTRY(arm920_flush_kern_dcache_page) - add r1, r0, #PAGE_SZ +ENTRY(arm920_flush_kern_dcache_area) + add r1, r0, r1 1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry add r0, r0, #CACHE_DLINESIZE cmp r0, r1 @@ -293,7 +294,7 @@ ENTRY(arm920_cache_fns) .long arm920_flush_user_cache_range .long arm920_coherent_kern_range .long arm920_coherent_user_range - .long arm920_flush_kern_dcache_page + .long arm920_flush_kern_dcache_area .long arm920_dma_inv_range .long arm920_dma_clean_range .long arm920_dma_flush_range diff --git a/arch/arm/mm/proc-arm922.S b/arch/arm/mm/proc-arm922.S index 06a1aa4..ee111b0 100644 --- a/arch/arm/mm/proc-arm922.S +++ b/arch/arm/mm/proc-arm922.S @@ -209,15 +209,16 @@ ENTRY(arm922_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_page(void *page) + * flush_kern_dcache_area(void *addr, size_t size) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - addr - page aligned address + * - addr - kernel address + * - size - region size */ -ENTRY(arm922_flush_kern_dcache_page) - add r1, r0, #PAGE_SZ +ENTRY(arm922_flush_kern_dcache_area) + add r1, r0, r1 1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry add r0, r0, #CACHE_DLINESIZE cmp r0, r1 @@ -295,7 +296,7 @@ ENTRY(arm922_cache_fns) .long arm922_flush_user_cache_range .long arm922_coherent_kern_range .long arm922_coherent_user_range - .long arm922_flush_kern_dcache_page + .long arm922_flush_kern_dcache_area .long arm922_dma_inv_range .long arm922_dma_clean_range .long arm922_dma_flush_range diff --git a/arch/arm/mm/proc-arm925.S b/arch/arm/mm/proc-arm925.S index cb53435..8deb5bd 100644 --- a/arch/arm/mm/proc-arm925.S +++ b/arch/arm/mm/proc-arm925.S @@ -251,15 +251,16 @@ ENTRY(arm925_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_page(void *page) + * flush_kern_dcache_area(void *addr, size_t size) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - addr - page aligned address + * - addr - kernel address + * - size - region size */ -ENTRY(arm925_flush_kern_dcache_page) - add r1, r0, #PAGE_SZ +ENTRY(arm925_flush_kern_dcache_area) + add r1, r0, r1 1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry add r0, r0, #CACHE_DLINESIZE cmp r0, r1 @@ -346,7 +347,7 @@ ENTRY(arm925_cache_fns) .long arm925_flush_user_cache_range .long arm925_coherent_kern_range .long arm925_coherent_user_range - .long arm925_flush_kern_dcache_page + .long arm925_flush_kern_dcache_area .long arm925_dma_inv_range .long arm925_dma_clean_range .long arm925_dma_flush_range diff --git a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S index 1c48487..64db6e2 100644 --- a/arch/arm/mm/proc-arm926.S +++ b/arch/arm/mm/proc-arm926.S @@ -214,15 +214,16 @@ ENTRY(arm926_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_page(void *page) + * flush_kern_dcache_area(void *addr, size_t size) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - addr - page aligned address + * - addr - kernel address + * - size - region size */ -ENTRY(arm926_flush_kern_dcache_page) - add r1, r0, #PAGE_SZ +ENTRY(arm926_flush_kern_dcache_area) + add r1, r0, r1 1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry add r0, r0, #CACHE_DLINESIZE cmp r0, r1 @@ -309,7 +310,7 @@ ENTRY(arm926_cache_fns) .long arm926_flush_user_cache_range .long arm926_coherent_kern_range .long arm926_coherent_user_range - .long arm926_flush_kern_dcache_page + .long arm926_flush_kern_dcache_area .long arm926_dma_inv_range .long arm926_dma_clean_range .long arm926_dma_flush_range diff --git a/arch/arm/mm/proc-arm940.S b/arch/arm/mm/proc-arm940.S index 5b0f846..8196b9f 100644 --- a/arch/arm/mm/proc-arm940.S +++ b/arch/arm/mm/proc-arm940.S @@ -141,14 +141,15 @@ ENTRY(arm940_coherent_user_range) /* FALLTHROUGH */ /* - * flush_kern_dcache_page(void *page) + * flush_kern_dcache_area(void *addr, size_t size) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - addr - page aligned address + * - addr - kernel address + * - size - region size */ -ENTRY(arm940_flush_kern_dcache_page) +ENTRY(arm940_flush_kern_dcache_area) mov ip, #0 mov r1, #(CACHE_DSEGMENTS - 1) << 4 @ 4 segments 1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries @@ -238,7 +239,7 @@ ENTRY(arm940_cache_fns) .long arm940_flush_user_cache_range .long arm940_coherent_kern_range .long arm940_coherent_user_range - .long arm940_flush_kern_dcache_page + .long arm940_flush_kern_dcache_area .long arm940_dma_inv_range .long arm940_dma_clean_range .long arm940_dma_flush_range diff --git a/arch/arm/mm/proc-arm946.S b/arch/arm/mm/proc-arm946.S index 40c0449..9a95123 100644 --- a/arch/arm/mm/proc-arm946.S +++ b/arch/arm/mm/proc-arm946.S @@ -183,16 +183,17 @@ ENTRY(arm946_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_page(void *page) + * flush_kern_dcache_area(void *addr, size_t size) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - addr - page aligned address + * - addr - kernel address + * - size - region size * (same as arm926) */ -ENTRY(arm946_flush_kern_dcache_page) - add r1, r0, #PAGE_SZ +ENTRY(arm946_flush_kern_dcache_area) + add r1, r0, r1 1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry add r0, r0, #CACHE_DLINESIZE cmp r0, r1 @@ -280,7 +281,7 @@ ENTRY(arm946_cache_fns) .long arm946_flush_user_cache_range .long arm946_coherent_kern_range .long arm946_coherent_user_range - .long arm946_flush_kern_dcache_page + .long arm946_flush_kern_dcache_area .long arm946_dma_inv_range .long arm946_dma_clean_range .long arm946_dma_flush_range diff --git a/arch/arm/mm/proc-feroceon.S b/arch/arm/mm/proc-feroceon.S index d0d7795..dbc3938 100644 --- a/arch/arm/mm/proc-feroceon.S +++ b/arch/arm/mm/proc-feroceon.S @@ -226,16 +226,17 @@ ENTRY(feroceon_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_page(void *page) + * flush_kern_dcache_area(void *addr, size_t size) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - addr - page aligned address + * - addr - kernel address + * - size - region size */ .align 5 -ENTRY(feroceon_flush_kern_dcache_page) - add r1, r0, #PAGE_SZ +ENTRY(feroceon_flush_kern_dcache_area) + add r1, r0, r1 1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry add r0, r0, #CACHE_DLINESIZE cmp r0, r1 @@ -246,7 +247,7 @@ ENTRY(feroceon_flush_kern_dcache_page) mov pc, lr .align 5 -ENTRY(feroceon_range_flush_kern_dcache_page) +ENTRY(feroceon_range_flush_kern_dcache_area) mrs r2, cpsr add r1, r0, #PAGE_SZ - CACHE_DLINESIZE @ top addr is inclusive orr r3, r2, #PSR_I_BIT @@ -372,7 +373,7 @@ ENTRY(feroceon_cache_fns) .long feroceon_flush_user_cache_range .long feroceon_coherent_kern_range .long feroceon_coherent_user_range - .long feroceon_flush_kern_dcache_page + .long feroceon_flush_kern_dcache_area .long feroceon_dma_inv_range .long feroceon_dma_clean_range .long feroceon_dma_flush_range @@ -383,7 +384,7 @@ ENTRY(feroceon_range_cache_fns) .long feroceon_flush_user_cache_range .long feroceon_coherent_kern_range .long feroceon_coherent_user_range - .long feroceon_range_flush_kern_dcache_page + .long feroceon_range_flush_kern_dcache_area .long feroceon_range_dma_inv_range .long feroceon_range_dma_clean_range .long feroceon_range_dma_flush_range diff --git a/arch/arm/mm/proc-mohawk.S b/arch/arm/mm/proc-mohawk.S index 52b5fd7..9674d36 100644 --- a/arch/arm/mm/proc-mohawk.S +++ b/arch/arm/mm/proc-mohawk.S @@ -186,15 +186,16 @@ ENTRY(mohawk_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_page(void *page) + * flush_kern_dcache_area(void *addr, size_t size) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - addr - page aligned address + * - addr - kernel address + * - size - region size */ -ENTRY(mohawk_flush_kern_dcache_page) - add r1, r0, #PAGE_SZ +ENTRY(mohawk_flush_kern_dcache_area) + add r1, r0, r1 1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry add r0, r0, #CACHE_DLINESIZE cmp r0, r1 @@ -273,7 +274,7 @@ ENTRY(mohawk_cache_fns) .long mohawk_flush_user_cache_range .long mohawk_coherent_kern_range .long mohawk_coherent_user_range - .long mohawk_flush_kern_dcache_page + .long mohawk_flush_kern_dcache_area .long mohawk_dma_inv_range .long mohawk_dma_clean_range .long mohawk_dma_flush_range diff --git a/arch/arm/mm/proc-syms.c b/arch/arm/mm/proc-syms.c index f604aa8..3e6210b 100644 --- a/arch/arm/mm/proc-syms.c +++ b/arch/arm/mm/proc-syms.c @@ -27,7 +27,7 @@ EXPORT_SYMBOL(__cpuc_flush_kern_all); EXPORT_SYMBOL(__cpuc_flush_user_all); EXPORT_SYMBOL(__cpuc_flush_user_range); EXPORT_SYMBOL(__cpuc_coherent_kern_range); -EXPORT_SYMBOL(__cpuc_flush_dcache_page); +EXPORT_SYMBOL(__cpuc_flush_dcache_area); #else EXPORT_SYMBOL(cpu_cache); #endif diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S index fab134e..96456f5 100644 --- a/arch/arm/mm/proc-xsc3.S +++ b/arch/arm/mm/proc-xsc3.S @@ -226,15 +226,16 @@ ENTRY(xsc3_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_page(void *page) + * flush_kern_dcache_area(void *addr, size_t size) * * Ensure no D cache aliasing occurs, either with itself or * the I cache. * - * - addr - page aligned address + * - addr - kernel address + * - size - region size */ -ENTRY(xsc3_flush_kern_dcache_page) - add r1, r0, #PAGE_SZ +ENTRY(xsc3_flush_kern_dcache_area) + add r1, r0, r1 1: mcr p15, 0, r0, c7, c14, 1 @ clean/invalidate L1 D line add r0, r0, #CACHELINESIZE cmp r0, r1 @@ -309,7 +310,7 @@ ENTRY(xsc3_cache_fns) .long xsc3_flush_user_cache_range .long xsc3_coherent_kern_range .long xsc3_coherent_user_range - .long xsc3_flush_kern_dcache_page + .long xsc3_flush_kern_dcache_area .long xsc3_dma_inv_range .long xsc3_dma_clean_range .long xsc3_dma_flush_range diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S index f056c28..93df472 100644 --- a/arch/arm/mm/proc-xscale.S +++ b/arch/arm/mm/proc-xscale.S @@ -284,15 +284,16 @@ ENTRY(xscale_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_page(void *page) + * flush_kern_dcache_area(void *addr, size_t size) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - addr - page aligned address + * - addr - kernel address + * - size - region size */ -ENTRY(xscale_flush_kern_dcache_page) - add r1, r0, #PAGE_SZ +ENTRY(xscale_flush_kern_dcache_area) + add r1, r0, r1 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry add r0, r0, #CACHELINESIZE @@ -368,7 +369,7 @@ ENTRY(xscale_cache_fns) .long xscale_flush_user_cache_range .long xscale_coherent_kern_range .long xscale_coherent_user_range - .long xscale_flush_kern_dcache_page + .long xscale_flush_kern_dcache_area .long xscale_dma_inv_range .long xscale_dma_clean_range .long xscale_dma_flush_range @@ -392,7 +393,7 @@ ENTRY(xscale_80200_A0_A1_cache_fns) .long xscale_flush_user_cache_range .long xscale_coherent_kern_range .long xscale_coherent_user_range - .long xscale_flush_kern_dcache_page + .long xscale_flush_kern_dcache_area .long xscale_dma_flush_range .long xscale_dma_clean_range .long xscale_dma_flush_range -- cgit v0.10.2 From f74f7e57ae9fa12b2951ae62ce3557799b318399 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 26 Nov 2009 12:31:15 +0000 Subject: ARM: use flush_kernel_dcache_area() for dmabounce After copying data from the bounce buffer to the real buffer, use flush_kernel_dcache_page() to ensure that data is written back in manner coherent with future userspace mappings. Signed-off-by: Russell King diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c index 5a375e5..bc90364 100644 --- a/arch/arm/common/dmabounce.c +++ b/arch/arm/common/dmabounce.c @@ -308,15 +308,11 @@ static inline void unmap_single(struct device *dev, dma_addr_t dma_addr, memcpy(ptr, buf->safe, size); /* - * DMA buffers must have the same cache properties - * as if they were really used for DMA - which means - * data must be written back to RAM. Note that - * we don't use dmac_flush_range() here for the - * bidirectional case because we know the cache - * lines will be coherent with the data written. + * Since we may have written to a page cache page, + * we need to ensure that the data will be coherent + * with user mappings. */ - dmac_clean_range(ptr, ptr + size); - outer_clean_range(__pa(ptr), __pa(ptr) + size); + __cpuc_flush_kernel_dcache_area(ptr, size); } free_safe_buffer(dev->archdata.dmabounce, buf); } -- cgit v0.10.2 From 84c664730374248adaf420c0846a6158d64413c7 Mon Sep 17 00:00:00 2001 From: David Howells Date: Mon, 21 Dec 2009 10:54:09 -0500 Subject: ext4: Don't ask about supporting ext2/3 in ext4 if ext4 is not configured Don't offer to build ext2/3 support into ext4 if ext4 itself is not configured on. Signed-off-by: David Howells Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/Kconfig b/fs/ext4/Kconfig index 9acf7e8..9ed1bb1 100644 --- a/fs/ext4/Kconfig +++ b/fs/ext4/Kconfig @@ -28,6 +28,7 @@ config EXT4_FS config EXT4_USE_FOR_EXT23 bool "Use ext4 for ext2/ext3 file systems" + depends on EXT4_FS depends on EXT3_FS=n || EXT2_FS=n default y help -- cgit v0.10.2 From 51b7e3c9fbe7d22d4e355101e9a73b44fc5c9feb Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Mon, 21 Dec 2009 10:56:09 -0500 Subject: ext4: add module aliases for ext2 and ext3 Add module aliases for ext2 and ext3 when CONFIG_EXT4_USE_FOR_EXT23 is set. This makes the existing user-space stuff like mkinitrd working as is. Signed-off-by: Takashi Iwai Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 6ed9aa9..0a06fe6 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -4005,6 +4005,7 @@ static inline void unregister_as_ext2(void) { unregister_filesystem(&ext2_fs_type); } +MODULE_ALIAS("ext2"); #else static inline void register_as_ext2(void) { } static inline void unregister_as_ext2(void) { } @@ -4031,6 +4032,7 @@ static inline void unregister_as_ext3(void) { unregister_filesystem(&ext3_fs_type); } +MODULE_ALIAS("ext3"); #else static inline void register_as_ext3(void) { } static inline void unregister_as_ext3(void) { } -- cgit v0.10.2 From 034fb4c95fc0fed4ec4a50778127b92c6f2aec01 Mon Sep 17 00:00:00 2001 From: Surbhi Palande Date: Mon, 14 Dec 2009 09:53:52 -0500 Subject: ext4: replace BUG() with return -EIO in ext4_ext_get_blocks This patch fixes the Kernel BZ #14286. When the address of an extent corresponding to a valid block is corrupted, a -EIO should be reported instead of a BUG(). This situation should not normally not occur except in the case of a corrupted filesystem. If however it does, then the system should not panic directly but depending on the mount time options appropriate action should be taken. If the mount options so permit, the I/O should be gracefully aborted by returning a -EIO. http://bugzilla.kernel.org/show_bug.cgi?id=14286 Signed-off-by: Surbhi Palande Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 3a7928f..8fd6c56 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -3190,7 +3190,13 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, * this situation is possible, though, _during_ tree modification; * this is why assert can't be put in ext4_ext_find_extent() */ - BUG_ON(path[depth].p_ext == NULL && depth != 0); + if (path[depth].p_ext == NULL && depth != 0) { + ext4_error(inode->i_sb, __func__, "bad extent address " + "inode: %lu, iblock: %d, depth: %d", + inode->i_ino, iblock, depth); + err = -EIO; + goto out2; + } eh = path[depth].p_hdr; ex = path[depth].p_ext; -- cgit v0.10.2 From 5fe85be081edf0ac92d83f9c39e0ab5c1371eb82 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 9 Dec 2009 10:14:58 +0000 Subject: sched: Use rcu in sys_sched_getscheduler/sys_sched_getparam() read_lock(&tasklist_lock) does not protect sys_sched_getscheduler and sys_sched_getparam() against a concurrent update of the policy or scheduler parameters as do_sched_setscheduler() does not take the tasklist_lock. The accessed integers can be retrieved w/o locking and are snapshots anyway. Using rcu_read_lock() to protect find_task_by_vpid() and prevent the task struct from going away is not changing the above situation. Signed-off-by: Thomas Gleixner Cc: Peter Zijlstra LKML-Reference: <20091209100706.753790977@linutronix.de> Signed-off-by: Ingo Molnar diff --git a/kernel/sched.c b/kernel/sched.c index 258c73c..1782bee 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -6458,7 +6458,7 @@ SYSCALL_DEFINE1(sched_getscheduler, pid_t, pid) return -EINVAL; retval = -ESRCH; - read_lock(&tasklist_lock); + rcu_read_lock(); p = find_process_by_pid(pid); if (p) { retval = security_task_getscheduler(p); @@ -6466,7 +6466,7 @@ SYSCALL_DEFINE1(sched_getscheduler, pid_t, pid) retval = p->policy | (p->sched_reset_on_fork ? SCHED_RESET_ON_FORK : 0); } - read_unlock(&tasklist_lock); + rcu_read_unlock(); return retval; } @@ -6484,7 +6484,7 @@ SYSCALL_DEFINE2(sched_getparam, pid_t, pid, struct sched_param __user *, param) if (!param || pid < 0) return -EINVAL; - read_lock(&tasklist_lock); + rcu_read_lock(); p = find_process_by_pid(pid); retval = -ESRCH; if (!p) @@ -6495,7 +6495,7 @@ SYSCALL_DEFINE2(sched_getparam, pid_t, pid, struct sched_param __user *, param) goto out_unlock; lp.sched_priority = p->rt_priority; - read_unlock(&tasklist_lock); + rcu_read_unlock(); /* * This one might sleep, we cannot do it with a spinlock held ... @@ -6505,7 +6505,7 @@ SYSCALL_DEFINE2(sched_getparam, pid_t, pid, struct sched_param __user *, param) return retval; out_unlock: - read_unlock(&tasklist_lock); + rcu_read_unlock(); return retval; } -- cgit v0.10.2 From 23f5d142519621b16cf2b378cf8adf4dcf01a616 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 9 Dec 2009 10:15:01 +0000 Subject: sched: Use rcu in sched_get/set_affinity() tasklist_lock is held read locked to protect the find_task_by_vpid() call and to prevent the task going away. sched_setaffinity acquires a task struct ref and drops tasklist lock right away. The access to the cpus_allowed mask is protected by rq->lock. rcu_read_lock() provides the same protection here. Signed-off-by: Thomas Gleixner Cc: Peter Zijlstra LKML-Reference: <20091209100706.789059966@linutronix.de> Signed-off-by: Ingo Molnar diff --git a/kernel/sched.c b/kernel/sched.c index 1782bee..7989312 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -6516,22 +6516,18 @@ long sched_setaffinity(pid_t pid, const struct cpumask *in_mask) int retval; get_online_cpus(); - read_lock(&tasklist_lock); + rcu_read_lock(); p = find_process_by_pid(pid); if (!p) { - read_unlock(&tasklist_lock); + rcu_read_unlock(); put_online_cpus(); return -ESRCH; } - /* - * It is not safe to call set_cpus_allowed with the - * tasklist_lock held. We will bump the task_struct's - * usage count and then drop tasklist_lock. - */ + /* Prevent p going away */ get_task_struct(p); - read_unlock(&tasklist_lock); + rcu_read_unlock(); if (!alloc_cpumask_var(&cpus_allowed, GFP_KERNEL)) { retval = -ENOMEM; @@ -6617,7 +6613,7 @@ long sched_getaffinity(pid_t pid, struct cpumask *mask) int retval; get_online_cpus(); - read_lock(&tasklist_lock); + rcu_read_lock(); retval = -ESRCH; p = find_process_by_pid(pid); @@ -6633,7 +6629,7 @@ long sched_getaffinity(pid_t pid, struct cpumask *mask) task_rq_unlock(rq, &flags); out_unlock: - read_unlock(&tasklist_lock); + rcu_read_unlock(); put_online_cpus(); return retval; -- cgit v0.10.2 From 1a551ae715825bb2a2107a2dd68de024a1fa4e32 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 9 Dec 2009 10:15:11 +0000 Subject: sched: Use rcu in sched_get_rr_param() read_lock(&tasklist_lock) does not protect sys_sched_get_rr_param() against a concurrent update of the policy or scheduler parameters as do_sched_scheduler() does not take the tasklist_lock. The access to task->sched_class->get_rr_interval is protected by task_rq_lock(task). Use rcu_read_lock() to protect find_task_by_vpid() and prevent the task struct from going away. Signed-off-by: Thomas Gleixner Cc: Peter Zijlstra LKML-Reference: <20091209100706.862897167@linutronix.de> Signed-off-by: Ingo Molnar diff --git a/kernel/sched.c b/kernel/sched.c index 7989312..db5c266 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -6873,7 +6873,7 @@ SYSCALL_DEFINE2(sched_rr_get_interval, pid_t, pid, return -EINVAL; retval = -ESRCH; - read_lock(&tasklist_lock); + rcu_read_lock(); p = find_process_by_pid(pid); if (!p) goto out_unlock; @@ -6886,13 +6886,13 @@ SYSCALL_DEFINE2(sched_rr_get_interval, pid_t, pid, time_slice = p->sched_class->get_rr_interval(rq, p); task_rq_unlock(rq, &flags); - read_unlock(&tasklist_lock); + rcu_read_unlock(); jiffies_to_timespec(time_slice, &t); retval = copy_to_user(interval, &t, sizeof(t)) ? -EFAULT : 0; return retval; out_unlock: - read_unlock(&tasklist_lock); + rcu_read_unlock(); return retval; } -- cgit v0.10.2 From b2ec153a637409bd87952d44409905b7d98418b8 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Mon, 14 Dec 2009 14:09:49 -0500 Subject: rt2x00: Fix rt2800usb detection in rt2800lib. rt2800lib incorrectly detected whether RT2800USB was enabled because it didn't account for a modularized RT2800USB driver. Signed-off-by: Gertjan van Wingerde Acked-by: Ivo van Doorn Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index eb1e1d0..6e13650 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -37,7 +37,7 @@ #include #include "rt2x00.h" -#ifdef CONFIG_RT2800USB +#if defined(CONFIG_RT2800USB) || defined(CONFIG_RT2800USB_MODULE) #include "rt2x00usb.h" #endif #include "rt2800lib.h" @@ -1121,7 +1121,7 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) if (rt2x00_intf_is_usb(rt2x00dev)) { rt2800_register_write(rt2x00dev, USB_DMA_CFG, 0x00000000); -#ifdef CONFIG_RT2800USB +#if defined(CONFIG_RT2800USB) || defined(CONFIG_RT2800USB_MODULE) rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0, USB_MODE_RESET, REGISTER_TIMEOUT); #endif -- cgit v0.10.2 From d24deb2580823ab0b8425790c6f5d18e2ff749d8 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Fri, 4 Dec 2009 23:46:54 +0100 Subject: mac80211: Add define for TX headroom reserved by mac80211 itself. Add a definition of the amount of TX headroom reserved by mac80211 itself for its own purposes. Also add BUILD_BUG_ON to validate the value. This define can then be used by drivers to request additional TX headroom in the most efficient manner. Signed-off-by: Gertjan van Wingerde Acked-by: Johannes Berg Signed-off-by: John W. Linville diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 2aff490..538d6b7 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -1737,6 +1737,12 @@ static inline void ieee80211_rx_ni(struct ieee80211_hw *hw, local_bh_enable(); } +/* + * The TX headroom reserved by mac80211 for its own tx_status functions. + * This is enough for the radiotap header. + */ +#define IEEE80211_TX_STATUS_HEADROOM 13 + /** * ieee80211_tx_status - transmit status callback * diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 8116d1a..0d2d948 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -515,6 +515,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) * and we need some headroom for passing the frame to monitor * interfaces, but never both at the same time. */ + BUILD_BUG_ON(IEEE80211_TX_STATUS_HEADROOM != + sizeof(struct ieee80211_tx_status_rtap_hdr)); local->tx_headroom = max_t(unsigned int , local->hw.extra_tx_headroom, sizeof(struct ieee80211_tx_status_rtap_hdr)); -- cgit v0.10.2 From b9f8fcd55bbdb037e5332dbdb7b494f0b70861ac Mon Sep 17 00:00:00 2001 From: David Miller Date: Sun, 13 Dec 2009 18:25:02 -0800 Subject: sched: Fix cpu_clock() in NMIs, on !CONFIG_HAVE_UNSTABLE_SCHED_CLOCK Relax stable-sched-clock architectures to not save/disable/restore hardirqs in cpu_clock(). The background is that I was trying to resolve a sparc64 perf issue when I discovered this problem. On sparc64 I implement pseudo NMIs by simply running the kernel at IRQ level 14 when local_irq_disable() is called, this allows performance counter events to still come in at IRQ level 15. This doesn't work if any code in an NMI handler does local_irq_save() or local_irq_disable() since the "disable" will kick us back to cpu IRQ level 14 thus letting NMIs back in and we recurse. The only path which that does that in the perf event IRQ handling path is the code supporting frequency based events. It uses cpu_clock(). cpu_clock() simply invokes sched_clock() with IRQs disabled. And that's a fundamental bug all on it's own, particularly for the HAVE_UNSTABLE_SCHED_CLOCK case. NMIs can thus get into the sched_clock() code interrupting the local IRQ disable code sections of it. Furthermore, for the not-HAVE_UNSTABLE_SCHED_CLOCK case, the IRQ disabling done by cpu_clock() is just pure overhead and completely unnecessary. So the core problem is that sched_clock() is not NMI safe, but we are invoking it from NMI contexts in the perf events code (via cpu_clock()). A less important issue is the overhead of IRQ disabling when it isn't necessary in cpu_clock(). CONFIG_HAVE_UNSTABLE_SCHED_CLOCK architectures are not affected by this patch. Signed-off-by: David S. Miller Acked-by: Peter Zijlstra Cc: Mike Galbraith LKML-Reference: <20091213.182502.215092085.davem@davemloft.net> Signed-off-by: Ingo Molnar diff --git a/kernel/sched_clock.c b/kernel/sched_clock.c index 479ce56..5b49613 100644 --- a/kernel/sched_clock.c +++ b/kernel/sched_clock.c @@ -236,6 +236,18 @@ void sched_clock_idle_wakeup_event(u64 delta_ns) } EXPORT_SYMBOL_GPL(sched_clock_idle_wakeup_event); +unsigned long long cpu_clock(int cpu) +{ + unsigned long long clock; + unsigned long flags; + + local_irq_save(flags); + clock = sched_clock_cpu(cpu); + local_irq_restore(flags); + + return clock; +} + #else /* CONFIG_HAVE_UNSTABLE_SCHED_CLOCK */ void sched_clock_init(void) @@ -251,17 +263,12 @@ u64 sched_clock_cpu(int cpu) return sched_clock(); } -#endif /* CONFIG_HAVE_UNSTABLE_SCHED_CLOCK */ unsigned long long cpu_clock(int cpu) { - unsigned long long clock; - unsigned long flags; + return sched_clock_cpu(cpu); +} - local_irq_save(flags); - clock = sched_clock_cpu(cpu); - local_irq_restore(flags); +#endif /* CONFIG_HAVE_UNSTABLE_SCHED_CLOCK */ - return clock; -} EXPORT_SYMBOL_GPL(cpu_clock); -- cgit v0.10.2 From 1cf86f6f9b000e98c1b7f866f99633ae67464e2f Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 15 Dec 2009 15:54:21 +0900 Subject: ASoC: ak4642: Add default return value in ak4642_modinit If ak4642 driver was compiled without I2C configs, ak4642_modinit return value will become un-stable. This patch modify this bug Reported-by: Magnus Damm Signed-off-by: Kuninori Morimoto Acked-by: Liam Girdwood Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c index b69861d..3ef16bb 100644 --- a/sound/soc/codecs/ak4642.c +++ b/sound/soc/codecs/ak4642.c @@ -470,7 +470,7 @@ EXPORT_SYMBOL_GPL(soc_codec_dev_ak4642); static int __init ak4642_modinit(void) { - int ret; + int ret = 0; #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) ret = i2c_add_driver(&ak4642_i2c_driver); #endif -- cgit v0.10.2 From 35358281bbc527cd4b0a8d39266c9ad554643e9f Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Tue, 15 Dec 2009 10:34:12 -0800 Subject: omap3: Allow EHCI to be built on OMAP3 OMAP34XX has EHCI, so select USB_ARCH_HAS_EHCI. Signed-off-by: Olof Johansson Acked-by: Anand Gadiyar Acked-by: Felipe Balbi Signed-off-by: Tony Lindgren diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 76c11ee..10eafa7 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -18,6 +18,7 @@ config ARCH_OMAP2430 config ARCH_OMAP34XX bool "OMAP34xx Based System" depends on ARCH_OMAP3 + select USB_ARCH_HAS_EHCI config ARCH_OMAP3430 bool "OMAP3430 support" -- cgit v0.10.2 From 656cb79322319a7bbafec7912d262142e9a38bc0 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 14 Dec 2009 13:12:45 -0800 Subject: drm/i915: In the debugfs interface, unmap our address instead of the page's. Fixes a BUG_ON in kmap_atomic for the following atomic mapping with USER0 type. Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 18476bf..463e8d0 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -272,7 +272,7 @@ static void i915_dump_pages(struct seq_file *m, struct page **pages, int page_co mem = kmap_atomic(pages[page], KM_USER0); for (i = 0; i < PAGE_SIZE; i += 4) seq_printf(m, "%08x : %08x\n", i, mem[i / 4]); - kunmap_atomic(pages[page], KM_USER0); + kunmap_atomic(mem, KM_USER0); } } -- cgit v0.10.2 From c1e7c3ae59b065bf7ff24a05cb609b2f9e314db6 Mon Sep 17 00:00:00 2001 From: Phillip Lougher Date: Mon, 14 Dec 2009 21:45:19 +0000 Subject: bzip2/lzma/gzip: pre-boot malloc doesn't return NULL on failure The trivial malloc implementation used in the pre-boot environment by the decompressors returns a bad pointer on failure (falling through after calling error). This is doubly wrong - the callers expect malloc to return NULL on failure, second the error function is intended to be used by the decompressors to propagate errors to *their* callers. The decompressors have no access to any state set by the error function. Signed-off-by: Phillip Lougher LKML-Reference: <4b26b1ef.hIInb2AYPMtImAJO%phillip@lougher.demon.co.uk> Signed-off-by: H. Peter Anvin diff --git a/include/linux/decompress/mm.h b/include/linux/decompress/mm.h index 12ff8c3..5032b9a 100644 --- a/include/linux/decompress/mm.h +++ b/include/linux/decompress/mm.h @@ -25,7 +25,7 @@ static void *malloc(int size) void *p; if (size < 0) - error("Malloc error"); + return NULL; if (!malloc_ptr) malloc_ptr = free_mem_ptr; @@ -35,7 +35,7 @@ static void *malloc(int size) malloc_ptr += size; if (free_mem_end_ptr && malloc_ptr >= free_mem_end_ptr) - error("Out of memory"); + return NULL; malloc_count++; return p; -- cgit v0.10.2 From d4529862cae4de19fda8d4bbcbddc60f3e48a4cf Mon Sep 17 00:00:00 2001 From: Phillip Lougher Date: Mon, 14 Dec 2009 21:45:19 +0000 Subject: bzip2: Add missing checks for malloc returning NULL Signed-off-by: Phillip Lougher LKML-Reference: <4b26b1ef.ln20bM9Mn4gzB21L%phillip@lougher.demon.co.uk> Signed-off-by: H. Peter Anvin diff --git a/lib/decompress_bunzip2.c b/lib/decompress_bunzip2.c index 7607420..a4e971d 100644 --- a/lib/decompress_bunzip2.c +++ b/lib/decompress_bunzip2.c @@ -637,6 +637,8 @@ static int INIT start_bunzip(struct bunzip_data **bdp, void *inbuf, int len, /* Allocate bunzip_data. Most fields initialize to zero. */ bd = *bdp = malloc(i); + if (!bd) + return RETVAL_OUT_OF_MEMORY; memset(bd, 0, sizeof(struct bunzip_data)); /* Setup input buffer */ bd->inbuf = inbuf; @@ -664,6 +666,8 @@ static int INIT start_bunzip(struct bunzip_data **bdp, void *inbuf, int len, bd->dbufSize = 100000*(i-BZh0); bd->dbuf = large_malloc(bd->dbufSize * sizeof(int)); + if (!bd->dbuf) + return RETVAL_OUT_OF_MEMORY; return RETVAL_OK; } @@ -686,7 +690,7 @@ STATIC int INIT bunzip2(unsigned char *buf, int len, if (!outbuf) { error("Could not allocate output bufer"); - return -1; + return RETVAL_OUT_OF_MEMORY; } if (buf) inbuf = buf; @@ -694,6 +698,7 @@ STATIC int INIT bunzip2(unsigned char *buf, int len, inbuf = malloc(BZIP2_IOBUF_SIZE); if (!inbuf) { error("Could not allocate input bufer"); + i = RETVAL_OUT_OF_MEMORY; goto exit_0; } i = start_bunzip(&bd, inbuf, len, fill); @@ -720,11 +725,14 @@ STATIC int INIT bunzip2(unsigned char *buf, int len, } else if (i == RETVAL_UNEXPECTED_OUTPUT_EOF) { error("Compressed file ends unexpectedly"); } + if (!bd) + goto exit_1; if (bd->dbuf) large_free(bd->dbuf); if (pos) *pos = bd->inbufPos; free(bd); +exit_1: if (!buf) free(inbuf); exit_0: -- cgit v0.10.2 From 54291362d2a5738e1b0495df2abcb9e6b0563a3f Mon Sep 17 00:00:00 2001 From: Phillip Lougher Date: Mon, 14 Dec 2009 21:45:19 +0000 Subject: initramfs: add missing decompressor error check The decompressors return error by calling a supplied error function, and/or by returning an error return value. The initramfs code, however, fails to check the exit code returned by the decompressor, and only checks the error status set by calling the error function. This patch adds a return code check and calls the error function. Signed-off-by: Phillip Lougher LKML-Reference: <4b26b1ef.0+ZWxT6886olqcSc%phillip@lougher.demon.co.uk> Signed-off-by: H. Peter Anvin diff --git a/init/initramfs.c b/init/initramfs.c index 4c00edc..b37d34b 100644 --- a/init/initramfs.c +++ b/init/initramfs.c @@ -413,7 +413,7 @@ static unsigned my_inptr; /* index of next byte to be processed in inbuf */ static char * __init unpack_to_rootfs(char *buf, unsigned len) { - int written; + int written, res; decompress_fn decompress; const char *compress_name; static __initdata char msg_buf[64]; @@ -445,10 +445,12 @@ static char * __init unpack_to_rootfs(char *buf, unsigned len) } this_header = 0; decompress = decompress_method(buf, len, &compress_name); - if (decompress) - decompress(buf, len, NULL, flush_buffer, NULL, + if (decompress) { + res = decompress(buf, len, NULL, flush_buffer, NULL, &my_inptr, error); - else if (compress_name) { + if (res) + error("decompressor failed"); + } else if (compress_name) { if (!message) { snprintf(msg_buf, sizeof msg_buf, "compression method %s not configured", -- cgit v0.10.2 From 0b962d473af32ec334df271b54ff4973cb2b4c73 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Tue, 15 Dec 2009 15:13:07 -0800 Subject: x86, msr/cpuid: Register enough minors for the MSR and CPUID drivers register_chrdev() hardcodes registering 256 minors, presumably to avoid breaking old drivers. However, we need to register enough minors so that we have all possible CPUs. checkpatch warns on this patch, but the patch is correct: NR_CPUS here is a static *upper bound* on the *maximum CPU index* (not *number of CPUs!*) and that is what we want. Reported-and-tested-by: Russ Anderson Cc: Tejun Heo Cc: Alan Cox Cc: Takashi Iwai Cc: Alexander Viro Signed-off-by: H. Peter Anvin LKML-Reference: diff --git a/arch/x86/kernel/cpuid.c b/arch/x86/kernel/cpuid.c index 7ef24a7..cb27fd6 100644 --- a/arch/x86/kernel/cpuid.c +++ b/arch/x86/kernel/cpuid.c @@ -187,7 +187,8 @@ static int __init cpuid_init(void) int i, err = 0; i = 0; - if (register_chrdev(CPUID_MAJOR, "cpu/cpuid", &cpuid_fops)) { + if (__register_chrdev(CPUID_MAJOR, 0, NR_CPUS, + "cpu/cpuid", &cpuid_fops)) { printk(KERN_ERR "cpuid: unable to get major %d for cpuid\n", CPUID_MAJOR); err = -EBUSY; @@ -216,7 +217,7 @@ out_class: } class_destroy(cpuid_class); out_chrdev: - unregister_chrdev(CPUID_MAJOR, "cpu/cpuid"); + __unregister_chrdev(CPUID_MAJOR, 0, NR_CPUS, "cpu/cpuid"); out: return err; } diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c index 572b07e..4bd93c9 100644 --- a/arch/x86/kernel/msr.c +++ b/arch/x86/kernel/msr.c @@ -246,7 +246,7 @@ static int __init msr_init(void) int i, err = 0; i = 0; - if (register_chrdev(MSR_MAJOR, "cpu/msr", &msr_fops)) { + if (__register_chrdev(MSR_MAJOR, 0, NR_CPUS, "cpu/msr", &msr_fops)) { printk(KERN_ERR "msr: unable to get major %d for msr\n", MSR_MAJOR); err = -EBUSY; @@ -274,7 +274,7 @@ out_class: msr_device_destroy(i); class_destroy(msr_class); out_chrdev: - unregister_chrdev(MSR_MAJOR, "cpu/msr"); + __unregister_chrdev(MSR_MAJOR, 0, NR_CPUS, "cpu/msr"); out: return err; } -- cgit v0.10.2 From 8cef4e160d74920ad1725f58c89fd75ec4c4ac38 Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Thu, 12 Nov 2009 09:33:26 +0000 Subject: Btrfs: Avoid superfluous tree-log writeout We allow two log transactions at a time, but use same flag to mark dirty tree-log btree blocks. So we may flush dirty blocks belonging to newer log transaction when committing a log transaction. This patch fixes the issue by using two flags to mark dirty tree-log btree blocks. Signed-off-by: Yan Zheng Signed-off-by: Chris Mason diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 02b6afb..101940f 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -980,12 +980,12 @@ int btrfs_free_log_root_tree(struct btrfs_trans_handle *trans, while (1) { ret = find_first_extent_bit(&log_root_tree->dirty_log_pages, - 0, &start, &end, EXTENT_DIRTY); + 0, &start, &end, EXTENT_DIRTY | EXTENT_NEW); if (ret) break; - clear_extent_dirty(&log_root_tree->dirty_log_pages, - start, end, GFP_NOFS); + clear_extent_bits(&log_root_tree->dirty_log_pages, start, end, + EXTENT_DIRTY | EXTENT_NEW, GFP_NOFS); } eb = fs_info->log_root_tree->node; diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 94627c4..4a86508 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -4919,8 +4919,16 @@ struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans, btrfs_set_buffer_uptodate(buf); if (root->root_key.objectid == BTRFS_TREE_LOG_OBJECTID) { - set_extent_dirty(&root->dirty_log_pages, buf->start, - buf->start + buf->len - 1, GFP_NOFS); + /* + * we allow two log transactions at a time, use different + * EXENT bit to differentiate dirty pages. + */ + if (root->log_transid % 2 == 0) + set_extent_dirty(&root->dirty_log_pages, buf->start, + buf->start + buf->len - 1, GFP_NOFS); + else + set_extent_new(&root->dirty_log_pages, buf->start, + buf->start + buf->len - 1, GFP_NOFS); } else { set_extent_dirty(&trans->transaction->dirty_pages, buf->start, buf->start + buf->len - 1, GFP_NOFS); diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index c207e8c..b7b22c3 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c @@ -354,7 +354,7 @@ int btrfs_end_transaction_throttle(struct btrfs_trans_handle *trans, * those extents are sent to disk but does not wait on them */ int btrfs_write_marked_extents(struct btrfs_root *root, - struct extent_io_tree *dirty_pages) + struct extent_io_tree *dirty_pages, int mark) { int ret; int err = 0; @@ -367,7 +367,7 @@ int btrfs_write_marked_extents(struct btrfs_root *root, while (1) { ret = find_first_extent_bit(dirty_pages, start, &start, &end, - EXTENT_DIRTY); + mark); if (ret) break; while (start <= end) { @@ -413,7 +413,7 @@ int btrfs_write_marked_extents(struct btrfs_root *root, * on all the pages and clear them from the dirty pages state tree */ int btrfs_wait_marked_extents(struct btrfs_root *root, - struct extent_io_tree *dirty_pages) + struct extent_io_tree *dirty_pages, int mark) { int ret; int err = 0; @@ -425,12 +425,12 @@ int btrfs_wait_marked_extents(struct btrfs_root *root, unsigned long index; while (1) { - ret = find_first_extent_bit(dirty_pages, 0, &start, &end, - EXTENT_DIRTY); + ret = find_first_extent_bit(dirty_pages, start, &start, &end, + mark); if (ret) break; - clear_extent_dirty(dirty_pages, start, end, GFP_NOFS); + clear_extent_bits(dirty_pages, start, end, mark, GFP_NOFS); while (start <= end) { index = start >> PAGE_CACHE_SHIFT; start = (u64)(index + 1) << PAGE_CACHE_SHIFT; @@ -460,13 +460,13 @@ int btrfs_wait_marked_extents(struct btrfs_root *root, * those extents are on disk for transaction or log commit */ int btrfs_write_and_wait_marked_extents(struct btrfs_root *root, - struct extent_io_tree *dirty_pages) + struct extent_io_tree *dirty_pages, int mark) { int ret; int ret2; - ret = btrfs_write_marked_extents(root, dirty_pages); - ret2 = btrfs_wait_marked_extents(root, dirty_pages); + ret = btrfs_write_marked_extents(root, dirty_pages, mark); + ret2 = btrfs_wait_marked_extents(root, dirty_pages, mark); return ret || ret2; } @@ -479,7 +479,8 @@ int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans, return filemap_write_and_wait(btree_inode->i_mapping); } return btrfs_write_and_wait_marked_extents(root, - &trans->transaction->dirty_pages); + &trans->transaction->dirty_pages, + EXTENT_DIRTY); } /* diff --git a/fs/btrfs/transaction.h b/fs/btrfs/transaction.h index d4e3e7a..93c7ccb 100644 --- a/fs/btrfs/transaction.h +++ b/fs/btrfs/transaction.h @@ -107,10 +107,10 @@ void btrfs_throttle(struct btrfs_root *root); int btrfs_record_root_in_trans(struct btrfs_trans_handle *trans, struct btrfs_root *root); int btrfs_write_and_wait_marked_extents(struct btrfs_root *root, - struct extent_io_tree *dirty_pages); + struct extent_io_tree *dirty_pages, int mark); int btrfs_write_marked_extents(struct btrfs_root *root, - struct extent_io_tree *dirty_pages); + struct extent_io_tree *dirty_pages, int mark); int btrfs_wait_marked_extents(struct btrfs_root *root, - struct extent_io_tree *dirty_pages); + struct extent_io_tree *dirty_pages, int mark); int btrfs_transaction_in_commit(struct btrfs_fs_info *info); #endif diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 741666a..31da000 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -1977,10 +1977,11 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, { int index1; int index2; + int mark; int ret; struct btrfs_root *log = root->log_root; struct btrfs_root *log_root_tree = root->fs_info->log_root_tree; - u64 log_transid = 0; + unsigned long log_transid = 0; mutex_lock(&root->log_mutex); index1 = root->log_transid % 2; @@ -2014,24 +2015,29 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, goto out; } + log_transid = root->log_transid; + if (log_transid % 2 == 0) + mark = EXTENT_DIRTY; + else + mark = EXTENT_NEW; + /* we start IO on all the marked extents here, but we don't actually * wait for them until later. */ - ret = btrfs_write_marked_extents(log, &log->dirty_log_pages); + ret = btrfs_write_marked_extents(log, &log->dirty_log_pages, mark); BUG_ON(ret); btrfs_set_root_node(&log->root_item, log->node); root->log_batch = 0; - log_transid = root->log_transid; root->log_transid++; log->log_transid = root->log_transid; root->log_start_pid = 0; smp_mb(); /* - * log tree has been flushed to disk, new modifications of - * the log will be written to new positions. so it's safe to - * allow log writers to go in. + * IO has been started, blocks of the log tree have WRITTEN flag set + * in their headers. new modifications of the log will be written to + * new positions. so it's safe to allow log writers to go in. */ mutex_unlock(&root->log_mutex); @@ -2052,7 +2058,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, index2 = log_root_tree->log_transid % 2; if (atomic_read(&log_root_tree->log_commit[index2])) { - btrfs_wait_marked_extents(log, &log->dirty_log_pages); + btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark); wait_log_commit(trans, log_root_tree, log_root_tree->log_transid); mutex_unlock(&log_root_tree->log_mutex); @@ -2072,16 +2078,17 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, * check the full commit flag again */ if (root->fs_info->last_trans_log_full_commit == trans->transid) { - btrfs_wait_marked_extents(log, &log->dirty_log_pages); + btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark); mutex_unlock(&log_root_tree->log_mutex); ret = -EAGAIN; goto out_wake_log_root; } ret = btrfs_write_and_wait_marked_extents(log_root_tree, - &log_root_tree->dirty_log_pages); + &log_root_tree->dirty_log_pages, + EXTENT_DIRTY | EXTENT_NEW); BUG_ON(ret); - btrfs_wait_marked_extents(log, &log->dirty_log_pages); + btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark); btrfs_set_super_log_root(&root->fs_info->super_for_commit, log_root_tree->node->start); @@ -2147,12 +2154,12 @@ int btrfs_free_log(struct btrfs_trans_handle *trans, struct btrfs_root *root) while (1) { ret = find_first_extent_bit(&log->dirty_log_pages, - 0, &start, &end, EXTENT_DIRTY); + 0, &start, &end, EXTENT_DIRTY | EXTENT_NEW); if (ret) break; - clear_extent_dirty(&log->dirty_log_pages, - start, end, GFP_NOFS); + clear_extent_bits(&log->dirty_log_pages, start, end, + EXTENT_DIRTY | EXTENT_NEW, GFP_NOFS); } if (log->log_transid > 0) { -- cgit v0.10.2 From ad48fd754676bfae4139be1a897b1ea58f9aaf21 Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Thu, 12 Nov 2009 09:33:58 +0000 Subject: Btrfs: Add btrfs_duplicate_item btrfs_duplicate_item duplicates item with new key, guaranteeing the source item and the new items are in the same tree leaf and contiguous. It allows us to split file extent in place, without using lock_extent to prevent bookend extent race. Signed-off-by: Yan Zheng Signed-off-by: Chris Mason diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index ec96f3a..9d4ba34 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -37,6 +37,11 @@ static int balance_node_right(struct btrfs_trans_handle *trans, struct extent_buffer *src_buf); static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_path *path, int level, int slot); +static int setup_items_for_insert(struct btrfs_trans_handle *trans, + struct btrfs_root *root, struct btrfs_path *path, + struct btrfs_key *cpu_key, u32 *data_size, + u32 total_data, u32 total_size, int nr); + struct btrfs_path *btrfs_alloc_path(void) { @@ -2997,75 +3002,85 @@ again: return ret; } -/* - * This function splits a single item into two items, - * giving 'new_key' to the new item and splitting the - * old one at split_offset (from the start of the item). - * - * The path may be released by this operation. After - * the split, the path is pointing to the old item. The - * new item is going to be in the same node as the old one. - * - * Note, the item being split must be smaller enough to live alone on - * a tree block with room for one extra struct btrfs_item - * - * This allows us to split the item in place, keeping a lock on the - * leaf the entire time. - */ -int btrfs_split_item(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - struct btrfs_path *path, - struct btrfs_key *new_key, - unsigned long split_offset) +static noinline int setup_leaf_for_split(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct btrfs_path *path, int ins_len) { - u32 item_size; + struct btrfs_key key; struct extent_buffer *leaf; - struct btrfs_key orig_key; - struct btrfs_item *item; - struct btrfs_item *new_item; - int ret = 0; - int slot; - u32 nritems; - u32 orig_offset; - struct btrfs_disk_key disk_key; - char *buf; + struct btrfs_file_extent_item *fi; + u64 extent_len = 0; + u32 item_size; + int ret; leaf = path->nodes[0]; - btrfs_item_key_to_cpu(leaf, &orig_key, path->slots[0]); - if (btrfs_leaf_free_space(root, leaf) >= sizeof(struct btrfs_item)) - goto split; + btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); + + BUG_ON(key.type != BTRFS_EXTENT_DATA_KEY && + key.type != BTRFS_EXTENT_CSUM_KEY); + + if (btrfs_leaf_free_space(root, leaf) >= ins_len) + return 0; item_size = btrfs_item_size_nr(leaf, path->slots[0]); + if (key.type == BTRFS_EXTENT_DATA_KEY) { + fi = btrfs_item_ptr(leaf, path->slots[0], + struct btrfs_file_extent_item); + extent_len = btrfs_file_extent_num_bytes(leaf, fi); + } btrfs_release_path(root, path); - path->search_for_split = 1; path->keep_locks = 1; - - ret = btrfs_search_slot(trans, root, &orig_key, path, 0, 1); + path->search_for_split = 1; + ret = btrfs_search_slot(trans, root, &key, path, 0, 1); path->search_for_split = 0; + if (ret < 0) + goto err; + ret = -EAGAIN; + leaf = path->nodes[0]; /* if our item isn't there or got smaller, return now */ - if (ret != 0 || item_size != btrfs_item_size_nr(path->nodes[0], - path->slots[0])) { - path->keep_locks = 0; - return -EAGAIN; + if (ret > 0 || item_size != btrfs_item_size_nr(leaf, path->slots[0])) + goto err; + + if (key.type == BTRFS_EXTENT_DATA_KEY) { + fi = btrfs_item_ptr(leaf, path->slots[0], + struct btrfs_file_extent_item); + if (extent_len != btrfs_file_extent_num_bytes(leaf, fi)) + goto err; } btrfs_set_path_blocking(path); - ret = split_leaf(trans, root, &orig_key, path, - sizeof(struct btrfs_item), 1); - path->keep_locks = 0; + ret = split_leaf(trans, root, &key, path, ins_len, 1); BUG_ON(ret); + path->keep_locks = 0; btrfs_unlock_up_safe(path, 1); + return 0; +err: + path->keep_locks = 0; + return ret; +} + +static noinline int split_item(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct btrfs_path *path, + struct btrfs_key *new_key, + unsigned long split_offset) +{ + struct extent_buffer *leaf; + struct btrfs_item *item; + struct btrfs_item *new_item; + int slot; + char *buf; + u32 nritems; + u32 item_size; + u32 orig_offset; + struct btrfs_disk_key disk_key; + leaf = path->nodes[0]; BUG_ON(btrfs_leaf_free_space(root, leaf) < sizeof(struct btrfs_item)); -split: - /* - * make sure any changes to the path from split_leaf leave it - * in a blocking state - */ btrfs_set_path_blocking(path); item = btrfs_item_nr(leaf, path->slots[0]); @@ -3073,19 +3088,19 @@ split: item_size = btrfs_item_size(leaf, item); buf = kmalloc(item_size, GFP_NOFS); + if (!buf) + return -ENOMEM; + read_extent_buffer(leaf, buf, btrfs_item_ptr_offset(leaf, path->slots[0]), item_size); - slot = path->slots[0] + 1; - leaf = path->nodes[0]; + slot = path->slots[0] + 1; nritems = btrfs_header_nritems(leaf); - if (slot != nritems) { /* shift the items */ memmove_extent_buffer(leaf, btrfs_item_nr_offset(slot + 1), - btrfs_item_nr_offset(slot), - (nritems - slot) * sizeof(struct btrfs_item)); - + btrfs_item_nr_offset(slot), + (nritems - slot) * sizeof(struct btrfs_item)); } btrfs_cpu_key_to_disk(&disk_key, new_key); @@ -3113,16 +3128,81 @@ split: item_size - split_offset); btrfs_mark_buffer_dirty(leaf); - ret = 0; - if (btrfs_leaf_free_space(root, leaf) < 0) { - btrfs_print_leaf(root, leaf); - BUG(); - } + BUG_ON(btrfs_leaf_free_space(root, leaf) < 0); kfree(buf); + return 0; +} + +/* + * This function splits a single item into two items, + * giving 'new_key' to the new item and splitting the + * old one at split_offset (from the start of the item). + * + * The path may be released by this operation. After + * the split, the path is pointing to the old item. The + * new item is going to be in the same node as the old one. + * + * Note, the item being split must be smaller enough to live alone on + * a tree block with room for one extra struct btrfs_item + * + * This allows us to split the item in place, keeping a lock on the + * leaf the entire time. + */ +int btrfs_split_item(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct btrfs_path *path, + struct btrfs_key *new_key, + unsigned long split_offset) +{ + int ret; + ret = setup_leaf_for_split(trans, root, path, + sizeof(struct btrfs_item)); + if (ret) + return ret; + + ret = split_item(trans, root, path, new_key, split_offset); return ret; } /* + * This function duplicate a item, giving 'new_key' to the new item. + * It guarantees both items live in the same tree leaf and the new item + * is contiguous with the original item. + * + * This allows us to split file extent in place, keeping a lock on the + * leaf the entire time. + */ +int btrfs_duplicate_item(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct btrfs_path *path, + struct btrfs_key *new_key) +{ + struct extent_buffer *leaf; + int ret; + u32 item_size; + + leaf = path->nodes[0]; + item_size = btrfs_item_size_nr(leaf, path->slots[0]); + ret = setup_leaf_for_split(trans, root, path, + item_size + sizeof(struct btrfs_item)); + if (ret) + return ret; + + path->slots[0]++; + ret = setup_items_for_insert(trans, root, path, new_key, &item_size, + item_size, item_size + + sizeof(struct btrfs_item), 1); + BUG_ON(ret); + + leaf = path->nodes[0]; + memcpy_extent_buffer(leaf, + btrfs_item_ptr_offset(leaf, path->slots[0]), + btrfs_item_ptr_offset(leaf, path->slots[0] - 1), + item_size); + return 0; +} + +/* * make the item pointed to by the path smaller. new_size indicates * how small to make it, and from_end tells us if we just chop bytes * off the end of the item or if we shift the item to chop bytes off diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 444b3e9..e3b5800 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -2089,6 +2089,10 @@ int btrfs_split_item(struct btrfs_trans_handle *trans, struct btrfs_path *path, struct btrfs_key *new_key, unsigned long split_offset); +int btrfs_duplicate_item(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct btrfs_path *path, + struct btrfs_key *new_key); int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_key *key, struct btrfs_path *p, int ins_len, int cow); -- cgit v0.10.2 From 920bbbfb05c9fce22e088d20eb9dcb8f96342de9 Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Thu, 12 Nov 2009 09:34:08 +0000 Subject: Btrfs: Rewrite btrfs_drop_extents Rewrite btrfs_drop_extents by using btrfs_duplicate_item, so we can avoid calling lock_extent within transaction. Signed-off-by: Yan Zheng Signed-off-by: Chris Mason diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index e3b5800..ae5b0aa 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -2349,12 +2349,9 @@ int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end, int skip_pinned); int btrfs_check_file(struct btrfs_root *root, struct inode *inode); extern const struct file_operations btrfs_file_operations; -int btrfs_drop_extents(struct btrfs_trans_handle *trans, - struct btrfs_root *root, struct inode *inode, - u64 start, u64 end, u64 locked_end, - u64 inline_limit, u64 *hint_block, int drop_cache); +int btrfs_drop_extents(struct btrfs_trans_handle *trans, struct inode *inode, + u64 start, u64 end, u64 *hint_byte, int drop_cache); int btrfs_mark_extent_written(struct btrfs_trans_handle *trans, - struct btrfs_root *root, struct inode *inode, u64 start, u64 end); int btrfs_release_file(struct inode *inode, struct file *file); diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 06550af..3d2e45c 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -265,319 +265,247 @@ int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end, * If an extent intersects the range but is not entirely inside the range * it is either truncated or split. Anything entirely inside the range * is deleted from the tree. - * - * inline_limit is used to tell this code which offsets in the file to keep - * if they contain inline extents. */ -noinline int btrfs_drop_extents(struct btrfs_trans_handle *trans, - struct btrfs_root *root, struct inode *inode, - u64 start, u64 end, u64 locked_end, - u64 inline_limit, u64 *hint_byte, int drop_cache) +int btrfs_drop_extents(struct btrfs_trans_handle *trans, struct inode *inode, + u64 start, u64 end, u64 *hint_byte, int drop_cache) { - u64 extent_end = 0; - u64 search_start = start; - u64 ram_bytes = 0; - u64 disk_bytenr = 0; - u64 orig_locked_end = locked_end; - u8 compression; - u8 encryption; - u16 other_encoding = 0; + struct btrfs_root *root = BTRFS_I(inode)->root; struct extent_buffer *leaf; - struct btrfs_file_extent_item *extent; + struct btrfs_file_extent_item *fi; struct btrfs_path *path; struct btrfs_key key; - struct btrfs_file_extent_item old; - int keep; - int slot; - int bookend; - int found_type = 0; - int found_extent; - int found_inline; + struct btrfs_key new_key; + u64 search_start = start; + u64 disk_bytenr = 0; + u64 num_bytes = 0; + u64 extent_offset = 0; + u64 extent_end = 0; + int del_nr = 0; + int del_slot = 0; + int extent_type; int recow; int ret; - inline_limit = 0; if (drop_cache) btrfs_drop_extent_cache(inode, start, end - 1, 0); path = btrfs_alloc_path(); if (!path) return -ENOMEM; + while (1) { recow = 0; - btrfs_release_path(root, path); ret = btrfs_lookup_file_extent(trans, root, path, inode->i_ino, search_start, -1); if (ret < 0) - goto out; - if (ret > 0) { - if (path->slots[0] == 0) { - ret = 0; - goto out; - } - path->slots[0]--; + break; + if (ret > 0 && path->slots[0] > 0 && search_start == start) { + leaf = path->nodes[0]; + btrfs_item_key_to_cpu(leaf, &key, path->slots[0] - 1); + if (key.objectid == inode->i_ino && + key.type == BTRFS_EXTENT_DATA_KEY) + path->slots[0]--; } + ret = 0; next_slot: - keep = 0; - bookend = 0; - found_extent = 0; - found_inline = 0; - compression = 0; - encryption = 0; - extent = NULL; leaf = path->nodes[0]; - slot = path->slots[0]; - ret = 0; - btrfs_item_key_to_cpu(leaf, &key, slot); - if (btrfs_key_type(&key) == BTRFS_EXTENT_DATA_KEY && - key.offset >= end) { - goto out; - } - if (btrfs_key_type(&key) > BTRFS_EXTENT_DATA_KEY || - key.objectid != inode->i_ino) { - goto out; - } - if (recow) { - search_start = max(key.offset, start); - continue; - } - if (btrfs_key_type(&key) == BTRFS_EXTENT_DATA_KEY) { - extent = btrfs_item_ptr(leaf, slot, - struct btrfs_file_extent_item); - found_type = btrfs_file_extent_type(leaf, extent); - compression = btrfs_file_extent_compression(leaf, - extent); - encryption = btrfs_file_extent_encryption(leaf, - extent); - other_encoding = btrfs_file_extent_other_encoding(leaf, - extent); - if (found_type == BTRFS_FILE_EXTENT_REG || - found_type == BTRFS_FILE_EXTENT_PREALLOC) { - extent_end = - btrfs_file_extent_disk_bytenr(leaf, - extent); - if (extent_end) - *hint_byte = extent_end; - - extent_end = key.offset + - btrfs_file_extent_num_bytes(leaf, extent); - ram_bytes = btrfs_file_extent_ram_bytes(leaf, - extent); - found_extent = 1; - } else if (found_type == BTRFS_FILE_EXTENT_INLINE) { - found_inline = 1; - extent_end = key.offset + - btrfs_file_extent_inline_len(leaf, extent); + if (path->slots[0] >= btrfs_header_nritems(leaf)) { + BUG_ON(del_nr > 0); + ret = btrfs_next_leaf(root, path); + if (ret < 0) + break; + if (ret > 0) { + ret = 0; + break; } + leaf = path->nodes[0]; + recow = 1; + } + + btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); + if (key.objectid > inode->i_ino || + key.type > BTRFS_EXTENT_DATA_KEY || key.offset >= end) + break; + + fi = btrfs_item_ptr(leaf, path->slots[0], + struct btrfs_file_extent_item); + extent_type = btrfs_file_extent_type(leaf, fi); + + if (extent_type == BTRFS_FILE_EXTENT_REG || + extent_type == BTRFS_FILE_EXTENT_PREALLOC) { + disk_bytenr = btrfs_file_extent_disk_bytenr(leaf, fi); + num_bytes = btrfs_file_extent_disk_num_bytes(leaf, fi); + extent_offset = btrfs_file_extent_offset(leaf, fi); + extent_end = key.offset + + btrfs_file_extent_num_bytes(leaf, fi); + } else if (extent_type == BTRFS_FILE_EXTENT_INLINE) { + extent_end = key.offset + + btrfs_file_extent_inline_len(leaf, fi); } else { + WARN_ON(1); extent_end = search_start; } - /* we found nothing we can drop */ - if ((!found_extent && !found_inline) || - search_start >= extent_end) { - int nextret; - u32 nritems; - nritems = btrfs_header_nritems(leaf); - if (slot >= nritems - 1) { - nextret = btrfs_next_leaf(root, path); - if (nextret) - goto out; - recow = 1; - } else { - path->slots[0]++; - } + if (extent_end <= search_start) { + path->slots[0]++; goto next_slot; } - if (end <= extent_end && start >= key.offset && found_inline) - *hint_byte = EXTENT_MAP_INLINE; - - if (found_extent) { - read_extent_buffer(leaf, &old, (unsigned long)extent, - sizeof(old)); - } - - if (end < extent_end && end >= key.offset) { - bookend = 1; - if (found_inline && start <= key.offset) - keep = 1; + search_start = max(key.offset, start); + if (recow) { + btrfs_release_path(root, path); + continue; } - if (bookend && found_extent) { - if (locked_end < extent_end) { - ret = try_lock_extent(&BTRFS_I(inode)->io_tree, - locked_end, extent_end - 1, - GFP_NOFS); - if (!ret) { - btrfs_release_path(root, path); - lock_extent(&BTRFS_I(inode)->io_tree, - locked_end, extent_end - 1, - GFP_NOFS); - locked_end = extent_end; - continue; - } - locked_end = extent_end; + /* + * | - range to drop - | + * | -------- extent -------- | + */ + if (start > key.offset && end < extent_end) { + BUG_ON(del_nr > 0); + BUG_ON(extent_type == BTRFS_FILE_EXTENT_INLINE); + + memcpy(&new_key, &key, sizeof(new_key)); + new_key.offset = start; + ret = btrfs_duplicate_item(trans, root, path, + &new_key); + if (ret == -EAGAIN) { + btrfs_release_path(root, path); + continue; } - disk_bytenr = le64_to_cpu(old.disk_bytenr); - if (disk_bytenr != 0) { + if (ret < 0) + break; + + leaf = path->nodes[0]; + fi = btrfs_item_ptr(leaf, path->slots[0] - 1, + struct btrfs_file_extent_item); + btrfs_set_file_extent_num_bytes(leaf, fi, + start - key.offset); + + fi = btrfs_item_ptr(leaf, path->slots[0], + struct btrfs_file_extent_item); + + extent_offset += start - key.offset; + btrfs_set_file_extent_offset(leaf, fi, extent_offset); + btrfs_set_file_extent_num_bytes(leaf, fi, + extent_end - start); + btrfs_mark_buffer_dirty(leaf); + + if (disk_bytenr > 0) { ret = btrfs_inc_extent_ref(trans, root, - disk_bytenr, - le64_to_cpu(old.disk_num_bytes), 0, - root->root_key.objectid, - key.objectid, key.offset - - le64_to_cpu(old.offset)); + disk_bytenr, num_bytes, 0, + root->root_key.objectid, + new_key.objectid, + start - extent_offset); BUG_ON(ret); + *hint_byte = disk_bytenr; } + key.offset = start; } + /* + * | ---- range to drop ----- | + * | -------- extent -------- | + */ + if (start <= key.offset && end < extent_end) { + BUG_ON(extent_type == BTRFS_FILE_EXTENT_INLINE); + + memcpy(&new_key, &key, sizeof(new_key)); + new_key.offset = end; + btrfs_set_item_key_safe(trans, root, path, &new_key); - if (found_inline) { - u64 mask = root->sectorsize - 1; - search_start = (extent_end + mask) & ~mask; - } else - search_start = extent_end; - - /* truncate existing extent */ - if (start > key.offset) { - u64 new_num; - u64 old_num; - keep = 1; - WARN_ON(start & (root->sectorsize - 1)); - if (found_extent) { - new_num = start - key.offset; - old_num = btrfs_file_extent_num_bytes(leaf, - extent); - *hint_byte = - btrfs_file_extent_disk_bytenr(leaf, - extent); - if (btrfs_file_extent_disk_bytenr(leaf, - extent)) { - inode_sub_bytes(inode, old_num - - new_num); - } - btrfs_set_file_extent_num_bytes(leaf, - extent, new_num); - btrfs_mark_buffer_dirty(leaf); - } else if (key.offset < inline_limit && - (end > extent_end) && - (inline_limit < extent_end)) { - u32 new_size; - new_size = btrfs_file_extent_calc_inline_size( - inline_limit - key.offset); - inode_sub_bytes(inode, extent_end - - inline_limit); - btrfs_set_file_extent_ram_bytes(leaf, extent, - new_size); - if (!compression && !encryption) { - btrfs_truncate_item(trans, root, path, - new_size, 1); - } + extent_offset += end - key.offset; + btrfs_set_file_extent_offset(leaf, fi, extent_offset); + btrfs_set_file_extent_num_bytes(leaf, fi, + extent_end - end); + btrfs_mark_buffer_dirty(leaf); + if (disk_bytenr > 0) { + inode_sub_bytes(inode, end - key.offset); + *hint_byte = disk_bytenr; } + break; } - /* delete the entire extent */ - if (!keep) { - if (found_inline) - inode_sub_bytes(inode, extent_end - - key.offset); - ret = btrfs_del_item(trans, root, path); - /* TODO update progress marker and return */ - BUG_ON(ret); - extent = NULL; - btrfs_release_path(root, path); - /* the extent will be freed later */ - } - if (bookend && found_inline && start <= key.offset) { - u32 new_size; - new_size = btrfs_file_extent_calc_inline_size( - extent_end - end); - inode_sub_bytes(inode, end - key.offset); - btrfs_set_file_extent_ram_bytes(leaf, extent, - new_size); - if (!compression && !encryption) - ret = btrfs_truncate_item(trans, root, path, - new_size, 0); - BUG_ON(ret); - } - /* create bookend, splitting the extent in two */ - if (bookend && found_extent) { - struct btrfs_key ins; - ins.objectid = inode->i_ino; - ins.offset = end; - btrfs_set_key_type(&ins, BTRFS_EXTENT_DATA_KEY); - btrfs_release_path(root, path); - path->leave_spinning = 1; - ret = btrfs_insert_empty_item(trans, root, path, &ins, - sizeof(*extent)); - BUG_ON(ret); + search_start = extent_end; + /* + * | ---- range to drop ----- | + * | -------- extent -------- | + */ + if (start > key.offset && end >= extent_end) { + BUG_ON(del_nr > 0); + BUG_ON(extent_type == BTRFS_FILE_EXTENT_INLINE); - leaf = path->nodes[0]; - extent = btrfs_item_ptr(leaf, path->slots[0], - struct btrfs_file_extent_item); - write_extent_buffer(leaf, &old, - (unsigned long)extent, sizeof(old)); - - btrfs_set_file_extent_compression(leaf, extent, - compression); - btrfs_set_file_extent_encryption(leaf, extent, - encryption); - btrfs_set_file_extent_other_encoding(leaf, extent, - other_encoding); - btrfs_set_file_extent_offset(leaf, extent, - le64_to_cpu(old.offset) + end - key.offset); - WARN_ON(le64_to_cpu(old.num_bytes) < - (extent_end - end)); - btrfs_set_file_extent_num_bytes(leaf, extent, - extent_end - end); + btrfs_set_file_extent_num_bytes(leaf, fi, + start - key.offset); + btrfs_mark_buffer_dirty(leaf); + if (disk_bytenr > 0) { + inode_sub_bytes(inode, extent_end - start); + *hint_byte = disk_bytenr; + } + if (end == extent_end) + break; - /* - * set the ram bytes to the size of the full extent - * before splitting. This is a worst case flag, - * but its the best we can do because we don't know - * how splitting affects compression - */ - btrfs_set_file_extent_ram_bytes(leaf, extent, - ram_bytes); - btrfs_set_file_extent_type(leaf, extent, found_type); - - btrfs_unlock_up_safe(path, 1); - btrfs_mark_buffer_dirty(path->nodes[0]); - btrfs_set_lock_blocking(path->nodes[0]); - - path->leave_spinning = 0; - btrfs_release_path(root, path); - if (disk_bytenr != 0) - inode_add_bytes(inode, extent_end - end); + path->slots[0]++; + goto next_slot; } - if (found_extent && !keep) { - u64 old_disk_bytenr = le64_to_cpu(old.disk_bytenr); + /* + * | ---- range to drop ----- | + * | ------ extent ------ | + */ + if (start <= key.offset && end >= extent_end) { + if (del_nr == 0) { + del_slot = path->slots[0]; + del_nr = 1; + } else { + BUG_ON(del_slot + del_nr != path->slots[0]); + del_nr++; + } - if (old_disk_bytenr != 0) { + if (extent_type == BTRFS_FILE_EXTENT_INLINE) { inode_sub_bytes(inode, - le64_to_cpu(old.num_bytes)); + extent_end - key.offset); + extent_end = ALIGN(extent_end, + root->sectorsize); + } else if (disk_bytenr > 0) { ret = btrfs_free_extent(trans, root, - old_disk_bytenr, - le64_to_cpu(old.disk_num_bytes), - 0, root->root_key.objectid, + disk_bytenr, num_bytes, 0, + root->root_key.objectid, key.objectid, key.offset - - le64_to_cpu(old.offset)); + extent_offset); BUG_ON(ret); - *hint_byte = old_disk_bytenr; + inode_sub_bytes(inode, + extent_end - key.offset); + *hint_byte = disk_bytenr; } - } - if (search_start >= end) { - ret = 0; - goto out; + if (end == extent_end) + break; + + if (path->slots[0] + 1 < btrfs_header_nritems(leaf)) { + path->slots[0]++; + goto next_slot; + } + + ret = btrfs_del_items(trans, root, path, del_slot, + del_nr); + BUG_ON(ret); + + del_nr = 0; + del_slot = 0; + + btrfs_release_path(root, path); + continue; } + + BUG_ON(1); } -out: - btrfs_free_path(path); - if (locked_end > orig_locked_end) { - unlock_extent(&BTRFS_I(inode)->io_tree, orig_locked_end, - locked_end - 1, GFP_NOFS); + + if (del_nr > 0) { + ret = btrfs_del_items(trans, root, path, del_slot, del_nr); + BUG_ON(ret); } + + btrfs_free_path(path); return ret; } @@ -620,23 +548,23 @@ static int extent_mergeable(struct extent_buffer *leaf, int slot, * two or three. */ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans, - struct btrfs_root *root, struct inode *inode, u64 start, u64 end) { + struct btrfs_root *root = BTRFS_I(inode)->root; struct extent_buffer *leaf; struct btrfs_path *path; struct btrfs_file_extent_item *fi; struct btrfs_key key; + struct btrfs_key new_key; u64 bytenr; u64 num_bytes; u64 extent_end; u64 orig_offset; u64 other_start; u64 other_end; - u64 split = start; - u64 locked_end = end; - int extent_type; - int split_end = 1; + u64 split; + int del_nr = 0; + int del_slot = 0; int ret; btrfs_drop_extent_cache(inode, start, end - 1, 0); @@ -644,12 +572,10 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans, path = btrfs_alloc_path(); BUG_ON(!path); again: + split = start; key.objectid = inode->i_ino; key.type = BTRFS_EXTENT_DATA_KEY; - if (split == start) - key.offset = split; - else - key.offset = split - 1; + key.offset = split; ret = btrfs_search_slot(trans, root, &key, path, -1, 1); if (ret > 0 && path->slots[0] > 0) @@ -661,8 +587,8 @@ again: key.type != BTRFS_EXTENT_DATA_KEY); fi = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_file_extent_item); - extent_type = btrfs_file_extent_type(leaf, fi); - BUG_ON(extent_type != BTRFS_FILE_EXTENT_PREALLOC); + BUG_ON(btrfs_file_extent_type(leaf, fi) != + BTRFS_FILE_EXTENT_PREALLOC); extent_end = key.offset + btrfs_file_extent_num_bytes(leaf, fi); BUG_ON(key.offset > start || extent_end < end); @@ -670,150 +596,91 @@ again: num_bytes = btrfs_file_extent_disk_num_bytes(leaf, fi); orig_offset = key.offset - btrfs_file_extent_offset(leaf, fi); - if (key.offset == start) - split = end; - - if (key.offset == start && extent_end == end) { - int del_nr = 0; - int del_slot = 0; - other_start = end; - other_end = 0; - if (extent_mergeable(leaf, path->slots[0] + 1, inode->i_ino, - bytenr, &other_start, &other_end)) { - extent_end = other_end; - del_slot = path->slots[0] + 1; - del_nr++; - ret = btrfs_free_extent(trans, root, bytenr, num_bytes, - 0, root->root_key.objectid, - inode->i_ino, orig_offset); - BUG_ON(ret); - } - other_start = 0; - other_end = start; - if (extent_mergeable(leaf, path->slots[0] - 1, inode->i_ino, - bytenr, &other_start, &other_end)) { - key.offset = other_start; - del_slot = path->slots[0]; - del_nr++; - ret = btrfs_free_extent(trans, root, bytenr, num_bytes, - 0, root->root_key.objectid, - inode->i_ino, orig_offset); - BUG_ON(ret); - } - split_end = 0; - if (del_nr == 0) { - btrfs_set_file_extent_type(leaf, fi, - BTRFS_FILE_EXTENT_REG); - goto done; + while (start > key.offset || end < extent_end) { + if (key.offset == start) + split = end; + + memcpy(&new_key, &key, sizeof(new_key)); + new_key.offset = split; + ret = btrfs_duplicate_item(trans, root, path, &new_key); + if (ret == -EAGAIN) { + btrfs_release_path(root, path); + goto again; } + BUG_ON(ret < 0); - fi = btrfs_item_ptr(leaf, del_slot - 1, + leaf = path->nodes[0]; + fi = btrfs_item_ptr(leaf, path->slots[0] - 1, struct btrfs_file_extent_item); - btrfs_set_file_extent_type(leaf, fi, BTRFS_FILE_EXTENT_REG); btrfs_set_file_extent_num_bytes(leaf, fi, - extent_end - key.offset); + split - key.offset); + + fi = btrfs_item_ptr(leaf, path->slots[0], + struct btrfs_file_extent_item); + + btrfs_set_file_extent_offset(leaf, fi, split - orig_offset); + btrfs_set_file_extent_num_bytes(leaf, fi, + extent_end - split); btrfs_mark_buffer_dirty(leaf); - ret = btrfs_del_items(trans, root, path, del_slot, del_nr); + ret = btrfs_inc_extent_ref(trans, root, bytenr, num_bytes, 0, + root->root_key.objectid, + inode->i_ino, orig_offset); BUG_ON(ret); - goto release; - } else if (split == start) { - if (locked_end < extent_end) { - ret = try_lock_extent(&BTRFS_I(inode)->io_tree, - locked_end, extent_end - 1, GFP_NOFS); - if (!ret) { - btrfs_release_path(root, path); - lock_extent(&BTRFS_I(inode)->io_tree, - locked_end, extent_end - 1, GFP_NOFS); - locked_end = extent_end; - goto again; - } - locked_end = extent_end; - } - btrfs_set_file_extent_num_bytes(leaf, fi, split - key.offset); - } else { - BUG_ON(key.offset != start); - key.offset = split; - btrfs_set_file_extent_offset(leaf, fi, key.offset - - orig_offset); - btrfs_set_file_extent_num_bytes(leaf, fi, extent_end - split); - btrfs_set_item_key_safe(trans, root, path, &key); - extent_end = split; - } - if (extent_end == end) { - split_end = 0; - extent_type = BTRFS_FILE_EXTENT_REG; - } - if (extent_end == end && split == start) { - other_start = end; - other_end = 0; - if (extent_mergeable(leaf, path->slots[0] + 1, inode->i_ino, - bytenr, &other_start, &other_end)) { - path->slots[0]++; - fi = btrfs_item_ptr(leaf, path->slots[0], - struct btrfs_file_extent_item); - key.offset = split; - btrfs_set_item_key_safe(trans, root, path, &key); - btrfs_set_file_extent_offset(leaf, fi, key.offset - - orig_offset); - btrfs_set_file_extent_num_bytes(leaf, fi, - other_end - split); - goto done; - } - } - if (extent_end == end && split == end) { - other_start = 0; - other_end = start; - if (extent_mergeable(leaf, path->slots[0] - 1 , inode->i_ino, - bytenr, &other_start, &other_end)) { + if (split == start) { + key.offset = start; + } else { + BUG_ON(start != key.offset); path->slots[0]--; - fi = btrfs_item_ptr(leaf, path->slots[0], - struct btrfs_file_extent_item); - btrfs_set_file_extent_num_bytes(leaf, fi, extent_end - - other_start); - goto done; + extent_end = end; } } - btrfs_mark_buffer_dirty(leaf); - - ret = btrfs_inc_extent_ref(trans, root, bytenr, num_bytes, 0, - root->root_key.objectid, - inode->i_ino, orig_offset); - BUG_ON(ret); - btrfs_release_path(root, path); - - key.offset = start; - ret = btrfs_insert_empty_item(trans, root, path, &key, sizeof(*fi)); - BUG_ON(ret); - - leaf = path->nodes[0]; fi = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_file_extent_item); - btrfs_set_file_extent_generation(leaf, fi, trans->transid); - btrfs_set_file_extent_type(leaf, fi, extent_type); - btrfs_set_file_extent_disk_bytenr(leaf, fi, bytenr); - btrfs_set_file_extent_disk_num_bytes(leaf, fi, num_bytes); - btrfs_set_file_extent_offset(leaf, fi, key.offset - orig_offset); - btrfs_set_file_extent_num_bytes(leaf, fi, extent_end - key.offset); - btrfs_set_file_extent_ram_bytes(leaf, fi, num_bytes); - btrfs_set_file_extent_compression(leaf, fi, 0); - btrfs_set_file_extent_encryption(leaf, fi, 0); - btrfs_set_file_extent_other_encoding(leaf, fi, 0); -done: - btrfs_mark_buffer_dirty(leaf); -release: - btrfs_release_path(root, path); - if (split_end && split == start) { - split = end; - goto again; + other_start = end; + other_end = 0; + if (extent_mergeable(leaf, path->slots[0] + 1, inode->i_ino, + bytenr, &other_start, &other_end)) { + extent_end = other_end; + del_slot = path->slots[0] + 1; + del_nr++; + ret = btrfs_free_extent(trans, root, bytenr, num_bytes, + 0, root->root_key.objectid, + inode->i_ino, orig_offset); + BUG_ON(ret); } - if (locked_end > end) { - unlock_extent(&BTRFS_I(inode)->io_tree, end, locked_end - 1, - GFP_NOFS); + other_start = 0; + other_end = start; + if (extent_mergeable(leaf, path->slots[0] - 1, inode->i_ino, + bytenr, &other_start, &other_end)) { + key.offset = other_start; + del_slot = path->slots[0]; + del_nr++; + ret = btrfs_free_extent(trans, root, bytenr, num_bytes, + 0, root->root_key.objectid, + inode->i_ino, orig_offset); + BUG_ON(ret); } + if (del_nr == 0) { + btrfs_set_file_extent_type(leaf, fi, + BTRFS_FILE_EXTENT_REG); + btrfs_mark_buffer_dirty(leaf); + goto out; + } + + fi = btrfs_item_ptr(leaf, del_slot - 1, + struct btrfs_file_extent_item); + btrfs_set_file_extent_type(leaf, fi, BTRFS_FILE_EXTENT_REG); + btrfs_set_file_extent_num_bytes(leaf, fi, + extent_end - key.offset); + btrfs_mark_buffer_dirty(leaf); + + ret = btrfs_del_items(trans, root, path, del_slot, del_nr); + BUG_ON(ret); +out: btrfs_free_path(path); return 0; } diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index b3ad168..ef250be 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -230,8 +230,7 @@ static noinline int cow_file_range_inline(struct btrfs_trans_handle *trans, return 1; } - ret = btrfs_drop_extents(trans, root, inode, start, - aligned_end, aligned_end, start, + ret = btrfs_drop_extents(trans, inode, start, aligned_end, &hint_byte, 1); BUG_ON(ret); @@ -1596,7 +1595,6 @@ static int insert_reserved_file_extent(struct btrfs_trans_handle *trans, struct inode *inode, u64 file_pos, u64 disk_bytenr, u64 disk_num_bytes, u64 num_bytes, u64 ram_bytes, - u64 locked_end, u8 compression, u8 encryption, u16 other_encoding, int extent_type) { @@ -1622,9 +1620,8 @@ static int insert_reserved_file_extent(struct btrfs_trans_handle *trans, * the caller is expected to unpin it and allow it to be merged * with the others. */ - ret = btrfs_drop_extents(trans, root, inode, file_pos, - file_pos + num_bytes, locked_end, - file_pos, &hint, 0); + ret = btrfs_drop_extents(trans, inode, file_pos, file_pos + num_bytes, + &hint, 0); BUG_ON(ret); ins.objectid = inode->i_ino; @@ -1746,7 +1743,7 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) compressed = 1; if (test_bit(BTRFS_ORDERED_PREALLOC, &ordered_extent->flags)) { BUG_ON(compressed); - ret = btrfs_mark_extent_written(trans, root, inode, + ret = btrfs_mark_extent_written(trans, inode, ordered_extent->file_offset, ordered_extent->file_offset + ordered_extent->len); @@ -1758,8 +1755,6 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) ordered_extent->disk_len, ordered_extent->len, ordered_extent->len, - ordered_extent->file_offset + - ordered_extent->len, compressed, 0, 0, BTRFS_FILE_EXTENT_REG); unpin_extent_cache(&BTRFS_I(inode)->extent_tree, @@ -3209,11 +3204,9 @@ int btrfs_cont_expand(struct inode *inode, loff_t size) if (test_bit(EXTENT_FLAG_VACANCY, &em->flags)) { u64 hint_byte = 0; hole_size = last_byte - cur_offset; - err = btrfs_drop_extents(trans, root, inode, - cur_offset, + err = btrfs_drop_extents(trans, inode, cur_offset, cur_offset + hole_size, - block_end, - cur_offset, &hint_byte, 1); + &hint_byte, 1); if (err) break; @@ -5643,7 +5636,7 @@ out_fail: static int prealloc_file_range(struct btrfs_trans_handle *trans, struct inode *inode, u64 start, u64 end, - u64 locked_end, u64 alloc_hint, int mode) + u64 alloc_hint, int mode) { struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_key ins; @@ -5669,8 +5662,7 @@ static int prealloc_file_range(struct btrfs_trans_handle *trans, ret = insert_reserved_file_extent(trans, inode, cur_offset, ins.objectid, ins.offset, ins.offset, - ins.offset, locked_end, - 0, 0, 0, + ins.offset, 0, 0, 0, BTRFS_FILE_EXTENT_PREALLOC); BUG_ON(ret); btrfs_drop_extent_cache(inode, cur_offset, @@ -5779,8 +5771,7 @@ static long btrfs_fallocate(struct inode *inode, int mode, last_byte = (last_byte + mask) & ~mask; if (em->block_start == EXTENT_MAP_HOLE) { ret = prealloc_file_range(trans, inode, cur_offset, - last_byte, locked_end + 1, - alloc_hint, mode); + last_byte, alloc_hint, mode); if (ret < 0) { free_extent_map(em); break; diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index cdbb054..a1a8db8 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -1027,8 +1027,7 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, BUG_ON(!trans); /* punch hole in destination first */ - btrfs_drop_extents(trans, root, inode, off, off + len, - off + len, 0, &hint_byte, 1); + btrfs_drop_extents(trans, inode, off, off + len, &hint_byte, 1); /* clone data */ key.objectid = src->i_ino; diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 31da000..6bbaa10 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -542,8 +542,8 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans, saved_nbytes = inode_get_bytes(inode); /* drop any overlapping extents */ - ret = btrfs_drop_extents(trans, root, inode, - start, extent_end, extent_end, start, &alloc_hint, 1); + ret = btrfs_drop_extents(trans, inode, start, extent_end, + &alloc_hint, 1); BUG_ON(ret); if (found_type == BTRFS_FILE_EXTENT_REG || -- cgit v0.10.2 From 95f158eab42f971c2a6f82cc886ce657d92a25f4 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Fri, 11 Dec 2009 23:44:49 +0100 Subject: drm/nv04-nv40: Fix "conflicting memory types" when saving/restoring VGA fonts. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nv04_display.c b/drivers/gpu/drm/nouveau/nv04_display.c index b47c757..cdddbaa 100644 --- a/drivers/gpu/drm/nouveau/nv04_display.c +++ b/drivers/gpu/drm/nouveau/nv04_display.c @@ -103,6 +103,7 @@ nv04_display_create(struct drm_device *dev) if (nv_two_heads(dev)) nv04_display_store_initial_head_owner(dev); + nouveau_hw_save_vga_fonts(dev, 1); drm_mode_config_init(dev); drm_mode_create_scaling_mode_property(dev); @@ -203,8 +204,6 @@ nv04_display_create(struct drm_device *dev) /* Save previous state */ NVLockVgaCrtcs(dev, false); - nouveau_hw_save_vga_fonts(dev, 1); - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) crtc->funcs->save(crtc); @@ -246,9 +245,9 @@ nv04_display_destroy(struct drm_device *dev) list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) crtc->funcs->restore(crtc); - nouveau_hw_save_vga_fonts(dev, 0); - drm_mode_config_cleanup(dev); + + nouveau_hw_save_vga_fonts(dev, 0); } void -- cgit v0.10.2 From dc4a684ae80d914b2b7fe75b2733a3296a8b92d2 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Tue, 15 Dec 2009 01:34:42 +0100 Subject: drm/i2c/ch7006: Fix load detection false positives right after system init. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/i2c/ch7006_drv.c b/drivers/gpu/drm/i2c/ch7006_drv.c index 9422a74..81681a0 100644 --- a/drivers/gpu/drm/i2c/ch7006_drv.c +++ b/drivers/gpu/drm/i2c/ch7006_drv.c @@ -408,6 +408,11 @@ static int ch7006_probe(struct i2c_client *client, const struct i2c_device_id *i ch7006_info(client, "Detected version ID: %x\n", val); + /* I don't know what this is for, but otherwise I get no + * signal. + */ + ch7006_write(client, 0x3d, 0x0); + return 0; fail: diff --git a/drivers/gpu/drm/i2c/ch7006_mode.c b/drivers/gpu/drm/i2c/ch7006_mode.c index 87f5445..e447dfb 100644 --- a/drivers/gpu/drm/i2c/ch7006_mode.c +++ b/drivers/gpu/drm/i2c/ch7006_mode.c @@ -427,11 +427,6 @@ void ch7006_state_load(struct i2c_client *client, ch7006_load_reg(client, state, CH7006_SUBC_INC7); ch7006_load_reg(client, state, CH7006_PLL_CONTROL); ch7006_load_reg(client, state, CH7006_CALC_SUBC_INC0); - - /* I don't know what this is for, but otherwise I get no - * signal. - */ - ch7006_write(client, 0x3d, 0x0); } void ch7006_state_save(struct i2c_client *client, -- cgit v0.10.2 From ef2bb506687a5f1cc8ef2fef370bb168b2808106 Mon Sep 17 00:00:00 2001 From: Maarten Maathuis Date: Sun, 13 Dec 2009 16:53:12 +0100 Subject: drm/nouveau: use drm debug levels - Use driver level (0x2) for NV_DEBUG instead of all levels - Create a NV_DEBUG_KMS for KMS level (0x4) and use them in modesetting code - Remove a few odd NV_TRACE calls and replace some of them with NV_DEBUG_KMS or NV_INFO Signed-off-by: Maarten Maathuis Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 5eec5ed..62fadbb 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -3854,7 +3854,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, * script tables is a pointer to the script to execute. */ - NV_DEBUG(dev, "Searching for output entry for %d %d %d\n", + NV_DEBUG_KMS(dev, "Searching for output entry for %d %d %d\n", dcbent->type, dcbent->location, dcbent->or); otable = bios_output_config_match(dev, dcbent, table[1] + bios->display.script_table_ptr, @@ -3884,7 +3884,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, if (pxclk == 0) { script = ROM16(otable[6]); if (!script) { - NV_DEBUG(dev, "output script 0 not found\n"); + NV_DEBUG_KMS(dev, "output script 0 not found\n"); return 1; } @@ -3894,7 +3894,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, if (pxclk == -1) { script = ROM16(otable[8]); if (!script) { - NV_DEBUG(dev, "output script 1 not found\n"); + NV_DEBUG_KMS(dev, "output script 1 not found\n"); return 1; } @@ -3907,7 +3907,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, else script = 0; if (!script) { - NV_DEBUG(dev, "output script 2 not found\n"); + NV_DEBUG_KMS(dev, "output script 2 not found\n"); return 1; } @@ -3931,7 +3931,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, if (script) script = clkcmptable(bios, script, -pxclk); if (!script) { - NV_DEBUG(dev, "clock script 1 not found\n"); + NV_DEBUG_KMS(dev, "clock script 1 not found\n"); return 1; } @@ -5234,7 +5234,7 @@ parse_dcb_connector_table(struct nvbios *bios) int i; if (!bios->bdcb.connector_table_ptr) { - NV_DEBUG(dev, "No DCB connector table present\n"); + NV_DEBUG_KMS(dev, "No DCB connector table present\n"); return; } diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 032cf09..5a10deb 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -86,7 +86,7 @@ nouveau_connector_destroy(struct drm_connector *drm_connector) struct nouveau_connector *connector = nouveau_connector(drm_connector); struct drm_device *dev = connector->base.dev; - NV_DEBUG(dev, "\n"); + NV_DEBUG_KMS(dev, "\n"); if (!connector) return; @@ -420,7 +420,7 @@ nouveau_connector_native_mode(struct nouveau_connector *connector) /* Use preferred mode if there is one.. */ list_for_each_entry(mode, &connector->base.probed_modes, head) { if (mode->type & DRM_MODE_TYPE_PREFERRED) { - NV_DEBUG(dev, "native mode from preferred\n"); + NV_DEBUG_KMS(dev, "native mode from preferred\n"); return drm_mode_duplicate(dev, mode); } } @@ -445,7 +445,7 @@ nouveau_connector_native_mode(struct nouveau_connector *connector) largest = mode; } - NV_DEBUG(dev, "native mode from largest: %dx%d@%d\n", + NV_DEBUG_KMS(dev, "native mode from largest: %dx%d@%d\n", high_w, high_h, high_v); return largest ? drm_mode_duplicate(dev, largest) : NULL; } @@ -725,7 +725,7 @@ nouveau_connector_create(struct drm_device *dev, int index, int type) struct drm_encoder *encoder; int ret; - NV_DEBUG(dev, "\n"); + NV_DEBUG_KMS(dev, "\n"); nv_connector = kzalloc(sizeof(*nv_connector), GFP_KERNEL); if (!nv_connector) diff --git a/drivers/gpu/drm/nouveau/nouveau_dp.c b/drivers/gpu/drm/nouveau/nouveau_dp.c index de61f46..9e2926c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dp.c +++ b/drivers/gpu/drm/nouveau/nouveau_dp.c @@ -187,7 +187,7 @@ nouveau_dp_link_train_adjust(struct drm_encoder *encoder, uint8_t *config) if (ret) return false; - NV_DEBUG(dev, "\t\tadjust 0x%02x 0x%02x\n", request[0], request[1]); + NV_DEBUG_KMS(dev, "\t\tadjust 0x%02x 0x%02x\n", request[0], request[1]); /* Keep all lanes at the same level.. */ for (i = 0; i < nv_encoder->dp.link_nr; i++) { @@ -228,7 +228,7 @@ nouveau_dp_link_train_commit(struct drm_encoder *encoder, uint8_t *config) int or = nv_encoder->or, link = !(nv_encoder->dcb->sorconf.link & 1); int dpe_headerlen, ret, i; - NV_DEBUG(dev, "\t\tconfig 0x%02x 0x%02x 0x%02x 0x%02x\n", + NV_DEBUG_KMS(dev, "\t\tconfig 0x%02x 0x%02x 0x%02x 0x%02x\n", config[0], config[1], config[2], config[3]); dpe = nouveau_bios_dp_table(dev, nv_encoder->dcb, &dpe_headerlen); @@ -276,12 +276,12 @@ nouveau_dp_link_train(struct drm_encoder *encoder) bool cr_done, cr_max_vs, eq_done; int ret = 0, i, tries, voltage; - NV_DEBUG(dev, "link training!!\n"); + NV_DEBUG_KMS(dev, "link training!!\n"); train: cr_done = eq_done = false; /* set link configuration */ - NV_DEBUG(dev, "\tbegin train: bw %d, lanes %d\n", + NV_DEBUG_KMS(dev, "\tbegin train: bw %d, lanes %d\n", nv_encoder->dp.link_bw, nv_encoder->dp.link_nr); ret = nouveau_dp_link_bw_set(encoder, nv_encoder->dp.link_bw); @@ -297,7 +297,7 @@ train: return false; /* clock recovery */ - NV_DEBUG(dev, "\tbegin cr\n"); + NV_DEBUG_KMS(dev, "\tbegin cr\n"); ret = nouveau_dp_link_train_set(encoder, DP_TRAINING_PATTERN_1); if (ret) goto stop; @@ -314,7 +314,7 @@ train: ret = auxch_rd(encoder, DP_LANE0_1_STATUS, status, 2); if (ret) break; - NV_DEBUG(dev, "\t\tstatus: 0x%02x 0x%02x\n", + NV_DEBUG_KMS(dev, "\t\tstatus: 0x%02x 0x%02x\n", status[0], status[1]); cr_done = true; @@ -346,7 +346,7 @@ train: goto stop; /* channel equalisation */ - NV_DEBUG(dev, "\tbegin eq\n"); + NV_DEBUG_KMS(dev, "\tbegin eq\n"); ret = nouveau_dp_link_train_set(encoder, DP_TRAINING_PATTERN_2); if (ret) goto stop; @@ -357,7 +357,7 @@ train: ret = auxch_rd(encoder, DP_LANE0_1_STATUS, status, 3); if (ret) break; - NV_DEBUG(dev, "\t\tstatus: 0x%02x 0x%02x\n", + NV_DEBUG_KMS(dev, "\t\tstatus: 0x%02x 0x%02x\n", status[0], status[1]); eq_done = true; @@ -395,9 +395,9 @@ stop: /* retry at a lower setting, if possible */ if (!ret && !(eq_done && cr_done)) { - NV_DEBUG(dev, "\twe failed\n"); + NV_DEBUG_KMS(dev, "\twe failed\n"); if (nv_encoder->dp.link_bw != DP_LINK_BW_1_62) { - NV_DEBUG(dev, "retry link training at low rate\n"); + NV_DEBUG_KMS(dev, "retry link training at low rate\n"); nv_encoder->dp.link_bw = DP_LINK_BW_1_62; goto train; } @@ -418,7 +418,7 @@ nouveau_dp_detect(struct drm_encoder *encoder) if (ret) return false; - NV_DEBUG(dev, "encoder: link_bw %d, link_nr %d\n" + NV_DEBUG_KMS(dev, "encoder: link_bw %d, link_nr %d\n" "display: link_bw %d, link_nr %d version 0x%02x\n", nv_encoder->dcb->dpconf.link_bw, nv_encoder->dcb->dpconf.link_nr, @@ -446,7 +446,7 @@ nouveau_dp_auxch(struct nouveau_i2c_chan *auxch, int cmd, int addr, uint32_t tmp, ctrl, stat = 0, data32[4] = {}; int ret = 0, i, index = auxch->rd; - NV_DEBUG(dev, "ch %d cmd %d addr 0x%x len %d\n", index, cmd, addr, data_nr); + NV_DEBUG_KMS(dev, "ch %d cmd %d addr 0x%x len %d\n", index, cmd, addr, data_nr); tmp = nv_rd32(dev, NV50_AUXCH_CTRL(auxch->rd)); nv_wr32(dev, NV50_AUXCH_CTRL(auxch->rd), tmp | 0x00100000); @@ -472,7 +472,7 @@ nouveau_dp_auxch(struct nouveau_i2c_chan *auxch, int cmd, int addr, if (!(cmd & 1)) { memcpy(data32, data, data_nr); for (i = 0; i < 4; i++) { - NV_DEBUG(dev, "wr %d: 0x%08x\n", i, data32[i]); + NV_DEBUG_KMS(dev, "wr %d: 0x%08x\n", i, data32[i]); nv_wr32(dev, NV50_AUXCH_DATA_OUT(index, i), data32[i]); } } @@ -504,7 +504,7 @@ nouveau_dp_auxch(struct nouveau_i2c_chan *auxch, int cmd, int addr, if (cmd & 1) { for (i = 0; i < 4; i++) { data32[i] = nv_rd32(dev, NV50_AUXCH_DATA_IN(index, i)); - NV_DEBUG(dev, "rd %d: 0x%08x\n", i, data32[i]); + NV_DEBUG_KMS(dev, "rd %d: 0x%08x\n", i, data32[i]); } memcpy(data, data32, data_nr); } diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 88b4c7b..bc6ffa5 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -1207,14 +1207,24 @@ static inline void nv_wo32(struct drm_device *dev, struct nouveau_gpuobj *obj, pci_name(d->pdev), ##arg) #ifndef NV_DEBUG_NOTRACE #define NV_DEBUG(d, fmt, arg...) do { \ - if (drm_debug) { \ + if (drm_debug & DRM_UT_DRIVER) { \ + NV_PRINTK(KERN_DEBUG, d, "%s:%d - " fmt, __func__, \ + __LINE__, ##arg); \ + } \ +} while (0) +#define NV_DEBUG_KMS(d, fmt, arg...) do { \ + if (drm_debug & DRM_UT_KMS) { \ NV_PRINTK(KERN_DEBUG, d, "%s:%d - " fmt, __func__, \ __LINE__, ##arg); \ } \ } while (0) #else #define NV_DEBUG(d, fmt, arg...) do { \ - if (drm_debug) \ + if (drm_debug & DRM_UT_DRIVER) \ + NV_PRINTK(KERN_DEBUG, d, fmt, ##arg); \ +} while (0) +#define NV_DEBUG_KMS(d, fmt, arg...) do { \ + if (drm_debug & DRM_UT_KMS) \ NV_PRINTK(KERN_DEBUG, d, fmt, ##arg); \ } while (0) #endif diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 36e8c5e..489d492 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -347,7 +347,7 @@ out: int nouveau_fbcon_probe(struct drm_device *dev) { - NV_DEBUG(dev, "\n"); + NV_DEBUG_KMS(dev, "\n"); return drm_fb_helper_single_fb_probe(dev, 32, nouveau_fbcon_create); } diff --git a/drivers/gpu/drm/nouveau/nv04_crtc.c b/drivers/gpu/drm/nouveau/nv04_crtc.c index b913636..d2f143e 100644 --- a/drivers/gpu/drm/nouveau/nv04_crtc.c +++ b/drivers/gpu/drm/nouveau/nv04_crtc.c @@ -143,10 +143,10 @@ static void nv_crtc_calc_state_ext(struct drm_crtc *crtc, struct drm_display_mod state->pllsel |= nv_crtc->index ? PLLSEL_VPLL2_MASK : PLLSEL_VPLL1_MASK; if (pv->NM2) - NV_TRACE(dev, "vpll: n1 %d n2 %d m1 %d m2 %d log2p %d\n", + NV_DEBUG_KMS(dev, "vpll: n1 %d n2 %d m1 %d m2 %d log2p %d\n", pv->N1, pv->N2, pv->M1, pv->M2, pv->log2P); else - NV_TRACE(dev, "vpll: n %d m %d log2p %d\n", + NV_DEBUG_KMS(dev, "vpll: n %d m %d log2p %d\n", pv->N1, pv->M1, pv->log2P); nv_crtc->cursor.set_offset(nv_crtc, nv_crtc->cursor.offset); @@ -160,7 +160,7 @@ nv_crtc_dpms(struct drm_crtc *crtc, int mode) unsigned char seq1 = 0, crtc17 = 0; unsigned char crtc1A; - NV_TRACE(dev, "Setting dpms mode %d on CRTC %d\n", mode, + NV_DEBUG_KMS(dev, "Setting dpms mode %d on CRTC %d\n", mode, nv_crtc->index); if (nv_crtc->last_dpms == mode) /* Don't do unnecesary mode changes. */ @@ -603,7 +603,7 @@ nv_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); struct drm_nouveau_private *dev_priv = dev->dev_private; - NV_DEBUG(dev, "CTRC mode on CRTC %d:\n", nv_crtc->index); + NV_DEBUG_KMS(dev, "CTRC mode on CRTC %d:\n", nv_crtc->index); drm_mode_debug_printmodeline(adjusted_mode); /* unlock must come after turning off FP_TG_CONTROL in output_prepare */ @@ -703,7 +703,7 @@ static void nv_crtc_destroy(struct drm_crtc *crtc) { struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - NV_DEBUG(crtc->dev, "\n"); + NV_DEBUG_KMS(crtc->dev, "\n"); if (!nv_crtc) return; diff --git a/drivers/gpu/drm/nouveau/nv04_dac.c b/drivers/gpu/drm/nouveau/nv04_dac.c index a5fa517..d9f3287 100644 --- a/drivers/gpu/drm/nouveau/nv04_dac.c +++ b/drivers/gpu/drm/nouveau/nv04_dac.c @@ -205,7 +205,7 @@ out: NVWriteVgaSeq(dev, 0, NV_VIO_SR_CLOCK_INDEX, saved_seq1); if (blue == 0x18) { - NV_TRACE(dev, "Load detected on head A\n"); + NV_INFO(dev, "Load detected on head A\n"); return connector_status_connected; } @@ -350,14 +350,10 @@ static void nv04_dac_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); struct drm_device *dev = encoder->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; int head = nouveau_crtc(encoder->crtc)->index; - NV_TRACE(dev, "%s called for encoder %d\n", __func__, - nv_encoder->dcb->index); - if (nv_gf4_disp_arch(dev)) { struct drm_encoder *rebind; uint32_t dac_offset = nv04_dac_output_offset(encoder); @@ -466,7 +462,7 @@ static void nv04_dac_destroy(struct drm_encoder *encoder) { struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - NV_DEBUG(encoder->dev, "\n"); + NV_DEBUG_KMS(encoder->dev, "\n"); drm_encoder_cleanup(encoder); kfree(nv_encoder); diff --git a/drivers/gpu/drm/nouveau/nv04_dfp.c b/drivers/gpu/drm/nouveau/nv04_dfp.c index e5b3333..483f875 100644 --- a/drivers/gpu/drm/nouveau/nv04_dfp.c +++ b/drivers/gpu/drm/nouveau/nv04_dfp.c @@ -261,7 +261,7 @@ static void nv04_dfp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *output_mode = &nv_encoder->mode; uint32_t mode_ratio, panel_ratio; - NV_DEBUG(dev, "Output mode on CRTC %d:\n", nv_crtc->index); + NV_DEBUG_KMS(dev, "Output mode on CRTC %d:\n", nv_crtc->index); drm_mode_debug_printmodeline(output_mode); /* Initialize the FP registers in this CRTC. */ @@ -413,7 +413,9 @@ static void nv04_dfp_commit(struct drm_encoder *encoder) struct dcb_entry *dcbe = nv_encoder->dcb; int head = nouveau_crtc(encoder->crtc)->index; - NV_TRACE(dev, "%s called for encoder %d\n", __func__, nv_encoder->dcb->index); + NV_INFO(dev, "Output %s is running on CRTC %d using output %c\n", + drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), + nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); if (dcbe->type == OUTPUT_TMDS) run_tmds_table(dev, dcbe, head, nv_encoder->mode.clock); @@ -550,7 +552,7 @@ static void nv04_dfp_destroy(struct drm_encoder *encoder) { struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - NV_DEBUG(encoder->dev, "\n"); + NV_DEBUG_KMS(encoder->dev, "\n"); drm_encoder_cleanup(encoder); kfree(nv_encoder); diff --git a/drivers/gpu/drm/nouveau/nv04_display.c b/drivers/gpu/drm/nouveau/nv04_display.c index cdddbaa..ef77215 100644 --- a/drivers/gpu/drm/nouveau/nv04_display.c +++ b/drivers/gpu/drm/nouveau/nv04_display.c @@ -99,7 +99,7 @@ nv04_display_create(struct drm_device *dev) uint16_t connector[16] = { 0 }; int i, ret; - NV_DEBUG(dev, "\n"); + NV_DEBUG_KMS(dev, "\n"); if (nv_two_heads(dev)) nv04_display_store_initial_head_owner(dev); @@ -222,7 +222,7 @@ nv04_display_destroy(struct drm_device *dev) struct drm_encoder *encoder; struct drm_crtc *crtc; - NV_DEBUG(dev, "\n"); + NV_DEBUG_KMS(dev, "\n"); /* Turn every CRTC off. */ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { diff --git a/drivers/gpu/drm/nouveau/nv17_tv.c b/drivers/gpu/drm/nouveau/nv17_tv.c index 46cfd9c..81c0135 100644 --- a/drivers/gpu/drm/nouveau/nv17_tv.c +++ b/drivers/gpu/drm/nouveau/nv17_tv.c @@ -219,7 +219,7 @@ static void nv17_tv_dpms(struct drm_encoder *encoder, int mode) return; nouveau_encoder(encoder)->last_dpms = mode; - NV_TRACE(dev, "Setting dpms mode %d on TV encoder (output %d)\n", + NV_INFO(dev, "Setting dpms mode %d on TV encoder (output %d)\n", mode, nouveau_encoder(encoder)->dcb->index); regs->ptv_200 &= ~1; @@ -619,7 +619,7 @@ static void nv17_tv_destroy(struct drm_encoder *encoder) { struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder); - NV_DEBUG(encoder->dev, "\n"); + NV_DEBUG_KMS(encoder->dev, "\n"); drm_encoder_cleanup(encoder); kfree(tv_enc); diff --git a/drivers/gpu/drm/nouveau/nv50_crtc.c b/drivers/gpu/drm/nouveau/nv50_crtc.c index f8e28a1..118d328 100644 --- a/drivers/gpu/drm/nouveau/nv50_crtc.c +++ b/drivers/gpu/drm/nouveau/nv50_crtc.c @@ -45,7 +45,7 @@ nv50_crtc_lut_load(struct drm_crtc *crtc) void __iomem *lut = nvbo_kmap_obj_iovirtual(nv_crtc->lut.nvbo); int i; - NV_DEBUG(crtc->dev, "\n"); + NV_DEBUG_KMS(crtc->dev, "\n"); for (i = 0; i < 256; i++) { writew(nv_crtc->lut.r[i] >> 2, lut + 8*i + 0); @@ -68,8 +68,8 @@ nv50_crtc_blank(struct nouveau_crtc *nv_crtc, bool blanked) struct nouveau_channel *evo = dev_priv->evo; int index = nv_crtc->index, ret; - NV_DEBUG(dev, "index %d\n", nv_crtc->index); - NV_DEBUG(dev, "%s\n", blanked ? "blanked" : "unblanked"); + NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index); + NV_DEBUG_KMS(dev, "%s\n", blanked ? "blanked" : "unblanked"); if (blanked) { nv_crtc->cursor.hide(nv_crtc, false); @@ -139,7 +139,7 @@ nv50_crtc_set_dither(struct nouveau_crtc *nv_crtc, bool on, bool update) struct nouveau_channel *evo = dev_priv->evo; int ret; - NV_DEBUG(dev, "\n"); + NV_DEBUG_KMS(dev, "\n"); ret = RING_SPACE(evo, 2 + (update ? 2 : 0)); if (ret) { @@ -193,7 +193,7 @@ nv50_crtc_set_scale(struct nouveau_crtc *nv_crtc, int scaling_mode, bool update) uint32_t outX, outY, horiz, vert; int ret; - NV_DEBUG(dev, "\n"); + NV_DEBUG_KMS(dev, "\n"); switch (scaling_mode) { case DRM_MODE_SCALE_NONE: @@ -301,7 +301,7 @@ nv50_crtc_destroy(struct drm_crtc *crtc) struct drm_device *dev = crtc->dev; struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - NV_DEBUG(dev, "\n"); + NV_DEBUG_KMS(dev, "\n"); if (!crtc) return; @@ -433,7 +433,7 @@ nv50_crtc_prepare(struct drm_crtc *crtc) struct drm_device *dev = crtc->dev; struct drm_encoder *encoder; - NV_DEBUG(dev, "index %d\n", nv_crtc->index); + NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index); /* Disconnect all unused encoders. */ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { @@ -458,7 +458,7 @@ nv50_crtc_commit(struct drm_crtc *crtc) struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); int ret; - NV_DEBUG(dev, "index %d\n", nv_crtc->index); + NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index); nv50_crtc_blank(nv_crtc, false); @@ -497,7 +497,7 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, int x, int y, struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb); int ret, format; - NV_DEBUG(dev, "index %d\n", nv_crtc->index); + NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index); switch (drm_fb->depth) { case 8: @@ -612,7 +612,7 @@ nv50_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, *nv_crtc->mode = *adjusted_mode; - NV_DEBUG(dev, "index %d\n", nv_crtc->index); + NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index); hsync_dur = adjusted_mode->hsync_end - adjusted_mode->hsync_start; vsync_dur = adjusted_mode->vsync_end - adjusted_mode->vsync_start; @@ -706,7 +706,7 @@ nv50_crtc_create(struct drm_device *dev, int index) struct nouveau_crtc *nv_crtc = NULL; int ret, i; - NV_DEBUG(dev, "\n"); + NV_DEBUG_KMS(dev, "\n"); nv_crtc = kzalloc(sizeof(*nv_crtc), GFP_KERNEL); if (!nv_crtc) diff --git a/drivers/gpu/drm/nouveau/nv50_cursor.c b/drivers/gpu/drm/nouveau/nv50_cursor.c index e2e79a8..753e723 100644 --- a/drivers/gpu/drm/nouveau/nv50_cursor.c +++ b/drivers/gpu/drm/nouveau/nv50_cursor.c @@ -41,7 +41,7 @@ nv50_cursor_show(struct nouveau_crtc *nv_crtc, bool update) struct drm_device *dev = nv_crtc->base.dev; int ret; - NV_DEBUG(dev, "\n"); + NV_DEBUG_KMS(dev, "\n"); if (update && nv_crtc->cursor.visible) return; @@ -76,7 +76,7 @@ nv50_cursor_hide(struct nouveau_crtc *nv_crtc, bool update) struct drm_device *dev = nv_crtc->base.dev; int ret; - NV_DEBUG(dev, "\n"); + NV_DEBUG_KMS(dev, "\n"); if (update && !nv_crtc->cursor.visible) return; @@ -116,7 +116,7 @@ nv50_cursor_set_pos(struct nouveau_crtc *nv_crtc, int x, int y) static void nv50_cursor_set_offset(struct nouveau_crtc *nv_crtc, uint32_t offset) { - NV_DEBUG(nv_crtc->base.dev, "\n"); + NV_DEBUG_KMS(nv_crtc->base.dev, "\n"); if (offset == nv_crtc->cursor.offset) return; @@ -143,7 +143,7 @@ nv50_cursor_fini(struct nouveau_crtc *nv_crtc) struct drm_device *dev = nv_crtc->base.dev; int idx = nv_crtc->index; - NV_DEBUG(dev, "\n"); + NV_DEBUG_KMS(dev, "\n"); nv_wr32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx), 0); if (!nv_wait(NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx), diff --git a/drivers/gpu/drm/nouveau/nv50_dac.c b/drivers/gpu/drm/nouveau/nv50_dac.c index fb5838e..f08f042 100644 --- a/drivers/gpu/drm/nouveau/nv50_dac.c +++ b/drivers/gpu/drm/nouveau/nv50_dac.c @@ -44,7 +44,7 @@ nv50_dac_disconnect(struct nouveau_encoder *nv_encoder) struct nouveau_channel *evo = dev_priv->evo; int ret; - NV_DEBUG(dev, "Disconnecting DAC %d\n", nv_encoder->or); + NV_DEBUG_KMS(dev, "Disconnecting DAC %d\n", nv_encoder->or); ret = RING_SPACE(evo, 2); if (ret) { @@ -81,11 +81,11 @@ nv50_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) /* Use bios provided value if possible. */ if (dev_priv->vbios->dactestval) { load_pattern = dev_priv->vbios->dactestval; - NV_DEBUG(dev, "Using bios provided load_pattern of %d\n", + NV_DEBUG_KMS(dev, "Using bios provided load_pattern of %d\n", load_pattern); } else { load_pattern = 340; - NV_DEBUG(dev, "Using default load_pattern of %d\n", + NV_DEBUG_KMS(dev, "Using default load_pattern of %d\n", load_pattern); } @@ -103,9 +103,9 @@ nv50_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) status = connector_status_connected; if (status == connector_status_connected) - NV_DEBUG(dev, "Load was detected on output with or %d\n", or); + NV_DEBUG_KMS(dev, "Load was detected on output with or %d\n", or); else - NV_DEBUG(dev, "Load was not detected on output with or %d\n", or); + NV_DEBUG_KMS(dev, "Load was not detected on output with or %d\n", or); return status; } @@ -118,7 +118,7 @@ nv50_dac_dpms(struct drm_encoder *encoder, int mode) uint32_t val; int or = nv_encoder->or; - NV_DEBUG(dev, "or %d mode %d\n", or, mode); + NV_DEBUG_KMS(dev, "or %d mode %d\n", or, mode); /* wait for it to be done */ if (!nv_wait(NV50_PDISPLAY_DAC_DPMS_CTRL(or), @@ -173,7 +173,7 @@ nv50_dac_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); struct nouveau_connector *connector; - NV_DEBUG(encoder->dev, "or %d\n", nv_encoder->or); + NV_DEBUG_KMS(encoder->dev, "or %d\n", nv_encoder->or); connector = nouveau_encoder_connector_get(nv_encoder); if (!connector) { @@ -213,7 +213,7 @@ nv50_dac_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, uint32_t mode_ctl = 0, mode_ctl2 = 0; int ret; - NV_DEBUG(dev, "or %d\n", nv_encoder->or); + NV_DEBUG_KMS(dev, "or %d\n", nv_encoder->or); nv50_dac_dpms(encoder, DRM_MODE_DPMS_ON); @@ -264,7 +264,7 @@ nv50_dac_destroy(struct drm_encoder *encoder) if (!encoder) return; - NV_DEBUG(encoder->dev, "\n"); + NV_DEBUG_KMS(encoder->dev, "\n"); drm_encoder_cleanup(encoder); kfree(nv_encoder); @@ -280,7 +280,7 @@ nv50_dac_create(struct drm_device *dev, struct dcb_entry *entry) struct nouveau_encoder *nv_encoder; struct drm_encoder *encoder; - NV_DEBUG(dev, "\n"); + NV_DEBUG_KMS(dev, "\n"); NV_INFO(dev, "Detected a DAC output\n"); nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL); diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 12c5ee6..a9263d9 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -188,7 +188,7 @@ nv50_display_init(struct drm_device *dev) uint64_t start; int ret, i; - NV_DEBUG(dev, "\n"); + NV_DEBUG_KMS(dev, "\n"); nv_wr32(dev, 0x00610184, nv_rd32(dev, 0x00614004)); /* @@ -232,7 +232,7 @@ nv50_display_init(struct drm_device *dev) nv_wr32(dev, NV50_PDISPLAY_UNK_380, 0); /* RAM is clamped to 256 MiB. */ ram_amount = nouveau_mem_fb_amount(dev); - NV_DEBUG(dev, "ram_amount %d\n", ram_amount); + NV_DEBUG_KMS(dev, "ram_amount %d\n", ram_amount); if (ram_amount > 256*1024*1024) ram_amount = 256*1024*1024; nv_wr32(dev, NV50_PDISPLAY_RAM_AMOUNT, ram_amount - 1); @@ -398,7 +398,7 @@ static int nv50_display_disable(struct drm_device *dev) struct drm_crtc *drm_crtc; int ret, i; - NV_DEBUG(dev, "\n"); + NV_DEBUG_KMS(dev, "\n"); list_for_each_entry(drm_crtc, &dev->mode_config.crtc_list, head) { struct nouveau_crtc *crtc = nouveau_crtc(drm_crtc); @@ -469,7 +469,7 @@ int nv50_display_create(struct drm_device *dev) uint32_t connector[16] = {}; int ret, i; - NV_DEBUG(dev, "\n"); + NV_DEBUG_KMS(dev, "\n"); /* init basic kernel modesetting */ drm_mode_config_init(dev); @@ -573,7 +573,7 @@ int nv50_display_destroy(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; - NV_DEBUG(dev, "\n"); + NV_DEBUG_KMS(dev, "\n"); drm_mode_config_cleanup(dev); @@ -617,7 +617,7 @@ nv50_display_irq_head(struct drm_device *dev, int *phead, * CRTC separately, and submission will be blocked by the GPU * until we handle each in turn. */ - NV_DEBUG(dev, "0x610030: 0x%08x\n", unk30); + NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30); head = ffs((unk30 >> 9) & 3) - 1; if (head < 0) return -EINVAL; @@ -661,7 +661,7 @@ nv50_display_irq_head(struct drm_device *dev, int *phead, or = i; } - NV_DEBUG(dev, "type %d, or %d\n", type, or); + NV_DEBUG_KMS(dev, "type %d, or %d\n", type, or); if (type == OUTPUT_ANY) { NV_ERROR(dev, "unknown encoder!!\n"); return -1; @@ -811,7 +811,7 @@ nv50_display_unk20_handler(struct drm_device *dev) pclk = nv_rd32(dev, NV50_PDISPLAY_CRTC_P(head, CLOCK)) & 0x3fffff; script = nv50_display_script_select(dev, dcbent, pclk); - NV_DEBUG(dev, "head %d pxclk: %dKHz\n", head, pclk); + NV_DEBUG_KMS(dev, "head %d pxclk: %dKHz\n", head, pclk); if (dcbent->type != OUTPUT_DP) nouveau_bios_run_display_table(dev, dcbent, 0, -2); @@ -870,7 +870,7 @@ nv50_display_irq_handler_bh(struct work_struct *work) uint32_t intr0 = nv_rd32(dev, NV50_PDISPLAY_INTR_0); uint32_t intr1 = nv_rd32(dev, NV50_PDISPLAY_INTR_1); - NV_DEBUG(dev, "PDISPLAY_INTR_BH 0x%08x 0x%08x\n", intr0, intr1); + NV_DEBUG_KMS(dev, "PDISPLAY_INTR_BH 0x%08x 0x%08x\n", intr0, intr1); if (intr1 & NV50_PDISPLAY_INTR_1_CLK_UNK10) nv50_display_unk10_handler(dev); @@ -974,7 +974,7 @@ nv50_display_irq_handler(struct drm_device *dev) uint32_t intr1 = nv_rd32(dev, NV50_PDISPLAY_INTR_1); uint32_t clock; - NV_DEBUG(dev, "PDISPLAY_INTR 0x%08x 0x%08x\n", intr0, intr1); + NV_DEBUG_KMS(dev, "PDISPLAY_INTR 0x%08x 0x%08x\n", intr0, intr1); if (!intr0 && !(intr1 & ~delayed)) break; diff --git a/drivers/gpu/drm/nouveau/nv50_sor.c b/drivers/gpu/drm/nouveau/nv50_sor.c index 8c28046..e395c16 100644 --- a/drivers/gpu/drm/nouveau/nv50_sor.c +++ b/drivers/gpu/drm/nouveau/nv50_sor.c @@ -44,7 +44,7 @@ nv50_sor_disconnect(struct nouveau_encoder *nv_encoder) struct nouveau_channel *evo = dev_priv->evo; int ret; - NV_DEBUG(dev, "Disconnecting SOR %d\n", nv_encoder->or); + NV_DEBUG_KMS(dev, "Disconnecting SOR %d\n", nv_encoder->or); ret = RING_SPACE(evo, 2); if (ret) { @@ -70,7 +70,7 @@ nv50_sor_dp_link_train(struct drm_encoder *encoder) } if (dpe->script0) { - NV_DEBUG(dev, "SOR-%d: running DP script 0\n", nv_encoder->or); + NV_DEBUG_KMS(dev, "SOR-%d: running DP script 0\n", nv_encoder->or); nouveau_bios_run_init_table(dev, le16_to_cpu(dpe->script0), nv_encoder->dcb); } @@ -79,7 +79,7 @@ nv50_sor_dp_link_train(struct drm_encoder *encoder) NV_ERROR(dev, "SOR-%d: link training failed\n", nv_encoder->or); if (dpe->script1) { - NV_DEBUG(dev, "SOR-%d: running DP script 1\n", nv_encoder->or); + NV_DEBUG_KMS(dev, "SOR-%d: running DP script 1\n", nv_encoder->or); nouveau_bios_run_init_table(dev, le16_to_cpu(dpe->script1), nv_encoder->dcb); } @@ -93,7 +93,7 @@ nv50_sor_dpms(struct drm_encoder *encoder, int mode) uint32_t val; int or = nv_encoder->or; - NV_DEBUG(dev, "or %d mode %d\n", or, mode); + NV_DEBUG_KMS(dev, "or %d mode %d\n", or, mode); /* wait for it to be done */ if (!nv_wait(NV50_PDISPLAY_SOR_DPMS_CTRL(or), @@ -142,7 +142,7 @@ nv50_sor_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); struct nouveau_connector *connector; - NV_DEBUG(encoder->dev, "or %d\n", nv_encoder->or); + NV_DEBUG_KMS(encoder->dev, "or %d\n", nv_encoder->or); connector = nouveau_encoder_connector_get(nv_encoder); if (!connector) { @@ -182,7 +182,7 @@ nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, uint32_t mode_ctl = 0; int ret; - NV_DEBUG(dev, "or %d\n", nv_encoder->or); + NV_DEBUG_KMS(dev, "or %d\n", nv_encoder->or); nv50_sor_dpms(encoder, DRM_MODE_DPMS_ON); @@ -246,7 +246,7 @@ nv50_sor_destroy(struct drm_encoder *encoder) if (!encoder) return; - NV_DEBUG(encoder->dev, "\n"); + NV_DEBUG_KMS(encoder->dev, "\n"); drm_encoder_cleanup(encoder); @@ -265,7 +265,7 @@ nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry) bool dum; int type; - NV_DEBUG(dev, "\n"); + NV_DEBUG_KMS(dev, "\n"); switch (entry->type) { case OUTPUT_TMDS: -- cgit v0.10.2 From 657b6245ba23d32c7a4fd273549c8c0beebec770 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Ko=C5=9Bcielnicki?= Date: Tue, 15 Dec 2009 00:37:30 +0000 Subject: drm/nouveau: Kill global state in NvShadowBIOS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marcin Kościelnicki Signed-off-by: Maarten Maathuis Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 62fadbb..519faa9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -181,43 +181,42 @@ struct methods { const char desc[8]; void (*loadbios)(struct drm_device *, uint8_t *); const bool rw; - int score; }; static struct methods nv04_methods[] = { { "PROM", load_vbios_prom, false }, { "PRAMIN", load_vbios_pramin, true }, { "PCIROM", load_vbios_pci, true }, - { } }; static struct methods nv50_methods[] = { { "PRAMIN", load_vbios_pramin, true }, { "PROM", load_vbios_prom, false }, { "PCIROM", load_vbios_pci, true }, - { } }; +#define METHODCNT 3 + static bool NVShadowVBIOS(struct drm_device *dev, uint8_t *data) { struct drm_nouveau_private *dev_priv = dev->dev_private; - struct methods *methods, *method; + struct methods *methods; + int i; int testscore = 3; + int scores[METHODCNT]; if (nouveau_vbios) { - method = nv04_methods; - while (method->loadbios) { - if (!strcasecmp(nouveau_vbios, method->desc)) + methods = nv04_methods; + for (i = 0; i < METHODCNT; i++) + if (!strcasecmp(nouveau_vbios, methods[i].desc)) break; - method++; - } - if (method->loadbios) { + if (i < METHODCNT) { NV_INFO(dev, "Attempting to use BIOS image from %s\n", - method->desc); + methods[i].desc); - method->loadbios(dev, data); - if (score_vbios(dev, data, method->rw)) + methods[i].loadbios(dev, data); + if (score_vbios(dev, data, methods[i].rw)) return true; } @@ -229,28 +228,24 @@ static bool NVShadowVBIOS(struct drm_device *dev, uint8_t *data) else methods = nv50_methods; - method = methods; - while (method->loadbios) { + for (i = 0; i < METHODCNT; i++) { NV_TRACE(dev, "Attempting to load BIOS image from %s\n", - method->desc); + methods[i].desc); data[0] = data[1] = 0; /* avoid reuse of previous image */ - method->loadbios(dev, data); - method->score = score_vbios(dev, data, method->rw); - if (method->score == testscore) + methods[i].loadbios(dev, data); + scores[i] = score_vbios(dev, data, methods[i].rw); + if (scores[i] == testscore) return true; - method++; } while (--testscore > 0) { - method = methods; - while (method->loadbios) { - if (method->score == testscore) { + for (i = 0; i < METHODCNT; i++) { + if (scores[i] == testscore) { NV_TRACE(dev, "Using BIOS image from %s\n", - method->desc); - method->loadbios(dev, data); + methods[i].desc); + methods[i].loadbios(dev, data); return true; } - method++; } } -- cgit v0.10.2 From 37383650e4f47aef633055e3f62e87a44d83312d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Ko=C5=9Bcielnicki?= Date: Tue, 15 Dec 2009 00:37:31 +0000 Subject: drm/nouveau: Kill global state in BIOS script interpreter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marcin Kościelnicki Signed-off-by: Maarten Maathuis Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 519faa9..ba14397 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -256,10 +256,7 @@ static bool NVShadowVBIOS(struct drm_device *dev, uint8_t *data) struct init_tbl_entry { char *name; uint8_t id; - int length; - int length_offset; - int length_multiplier; - bool (*handler)(struct nvbios *, uint16_t, struct init_exec *); + int (*handler)(struct nvbios *, uint16_t, struct init_exec *); }; struct bit_entry { @@ -815,7 +812,7 @@ static uint32_t get_tmds_index_reg(struct drm_device *dev, uint8_t mlv) } } -static bool +static int init_io_restrict_prog(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { @@ -847,9 +844,10 @@ init_io_restrict_prog(struct nvbios *bios, uint16_t offset, uint32_t reg = ROM32(bios->data[offset + 7]); uint8_t config; uint32_t configval; + int len = 11 + count * 4; if (!iexec->execute) - return true; + return len; BIOSLOG(bios, "0x%04X: Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X, " "Shift: 0x%02X, Count: 0x%02X, Reg: 0x%08X\n", @@ -860,7 +858,7 @@ init_io_restrict_prog(struct nvbios *bios, uint16_t offset, NV_ERROR(bios->dev, "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n", offset, config, count); - return false; + return 0; } configval = ROM32(bios->data[offset + 11 + config * 4]); @@ -869,10 +867,10 @@ init_io_restrict_prog(struct nvbios *bios, uint16_t offset, bios_wr32(bios, reg, configval); - return true; + return len; } -static bool +static int init_repeat(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { /* @@ -907,10 +905,10 @@ init_repeat(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) iexec->repeat = false; - return true; + return 2; } -static bool +static int init_io_restrict_pll(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { @@ -946,9 +944,10 @@ init_io_restrict_pll(struct nvbios *bios, uint16_t offset, uint32_t reg = ROM32(bios->data[offset + 8]); uint8_t config; uint16_t freq; + int len = 12 + count * 2; if (!iexec->execute) - return true; + return len; BIOSLOG(bios, "0x%04X: Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X, " "Shift: 0x%02X, IO Flag Condition: 0x%02X, " @@ -961,7 +960,7 @@ init_io_restrict_pll(struct nvbios *bios, uint16_t offset, NV_ERROR(bios->dev, "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n", offset, config, count); - return false; + return 0; } freq = ROM16(bios->data[offset + 12 + config * 2]); @@ -981,10 +980,10 @@ init_io_restrict_pll(struct nvbios *bios, uint16_t offset, setPLL(bios, reg, freq * 10); - return true; + return len; } -static bool +static int init_end_repeat(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { /* @@ -1002,12 +1001,12 @@ init_end_repeat(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) * we're not in repeat mode */ if (iexec->repeat) - return false; + return 0; - return true; + return 1; } -static bool +static int init_copy(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { /* @@ -1036,7 +1035,7 @@ init_copy(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) uint8_t crtcdata; if (!iexec->execute) - return true; + return 11; BIOSLOG(bios, "0x%04X: Reg: 0x%08X, Shift: 0x%02X, SrcMask: 0x%02X, " "Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X\n", @@ -1055,10 +1054,10 @@ init_copy(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) crtcdata |= (uint8_t)data; bios_idxprt_wr(bios, crtcport, crtcindex, crtcdata); - return true; + return 11; } -static bool +static int init_not(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { /* @@ -1074,10 +1073,10 @@ init_not(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) BIOSLOG(bios, "0x%04X: ------ Executing following commands ------\n", offset); iexec->execute = !iexec->execute; - return true; + return 1; } -static bool +static int init_io_flag_condition(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { @@ -1095,7 +1094,7 @@ init_io_flag_condition(struct nvbios *bios, uint16_t offset, uint8_t cond = bios->data[offset + 1]; if (!iexec->execute) - return true; + return 2; if (io_flag_condition_met(bios, offset, cond)) BIOSLOG(bios, "0x%04X: Condition fulfilled -- continuing to execute\n", offset); @@ -1104,10 +1103,10 @@ init_io_flag_condition(struct nvbios *bios, uint16_t offset, iexec->execute = false; } - return true; + return 2; } -static bool +static int init_idx_addr_latched(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { @@ -1135,11 +1134,12 @@ init_idx_addr_latched(struct nvbios *bios, uint16_t offset, uint32_t mask = ROM32(bios->data[offset + 9]); uint32_t data = ROM32(bios->data[offset + 13]); uint8_t count = bios->data[offset + 17]; + int len = 18 + count * 2; uint32_t value; int i; if (!iexec->execute) - return true; + return len; BIOSLOG(bios, "0x%04X: ControlReg: 0x%08X, DataReg: 0x%08X, " "Mask: 0x%08X, Data: 0x%08X, Count: 0x%02X\n", @@ -1159,10 +1159,10 @@ init_idx_addr_latched(struct nvbios *bios, uint16_t offset, bios_wr32(bios, controlreg, value); } - return true; + return len; } -static bool +static int init_io_restrict_pll2(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { @@ -1191,25 +1191,26 @@ init_io_restrict_pll2(struct nvbios *bios, uint16_t offset, uint8_t shift = bios->data[offset + 5]; uint8_t count = bios->data[offset + 6]; uint32_t reg = ROM32(bios->data[offset + 7]); + int len = 11 + count * 4; uint8_t config; uint32_t freq; if (!iexec->execute) - return true; + return len; BIOSLOG(bios, "0x%04X: Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X, " "Shift: 0x%02X, Count: 0x%02X, Reg: 0x%08X\n", offset, crtcport, crtcindex, mask, shift, count, reg); if (!reg) - return true; + return len; config = (bios_idxprt_rd(bios, crtcport, crtcindex) & mask) >> shift; if (config > count) { NV_ERROR(bios->dev, "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n", offset, config, count); - return false; + return 0; } freq = ROM32(bios->data[offset + 11 + config * 4]); @@ -1219,10 +1220,10 @@ init_io_restrict_pll2(struct nvbios *bios, uint16_t offset, setPLL(bios, reg, freq); - return true; + return len; } -static bool +static int init_pll2(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { /* @@ -1239,16 +1240,16 @@ init_pll2(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) uint32_t freq = ROM32(bios->data[offset + 5]); if (!iexec->execute) - return true; + return 9; BIOSLOG(bios, "0x%04X: Reg: 0x%04X, Freq: %dkHz\n", offset, reg, freq); setPLL(bios, reg, freq); - return true; + return 9; } -static bool +static int init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { /* @@ -1272,12 +1273,13 @@ init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) uint8_t i2c_index = bios->data[offset + 1]; uint8_t i2c_address = bios->data[offset + 2]; uint8_t count = bios->data[offset + 3]; + int len = 4 + count * 3; struct nouveau_i2c_chan *chan; struct i2c_msg msg; int i; if (!iexec->execute) - return true; + return len; BIOSLOG(bios, "0x%04X: DCBI2CIndex: 0x%02X, I2CAddress: 0x%02X, " "Count: 0x%02X\n", @@ -1285,7 +1287,7 @@ init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) chan = init_i2c_device_find(bios->dev, i2c_index); if (!chan) - return false; + return 0; for (i = 0; i < count; i++) { uint8_t i2c_reg = bios->data[offset + 4 + i * 3]; @@ -1298,7 +1300,7 @@ init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) msg.len = 1; msg.buf = &value; if (i2c_transfer(&chan->adapter, &msg, 1) != 1) - return false; + return 0; BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X, Value: 0x%02X, " "Mask: 0x%02X, Data: 0x%02X\n", @@ -1312,14 +1314,14 @@ init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) msg.len = 1; msg.buf = &value; if (i2c_transfer(&chan->adapter, &msg, 1) != 1) - return false; + return 0; } } - return true; + return len; } -static bool +static int init_zm_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { /* @@ -1341,12 +1343,13 @@ init_zm_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) uint8_t i2c_index = bios->data[offset + 1]; uint8_t i2c_address = bios->data[offset + 2]; uint8_t count = bios->data[offset + 3]; + int len = 4 + count * 2; struct nouveau_i2c_chan *chan; struct i2c_msg msg; int i; if (!iexec->execute) - return true; + return len; BIOSLOG(bios, "0x%04X: DCBI2CIndex: 0x%02X, I2CAddress: 0x%02X, " "Count: 0x%02X\n", @@ -1354,7 +1357,7 @@ init_zm_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) chan = init_i2c_device_find(bios->dev, i2c_index); if (!chan) - return false; + return 0; for (i = 0; i < count; i++) { uint8_t i2c_reg = bios->data[offset + 4 + i * 2]; @@ -1369,14 +1372,14 @@ init_zm_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) msg.len = 1; msg.buf = &data; if (i2c_transfer(&chan->adapter, &msg, 1) != 1) - return false; + return 0; } } - return true; + return len; } -static bool +static int init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { /* @@ -1396,13 +1399,14 @@ init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) uint8_t i2c_index = bios->data[offset + 1]; uint8_t i2c_address = bios->data[offset + 2]; uint8_t count = bios->data[offset + 3]; + int len = 4 + count; struct nouveau_i2c_chan *chan; struct i2c_msg msg; uint8_t data[256]; int i; if (!iexec->execute) - return true; + return len; BIOSLOG(bios, "0x%04X: DCBI2CIndex: 0x%02X, I2CAddress: 0x%02X, " "Count: 0x%02X\n", @@ -1410,7 +1414,7 @@ init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) chan = init_i2c_device_find(bios->dev, i2c_index); if (!chan) - return false; + return 0; for (i = 0; i < count; i++) { data[i] = bios->data[offset + 4 + i]; @@ -1424,13 +1428,13 @@ init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) msg.len = count; msg.buf = data; if (i2c_transfer(&chan->adapter, &msg, 1) != 1) - return false; + return 0; } - return true; + return len; } -static bool +static int init_tmds(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { /* @@ -1455,7 +1459,7 @@ init_tmds(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) uint32_t reg, value; if (!iexec->execute) - return true; + return 5; BIOSLOG(bios, "0x%04X: MagicLookupValue: 0x%02X, TMDSAddr: 0x%02X, " "Mask: 0x%02X, Data: 0x%02X\n", @@ -1463,7 +1467,7 @@ init_tmds(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) reg = get_tmds_index_reg(bios->dev, mlv); if (!reg) - return false; + return 0; bios_wr32(bios, reg, tmdsaddr | NV_PRAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE); @@ -1471,10 +1475,10 @@ init_tmds(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) bios_wr32(bios, reg + 4, value); bios_wr32(bios, reg, tmdsaddr); - return true; + return 5; } -static bool +static int init_zm_tmds_group(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { @@ -1495,18 +1499,19 @@ init_zm_tmds_group(struct nvbios *bios, uint16_t offset, uint8_t mlv = bios->data[offset + 1]; uint8_t count = bios->data[offset + 2]; + int len = 3 + count * 2; uint32_t reg; int i; if (!iexec->execute) - return true; + return len; BIOSLOG(bios, "0x%04X: MagicLookupValue: 0x%02X, Count: 0x%02X\n", offset, mlv, count); reg = get_tmds_index_reg(bios->dev, mlv); if (!reg) - return false; + return 0; for (i = 0; i < count; i++) { uint8_t tmdsaddr = bios->data[offset + 3 + i * 2]; @@ -1516,10 +1521,10 @@ init_zm_tmds_group(struct nvbios *bios, uint16_t offset, bios_wr32(bios, reg, tmdsaddr); } - return true; + return len; } -static bool +static int init_cr_idx_adr_latch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { @@ -1542,11 +1547,12 @@ init_cr_idx_adr_latch(struct nvbios *bios, uint16_t offset, uint8_t crtcindex2 = bios->data[offset + 2]; uint8_t baseaddr = bios->data[offset + 3]; uint8_t count = bios->data[offset + 4]; + int len = 5 + count; uint8_t oldaddr, data; int i; if (!iexec->execute) - return true; + return len; BIOSLOG(bios, "0x%04X: Index1: 0x%02X, Index2: 0x%02X, " "BaseAddr: 0x%02X, Count: 0x%02X\n", @@ -1563,10 +1569,10 @@ init_cr_idx_adr_latch(struct nvbios *bios, uint16_t offset, bios_idxprt_wr(bios, NV_CIO_CRX__COLOR, crtcindex1, oldaddr); - return true; + return len; } -static bool +static int init_cr(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { /* @@ -1587,7 +1593,7 @@ init_cr(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) uint8_t value; if (!iexec->execute) - return true; + return 4; BIOSLOG(bios, "0x%04X: Index: 0x%02X, Mask: 0x%02X, Data: 0x%02X\n", offset, crtcindex, mask, data); @@ -1596,10 +1602,10 @@ init_cr(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) value |= data; bios_idxprt_wr(bios, NV_CIO_CRX__COLOR, crtcindex, value); - return true; + return 4; } -static bool +static int init_zm_cr(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { /* @@ -1616,14 +1622,14 @@ init_zm_cr(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) uint8_t data = bios->data[offset + 2]; if (!iexec->execute) - return true; + return 3; bios_idxprt_wr(bios, NV_CIO_CRX__COLOR, crtcindex, data); - return true; + return 3; } -static bool +static int init_zm_cr_group(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { /* @@ -1640,18 +1646,19 @@ init_zm_cr_group(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) */ uint8_t count = bios->data[offset + 1]; + int len = 2 + count * 2; int i; if (!iexec->execute) - return true; + return len; for (i = 0; i < count; i++) init_zm_cr(bios, offset + 2 + 2 * i - 1, iexec); - return true; + return len; } -static bool +static int init_condition_time(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { @@ -1675,7 +1682,7 @@ init_condition_time(struct nvbios *bios, uint16_t offset, unsigned cnt; if (!iexec->execute) - return true; + return 3; if (retries > 100) retries = 100; @@ -1706,10 +1713,10 @@ init_condition_time(struct nvbios *bios, uint16_t offset, iexec->execute = false; } - return true; + return 3; } -static bool +static int init_zm_reg_sequence(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { @@ -1729,10 +1736,11 @@ init_zm_reg_sequence(struct nvbios *bios, uint16_t offset, uint32_t basereg = ROM32(bios->data[offset + 1]); uint32_t count = bios->data[offset + 5]; + int len = 6 + count * 4; int i; if (!iexec->execute) - return true; + return len; BIOSLOG(bios, "0x%04X: BaseReg: 0x%08X, Count: 0x%02X\n", offset, basereg, count); @@ -1744,10 +1752,10 @@ init_zm_reg_sequence(struct nvbios *bios, uint16_t offset, bios_wr32(bios, reg, data); } - return true; + return len; } -static bool +static int init_sub_direct(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { /* @@ -1763,7 +1771,7 @@ init_sub_direct(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) uint16_t sub_offset = ROM16(bios->data[offset + 1]); if (!iexec->execute) - return true; + return 3; BIOSLOG(bios, "0x%04X: Executing subroutine at 0x%04X\n", offset, sub_offset); @@ -1772,10 +1780,10 @@ init_sub_direct(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) BIOSLOG(bios, "0x%04X: End of 0x%04X subroutine\n", offset, sub_offset); - return true; + return 3; } -static bool +static int init_copy_nv_reg(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { /* @@ -1803,7 +1811,7 @@ init_copy_nv_reg(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) uint32_t srcvalue, dstvalue; if (!iexec->execute) - return true; + return 22; BIOSLOG(bios, "0x%04X: SrcReg: 0x%08X, Shift: 0x%02X, SrcMask: 0x%08X, " "Xor: 0x%08X, DstReg: 0x%08X, DstMask: 0x%08X\n", @@ -1822,10 +1830,10 @@ init_copy_nv_reg(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) bios_wr32(bios, dstreg, dstvalue | srcvalue); - return true; + return 22; } -static bool +static int init_zm_index_io(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { /* @@ -1843,14 +1851,14 @@ init_zm_index_io(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) uint8_t data = bios->data[offset + 4]; if (!iexec->execute) - return true; + return 5; bios_idxprt_wr(bios, crtcport, crtcindex, data); - return true; + return 5; } -static bool +static int init_compute_mem(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { /* @@ -1899,7 +1907,7 @@ init_compute_mem(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) struct drm_nouveau_private *dev_priv = bios->dev->dev_private; if (dev_priv->card_type >= NV_50) - return true; + return 1; /* * On every card I've seen, this step gets done for us earlier in @@ -1917,10 +1925,10 @@ init_compute_mem(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) /* write back the saved configuration value */ bios_wr32(bios, NV_PFB_CFG0, bios->state.saved_nv_pfb_cfg0); - return true; + return 1; } -static bool +static int init_reset(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { /* @@ -1954,10 +1962,10 @@ init_reset(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) pci_nv_20 &= ~NV_PBUS_PCI_NV_20_ROM_SHADOW_ENABLED; /* 0xfffffffe */ bios_wr32(bios, NV_PBUS_PCI_NV_20, pci_nv_20); - return true; + return 13; } -static bool +static int init_configure_mem(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { @@ -1978,7 +1986,7 @@ init_configure_mem(struct nvbios *bios, uint16_t offset, uint32_t reg, data; if (bios->major_version > 2) - return false; + return 0; bios_idxprt_wr(bios, NV_VIO_SRX, NV_VIO_SR_CLOCK_INDEX, bios_idxprt_rd( bios, NV_VIO_SRX, NV_VIO_SR_CLOCK_INDEX) | 0x20); @@ -2010,10 +2018,10 @@ init_configure_mem(struct nvbios *bios, uint16_t offset, bios_wr32(bios, reg, data); } - return true; + return 1; } -static bool +static int init_configure_clk(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { @@ -2033,7 +2041,7 @@ init_configure_clk(struct nvbios *bios, uint16_t offset, int clock; if (bios->major_version > 2) - return false; + return 0; clock = ROM16(bios->data[meminitoffs + 4]) * 10; setPLL(bios, NV_PRAMDAC_NVPLL_COEFF, clock); @@ -2043,10 +2051,10 @@ init_configure_clk(struct nvbios *bios, uint16_t offset, clock *= 2; setPLL(bios, NV_PRAMDAC_MPLL_COEFF, clock); - return true; + return 1; } -static bool +static int init_configure_preinit(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { @@ -2066,15 +2074,15 @@ init_configure_preinit(struct nvbios *bios, uint16_t offset, uint8_t cr3c = ((straps << 2) & 0xf0) | (straps & (1 << 6)); if (bios->major_version > 2) - return false; + return 0; bios_idxprt_wr(bios, NV_CIO_CRX__COLOR, NV_CIO_CRE_SCRATCH4__INDEX, cr3c); - return true; + return 1; } -static bool +static int init_io(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { /* @@ -2094,7 +2102,7 @@ init_io(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) uint8_t data = bios->data[offset + 4]; if (!iexec->execute) - return true; + return 5; BIOSLOG(bios, "0x%04X: Port: 0x%04X, Mask: 0x%02X, Data: 0x%02X\n", offset, crtcport, mask, data); @@ -2153,15 +2161,15 @@ init_io(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) for (i = 0; i < 2; i++) bios_wr32(bios, 0x614108 + (i*0x800), bios_rd32( bios, 0x614108 + (i*0x800)) & 0x0fffffff); - return true; + return 5; } bios_port_wr(bios, crtcport, (bios_port_rd(bios, crtcport) & mask) | data); - return true; + return 5; } -static bool +static int init_sub(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { /* @@ -2176,7 +2184,7 @@ init_sub(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) uint8_t sub = bios->data[offset + 1]; if (!iexec->execute) - return true; + return 2; BIOSLOG(bios, "0x%04X: Calling script %d\n", offset, sub); @@ -2186,10 +2194,10 @@ init_sub(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) BIOSLOG(bios, "0x%04X: End of script %d\n", offset, sub); - return true; + return 2; } -static bool +static int init_ram_condition(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { @@ -2210,7 +2218,7 @@ init_ram_condition(struct nvbios *bios, uint16_t offset, uint8_t data; if (!iexec->execute) - return true; + return 3; data = bios_rd32(bios, NV_PFB_BOOT_0) & mask; @@ -2224,10 +2232,10 @@ init_ram_condition(struct nvbios *bios, uint16_t offset, iexec->execute = false; } - return true; + return 3; } -static bool +static int init_nv_reg(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { /* @@ -2246,17 +2254,17 @@ init_nv_reg(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) uint32_t data = ROM32(bios->data[offset + 9]); if (!iexec->execute) - return true; + return 13; BIOSLOG(bios, "0x%04X: Reg: 0x%08X, Mask: 0x%08X, Data: 0x%08X\n", offset, reg, mask, data); bios_wr32(bios, reg, (bios_rd32(bios, reg) & mask) | data); - return true; + return 13; } -static bool +static int init_macro(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { /* @@ -2280,7 +2288,7 @@ init_macro(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) int i; if (!iexec->execute) - return true; + return 2; BIOSLOG(bios, "0x%04X: Macro: 0x%02X, MacroTableIndex: 0x%02X, " "Count: 0x%02X\n", @@ -2295,10 +2303,10 @@ init_macro(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) bios_wr32(bios, reg, data); } - return true; + return 2; } -static bool +static int init_done(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { /* @@ -2310,10 +2318,10 @@ init_done(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) */ /* mild retval abuse to stop parsing this table */ - return false; + return 0; } -static bool +static int init_resume(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { /* @@ -2325,15 +2333,15 @@ init_resume(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) */ if (iexec->execute) - return true; + return 1; iexec->execute = true; BIOSLOG(bios, "0x%04X: ---- Executing following commands ----\n", offset); - return true; + return 1; } -static bool +static int init_time(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { /* @@ -2348,7 +2356,7 @@ init_time(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) unsigned time = ROM16(bios->data[offset + 1]); if (!iexec->execute) - return true; + return 3; BIOSLOG(bios, "0x%04X: Sleeping for 0x%04X microseconds\n", offset, time); @@ -2358,10 +2366,10 @@ init_time(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) else msleep((time + 900) / 1000); - return true; + return 3; } -static bool +static int init_condition(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { /* @@ -2378,7 +2386,7 @@ init_condition(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) uint8_t cond = bios->data[offset + 1]; if (!iexec->execute) - return true; + return 2; BIOSLOG(bios, "0x%04X: Condition: 0x%02X\n", offset, cond); @@ -2389,10 +2397,10 @@ init_condition(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) iexec->execute = false; } - return true; + return 2; } -static bool +static int init_io_condition(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { /* @@ -2409,7 +2417,7 @@ init_io_condition(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) uint8_t cond = bios->data[offset + 1]; if (!iexec->execute) - return true; + return 2; BIOSLOG(bios, "0x%04X: IO condition: 0x%02X\n", offset, cond); @@ -2420,10 +2428,10 @@ init_io_condition(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) iexec->execute = false; } - return true; + return 2; } -static bool +static int init_index_io(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { /* @@ -2446,7 +2454,7 @@ init_index_io(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) uint8_t value; if (!iexec->execute) - return true; + return 6; BIOSLOG(bios, "0x%04X: Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X, " "Data: 0x%02X\n", @@ -2455,10 +2463,10 @@ init_index_io(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) value = (bios_idxprt_rd(bios, crtcport, crtcindex) & mask) | data; bios_idxprt_wr(bios, crtcport, crtcindex, value); - return true; + return 6; } -static bool +static int init_pll(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { /* @@ -2476,16 +2484,16 @@ init_pll(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) uint16_t freq = ROM16(bios->data[offset + 5]); if (!iexec->execute) - return true; + return 7; BIOSLOG(bios, "0x%04X: Reg: 0x%08X, Freq: %d0kHz\n", offset, reg, freq); setPLL(bios, reg, freq * 10); - return true; + return 7; } -static bool +static int init_zm_reg(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { /* @@ -2502,17 +2510,17 @@ init_zm_reg(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) uint32_t value = ROM32(bios->data[offset + 5]); if (!iexec->execute) - return true; + return 9; if (reg == 0x000200) value |= 1; bios_wr32(bios, reg, value); - return true; + return 9; } -static bool +static int init_ram_restrict_pll(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { @@ -2538,14 +2546,15 @@ init_ram_restrict_pll(struct nvbios *bios, uint16_t offset, uint8_t type = bios->data[offset + 1]; uint32_t freq = ROM32(bios->data[offset + 2 + (index * 4)]); uint8_t *pll_limits = &bios->data[bios->pll_limit_tbl_ptr], *entry; + int len = 2 + bios->ram_restrict_group_count * 4; int i; if (!iexec->execute) - return true; + return len; if (!bios->pll_limit_tbl_ptr || (pll_limits[0] & 0xf0) != 0x30) { NV_ERROR(dev, "PLL limits table not version 3.x\n"); - return true; /* deliberate, allow default clocks to remain */ + return len; /* deliberate, allow default clocks to remain */ } entry = pll_limits + pll_limits[1]; @@ -2558,15 +2567,15 @@ init_ram_restrict_pll(struct nvbios *bios, uint16_t offset, offset, type, reg, freq); setPLL(bios, reg, freq); - return true; + return len; } } NV_ERROR(dev, "PLL type 0x%02x not found in PLL limits table", type); - return true; + return len; } -static bool +static int init_8c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { /* @@ -2576,10 +2585,10 @@ init_8c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) * */ - return true; + return 1; } -static bool +static int init_8d(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { /* @@ -2589,10 +2598,10 @@ init_8d(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) * */ - return true; + return 1; } -static bool +static int init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { /* @@ -2610,14 +2619,17 @@ init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) const uint8_t *gpio_entry; int i; + if (!iexec->execute) + return 1; + if (bios->bdcb.version != 0x40) { NV_ERROR(bios->dev, "DCB table not version 4.0\n"); - return false; + return 0; } if (!bios->bdcb.gpio_table_ptr) { NV_WARN(bios->dev, "Invalid pointer to INIT_8E table\n"); - return false; + return 0; } gpio_entry = gpio_table + gpio_table[1]; @@ -2655,13 +2667,10 @@ init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) bios_wr32(bios, r, v); } - return true; + return 1; } -/* hack to avoid moving the itbl_entry array before this function */ -int init_ram_restrict_zm_reg_group_blocklen; - -static bool +static int init_ram_restrict_zm_reg_group(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { @@ -2687,21 +2696,21 @@ init_ram_restrict_zm_reg_group(struct nvbios *bios, uint16_t offset, uint8_t regincrement = bios->data[offset + 5]; uint8_t count = bios->data[offset + 6]; uint32_t strap_ramcfg, data; - uint16_t blocklen; + /* previously set by 'M' BIT table */ + uint16_t blocklen = bios->ram_restrict_group_count * 4; + int len = 7 + count * blocklen; uint8_t index; int i; - /* previously set by 'M' BIT table */ - blocklen = init_ram_restrict_zm_reg_group_blocklen; if (!iexec->execute) - return true; + return len; if (!blocklen) { NV_ERROR(bios->dev, "0x%04X: Zero block length - has the M table " "been parsed?\n", offset); - return false; + return 0; } strap_ramcfg = (bios_rd32(bios, NV_PEXTDEV_BOOT_0) >> 2) & 0xf; @@ -2719,10 +2728,10 @@ init_ram_restrict_zm_reg_group(struct nvbios *bios, uint16_t offset, reg += regincrement; } - return true; + return len; } -static bool +static int init_copy_zm_reg(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { /* @@ -2739,14 +2748,14 @@ init_copy_zm_reg(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) uint32_t dstreg = ROM32(bios->data[offset + 5]); if (!iexec->execute) - return true; + return 9; bios_wr32(bios, dstreg, bios_rd32(bios, srcreg)); - return true; + return 9; } -static bool +static int init_zm_reg_group_addr_latched(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { @@ -2764,20 +2773,21 @@ init_zm_reg_group_addr_latched(struct nvbios *bios, uint16_t offset, uint32_t reg = ROM32(bios->data[offset + 1]); uint8_t count = bios->data[offset + 5]; + int len = 6 + count * 4; int i; if (!iexec->execute) - return true; + return len; for (i = 0; i < count; i++) { uint32_t data = ROM32(bios->data[offset + 6 + 4 * i]); bios_wr32(bios, reg, data); } - return true; + return len; } -static bool +static int init_reserved(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { /* @@ -2788,10 +2798,10 @@ init_reserved(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) * Seemingly does nothing */ - return true; + return 1; } -static bool +static int init_96(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { /* @@ -2824,13 +2834,13 @@ init_96(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) val <<= bios->data[offset + 16]; if (!iexec->execute) - return true; + return 17; bios_wr32(bios, reg, (bios_rd32(bios, reg) & mask) | val); - return true; + return 17; } -static bool +static int init_97(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { /* @@ -2854,13 +2864,13 @@ init_97(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) val = (val & mask) | ((val + add) & ~mask); if (!iexec->execute) - return true; + return 13; bios_wr32(bios, reg, val); - return true; + return 13; } -static bool +static int init_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { /* @@ -2878,32 +2888,33 @@ init_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) struct drm_device *dev = bios->dev; struct nouveau_i2c_chan *auxch; uint32_t addr = ROM32(bios->data[offset + 1]); - uint8_t len = bios->data[offset + 5]; + uint8_t count = bios->data[offset + 5]; + int len = 6 + count * 2; int ret, i; if (!bios->display.output) { NV_ERROR(dev, "INIT_AUXCH: no active output\n"); - return false; + return 0; } auxch = init_i2c_device_find(dev, bios->display.output->i2c_index); if (!auxch) { NV_ERROR(dev, "INIT_AUXCH: couldn't get auxch %d\n", bios->display.output->i2c_index); - return false; + return 0; } if (!iexec->execute) - return true; + return len; offset += 6; - for (i = 0; i < len; i++, offset += 2) { + for (i = 0; i < count; i++, offset += 2) { uint8_t data; ret = nouveau_dp_auxch(auxch, 9, addr, &data, 1); if (ret) { NV_ERROR(dev, "INIT_AUXCH: rd auxch fail %d\n", ret); - return false; + return 0; } data &= bios->data[offset + 0]; @@ -2912,14 +2923,14 @@ init_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) ret = nouveau_dp_auxch(auxch, 8, addr, &data, 1); if (ret) { NV_ERROR(dev, "INIT_AUXCH: wr auxch fail %d\n", ret); - return false; + return 0; } } - return true; + return len; } -static bool +static int init_zm_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { /* @@ -2936,106 +2947,99 @@ init_zm_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) struct drm_device *dev = bios->dev; struct nouveau_i2c_chan *auxch; uint32_t addr = ROM32(bios->data[offset + 1]); - uint8_t len = bios->data[offset + 5]; + uint8_t count = bios->data[offset + 5]; + int len = 6 + count; int ret, i; if (!bios->display.output) { NV_ERROR(dev, "INIT_ZM_AUXCH: no active output\n"); - return false; + return 0; } auxch = init_i2c_device_find(dev, bios->display.output->i2c_index); if (!auxch) { NV_ERROR(dev, "INIT_ZM_AUXCH: couldn't get auxch %d\n", bios->display.output->i2c_index); - return false; + return 0; } if (!iexec->execute) - return true; + return len; offset += 6; - for (i = 0; i < len; i++, offset++) { + for (i = 0; i < count; i++, offset++) { ret = nouveau_dp_auxch(auxch, 8, addr, &bios->data[offset], 1); if (ret) { NV_ERROR(dev, "INIT_ZM_AUXCH: wr auxch fail %d\n", ret); - return false; + return 0; } } - return true; + return len; } static struct init_tbl_entry itbl_entry[] = { /* command name , id , length , offset , mult , command handler */ /* INIT_PROG (0x31, 15, 10, 4) removed due to no example of use */ - { "INIT_IO_RESTRICT_PROG" , 0x32, 11 , 6 , 4 , init_io_restrict_prog }, - { "INIT_REPEAT" , 0x33, 2 , 0 , 0 , init_repeat }, - { "INIT_IO_RESTRICT_PLL" , 0x34, 12 , 7 , 2 , init_io_restrict_pll }, - { "INIT_END_REPEAT" , 0x36, 1 , 0 , 0 , init_end_repeat }, - { "INIT_COPY" , 0x37, 11 , 0 , 0 , init_copy }, - { "INIT_NOT" , 0x38, 1 , 0 , 0 , init_not }, - { "INIT_IO_FLAG_CONDITION" , 0x39, 2 , 0 , 0 , init_io_flag_condition }, - { "INIT_INDEX_ADDRESS_LATCHED" , 0x49, 18 , 17 , 2 , init_idx_addr_latched }, - { "INIT_IO_RESTRICT_PLL2" , 0x4A, 11 , 6 , 4 , init_io_restrict_pll2 }, - { "INIT_PLL2" , 0x4B, 9 , 0 , 0 , init_pll2 }, - { "INIT_I2C_BYTE" , 0x4C, 4 , 3 , 3 , init_i2c_byte }, - { "INIT_ZM_I2C_BYTE" , 0x4D, 4 , 3 , 2 , init_zm_i2c_byte }, - { "INIT_ZM_I2C" , 0x4E, 4 , 3 , 1 , init_zm_i2c }, - { "INIT_TMDS" , 0x4F, 5 , 0 , 0 , init_tmds }, - { "INIT_ZM_TMDS_GROUP" , 0x50, 3 , 2 , 2 , init_zm_tmds_group }, - { "INIT_CR_INDEX_ADDRESS_LATCHED" , 0x51, 5 , 4 , 1 , init_cr_idx_adr_latch }, - { "INIT_CR" , 0x52, 4 , 0 , 0 , init_cr }, - { "INIT_ZM_CR" , 0x53, 3 , 0 , 0 , init_zm_cr }, - { "INIT_ZM_CR_GROUP" , 0x54, 2 , 1 , 2 , init_zm_cr_group }, - { "INIT_CONDITION_TIME" , 0x56, 3 , 0 , 0 , init_condition_time }, - { "INIT_ZM_REG_SEQUENCE" , 0x58, 6 , 5 , 4 , init_zm_reg_sequence }, + { "INIT_IO_RESTRICT_PROG" , 0x32, init_io_restrict_prog }, + { "INIT_REPEAT" , 0x33, init_repeat }, + { "INIT_IO_RESTRICT_PLL" , 0x34, init_io_restrict_pll }, + { "INIT_END_REPEAT" , 0x36, init_end_repeat }, + { "INIT_COPY" , 0x37, init_copy }, + { "INIT_NOT" , 0x38, init_not }, + { "INIT_IO_FLAG_CONDITION" , 0x39, init_io_flag_condition }, + { "INIT_INDEX_ADDRESS_LATCHED" , 0x49, init_idx_addr_latched }, + { "INIT_IO_RESTRICT_PLL2" , 0x4A, init_io_restrict_pll2 }, + { "INIT_PLL2" , 0x4B, init_pll2 }, + { "INIT_I2C_BYTE" , 0x4C, init_i2c_byte }, + { "INIT_ZM_I2C_BYTE" , 0x4D, init_zm_i2c_byte }, + { "INIT_ZM_I2C" , 0x4E, init_zm_i2c }, + { "INIT_TMDS" , 0x4F, init_tmds }, + { "INIT_ZM_TMDS_GROUP" , 0x50, init_zm_tmds_group }, + { "INIT_CR_INDEX_ADDRESS_LATCHED" , 0x51, init_cr_idx_adr_latch }, + { "INIT_CR" , 0x52, init_cr }, + { "INIT_ZM_CR" , 0x53, init_zm_cr }, + { "INIT_ZM_CR_GROUP" , 0x54, init_zm_cr_group }, + { "INIT_CONDITION_TIME" , 0x56, init_condition_time }, + { "INIT_ZM_REG_SEQUENCE" , 0x58, init_zm_reg_sequence }, /* INIT_INDIRECT_REG (0x5A, 7, 0, 0) removed due to no example of use */ - { "INIT_SUB_DIRECT" , 0x5B, 3 , 0 , 0 , init_sub_direct }, - { "INIT_COPY_NV_REG" , 0x5F, 22 , 0 , 0 , init_copy_nv_reg }, - { "INIT_ZM_INDEX_IO" , 0x62, 5 , 0 , 0 , init_zm_index_io }, - { "INIT_COMPUTE_MEM" , 0x63, 1 , 0 , 0 , init_compute_mem }, - { "INIT_RESET" , 0x65, 13 , 0 , 0 , init_reset }, - { "INIT_CONFIGURE_MEM" , 0x66, 1 , 0 , 0 , init_configure_mem }, - { "INIT_CONFIGURE_CLK" , 0x67, 1 , 0 , 0 , init_configure_clk }, - { "INIT_CONFIGURE_PREINIT" , 0x68, 1 , 0 , 0 , init_configure_preinit }, - { "INIT_IO" , 0x69, 5 , 0 , 0 , init_io }, - { "INIT_SUB" , 0x6B, 2 , 0 , 0 , init_sub }, - { "INIT_RAM_CONDITION" , 0x6D, 3 , 0 , 0 , init_ram_condition }, - { "INIT_NV_REG" , 0x6E, 13 , 0 , 0 , init_nv_reg }, - { "INIT_MACRO" , 0x6F, 2 , 0 , 0 , init_macro }, - { "INIT_DONE" , 0x71, 1 , 0 , 0 , init_done }, - { "INIT_RESUME" , 0x72, 1 , 0 , 0 , init_resume }, + { "INIT_SUB_DIRECT" , 0x5B, init_sub_direct }, + { "INIT_COPY_NV_REG" , 0x5F, init_copy_nv_reg }, + { "INIT_ZM_INDEX_IO" , 0x62, init_zm_index_io }, + { "INIT_COMPUTE_MEM" , 0x63, init_compute_mem }, + { "INIT_RESET" , 0x65, init_reset }, + { "INIT_CONFIGURE_MEM" , 0x66, init_configure_mem }, + { "INIT_CONFIGURE_CLK" , 0x67, init_configure_clk }, + { "INIT_CONFIGURE_PREINIT" , 0x68, init_configure_preinit }, + { "INIT_IO" , 0x69, init_io }, + { "INIT_SUB" , 0x6B, init_sub }, + { "INIT_RAM_CONDITION" , 0x6D, init_ram_condition }, + { "INIT_NV_REG" , 0x6E, init_nv_reg }, + { "INIT_MACRO" , 0x6F, init_macro }, + { "INIT_DONE" , 0x71, init_done }, + { "INIT_RESUME" , 0x72, init_resume }, /* INIT_RAM_CONDITION2 (0x73, 9, 0, 0) removed due to no example of use */ - { "INIT_TIME" , 0x74, 3 , 0 , 0 , init_time }, - { "INIT_CONDITION" , 0x75, 2 , 0 , 0 , init_condition }, - { "INIT_IO_CONDITION" , 0x76, 2 , 0 , 0 , init_io_condition }, - { "INIT_INDEX_IO" , 0x78, 6 , 0 , 0 , init_index_io }, - { "INIT_PLL" , 0x79, 7 , 0 , 0 , init_pll }, - { "INIT_ZM_REG" , 0x7A, 9 , 0 , 0 , init_zm_reg }, - /* INIT_RAM_RESTRICT_PLL's length is adjusted by the BIT M table */ - { "INIT_RAM_RESTRICT_PLL" , 0x87, 2 , 0 , 0 , init_ram_restrict_pll }, - { "INIT_8C" , 0x8C, 1 , 0 , 0 , init_8c }, - { "INIT_8D" , 0x8D, 1 , 0 , 0 , init_8d }, - { "INIT_GPIO" , 0x8E, 1 , 0 , 0 , init_gpio }, - /* INIT_RAM_RESTRICT_ZM_REG_GROUP's mult is loaded by M table in BIT */ - { "INIT_RAM_RESTRICT_ZM_REG_GROUP" , 0x8F, 7 , 6 , 0 , init_ram_restrict_zm_reg_group }, - { "INIT_COPY_ZM_REG" , 0x90, 9 , 0 , 0 , init_copy_zm_reg }, - { "INIT_ZM_REG_GROUP_ADDRESS_LATCHED" , 0x91, 6 , 5 , 4 , init_zm_reg_group_addr_latched }, - { "INIT_RESERVED" , 0x92, 1 , 0 , 0 , init_reserved }, - { "INIT_96" , 0x96, 17 , 0 , 0 , init_96 }, - { "INIT_97" , 0x97, 13 , 0 , 0 , init_97 }, - { "INIT_AUXCH" , 0x98, 6 , 5 , 2 , init_auxch }, - { "INIT_ZM_AUXCH" , 0x99, 6 , 5 , 1 , init_zm_auxch }, - { NULL , 0 , 0 , 0 , 0 , NULL } + { "INIT_TIME" , 0x74, init_time }, + { "INIT_CONDITION" , 0x75, init_condition }, + { "INIT_IO_CONDITION" , 0x76, init_io_condition }, + { "INIT_INDEX_IO" , 0x78, init_index_io }, + { "INIT_PLL" , 0x79, init_pll }, + { "INIT_ZM_REG" , 0x7A, init_zm_reg }, + { "INIT_RAM_RESTRICT_PLL" , 0x87, init_ram_restrict_pll }, + { "INIT_8C" , 0x8C, init_8c }, + { "INIT_8D" , 0x8D, init_8d }, + { "INIT_GPIO" , 0x8E, init_gpio }, + { "INIT_RAM_RESTRICT_ZM_REG_GROUP" , 0x8F, init_ram_restrict_zm_reg_group }, + { "INIT_COPY_ZM_REG" , 0x90, init_copy_zm_reg }, + { "INIT_ZM_REG_GROUP_ADDRESS_LATCHED" , 0x91, init_zm_reg_group_addr_latched }, + { "INIT_RESERVED" , 0x92, init_reserved }, + { "INIT_96" , 0x96, init_96 }, + { "INIT_97" , 0x97, init_97 }, + { "INIT_AUXCH" , 0x98, init_auxch }, + { "INIT_ZM_AUXCH" , 0x99, init_zm_auxch }, + { NULL , 0 , NULL } }; -static unsigned int get_init_table_entry_length(struct nvbios *bios, unsigned int offset, int i) -{ - /* Calculates the length of a given init table entry. */ - return itbl_entry[i].length + bios->data[offset + itbl_entry[i].length_offset]*itbl_entry[i].length_multiplier; -} - #define MAX_TABLE_OPS 1000 static int @@ -3051,7 +3055,7 @@ parse_init_table(struct nvbios *bios, unsigned int offset, * is changed back to EXECUTE. */ - int count = 0, i; + int count = 0, i, res; uint8_t id; /* @@ -3071,22 +3075,21 @@ parse_init_table(struct nvbios *bios, unsigned int offset, offset, itbl_entry[i].id, itbl_entry[i].name); /* execute eventual command handler */ - if (itbl_entry[i].handler) - if (!(*itbl_entry[i].handler)(bios, offset, iexec)) - break; + res = (*itbl_entry[i].handler)(bios, offset, iexec); + if (!res) + break; + /* + * Add the offset of the current command including all data + * of that command. The offset will then be pointing on the + * next op code. + */ + offset += res; } else { NV_ERROR(bios->dev, "0x%04X: Init table command not found: " "0x%02X\n", offset, id); return -ENOENT; } - - /* - * Add the offset of the current command including all data - * of that command. The offset will then be pointing on the - * next op code. - */ - offset += get_init_table_entry_length(bios, offset, i); } if (offset >= bios->length) @@ -4601,10 +4604,6 @@ parse_bit_M_tbl_entry(struct drm_device *dev, struct nvbios *bios, * stuff that we don't use - their use currently unknown */ - uint16_t rr_strap_xlat; - uint8_t rr_group_count; - int i; - /* * Older bios versions don't have a sufficiently long table for * what we want @@ -4613,24 +4612,13 @@ parse_bit_M_tbl_entry(struct drm_device *dev, struct nvbios *bios, return 0; if (bitentry->id[1] < 2) { - rr_group_count = bios->data[bitentry->offset + 2]; - rr_strap_xlat = ROM16(bios->data[bitentry->offset + 3]); + bios->ram_restrict_group_count = bios->data[bitentry->offset + 2]; + bios->ram_restrict_tbl_ptr = ROM16(bios->data[bitentry->offset + 3]); } else { - rr_group_count = bios->data[bitentry->offset + 0]; - rr_strap_xlat = ROM16(bios->data[bitentry->offset + 1]); + bios->ram_restrict_group_count = bios->data[bitentry->offset + 0]; + bios->ram_restrict_tbl_ptr = ROM16(bios->data[bitentry->offset + 1]); } - /* adjust length of INIT_87 */ - for (i = 0; itbl_entry[i].name && (itbl_entry[i].id != 0x87); i++); - itbl_entry[i].length += rr_group_count * 4; - - /* set up multiplier for INIT_RAM_RESTRICT_ZM_REG_GROUP */ - for (; itbl_entry[i].name && (itbl_entry[i].id != 0x8f); i++); - itbl_entry[i].length_multiplier = rr_group_count * 4; - - init_ram_restrict_zm_reg_group_blocklen = itbl_entry[i].length_multiplier; - bios->ram_restrict_tbl_ptr = rr_strap_xlat; - return 0; } diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.h b/drivers/gpu/drm/nouveau/nouveau_bios.h index 1d5f10b..058e98c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.h +++ b/drivers/gpu/drm/nouveau/nouveau_bios.h @@ -227,6 +227,7 @@ struct nvbios { uint16_t pll_limit_tbl_ptr; uint16_t ram_restrict_tbl_ptr; + uint8_t ram_restrict_group_count; uint16_t some_script_ptr; /* BIT I + 14 */ uint16_t init96_tbl_ptr; /* BIT I + 16 */ -- cgit v0.10.2 From 13c5443b515109f175bb9917c578a7ae973f6851 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Ko=C5=9Bcielnicki?= Date: Mon, 14 Dec 2009 20:38:17 +0000 Subject: drm/nv04: Fix NV04 set_operation software method. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marcin Kościelnicki Signed-off-by: Maarten Maathuis Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nv04_graph.c b/drivers/gpu/drm/nouveau/nv04_graph.c index 396ee92..d561d77 100644 --- a/drivers/gpu/drm/nouveau/nv04_graph.c +++ b/drivers/gpu/drm/nouveau/nv04_graph.c @@ -543,7 +543,7 @@ nv04_graph_mthd_set_operation(struct nouveau_channel *chan, int grclass, nv_wi32(dev, instance, tmp); nv_wr32(dev, NV04_PGRAPH_CTX_SWITCH1, tmp); - nv_wr32(dev, NV04_PGRAPH_CTX_CACHE1 + subc, tmp); + nv_wr32(dev, NV04_PGRAPH_CTX_CACHE1 + (subc<<2), tmp); return 0; } -- cgit v0.10.2 From c5804be0627508487bd9eacebf9de7f807e5d4e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Ko=C5=9Bcielnicki?= Date: Mon, 14 Dec 2009 20:58:39 +0000 Subject: drm/nouveau: Add proper error handling to nouveau_card_init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marcin Kościelnicki Signed-off-by: Maarten Maathuis Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 2ed41d3..9fc5824 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -317,7 +317,7 @@ nouveau_card_init(struct drm_device *dev) /* Initialise internal driver API hooks */ ret = nouveau_init_engine_ptrs(dev); if (ret) - return ret; + goto out; engine = &dev_priv->engine; dev_priv->init_state = NOUVEAU_CARD_INIT_FAILED; @@ -325,12 +325,12 @@ nouveau_card_init(struct drm_device *dev) if (drm_core_check_feature(dev, DRIVER_MODESET)) { ret = nouveau_bios_init(dev); if (ret) - return ret; + goto out; } ret = nouveau_gpuobj_early_init(dev); if (ret) - return ret; + goto out_bios; /* Initialise instance memory, must happen before mem_init so we * know exactly how much VRAM we're able to use for "normal" @@ -338,52 +338,52 @@ nouveau_card_init(struct drm_device *dev) */ ret = engine->instmem.init(dev); if (ret) - return ret; + goto out_gpuobj_early; /* Setup the memory manager */ ret = nouveau_mem_init(dev); if (ret) - return ret; + goto out_instmem; ret = nouveau_gpuobj_init(dev); if (ret) - return ret; + goto out_mem; /* PMC */ ret = engine->mc.init(dev); if (ret) - return ret; + goto out_gpuobj; /* PTIMER */ ret = engine->timer.init(dev); if (ret) - return ret; + goto out_mc; /* PFB */ ret = engine->fb.init(dev); if (ret) - return ret; + goto out_timer; /* PGRAPH */ ret = engine->graph.init(dev); if (ret) - return ret; + goto out_fb; /* PFIFO */ ret = engine->fifo.init(dev); if (ret) - return ret; + goto out_graph; /* this call irq_preinstall, register irq handler and * call irq_postinstall */ ret = drm_irq_install(dev); if (ret) - return ret; + goto out_fifo; ret = drm_vblank_init(dev, 0); if (ret) - return ret; + goto out_irq; /* what about PVIDEO/PCRTC/PRAMDAC etc? */ @@ -391,7 +391,7 @@ nouveau_card_init(struct drm_device *dev) (struct drm_file *)-2, NvDmaFB, NvDmaTT); if (ret) - return ret; + goto out_irq; gpuobj = NULL; ret = nouveau_gpuobj_dma_new(dev_priv->channel, NV_CLASS_DMA_IN_MEMORY, @@ -399,13 +399,13 @@ nouveau_card_init(struct drm_device *dev) NV_DMA_ACCESS_RW, NV_DMA_TARGET_VIDMEM, &gpuobj); if (ret) - return ret; + goto out_irq; ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, NvDmaVRAM, gpuobj, NULL); if (ret) { nouveau_gpuobj_del(dev, &gpuobj); - return ret; + goto out_irq; } gpuobj = NULL; @@ -413,25 +413,22 @@ nouveau_card_init(struct drm_device *dev) dev_priv->gart_info.aper_size, NV_DMA_ACCESS_RW, &gpuobj, NULL); if (ret) - return ret; + goto out_irq; ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, NvDmaGART, gpuobj, NULL); if (ret) { nouveau_gpuobj_del(dev, &gpuobj); - return ret; + goto out_irq; } if (drm_core_check_feature(dev, DRIVER_MODESET)) { - if (dev_priv->card_type >= NV_50) { + if (dev_priv->card_type >= NV_50) ret = nv50_display_create(dev); - if (ret) - return ret; - } else { + else ret = nv04_display_create(dev); - if (ret) - return ret; - } + if (ret) + goto out_irq; } ret = nouveau_backlight_init(dev); @@ -444,6 +441,32 @@ nouveau_card_init(struct drm_device *dev) drm_helper_initial_config(dev); return 0; + +out_irq: + drm_irq_uninstall(dev); +out_fifo: + engine->fifo.takedown(dev); +out_graph: + engine->graph.takedown(dev); +out_fb: + engine->fb.takedown(dev); +out_timer: + engine->timer.takedown(dev); +out_mc: + engine->mc.takedown(dev); +out_gpuobj: + nouveau_gpuobj_takedown(dev); +out_mem: + nouveau_mem_close(dev); +out_instmem: + engine->instmem.takedown(dev); +out_gpuobj_early: + nouveau_gpuobj_late_takedown(dev); +out_bios: + nouveau_bios_takedown(dev); +out: + vga_client_register(dev->pdev, NULL, NULL, NULL); + return ret; } static void nouveau_card_takedown(struct drm_device *dev) -- cgit v0.10.2 From 22fbd53809eb7a1b00fe09159fe0a565fb6c725c Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Fri, 11 Dec 2009 18:40:17 +0100 Subject: drm/nouveau: Fix up buffer eviction, and evict them to GART, if possible. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index aa2dfbc..e9f0190 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -400,10 +400,16 @@ nouveau_bo_evict_flags(struct ttm_buffer_object *bo, struct ttm_placement *pl) struct nouveau_bo *nvbo = nouveau_bo(bo); switch (bo->mem.mem_type) { + case TTM_PL_VRAM: + nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_TT | + TTM_PL_FLAG_SYSTEM); + break; default: nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_SYSTEM); break; } + + *pl = nvbo->placement; } -- cgit v0.10.2 From 15bee69ee1532a29e13124b298027ee6ef54bac8 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Mon, 14 Dec 2009 15:00:30 +0100 Subject: drm/nv10: Add the initial graph context and soft methods needed for LMA. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nv10_graph.c b/drivers/gpu/drm/nouveau/nv10_graph.c index 6bf6804..6870e0e 100644 --- a/drivers/gpu/drm/nouveau/nv10_graph.c +++ b/drivers/gpu/drm/nouveau/nv10_graph.c @@ -389,49 +389,50 @@ struct graph_state { int nv10[ARRAY_SIZE(nv10_graph_ctx_regs)]; int nv17[ARRAY_SIZE(nv17_graph_ctx_regs)]; struct pipe_state pipe_state; + uint32_t lma_window[4]; }; +#define PIPE_SAVE(dev, state, addr) \ + do { \ + int __i; \ + nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, addr); \ + for (__i = 0; __i < ARRAY_SIZE(state); __i++) \ + state[__i] = nv_rd32(dev, NV10_PGRAPH_PIPE_DATA); \ + } while (0) + +#define PIPE_RESTORE(dev, state, addr) \ + do { \ + int __i; \ + nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, addr); \ + for (__i = 0; __i < ARRAY_SIZE(state); __i++) \ + nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, state[__i]); \ + } while (0) + static void nv10_graph_save_pipe(struct nouveau_channel *chan) { struct drm_device *dev = chan->dev; struct graph_state *pgraph_ctx = chan->pgraph_ctx; - struct pipe_state *fifo_pipe_state = &pgraph_ctx->pipe_state; - int i; -#define PIPE_SAVE(addr) \ - do { \ - nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, addr); \ - for (i = 0; i < ARRAY_SIZE(fifo_pipe_state->pipe_##addr); i++) \ - fifo_pipe_state->pipe_##addr[i] = nv_rd32(dev, NV10_PGRAPH_PIPE_DATA); \ - } while (0) - - PIPE_SAVE(0x4400); - PIPE_SAVE(0x0200); - PIPE_SAVE(0x6400); - PIPE_SAVE(0x6800); - PIPE_SAVE(0x6c00); - PIPE_SAVE(0x7000); - PIPE_SAVE(0x7400); - PIPE_SAVE(0x7800); - PIPE_SAVE(0x0040); - PIPE_SAVE(0x0000); - -#undef PIPE_SAVE + struct pipe_state *pipe = &pgraph_ctx->pipe_state; + + PIPE_SAVE(dev, pipe->pipe_0x4400, 0x4400); + PIPE_SAVE(dev, pipe->pipe_0x0200, 0x0200); + PIPE_SAVE(dev, pipe->pipe_0x6400, 0x6400); + PIPE_SAVE(dev, pipe->pipe_0x6800, 0x6800); + PIPE_SAVE(dev, pipe->pipe_0x6c00, 0x6c00); + PIPE_SAVE(dev, pipe->pipe_0x7000, 0x7000); + PIPE_SAVE(dev, pipe->pipe_0x7400, 0x7400); + PIPE_SAVE(dev, pipe->pipe_0x7800, 0x7800); + PIPE_SAVE(dev, pipe->pipe_0x0040, 0x0040); + PIPE_SAVE(dev, pipe->pipe_0x0000, 0x0000); } static void nv10_graph_load_pipe(struct nouveau_channel *chan) { struct drm_device *dev = chan->dev; struct graph_state *pgraph_ctx = chan->pgraph_ctx; - struct pipe_state *fifo_pipe_state = &pgraph_ctx->pipe_state; - int i; + struct pipe_state *pipe = &pgraph_ctx->pipe_state; uint32_t xfmode0, xfmode1; -#define PIPE_RESTORE(addr) \ - do { \ - nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, addr); \ - for (i = 0; i < ARRAY_SIZE(fifo_pipe_state->pipe_##addr); i++) \ - nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, fifo_pipe_state->pipe_##addr[i]); \ - } while (0) - + int i; nouveau_wait_for_idle(dev); /* XXX check haiku comments */ @@ -457,24 +458,22 @@ static void nv10_graph_load_pipe(struct nouveau_channel *chan) nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000008); - PIPE_RESTORE(0x0200); + PIPE_RESTORE(dev, pipe->pipe_0x0200, 0x0200); nouveau_wait_for_idle(dev); /* restore XFMODE */ nv_wr32(dev, NV10_PGRAPH_XFMODE0, xfmode0); nv_wr32(dev, NV10_PGRAPH_XFMODE1, xfmode1); - PIPE_RESTORE(0x6400); - PIPE_RESTORE(0x6800); - PIPE_RESTORE(0x6c00); - PIPE_RESTORE(0x7000); - PIPE_RESTORE(0x7400); - PIPE_RESTORE(0x7800); - PIPE_RESTORE(0x4400); - PIPE_RESTORE(0x0000); - PIPE_RESTORE(0x0040); + PIPE_RESTORE(dev, pipe->pipe_0x6400, 0x6400); + PIPE_RESTORE(dev, pipe->pipe_0x6800, 0x6800); + PIPE_RESTORE(dev, pipe->pipe_0x6c00, 0x6c00); + PIPE_RESTORE(dev, pipe->pipe_0x7000, 0x7000); + PIPE_RESTORE(dev, pipe->pipe_0x7400, 0x7400); + PIPE_RESTORE(dev, pipe->pipe_0x7800, 0x7800); + PIPE_RESTORE(dev, pipe->pipe_0x4400, 0x4400); + PIPE_RESTORE(dev, pipe->pipe_0x0000, 0x0000); + PIPE_RESTORE(dev, pipe->pipe_0x0040, 0x0040); nouveau_wait_for_idle(dev); - -#undef PIPE_RESTORE } static void nv10_graph_create_pipe(struct nouveau_channel *chan) @@ -832,6 +831,9 @@ int nv10_graph_init(struct drm_device *dev) (1<<31)); if (dev_priv->chipset >= 0x17) { nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x1f000000); + nv_wr32(dev, 0x400a10, 0x3ff3fb6); + nv_wr32(dev, 0x400838, 0x2f8684); + nv_wr32(dev, 0x40083c, 0x115f3f); nv_wr32(dev, 0x004006b0, 0x40000020); } else nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x00000000); @@ -867,6 +869,115 @@ void nv10_graph_takedown(struct drm_device *dev) { } +static int +nv17_graph_mthd_lma_window(struct nouveau_channel *chan, int grclass, + int mthd, uint32_t data) +{ + struct drm_device *dev = chan->dev; + struct graph_state *ctx = chan->pgraph_ctx; + struct pipe_state *pipe = &ctx->pipe_state; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; + uint32_t pipe_0x0040[1], pipe_0x64c0[8], pipe_0x6a80[3], pipe_0x6ab0[3]; + uint32_t xfmode0, xfmode1; + int i; + + ctx->lma_window[(mthd - 0x1638) / 4] = data; + + if (mthd != 0x1644) + return 0; + + nouveau_wait_for_idle(dev); + + PIPE_SAVE(dev, pipe_0x0040, 0x0040); + PIPE_SAVE(dev, pipe->pipe_0x0200, 0x0200); + + PIPE_RESTORE(dev, ctx->lma_window, 0x6790); + + nouveau_wait_for_idle(dev); + + xfmode0 = nv_rd32(dev, NV10_PGRAPH_XFMODE0); + xfmode1 = nv_rd32(dev, NV10_PGRAPH_XFMODE1); + + PIPE_SAVE(dev, pipe->pipe_0x4400, 0x4400); + PIPE_SAVE(dev, pipe_0x64c0, 0x64c0); + PIPE_SAVE(dev, pipe_0x6ab0, 0x6ab0); + PIPE_SAVE(dev, pipe_0x6a80, 0x6a80); + + nouveau_wait_for_idle(dev); + + nv_wr32(dev, NV10_PGRAPH_XFMODE0, 0x10000000); + nv_wr32(dev, NV10_PGRAPH_XFMODE1, 0x00000000); + nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x000064c0); + for (i = 0; i < 4; i++) + nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x3f800000); + for (i = 0; i < 4; i++) + nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000000); + + nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00006ab0); + for (i = 0; i < 3; i++) + nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x3f800000); + + nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00006a80); + for (i = 0; i < 3; i++) + nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000000); + + nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00000040); + nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000008); + + PIPE_RESTORE(dev, pipe->pipe_0x0200, 0x0200); + + nouveau_wait_for_idle(dev); + + PIPE_RESTORE(dev, pipe_0x0040, 0x0040); + + nv_wr32(dev, NV10_PGRAPH_XFMODE0, xfmode0); + nv_wr32(dev, NV10_PGRAPH_XFMODE1, xfmode1); + + PIPE_RESTORE(dev, pipe_0x64c0, 0x64c0); + PIPE_RESTORE(dev, pipe_0x6ab0, 0x6ab0); + PIPE_RESTORE(dev, pipe_0x6a80, 0x6a80); + PIPE_RESTORE(dev, pipe->pipe_0x4400, 0x4400); + + nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x000000c0); + nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000000); + + nouveau_wait_for_idle(dev); + + pgraph->fifo_access(dev, true); + + return 0; +} + +static int +nv17_graph_mthd_lma_enable(struct nouveau_channel *chan, int grclass, + int mthd, uint32_t data) +{ + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; + + nouveau_wait_for_idle(dev); + + nv_wr32(dev, NV10_PGRAPH_DEBUG_4, + nv_rd32(dev, NV10_PGRAPH_DEBUG_4) | 0x1 << 8); + nv_wr32(dev, 0x004006b0, + nv_rd32(dev, 0x004006b0) | 0x8 << 24); + + pgraph->fifo_access(dev, true); + + return 0; +} + +static struct nouveau_pgraph_object_method nv17_graph_celsius_mthds[] = { + { 0x1638, nv17_graph_mthd_lma_window }, + { 0x163c, nv17_graph_mthd_lma_window }, + { 0x1640, nv17_graph_mthd_lma_window }, + { 0x1644, nv17_graph_mthd_lma_window }, + { 0x1658, nv17_graph_mthd_lma_enable }, + {} +}; + struct nouveau_pgraph_object_class nv10_graph_grclass[] = { { 0x0030, false, NULL }, /* null */ { 0x0039, false, NULL }, /* m2mf */ @@ -887,6 +998,6 @@ struct nouveau_pgraph_object_class nv10_graph_grclass[] = { { 0x0095, false, NULL }, /* multitex_tri */ { 0x0056, false, NULL }, /* celcius (nv10) */ { 0x0096, false, NULL }, /* celcius (nv11) */ - { 0x0099, false, NULL }, /* celcius (nv17) */ + { 0x0099, false, nv17_graph_celsius_mthds }, /* celcius (nv17) */ {} }; -- cgit v0.10.2 From 054b93e444550a72aef17115363cdef253b9ee7c Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 15 Dec 2009 22:02:47 +1000 Subject: drm/nv40: implement ctxprog/state generation The context programs are *very* simple compared to the ones used by the binary driver. There's notes in nv40_grctx.c explaining most of the things we don't implement. If we discover if/why any of it is required further down the track, we'll handle it then. The PGRAPH state generated for each chipset should match what NVIDIA do almost exactly (there's a couple of exceptions). If someone has a lot of time on their hands, they could figure out the mapping of object/method to PGRAPH register and demagic the initial state a little, it's not terribly important however. At time of commit, confirmed to be working at least well enough for accelerated X (and where tested, for 3D apps) on NV40, NV43, NV44, NV46, NV49, NV4A, NV4B and NV4E. A module option has been added to force the use of external firmware blobs if it becomes required. Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile index 1d90d4d..48c290b 100644 --- a/drivers/gpu/drm/nouveau/Makefile +++ b/drivers/gpu/drm/nouveau/Makefile @@ -8,14 +8,15 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \ nouveau_sgdma.o nouveau_dma.o \ nouveau_bo.o nouveau_fence.o nouveau_gem.o nouveau_ttm.o \ nouveau_hw.o nouveau_calc.o nouveau_bios.o nouveau_i2c.o \ - nouveau_display.o nouveau_connector.o nouveau_fbcon.o \ - nouveau_dp.o \ + nouveau_display.o nouveau_connector.o nouveau_fbcon.o \ + nouveau_dp.o nouveau_grctx.o \ nv04_timer.o \ nv04_mc.o nv40_mc.o nv50_mc.o \ nv04_fb.o nv10_fb.o nv40_fb.o \ nv04_fifo.o nv10_fifo.o nv40_fifo.o nv50_fifo.o \ nv04_graph.o nv10_graph.o nv20_graph.o \ nv40_graph.o nv50_graph.o \ + nv40_grctx.o \ nv04_instmem.o nv50_instmem.o \ nv50_crtc.o nv50_dac.o nv50_sor.o \ nv50_cursor.o nv50_display.o nv50_fbcon.o \ diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c index 35249c3..78662cc 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.c +++ b/drivers/gpu/drm/nouveau/nouveau_drv.c @@ -35,6 +35,10 @@ #include "drm_pciids.h" +MODULE_PARM_DESC(ctxfw, "Use external firmware blob for grctx init (NV40)"); +int nouveau_ctxfw = 0; +module_param_named(ctxfw, nouveau_ctxfw, int, 0400); + MODULE_PARM_DESC(noagp, "Disable AGP"); int nouveau_noagp; module_param_named(noagp, nouveau_noagp, int, 0400); diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index bc6ffa5..5f8cbb7 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -54,6 +54,7 @@ struct nouveau_fpriv { #include "nouveau_drm.h" #include "nouveau_reg.h" #include "nouveau_bios.h" +struct nouveau_grctx; #define MAX_NUM_DCB_ENTRIES 16 @@ -317,6 +318,7 @@ struct nouveau_pgraph_engine { bool accel_blocked; void *ctxprog; void *ctxvals; + int grctx_size; int (*init)(struct drm_device *); void (*takedown)(struct drm_device *); @@ -647,6 +649,7 @@ extern int nouveau_fbpercrtc; extern char *nouveau_tv_norm; extern int nouveau_reg_debug; extern char *nouveau_vbios; +extern int nouveau_ctxfw; /* nouveau_state.c */ extern void nouveau_preclose(struct drm_device *dev, struct drm_file *); @@ -959,9 +962,7 @@ extern int nv40_graph_create_context(struct nouveau_channel *); extern void nv40_graph_destroy_context(struct nouveau_channel *); extern int nv40_graph_load_context(struct nouveau_channel *); extern int nv40_graph_unload_context(struct drm_device *); -extern int nv40_grctx_init(struct drm_device *); -extern void nv40_grctx_fini(struct drm_device *); -extern void nv40_grctx_vals_load(struct drm_device *, struct nouveau_gpuobj *); +extern void nv40_grctx_init(struct nouveau_grctx *); /* nv50_graph.c */ extern struct nouveau_pgraph_object_class nv50_graph_grclass[]; @@ -975,6 +976,12 @@ extern int nv50_graph_load_context(struct nouveau_channel *); extern int nv50_graph_unload_context(struct drm_device *); extern void nv50_graph_context_switch(struct drm_device *); +/* nouveau_grctx.c */ +extern int nouveau_grctx_prog_load(struct drm_device *); +extern void nouveau_grctx_vals_load(struct drm_device *, + struct nouveau_gpuobj *); +extern void nouveau_grctx_fini(struct drm_device *); + /* nv04_instmem.c */ extern int nv04_instmem_init(struct drm_device *); extern void nv04_instmem_takedown(struct drm_device *); diff --git a/drivers/gpu/drm/nouveau/nouveau_grctx.c b/drivers/gpu/drm/nouveau/nouveau_grctx.c new file mode 100644 index 0000000..d5d84c8 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nouveau_grctx.c @@ -0,0 +1,158 @@ +/* + * Copyright 2009 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs + */ + +#include + +#include "drmP.h" +#include "nouveau_drv.h" + +struct nouveau_ctxprog { + uint32_t signature; + uint8_t version; + uint16_t length; + uint32_t data[]; +} __attribute__ ((packed)); + +struct nouveau_ctxvals { + uint32_t signature; + uint8_t version; + uint32_t length; + struct { + uint32_t offset; + uint32_t value; + } data[]; +} __attribute__ ((packed)); + +int +nouveau_grctx_prog_load(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; + const int chipset = dev_priv->chipset; + const struct firmware *fw; + const struct nouveau_ctxprog *cp; + const struct nouveau_ctxvals *cv; + char name[32]; + int ret, i; + + if (!pgraph->ctxprog) { + sprintf(name, "nouveau/nv%02x.ctxprog", chipset); + ret = request_firmware(&fw, name, &dev->pdev->dev); + if (ret) { + NV_ERROR(dev, "No ctxprog for NV%02x\n", chipset); + return ret; + } + + pgraph->ctxprog = kmalloc(fw->size, GFP_KERNEL); + if (!pgraph->ctxprog) { + NV_ERROR(dev, "OOM copying ctxprog\n"); + release_firmware(fw); + return -ENOMEM; + } + memcpy(pgraph->ctxprog, fw->data, fw->size); + + cp = pgraph->ctxprog; + if (le32_to_cpu(cp->signature) != 0x5043564e || + cp->version != 0 || + le16_to_cpu(cp->length) != ((fw->size - 7) / 4)) { + NV_ERROR(dev, "ctxprog invalid\n"); + release_firmware(fw); + nouveau_grctx_fini(dev); + return -EINVAL; + } + release_firmware(fw); + } + + if (!pgraph->ctxvals) { + sprintf(name, "nouveau/nv%02x.ctxvals", chipset); + ret = request_firmware(&fw, name, &dev->pdev->dev); + if (ret) { + NV_ERROR(dev, "No ctxvals for NV%02x\n", chipset); + nouveau_grctx_fini(dev); + return ret; + } + + pgraph->ctxvals = kmalloc(fw->size, GFP_KERNEL); + if (!pgraph->ctxprog) { + NV_ERROR(dev, "OOM copying ctxprog\n"); + release_firmware(fw); + nouveau_grctx_fini(dev); + return -ENOMEM; + } + memcpy(pgraph->ctxvals, fw->data, fw->size); + + cv = (void *)pgraph->ctxvals; + if (le32_to_cpu(cv->signature) != 0x5643564e || + cv->version != 0 || + le32_to_cpu(cv->length) != ((fw->size - 9) / 8)) { + NV_ERROR(dev, "ctxvals invalid\n"); + release_firmware(fw); + nouveau_grctx_fini(dev); + return -EINVAL; + } + release_firmware(fw); + } + + cp = pgraph->ctxprog; + + nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0); + for (i = 0; i < le16_to_cpu(cp->length); i++) + nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, + le32_to_cpu(cp->data[i])); + + return 0; +} + +void +nouveau_grctx_fini(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; + + if (pgraph->ctxprog) { + kfree(pgraph->ctxprog); + pgraph->ctxprog = NULL; + } + + if (pgraph->ctxvals) { + kfree(pgraph->ctxprog); + pgraph->ctxvals = NULL; + } +} + +void +nouveau_grctx_vals_load(struct drm_device *dev, struct nouveau_gpuobj *ctx) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; + struct nouveau_ctxvals *cv = pgraph->ctxvals; + int i; + + if (!cv) + return; + + for (i = 0; i < le32_to_cpu(cv->length); i++) + nv_wo32(dev, ctx, le32_to_cpu(cv->data[i].offset), + le32_to_cpu(cv->data[i].value)); +} diff --git a/drivers/gpu/drm/nouveau/nouveau_grctx.h b/drivers/gpu/drm/nouveau/nouveau_grctx.h new file mode 100644 index 0000000..5d39c4c --- /dev/null +++ b/drivers/gpu/drm/nouveau/nouveau_grctx.h @@ -0,0 +1,133 @@ +#ifndef __NOUVEAU_GRCTX_H__ +#define __NOUVEAU_GRCTX_H__ + +struct nouveau_grctx { + struct drm_device *dev; + + enum { + NOUVEAU_GRCTX_PROG, + NOUVEAU_GRCTX_VALS + } mode; + void *data; + + uint32_t ctxprog_max; + uint32_t ctxprog_len; + uint32_t ctxprog_reg; + int ctxprog_label[32]; + uint32_t ctxvals_pos; + uint32_t ctxvals_base; +}; + +#ifdef CP_CTX +static inline void +cp_out(struct nouveau_grctx *ctx, uint32_t inst) +{ + uint32_t *ctxprog = ctx->data; + + if (ctx->mode != NOUVEAU_GRCTX_PROG) + return; + + BUG_ON(ctx->ctxprog_len == ctx->ctxprog_max); + ctxprog[ctx->ctxprog_len++] = inst; +} + +static inline void +cp_lsr(struct nouveau_grctx *ctx, uint32_t val) +{ + cp_out(ctx, CP_LOAD_SR | val); +} + +static inline void +cp_ctx(struct nouveau_grctx *ctx, uint32_t reg, uint32_t length) +{ + ctx->ctxprog_reg = (reg - 0x00400000) >> 2; + + ctx->ctxvals_base = ctx->ctxvals_pos; + ctx->ctxvals_pos = ctx->ctxvals_base + length; + + if (length > (CP_CTX_COUNT >> CP_CTX_COUNT_SHIFT)) { + cp_lsr(ctx, length); + length = 0; + } + + cp_out(ctx, CP_CTX | (length << CP_CTX_COUNT_SHIFT) | ctx->ctxprog_reg); +} + +static inline void +cp_name(struct nouveau_grctx *ctx, int name) +{ + uint32_t *ctxprog = ctx->data; + int i; + + if (ctx->mode != NOUVEAU_GRCTX_PROG) + return; + + ctx->ctxprog_label[name] = ctx->ctxprog_len; + for (i = 0; i < ctx->ctxprog_len; i++) { + if ((ctxprog[i] & 0xfff00000) != 0xff400000) + continue; + if ((ctxprog[i] & CP_BRA_IP) != ((name) << CP_BRA_IP_SHIFT)) + continue; + ctxprog[i] = (ctxprog[i] & 0x00ff00ff) | + (ctx->ctxprog_len << CP_BRA_IP_SHIFT); + } +} + +static inline void +_cp_bra(struct nouveau_grctx *ctx, u32 mod, int flag, int state, int name) +{ + int ip = 0; + + if (mod != 2) { + ip = ctx->ctxprog_label[name] << CP_BRA_IP_SHIFT; + if (ip == 0) + ip = 0xff000000 | (name << CP_BRA_IP_SHIFT); + } + + cp_out(ctx, CP_BRA | (mod << 18) | ip | flag | + (state ? 0 : CP_BRA_IF_CLEAR)); +} +#define cp_bra(c,f,s,n) _cp_bra((c), 0, CP_FLAG_##f, CP_FLAG_##f##_##s, n) +#ifdef CP_BRA_MOD +#define cp_cal(c,f,s,n) _cp_bra((c), 1, CP_FLAG_##f, CP_FLAG_##f##_##s, n) +#define cp_ret(c,f,s) _cp_bra((c), 2, CP_FLAG_##f, CP_FLAG_##f##_##s, 0) +#endif + +static inline void +_cp_wait(struct nouveau_grctx *ctx, int flag, int state) +{ + cp_out(ctx, CP_WAIT | flag | (state ? CP_WAIT_SET : 0)); +} +#define cp_wait(c,f,s) _cp_wait((c), CP_FLAG_##f, CP_FLAG_##f##_##s) + +static inline void +_cp_set(struct nouveau_grctx *ctx, int flag, int state) +{ + cp_out(ctx, CP_SET | flag | (state ? CP_SET_1 : 0)); +} +#define cp_set(c,f,s) _cp_set((c), CP_FLAG_##f, CP_FLAG_##f##_##s) + +static inline void +cp_pos(struct nouveau_grctx *ctx, int offset) +{ + ctx->ctxvals_pos = offset; + ctx->ctxvals_base = ctx->ctxvals_pos; + + cp_lsr(ctx, ctx->ctxvals_pos); + cp_out(ctx, CP_SET_CONTEXT_POINTER); +} + +static inline void +gr_def(struct nouveau_grctx *ctx, uint32_t reg, uint32_t val) +{ + if (ctx->mode != NOUVEAU_GRCTX_VALS) + return; + + reg = (reg - 0x00400000) / 4; + reg = (reg - ctx->ctxprog_reg) + ctx->ctxvals_base; + + nv_wo32(ctx->dev, ctx->data, reg, val); +} +#endif + +#endif diff --git a/drivers/gpu/drm/nouveau/nv40_graph.c b/drivers/gpu/drm/nouveau/nv40_graph.c index 7e8547c..2b332bb 100644 --- a/drivers/gpu/drm/nouveau/nv40_graph.c +++ b/drivers/gpu/drm/nouveau/nv40_graph.c @@ -24,36 +24,10 @@ * */ -#include - #include "drmP.h" #include "drm.h" #include "nouveau_drv.h" - -MODULE_FIRMWARE("nouveau/nv40.ctxprog"); -MODULE_FIRMWARE("nouveau/nv40.ctxvals"); -MODULE_FIRMWARE("nouveau/nv41.ctxprog"); -MODULE_FIRMWARE("nouveau/nv41.ctxvals"); -MODULE_FIRMWARE("nouveau/nv42.ctxprog"); -MODULE_FIRMWARE("nouveau/nv42.ctxvals"); -MODULE_FIRMWARE("nouveau/nv43.ctxprog"); -MODULE_FIRMWARE("nouveau/nv43.ctxvals"); -MODULE_FIRMWARE("nouveau/nv44.ctxprog"); -MODULE_FIRMWARE("nouveau/nv44.ctxvals"); -MODULE_FIRMWARE("nouveau/nv46.ctxprog"); -MODULE_FIRMWARE("nouveau/nv46.ctxvals"); -MODULE_FIRMWARE("nouveau/nv47.ctxprog"); -MODULE_FIRMWARE("nouveau/nv47.ctxvals"); -MODULE_FIRMWARE("nouveau/nv49.ctxprog"); -MODULE_FIRMWARE("nouveau/nv49.ctxvals"); -MODULE_FIRMWARE("nouveau/nv4a.ctxprog"); -MODULE_FIRMWARE("nouveau/nv4a.ctxvals"); -MODULE_FIRMWARE("nouveau/nv4b.ctxprog"); -MODULE_FIRMWARE("nouveau/nv4b.ctxvals"); -MODULE_FIRMWARE("nouveau/nv4c.ctxprog"); -MODULE_FIRMWARE("nouveau/nv4c.ctxvals"); -MODULE_FIRMWARE("nouveau/nv4e.ctxprog"); -MODULE_FIRMWARE("nouveau/nv4e.ctxvals"); +#include "nouveau_grctx.h" struct nouveau_channel * nv40_graph_channel(struct drm_device *dev) @@ -83,27 +57,30 @@ nv40_graph_create_context(struct nouveau_channel *chan) { struct drm_device *dev = chan->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpuobj *ctx; + struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; int ret; - /* Allocate a 175KiB block of PRAMIN to store the context. This - * is massive overkill for a lot of chipsets, but it should be safe - * until we're able to implement this properly (will happen at more - * or less the same time we're able to write our own context programs. - */ - ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, 175*1024, 16, - NVOBJ_FLAG_ZERO_ALLOC, - &chan->ramin_grctx); + ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, pgraph->grctx_size, + 16, NVOBJ_FLAG_ZERO_ALLOC, + &chan->ramin_grctx); if (ret) return ret; - ctx = chan->ramin_grctx->gpuobj; /* Initialise default context values */ dev_priv->engine.instmem.prepare_access(dev, true); - nv40_grctx_vals_load(dev, ctx); - nv_wo32(dev, ctx, 0, ctx->im_pramin->start); - dev_priv->engine.instmem.finish_access(dev); + if (!pgraph->ctxprog) { + struct nouveau_grctx ctx = {}; + ctx.dev = chan->dev; + ctx.mode = NOUVEAU_GRCTX_VALS; + ctx.data = chan->ramin_grctx->gpuobj; + nv40_grctx_init(&ctx); + } else { + nouveau_grctx_vals_load(dev, chan->ramin_grctx->gpuobj); + } + nv_wo32(dev, chan->ramin_grctx->gpuobj, 0, + chan->ramin_grctx->gpuobj->im_pramin->start); + dev_priv->engine.instmem.finish_access(dev); return 0; } @@ -204,139 +181,6 @@ nv40_graph_unload_context(struct drm_device *dev) return ret; } -struct nouveau_ctxprog { - uint32_t signature; - uint8_t version; - uint16_t length; - uint32_t data[]; -} __attribute__ ((packed)); - -struct nouveau_ctxvals { - uint32_t signature; - uint8_t version; - uint32_t length; - struct { - uint32_t offset; - uint32_t value; - } data[]; -} __attribute__ ((packed)); - -int -nv40_grctx_init(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; - const int chipset = dev_priv->chipset; - const struct firmware *fw; - const struct nouveau_ctxprog *cp; - const struct nouveau_ctxvals *cv; - char name[32]; - int ret, i; - - pgraph->accel_blocked = true; - - if (!pgraph->ctxprog) { - sprintf(name, "nouveau/nv%02x.ctxprog", chipset); - ret = request_firmware(&fw, name, &dev->pdev->dev); - if (ret) { - NV_ERROR(dev, "No ctxprog for NV%02x\n", chipset); - return ret; - } - - pgraph->ctxprog = kmalloc(fw->size, GFP_KERNEL); - if (!pgraph->ctxprog) { - NV_ERROR(dev, "OOM copying ctxprog\n"); - release_firmware(fw); - return -ENOMEM; - } - memcpy(pgraph->ctxprog, fw->data, fw->size); - - cp = pgraph->ctxprog; - if (le32_to_cpu(cp->signature) != 0x5043564e || - cp->version != 0 || - le16_to_cpu(cp->length) != ((fw->size - 7) / 4)) { - NV_ERROR(dev, "ctxprog invalid\n"); - release_firmware(fw); - nv40_grctx_fini(dev); - return -EINVAL; - } - release_firmware(fw); - } - - if (!pgraph->ctxvals) { - sprintf(name, "nouveau/nv%02x.ctxvals", chipset); - ret = request_firmware(&fw, name, &dev->pdev->dev); - if (ret) { - NV_ERROR(dev, "No ctxvals for NV%02x\n", chipset); - nv40_grctx_fini(dev); - return ret; - } - - pgraph->ctxvals = kmalloc(fw->size, GFP_KERNEL); - if (!pgraph->ctxprog) { - NV_ERROR(dev, "OOM copying ctxprog\n"); - release_firmware(fw); - nv40_grctx_fini(dev); - return -ENOMEM; - } - memcpy(pgraph->ctxvals, fw->data, fw->size); - - cv = (void *)pgraph->ctxvals; - if (le32_to_cpu(cv->signature) != 0x5643564e || - cv->version != 0 || - le32_to_cpu(cv->length) != ((fw->size - 9) / 8)) { - NV_ERROR(dev, "ctxvals invalid\n"); - release_firmware(fw); - nv40_grctx_fini(dev); - return -EINVAL; - } - release_firmware(fw); - } - - cp = pgraph->ctxprog; - - nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0); - for (i = 0; i < le16_to_cpu(cp->length); i++) - nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, - le32_to_cpu(cp->data[i])); - - pgraph->accel_blocked = false; - return 0; -} - -void -nv40_grctx_fini(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; - - if (pgraph->ctxprog) { - kfree(pgraph->ctxprog); - pgraph->ctxprog = NULL; - } - - if (pgraph->ctxvals) { - kfree(pgraph->ctxprog); - pgraph->ctxvals = NULL; - } -} - -void -nv40_grctx_vals_load(struct drm_device *dev, struct nouveau_gpuobj *ctx) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; - struct nouveau_ctxvals *cv = pgraph->ctxvals; - int i; - - if (!cv) - return; - - for (i = 0; i < le32_to_cpu(cv->length); i++) - nv_wo32(dev, ctx, le32_to_cpu(cv->data[i].offset), - le32_to_cpu(cv->data[i].value)); -} - /* * G70 0x47 * G71 0x49 @@ -359,7 +203,26 @@ nv40_graph_init(struct drm_device *dev) nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) | NV_PMC_ENABLE_PGRAPH); - nv40_grctx_init(dev); + if (nouveau_ctxfw) { + nouveau_grctx_prog_load(dev); + dev_priv->engine.graph.grctx_size = 175 * 1024; + } + + if (!dev_priv->engine.graph.ctxprog) { + struct nouveau_grctx ctx = {}; + uint32_t cp[256]; + + ctx.dev = dev; + ctx.mode = NOUVEAU_GRCTX_PROG; + ctx.data = cp; + ctx.ctxprog_max = 256; + nv40_grctx_init(&ctx); + dev_priv->engine.graph.grctx_size = ctx.ctxvals_pos * 4; + + nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0); + for (i = 0; i < ctx.ctxprog_len; i++) + nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, cp[i]); + } /* No context present currently */ nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, 0x00000000); @@ -539,6 +402,7 @@ nv40_graph_init(struct drm_device *dev) void nv40_graph_takedown(struct drm_device *dev) { + nouveau_grctx_fini(dev); } struct nouveau_pgraph_object_class nv40_graph_grclass[] = { diff --git a/drivers/gpu/drm/nouveau/nv40_grctx.c b/drivers/gpu/drm/nouveau/nv40_grctx.c new file mode 100644 index 0000000..11b11c3 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nv40_grctx.c @@ -0,0 +1,678 @@ +/* + * Copyright 2009 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs + */ + +/* NVIDIA context programs handle a number of other conditions which are + * not implemented in our versions. It's not clear why NVIDIA context + * programs have this code, nor whether it's strictly necessary for + * correct operation. We'll implement additional handling if/when we + * discover it's necessary. + * + * - On context save, NVIDIA set 0x400314 bit 0 to 1 if the "3D state" + * flag is set, this gets saved into the context. + * - On context save, the context program for all cards load nsource + * into a flag register and check for ILLEGAL_MTHD. If it's set, + * opcode 0x60000d is called before resuming normal operation. + * - Some context programs check more conditions than the above. NV44 + * checks: ((nsource & 0x0857) || (0x400718 & 0x0100) || (intr & 0x0001)) + * and calls 0x60000d before resuming normal operation. + * - At the very beginning of NVIDIA's context programs, flag 9 is checked + * and if true 0x800001 is called with count=0, pos=0, the flag is cleared + * and then the ctxprog is aborted. It looks like a complicated NOP, + * its purpose is unknown. + * - In the section of code that loads the per-vs state, NVIDIA check + * flag 10. If it's set, they only transfer the small 0x300 byte block + * of state + the state for a single vs as opposed to the state for + * all vs units. It doesn't seem likely that it'll occur in normal + * operation, especially seeing as it appears NVIDIA may have screwed + * up the ctxprogs for some cards and have an invalid instruction + * rather than a cp_lsr(ctx, dwords_for_1_vs_unit) instruction. + * - There's a number of places where context offset 0 (where we place + * the PRAMIN offset of the context) is loaded into either 0x408000, + * 0x408004 or 0x408008. Not sure what's up there either. + * - The ctxprogs for some cards save 0x400a00 again during the cleanup + * path for auto-loadctx. + */ + +#define CP_FLAG_CLEAR 0 +#define CP_FLAG_SET 1 +#define CP_FLAG_SWAP_DIRECTION ((0 * 32) + 0) +#define CP_FLAG_SWAP_DIRECTION_LOAD 0 +#define CP_FLAG_SWAP_DIRECTION_SAVE 1 +#define CP_FLAG_USER_SAVE ((0 * 32) + 5) +#define CP_FLAG_USER_SAVE_NOT_PENDING 0 +#define CP_FLAG_USER_SAVE_PENDING 1 +#define CP_FLAG_USER_LOAD ((0 * 32) + 6) +#define CP_FLAG_USER_LOAD_NOT_PENDING 0 +#define CP_FLAG_USER_LOAD_PENDING 1 +#define CP_FLAG_STATUS ((3 * 32) + 0) +#define CP_FLAG_STATUS_IDLE 0 +#define CP_FLAG_STATUS_BUSY 1 +#define CP_FLAG_AUTO_SAVE ((3 * 32) + 4) +#define CP_FLAG_AUTO_SAVE_NOT_PENDING 0 +#define CP_FLAG_AUTO_SAVE_PENDING 1 +#define CP_FLAG_AUTO_LOAD ((3 * 32) + 5) +#define CP_FLAG_AUTO_LOAD_NOT_PENDING 0 +#define CP_FLAG_AUTO_LOAD_PENDING 1 +#define CP_FLAG_UNK54 ((3 * 32) + 6) +#define CP_FLAG_UNK54_CLEAR 0 +#define CP_FLAG_UNK54_SET 1 +#define CP_FLAG_ALWAYS ((3 * 32) + 8) +#define CP_FLAG_ALWAYS_FALSE 0 +#define CP_FLAG_ALWAYS_TRUE 1 +#define CP_FLAG_UNK57 ((3 * 32) + 9) +#define CP_FLAG_UNK57_CLEAR 0 +#define CP_FLAG_UNK57_SET 1 + +#define CP_CTX 0x00100000 +#define CP_CTX_COUNT 0x000fc000 +#define CP_CTX_COUNT_SHIFT 14 +#define CP_CTX_REG 0x00003fff +#define CP_LOAD_SR 0x00200000 +#define CP_LOAD_SR_VALUE 0x000fffff +#define CP_BRA 0x00400000 +#define CP_BRA_IP 0x0000ff00 +#define CP_BRA_IP_SHIFT 8 +#define CP_BRA_IF_CLEAR 0x00000080 +#define CP_BRA_FLAG 0x0000007f +#define CP_WAIT 0x00500000 +#define CP_WAIT_SET 0x00000080 +#define CP_WAIT_FLAG 0x0000007f +#define CP_SET 0x00700000 +#define CP_SET_1 0x00000080 +#define CP_SET_FLAG 0x0000007f +#define CP_NEXT_TO_SWAP 0x00600007 +#define CP_NEXT_TO_CURRENT 0x00600009 +#define CP_SET_CONTEXT_POINTER 0x0060000a +#define CP_END 0x0060000e +#define CP_LOAD_MAGIC_UNK01 0x00800001 /* unknown */ +#define CP_LOAD_MAGIC_NV44TCL 0x00800029 /* per-vs state (0x4497) */ +#define CP_LOAD_MAGIC_NV40TCL 0x00800041 /* per-vs state (0x4097) */ + +#include "drmP.h" +#include "nouveau_drv.h" +#include "nouveau_grctx.h" + +/* TODO: + * - get vs count from 0x1540 + * - document unimplemented bits compared to nvidia + * - nsource handling + * - R0 & 0x0200 handling + * - single-vs handling + * - 400314 bit 0 + */ + +static int +nv40_graph_4097(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + + if ((dev_priv->chipset & 0xf0) == 0x60) + return 0; + + return !!(0x0baf & (1 << dev_priv->chipset)); +} + +static int +nv40_graph_vs_count(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + + switch (dev_priv->chipset) { + case 0x47: + case 0x49: + case 0x4b: + return 8; + case 0x40: + return 6; + case 0x41: + case 0x42: + return 5; + case 0x43: + case 0x44: + case 0x46: + case 0x4a: + return 3; + case 0x4c: + case 0x4e: + case 0x67: + default: + return 1; + } +} + + +enum cp_label { + cp_check_load = 1, + cp_setup_auto_load, + cp_setup_load, + cp_setup_save, + cp_swap_state, + cp_swap_state3d_3_is_save, + cp_prepare_exit, + cp_exit, +}; + +static void +nv40_graph_construct_general(struct nouveau_grctx *ctx) +{ + struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; + int i; + + cp_ctx(ctx, 0x4000a4, 1); + gr_def(ctx, 0x4000a4, 0x00000008); + cp_ctx(ctx, 0x400144, 58); + gr_def(ctx, 0x400144, 0x00000001); + cp_ctx(ctx, 0x400314, 1); + gr_def(ctx, 0x400314, 0x00000000); + cp_ctx(ctx, 0x400400, 10); + cp_ctx(ctx, 0x400480, 10); + cp_ctx(ctx, 0x400500, 19); + gr_def(ctx, 0x400514, 0x00040000); + gr_def(ctx, 0x400524, 0x55555555); + gr_def(ctx, 0x400528, 0x55555555); + gr_def(ctx, 0x40052c, 0x55555555); + gr_def(ctx, 0x400530, 0x55555555); + cp_ctx(ctx, 0x400560, 6); + gr_def(ctx, 0x400568, 0x0000ffff); + gr_def(ctx, 0x40056c, 0x0000ffff); + cp_ctx(ctx, 0x40057c, 5); + cp_ctx(ctx, 0x400710, 3); + gr_def(ctx, 0x400710, 0x20010001); + gr_def(ctx, 0x400714, 0x0f73ef00); + cp_ctx(ctx, 0x400724, 1); + gr_def(ctx, 0x400724, 0x02008821); + cp_ctx(ctx, 0x400770, 3); + if (dev_priv->chipset == 0x40) { + cp_ctx(ctx, 0x400814, 4); + cp_ctx(ctx, 0x400828, 5); + cp_ctx(ctx, 0x400840, 5); + gr_def(ctx, 0x400850, 0x00000040); + cp_ctx(ctx, 0x400858, 4); + gr_def(ctx, 0x400858, 0x00000040); + gr_def(ctx, 0x40085c, 0x00000040); + gr_def(ctx, 0x400864, 0x80000000); + cp_ctx(ctx, 0x40086c, 9); + gr_def(ctx, 0x40086c, 0x80000000); + gr_def(ctx, 0x400870, 0x80000000); + gr_def(ctx, 0x400874, 0x80000000); + gr_def(ctx, 0x400878, 0x80000000); + gr_def(ctx, 0x400888, 0x00000040); + gr_def(ctx, 0x40088c, 0x80000000); + cp_ctx(ctx, 0x4009c0, 8); + gr_def(ctx, 0x4009cc, 0x80000000); + gr_def(ctx, 0x4009dc, 0x80000000); + } else { + cp_ctx(ctx, 0x400840, 20); + if (!nv40_graph_4097(ctx->dev)) { + for (i = 0; i < 8; i++) + gr_def(ctx, 0x400860 + (i * 4), 0x00000001); + } + gr_def(ctx, 0x400880, 0x00000040); + gr_def(ctx, 0x400884, 0x00000040); + gr_def(ctx, 0x400888, 0x00000040); + cp_ctx(ctx, 0x400894, 11); + gr_def(ctx, 0x400894, 0x00000040); + if (nv40_graph_4097(ctx->dev)) { + for (i = 0; i < 8; i++) + gr_def(ctx, 0x4008a0 + (i * 4), 0x80000000); + } + cp_ctx(ctx, 0x4008e0, 2); + cp_ctx(ctx, 0x4008f8, 2); + if (dev_priv->chipset == 0x4c || + (dev_priv->chipset & 0xf0) == 0x60) + cp_ctx(ctx, 0x4009f8, 1); + } + cp_ctx(ctx, 0x400a00, 73); + gr_def(ctx, 0x400b0c, 0x0b0b0b0c); + cp_ctx(ctx, 0x401000, 4); + cp_ctx(ctx, 0x405004, 1); + switch (dev_priv->chipset) { + case 0x47: + case 0x49: + case 0x4b: + cp_ctx(ctx, 0x403448, 1); + gr_def(ctx, 0x403448, 0x00001010); + break; + default: + cp_ctx(ctx, 0x403440, 1); + switch (dev_priv->chipset) { + case 0x40: + gr_def(ctx, 0x403440, 0x00000010); + break; + case 0x44: + case 0x46: + case 0x4a: + gr_def(ctx, 0x403440, 0x00003010); + break; + case 0x41: + case 0x42: + case 0x43: + case 0x4c: + case 0x4e: + case 0x67: + default: + gr_def(ctx, 0x403440, 0x00001010); + break; + } + break; + } +} + +static void +nv40_graph_construct_state3d(struct nouveau_grctx *ctx) +{ + struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; + int i; + + if (dev_priv->chipset == 0x40) { + cp_ctx(ctx, 0x401880, 51); + gr_def(ctx, 0x401940, 0x00000100); + } else + if (dev_priv->chipset == 0x46 || dev_priv->chipset == 0x47 || + dev_priv->chipset == 0x49 || dev_priv->chipset == 0x4b) { + cp_ctx(ctx, 0x401880, 32); + for (i = 0; i < 16; i++) + gr_def(ctx, 0x401880 + (i * 4), 0x00000111); + if (dev_priv->chipset == 0x46) + cp_ctx(ctx, 0x401900, 16); + cp_ctx(ctx, 0x401940, 3); + } + cp_ctx(ctx, 0x40194c, 18); + gr_def(ctx, 0x401954, 0x00000111); + gr_def(ctx, 0x401958, 0x00080060); + gr_def(ctx, 0x401974, 0x00000080); + gr_def(ctx, 0x401978, 0xffff0000); + gr_def(ctx, 0x40197c, 0x00000001); + gr_def(ctx, 0x401990, 0x46400000); + if (dev_priv->chipset == 0x40) { + cp_ctx(ctx, 0x4019a0, 2); + cp_ctx(ctx, 0x4019ac, 5); + } else { + cp_ctx(ctx, 0x4019a0, 1); + cp_ctx(ctx, 0x4019b4, 3); + } + gr_def(ctx, 0x4019bc, 0xffff0000); + switch (dev_priv->chipset) { + case 0x46: + case 0x47: + case 0x49: + case 0x4b: + cp_ctx(ctx, 0x4019c0, 18); + for (i = 0; i < 16; i++) + gr_def(ctx, 0x4019c0 + (i * 4), 0x88888888); + break; + } + cp_ctx(ctx, 0x401a08, 8); + gr_def(ctx, 0x401a10, 0x0fff0000); + gr_def(ctx, 0x401a14, 0x0fff0000); + gr_def(ctx, 0x401a1c, 0x00011100); + cp_ctx(ctx, 0x401a2c, 4); + cp_ctx(ctx, 0x401a44, 26); + for (i = 0; i < 16; i++) + gr_def(ctx, 0x401a44 + (i * 4), 0x07ff0000); + gr_def(ctx, 0x401a8c, 0x4b7fffff); + if (dev_priv->chipset == 0x40) { + cp_ctx(ctx, 0x401ab8, 3); + } else { + cp_ctx(ctx, 0x401ab8, 1); + cp_ctx(ctx, 0x401ac0, 1); + } + cp_ctx(ctx, 0x401ad0, 8); + gr_def(ctx, 0x401ad0, 0x30201000); + gr_def(ctx, 0x401ad4, 0x70605040); + gr_def(ctx, 0x401ad8, 0xb8a89888); + gr_def(ctx, 0x401adc, 0xf8e8d8c8); + cp_ctx(ctx, 0x401b10, dev_priv->chipset == 0x40 ? 2 : 1); + gr_def(ctx, 0x401b10, 0x40100000); + cp_ctx(ctx, 0x401b18, dev_priv->chipset == 0x40 ? 6 : 5); + gr_def(ctx, 0x401b28, dev_priv->chipset == 0x40 ? + 0x00000004 : 0x00000000); + cp_ctx(ctx, 0x401b30, 25); + gr_def(ctx, 0x401b34, 0x0000ffff); + gr_def(ctx, 0x401b68, 0x435185d6); + gr_def(ctx, 0x401b6c, 0x2155b699); + gr_def(ctx, 0x401b70, 0xfedcba98); + gr_def(ctx, 0x401b74, 0x00000098); + gr_def(ctx, 0x401b84, 0xffffffff); + gr_def(ctx, 0x401b88, 0x00ff7000); + gr_def(ctx, 0x401b8c, 0x0000ffff); + if (dev_priv->chipset != 0x44 && dev_priv->chipset != 0x4a && + dev_priv->chipset != 0x4e) + cp_ctx(ctx, 0x401b94, 1); + cp_ctx(ctx, 0x401b98, 8); + gr_def(ctx, 0x401b9c, 0x00ff0000); + cp_ctx(ctx, 0x401bc0, 9); + gr_def(ctx, 0x401be0, 0x00ffff00); + cp_ctx(ctx, 0x401c00, 192); + for (i = 0; i < 16; i++) { /* fragment texture units */ + gr_def(ctx, 0x401c40 + (i * 4), 0x00018488); + gr_def(ctx, 0x401c80 + (i * 4), 0x00028202); + gr_def(ctx, 0x401d00 + (i * 4), 0x0000aae4); + gr_def(ctx, 0x401d40 + (i * 4), 0x01012000); + gr_def(ctx, 0x401d80 + (i * 4), 0x00080008); + gr_def(ctx, 0x401e00 + (i * 4), 0x00100008); + } + for (i = 0; i < 4; i++) { /* vertex texture units */ + gr_def(ctx, 0x401e90 + (i * 4), 0x0001bc80); + gr_def(ctx, 0x401ea0 + (i * 4), 0x00000202); + gr_def(ctx, 0x401ec0 + (i * 4), 0x00000008); + gr_def(ctx, 0x401ee0 + (i * 4), 0x00080008); + } + cp_ctx(ctx, 0x400f5c, 3); + gr_def(ctx, 0x400f5c, 0x00000002); + cp_ctx(ctx, 0x400f84, 1); +} + +static void +nv40_graph_construct_state3d_2(struct nouveau_grctx *ctx) +{ + struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; + int i; + + cp_ctx(ctx, 0x402000, 1); + cp_ctx(ctx, 0x402404, dev_priv->chipset == 0x40 ? 1 : 2); + switch (dev_priv->chipset) { + case 0x40: + gr_def(ctx, 0x402404, 0x00000001); + break; + case 0x4c: + case 0x4e: + case 0x67: + gr_def(ctx, 0x402404, 0x00000020); + break; + case 0x46: + case 0x49: + case 0x4b: + gr_def(ctx, 0x402404, 0x00000421); + break; + default: + gr_def(ctx, 0x402404, 0x00000021); + } + if (dev_priv->chipset != 0x40) + gr_def(ctx, 0x402408, 0x030c30c3); + switch (dev_priv->chipset) { + case 0x44: + case 0x46: + case 0x4a: + case 0x4c: + case 0x4e: + case 0x67: + cp_ctx(ctx, 0x402440, 1); + gr_def(ctx, 0x402440, 0x00011001); + break; + default: + break; + } + cp_ctx(ctx, 0x402480, dev_priv->chipset == 0x40 ? 8 : 9); + gr_def(ctx, 0x402488, 0x3e020200); + gr_def(ctx, 0x40248c, 0x00ffffff); + switch (dev_priv->chipset) { + case 0x40: + gr_def(ctx, 0x402490, 0x60103f00); + break; + case 0x47: + gr_def(ctx, 0x402490, 0x40103f00); + break; + case 0x41: + case 0x42: + case 0x49: + case 0x4b: + gr_def(ctx, 0x402490, 0x20103f00); + break; + default: + gr_def(ctx, 0x402490, 0x0c103f00); + break; + } + gr_def(ctx, 0x40249c, dev_priv->chipset <= 0x43 ? + 0x00020000 : 0x00040000); + cp_ctx(ctx, 0x402500, 31); + gr_def(ctx, 0x402530, 0x00008100); + if (dev_priv->chipset == 0x40) + cp_ctx(ctx, 0x40257c, 6); + cp_ctx(ctx, 0x402594, 16); + cp_ctx(ctx, 0x402800, 17); + gr_def(ctx, 0x402800, 0x00000001); + switch (dev_priv->chipset) { + case 0x47: + case 0x49: + case 0x4b: + cp_ctx(ctx, 0x402864, 1); + gr_def(ctx, 0x402864, 0x00001001); + cp_ctx(ctx, 0x402870, 3); + gr_def(ctx, 0x402878, 0x00000003); + if (dev_priv->chipset != 0x47) { /* belong at end!! */ + cp_ctx(ctx, 0x402900, 1); + cp_ctx(ctx, 0x402940, 1); + cp_ctx(ctx, 0x402980, 1); + cp_ctx(ctx, 0x4029c0, 1); + cp_ctx(ctx, 0x402a00, 1); + cp_ctx(ctx, 0x402a40, 1); + cp_ctx(ctx, 0x402a80, 1); + cp_ctx(ctx, 0x402ac0, 1); + } + break; + case 0x40: + cp_ctx(ctx, 0x402844, 1); + gr_def(ctx, 0x402844, 0x00000001); + cp_ctx(ctx, 0x402850, 1); + break; + default: + cp_ctx(ctx, 0x402844, 1); + gr_def(ctx, 0x402844, 0x00001001); + cp_ctx(ctx, 0x402850, 2); + gr_def(ctx, 0x402854, 0x00000003); + break; + } + + cp_ctx(ctx, 0x402c00, 4); + gr_def(ctx, 0x402c00, dev_priv->chipset == 0x40 ? + 0x80800001 : 0x00888001); + switch (dev_priv->chipset) { + case 0x47: + case 0x49: + case 0x4b: + cp_ctx(ctx, 0x402c20, 40); + for (i = 0; i < 32; i++) + gr_def(ctx, 0x402c40 + (i * 4), 0xffffffff); + cp_ctx(ctx, 0x4030b8, 13); + gr_def(ctx, 0x4030dc, 0x00000005); + gr_def(ctx, 0x4030e8, 0x0000ffff); + break; + default: + cp_ctx(ctx, 0x402c10, 4); + if (dev_priv->chipset == 0x40) + cp_ctx(ctx, 0x402c20, 36); + else + if (dev_priv->chipset <= 0x42) + cp_ctx(ctx, 0x402c20, 24); + else + if (dev_priv->chipset <= 0x4a) + cp_ctx(ctx, 0x402c20, 16); + else + cp_ctx(ctx, 0x402c20, 8); + cp_ctx(ctx, 0x402cb0, dev_priv->chipset == 0x40 ? 12 : 13); + gr_def(ctx, 0x402cd4, 0x00000005); + if (dev_priv->chipset != 0x40) + gr_def(ctx, 0x402ce0, 0x0000ffff); + break; + } + + cp_ctx(ctx, 0x403400, dev_priv->chipset == 0x40 ? 4 : 3); + cp_ctx(ctx, 0x403410, dev_priv->chipset == 0x40 ? 4 : 3); + cp_ctx(ctx, 0x403420, nv40_graph_vs_count(ctx->dev)); + for (i = 0; i < nv40_graph_vs_count(ctx->dev); i++) + gr_def(ctx, 0x403420 + (i * 4), 0x00005555); + + if (dev_priv->chipset != 0x40) { + cp_ctx(ctx, 0x403600, 1); + gr_def(ctx, 0x403600, 0x00000001); + } + cp_ctx(ctx, 0x403800, 1); + + cp_ctx(ctx, 0x403c18, 1); + gr_def(ctx, 0x403c18, 0x00000001); + switch (dev_priv->chipset) { + case 0x46: + case 0x47: + case 0x49: + case 0x4b: + cp_ctx(ctx, 0x405018, 1); + gr_def(ctx, 0x405018, 0x08e00001); + cp_ctx(ctx, 0x405c24, 1); + gr_def(ctx, 0x405c24, 0x000e3000); + break; + } + if (dev_priv->chipset != 0x4e) + cp_ctx(ctx, 0x405800, 11); + cp_ctx(ctx, 0x407000, 1); +} + +static void +nv40_graph_construct_state3d_3(struct nouveau_grctx *ctx) +{ + int len = nv40_graph_4097(ctx->dev) ? 0x0684 : 0x0084; + + cp_out (ctx, 0x300000); + cp_lsr (ctx, len - 4); + cp_bra (ctx, SWAP_DIRECTION, SAVE, cp_swap_state3d_3_is_save); + cp_lsr (ctx, len); + cp_name(ctx, cp_swap_state3d_3_is_save); + cp_out (ctx, 0x800001); + + ctx->ctxvals_pos += len; +} + +static void +nv40_graph_construct_shader(struct nouveau_grctx *ctx) +{ + struct drm_device *dev = ctx->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_gpuobj *obj = ctx->data; + int vs, vs_nr, vs_len, vs_nr_b0, vs_nr_b1, b0_offset, b1_offset; + int offset, i; + + vs_nr = nv40_graph_vs_count(ctx->dev); + vs_nr_b0 = 363; + vs_nr_b1 = dev_priv->chipset == 0x40 ? 128 : 64; + if (dev_priv->chipset == 0x40) { + b0_offset = 0x2200/4; /* 33a0 */ + b1_offset = 0x55a0/4; /* 1500 */ + vs_len = 0x6aa0/4; + } else + if (dev_priv->chipset == 0x41 || dev_priv->chipset == 0x42) { + b0_offset = 0x2200/4; /* 2200 */ + b1_offset = 0x4400/4; /* 0b00 */ + vs_len = 0x4f00/4; + } else { + b0_offset = 0x1d40/4; /* 2200 */ + b1_offset = 0x3f40/4; /* 0b00 : 0a40 */ + vs_len = nv40_graph_4097(dev) ? 0x4a40/4 : 0x4980/4; + } + + cp_lsr(ctx, vs_len * vs_nr + 0x300/4); + cp_out(ctx, nv40_graph_4097(dev) ? 0x800041 : 0x800029); + + offset = ctx->ctxvals_pos; + ctx->ctxvals_pos += (0x0300/4 + (vs_nr * vs_len)); + + if (ctx->mode != NOUVEAU_GRCTX_VALS) + return; + + offset += 0x0280/4; + for (i = 0; i < 16; i++, offset += 2) + nv_wo32(dev, obj, offset, 0x3f800000); + + for (vs = 0; vs < vs_nr; vs++, offset += vs_len) { + for (i = 0; i < vs_nr_b0 * 6; i += 6) + nv_wo32(dev, obj, offset + b0_offset + i, 0x00000001); + for (i = 0; i < vs_nr_b1 * 4; i += 4) + nv_wo32(dev, obj, offset + b1_offset + i, 0x3f800000); + } +} + +void +nv40_grctx_init(struct nouveau_grctx *ctx) +{ + /* decide whether we're loading/unloading the context */ + cp_bra (ctx, AUTO_SAVE, PENDING, cp_setup_save); + cp_bra (ctx, USER_SAVE, PENDING, cp_setup_save); + + cp_name(ctx, cp_check_load); + cp_bra (ctx, AUTO_LOAD, PENDING, cp_setup_auto_load); + cp_bra (ctx, USER_LOAD, PENDING, cp_setup_load); + cp_bra (ctx, ALWAYS, TRUE, cp_exit); + + /* setup for context load */ + cp_name(ctx, cp_setup_auto_load); + cp_wait(ctx, STATUS, IDLE); + cp_out (ctx, CP_NEXT_TO_SWAP); + cp_name(ctx, cp_setup_load); + cp_wait(ctx, STATUS, IDLE); + cp_set (ctx, SWAP_DIRECTION, LOAD); + cp_out (ctx, 0x00910880); /* ?? */ + cp_out (ctx, 0x00901ffe); /* ?? */ + cp_out (ctx, 0x01940000); /* ?? */ + cp_lsr (ctx, 0x20); + cp_out (ctx, 0x0060000b); /* ?? */ + cp_wait(ctx, UNK57, CLEAR); + cp_out (ctx, 0x0060000c); /* ?? */ + cp_bra (ctx, ALWAYS, TRUE, cp_swap_state); + + /* setup for context save */ + cp_name(ctx, cp_setup_save); + cp_set (ctx, SWAP_DIRECTION, SAVE); + + /* general PGRAPH state */ + cp_name(ctx, cp_swap_state); + cp_pos (ctx, 0x00020/4); + nv40_graph_construct_general(ctx); + cp_wait(ctx, STATUS, IDLE); + + /* 3D state, block 1 */ + cp_bra (ctx, UNK54, CLEAR, cp_prepare_exit); + nv40_graph_construct_state3d(ctx); + cp_wait(ctx, STATUS, IDLE); + + /* 3D state, block 2 */ + nv40_graph_construct_state3d_2(ctx); + + /* Some other block of "random" state */ + nv40_graph_construct_state3d_3(ctx); + + /* Per-vertex shader state */ + cp_pos (ctx, ctx->ctxvals_pos); + nv40_graph_construct_shader(ctx); + + /* pre-exit state updates */ + cp_name(ctx, cp_prepare_exit); + cp_bra (ctx, SWAP_DIRECTION, SAVE, cp_check_load); + cp_bra (ctx, USER_SAVE, PENDING, cp_exit); + cp_out (ctx, CP_NEXT_TO_CURRENT); + + cp_name(ctx, cp_exit); + cp_set (ctx, USER_SAVE, NOT_PENDING); + cp_set (ctx, USER_LOAD, NOT_PENDING); + cp_out (ctx, CP_END); +} + diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c index 177d822..ca79f32 100644 --- a/drivers/gpu/drm/nouveau/nv50_graph.c +++ b/drivers/gpu/drm/nouveau/nv50_graph.c @@ -107,9 +107,13 @@ nv50_graph_init_regs(struct drm_device *dev) static int nv50_graph_init_ctxctl(struct drm_device *dev) { + struct drm_nouveau_private *dev_priv = dev->dev_private; + NV_DEBUG(dev, "\n"); - nv40_grctx_init(dev); + nouveau_grctx_prog_load(dev); + if (!dev_priv->engine.graph.ctxprog) + dev_priv->engine.graph.accel_blocked = true; nv_wr32(dev, 0x400320, 4); nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, 0); @@ -140,7 +144,7 @@ void nv50_graph_takedown(struct drm_device *dev) { NV_DEBUG(dev, "\n"); - nv40_grctx_fini(dev); + nouveau_grctx_fini(dev); } void @@ -207,7 +211,7 @@ nv50_graph_create_context(struct nouveau_channel *chan) dev_priv->engine.instmem.finish_access(dev); dev_priv->engine.instmem.prepare_access(dev, true); - nv40_grctx_vals_load(dev, ctx); + nouveau_grctx_vals_load(dev, ctx); nv_wo32(dev, ctx, 0x00000/4, chan->ramin->instance >> 12); if ((dev_priv->chipset & 0xf0) == 0xa0) nv_wo32(dev, ctx, 0x00004/4, 0x00000000); -- cgit v0.10.2 From 3c8868d3dbba5110bd43b49879f12d1a6b2a28ca Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 16 Dec 2009 14:51:13 +1000 Subject: drm/nv50: fix two potential suspend/resume oopses This avoids touching the dummy channel 0/127 we have on nv50. Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c index 78662cc..58c7172 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.c +++ b/drivers/gpu/drm/nouveau/nouveau_drv.c @@ -277,7 +277,7 @@ nouveau_pci_resume(struct pci_dev *pdev) for (i = 0; i < dev_priv->engine.fifo.channels; i++) { chan = dev_priv->fifos[i]; - if (!chan) + if (!chan || !chan->pushbuf_bo) continue; for (j = 0; j < NOUVEAU_DMA_SKIPS; j++) diff --git a/drivers/gpu/drm/nouveau/nv50_fifo.c b/drivers/gpu/drm/nouveau/nv50_fifo.c index 77ae1aa..b728228 100644 --- a/drivers/gpu/drm/nouveau/nv50_fifo.c +++ b/drivers/gpu/drm/nouveau/nv50_fifo.c @@ -416,7 +416,7 @@ nv50_fifo_unload_context(struct drm_device *dev) NV_DEBUG(dev, "\n"); chid = pfifo->channel_id(dev); - if (chid < 0 || chid >= dev_priv->engine.fifo.channels) + if (chid < 1 || chid >= dev_priv->engine.fifo.channels - 1) return 0; chan = dev_priv->fifos[chid]; -- cgit v0.10.2 From 0735f62e116fae1e4f36237a97de28e8a56b4c2c Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 16 Dec 2009 14:28:55 +1000 Subject: drm/nouveau: prevent all channel creation if accel not available Previously, if there was no firmware available, the DRM would just disable channel creation from userspace, but still use a single channel for its own purposes. With a bit of care it should actually be possible to do this, due to the DRM's very limited use of the engine. It currently doesn't work correctly however, resulting in corrupted fbcon and hangs on a number of cards. Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index e9f0190..2f5d470 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -461,11 +461,8 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, int no_wait, int ret; chan = nvbo->channel; - if (!chan || nvbo->tile_flags || nvbo->no_vm) { + if (!chan || nvbo->tile_flags || nvbo->no_vm) chan = dev_priv->channel; - if (!chan) - return -EINVAL; - } src_offset = old_mem->mm_node->start << PAGE_SHIFT; dst_offset = new_mem->mm_node->start << PAGE_SHIFT; @@ -631,7 +628,8 @@ nouveau_bo_move(struct ttm_buffer_object *bo, bool evict, bool intr, return ret; } - if (dev_priv->init_state != NOUVEAU_CARD_INIT_DONE) + if (dev_priv->init_state != NOUVEAU_CARD_INIT_DONE || + !dev_priv->channel) return ttm_bo_move_memcpy(bo, evict, no_wait, new_mem); if (old_mem->mem_type == TTM_PL_SYSTEM && !bo->ttm) { diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 489d492..84af25c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -58,7 +58,7 @@ nouveau_fbcon_sync(struct fb_info *info) struct nouveau_channel *chan = dev_priv->channel; int ret, i; - if (!chan->accel_done || + if (!chan || !chan->accel_done || info->state != FBINFO_STATE_RUNNING || info->flags & FBINFO_HWACCEL_DISABLED) return 0; @@ -318,14 +318,16 @@ nouveau_fbcon_create(struct drm_device *dev, uint32_t fb_width, par->nouveau_fb = nouveau_fb; par->dev = dev; - switch (dev_priv->card_type) { - case NV_50: - nv50_fbcon_accel_init(info); - break; - default: - nv04_fbcon_accel_init(info); - break; - }; + if (dev_priv->channel) { + switch (dev_priv->card_type) { + case NV_50: + nv50_fbcon_accel_init(info); + break; + default: + nv04_fbcon_accel_init(info); + break; + }; + } nouveau_fbcon_zfill(dev); diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 9fc5824..e76ec2d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -299,12 +299,57 @@ nouveau_vga_set_decode(void *priv, bool state) return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM; } +static int +nouveau_card_init_channel(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_gpuobj *gpuobj; + int ret; + + ret = nouveau_channel_alloc(dev, &dev_priv->channel, + (struct drm_file *)-2, + NvDmaFB, NvDmaTT); + if (ret) + return ret; + + gpuobj = NULL; + ret = nouveau_gpuobj_dma_new(dev_priv->channel, NV_CLASS_DMA_IN_MEMORY, + 0, nouveau_mem_fb_amount(dev), + NV_DMA_ACCESS_RW, NV_DMA_TARGET_VIDMEM, + &gpuobj); + if (ret) + goto out_err; + + ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, NvDmaVRAM, + gpuobj, NULL); + if (ret) + goto out_err; + + gpuobj = NULL; + ret = nouveau_gpuobj_gart_dma_new(dev_priv->channel, 0, + dev_priv->gart_info.aper_size, + NV_DMA_ACCESS_RW, &gpuobj, NULL); + if (ret) + goto out_err; + + ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, NvDmaGART, + gpuobj, NULL); + if (ret) + goto out_err; + + return 0; +out_err: + nouveau_gpuobj_del(dev, &gpuobj); + nouveau_channel_free(dev_priv->channel); + dev_priv->channel = NULL; + return ret; +} + int nouveau_card_init(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_engine *engine; - struct nouveau_gpuobj *gpuobj; int ret; NV_DEBUG(dev, "prev state = %d\n", dev_priv->init_state); @@ -387,39 +432,10 @@ nouveau_card_init(struct drm_device *dev) /* what about PVIDEO/PCRTC/PRAMDAC etc? */ - ret = nouveau_channel_alloc(dev, &dev_priv->channel, - (struct drm_file *)-2, - NvDmaFB, NvDmaTT); - if (ret) - goto out_irq; - - gpuobj = NULL; - ret = nouveau_gpuobj_dma_new(dev_priv->channel, NV_CLASS_DMA_IN_MEMORY, - 0, nouveau_mem_fb_amount(dev), - NV_DMA_ACCESS_RW, NV_DMA_TARGET_VIDMEM, - &gpuobj); - if (ret) - goto out_irq; - - ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, NvDmaVRAM, - gpuobj, NULL); - if (ret) { - nouveau_gpuobj_del(dev, &gpuobj); - goto out_irq; - } - - gpuobj = NULL; - ret = nouveau_gpuobj_gart_dma_new(dev_priv->channel, 0, - dev_priv->gart_info.aper_size, - NV_DMA_ACCESS_RW, &gpuobj, NULL); - if (ret) - goto out_irq; - - ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, NvDmaGART, - gpuobj, NULL); - if (ret) { - nouveau_gpuobj_del(dev, &gpuobj); - goto out_irq; + if (!engine->graph.accel_blocked) { + ret = nouveau_card_init_channel(dev); + if (ret) + goto out_irq; } if (drm_core_check_feature(dev, DRIVER_MODESET)) { -- cgit v0.10.2 From 65ec01a9406327f22b1c740f8a42cb93eb676eb5 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 16 Dec 2009 15:07:45 +1000 Subject: drm/nv50: fix suspend/resume delays without firmware present Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_grctx.c b/drivers/gpu/drm/nouveau/nouveau_grctx.c index d5d84c8..419f4c2 100644 --- a/drivers/gpu/drm/nouveau/nouveau_grctx.c +++ b/drivers/gpu/drm/nouveau/nouveau_grctx.c @@ -56,6 +56,9 @@ nouveau_grctx_prog_load(struct drm_device *dev) char name[32]; int ret, i; + if (pgraph->accel_blocked) + return -ENODEV; + if (!pgraph->ctxprog) { sprintf(name, "nouveau/nv%02x.ctxprog", chipset); ret = request_firmware(&fw, name, &dev->pdev->dev); -- cgit v0.10.2 From 37cb3e08852be92d94e6a65c489bd8afa2e8a15f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 16 Dec 2009 16:22:42 +1000 Subject: drm/nouveau: fix bug causing pinned buffers to lose their NO_EVICT flag Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 2f5d470..0cad6d8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -154,6 +154,11 @@ nouveau_bo_placement_set(struct nouveau_bo *nvbo, uint32_t memtype) nvbo->placement.busy_placement = nvbo->placements; nvbo->placement.num_placement = n; nvbo->placement.num_busy_placement = n; + + if (nvbo->pin_refcnt) { + while (n--) + nvbo->placements[n] |= TTM_PL_FLAG_NO_EVICT; + } } int -- cgit v0.10.2 From 5df974009fe513c664303de24725ea0f8b47f12e Mon Sep 17 00:00:00 2001 From: Sheng Yang Date: Wed, 16 Dec 2009 13:48:04 +0800 Subject: x86: Add IA32_TSC_AUX MSR and use it Clean up write_tsc() and write_tscp_aux() by replacing hardcoded values. No change in functionality. Signed-off-by: Sheng Yang Cc: Avi Kivity Cc: Marcelo Tosatti LKML-Reference: <1260942485-19156-4-git-send-email-sheng@linux.intel.com> Signed-off-by: Ingo Molnar diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index 4ffe09b..ac98d29 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -12,6 +12,7 @@ #define MSR_FS_BASE 0xc0000100 /* 64bit FS base */ #define MSR_GS_BASE 0xc0000101 /* 64bit GS base */ #define MSR_KERNEL_GS_BASE 0xc0000102 /* SwapGS GS shadow */ +#define MSR_TSC_AUX 0xc0000103 /* Auxiliary TSC */ /* EFER bits: */ #define _EFER_SCE 0 /* SYSCALL/SYSRET */ diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h index 2d228fc..cf985aa 100644 --- a/arch/x86/include/asm/msr.h +++ b/arch/x86/include/asm/msr.h @@ -240,9 +240,9 @@ do { \ #define checking_wrmsrl(msr, val) wrmsr_safe((msr), (u32)(val), \ (u32)((val) >> 32)) -#define write_tsc(val1, val2) wrmsr(0x10, (val1), (val2)) +#define write_tsc(val1, val2) wrmsr(MSR_IA32_TSC, (val1), (val2)) -#define write_rdtscp_aux(val) wrmsr(0xc0000103, (val), 0) +#define write_rdtscp_aux(val) wrmsr(MSR_TSC_AUX, (val), 0) struct msr *msrs_alloc(void); void msrs_free(struct msr *msrs); -- cgit v0.10.2 From 5c3804629e69bf48474bb53038d5dcc5a8d25959 Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Wed, 16 Dec 2009 16:41:30 +0800 Subject: revert "[ARM] pxa/cm-x300: add PWM backlight support" Commit db205463fd24c0972ad2c4e4fafb1c76e51b4380 was incorrectly applied, and reverted here to re-apply. Signed-off-by: Eric Miao diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index e6d8e10..6f4f475 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -240,7 +240,6 @@ config MACH_COLIBRI300 select PXA3xx select CPU_PXA300 select CPU_PXA310 - select HAVE_PWM config MACH_COLIBRI320 bool "Toradex Colibri PXA320" diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c index d37cfa1..d564d8e 100644 --- a/arch/arm/mach-pxa/cm-x300.c +++ b/arch/arm/mach-pxa/cm-x300.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include @@ -51,7 +50,6 @@ #include #include "generic.h" -#include "devices.h" #define CM_X300_ETH_PHYS 0x08000010 @@ -162,9 +160,6 @@ static mfp_cfg_t cm_x3xx_mfp_cfg[] __initdata = { /* Standard I2C */ GPIO21_I2C_SCL, GPIO22_I2C_SDA, - - /* PWM Backlight */ - GPIO19_PWM2_OUT, }; static mfp_cfg_t cm_x3xx_rev_lt130_mfp_cfg[] __initdata = { @@ -295,30 +290,6 @@ static void __init cm_x300_init_lcd(void) static inline void cm_x300_init_lcd(void) {} #endif -#if defined(CONFIG_BACKLIGHT_PWM) || defined(CONFIG_BACKLIGHT_PWM_MODULE) -static struct platform_pwm_backlight_data cm_x300_backlight_data = { - .pwm_id = 2, - .max_brightness = 100, - .dft_brightness = 100, - .pwm_period_ns = 10000, -}; - -static struct platform_device cm_x300_backlight_device = { - .name = "pwm-backlight", - .dev = { - .parent = &pxa27x_device_pwm0.dev, - .platform_data = &cm_x300_backlight_data, - }, -}; - -static void cm_x300_init_bl(void) -{ - platform_device_register(&cm_x300_backlight_device); -} -#else -static inline void cm_x300_init_bl(void) {} -#endif - #if defined(CONFIG_SPI_GPIO) || defined(CONFIG_SPI_GPIO_MODULE) #define GPIO_LCD_BASE (144) #define GPIO_LCD_DIN (GPIO_LCD_BASE + 8) /* aux_gpio3_0 */ @@ -683,7 +654,6 @@ static void __init cm_x300_init(void) cm_x300_init_rtc(); cm_x300_init_ac97(); cm_x300_init_wi2wi(); - cm_x300_init_bl(); } static void __init cm_x300_fixup(struct machine_desc *mdesc, struct tag *tags, diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c index 3395463..d4cc41d 100644 --- a/arch/arm/mach-pxa/devices.c +++ b/arch/arm/mach-pxa/devices.c @@ -4,7 +4,6 @@ #include #include -#include #include #include #include -- cgit v0.10.2 From 61e0ac03c8223d875de93da099737fbd45ff1492 Mon Sep 17 00:00:00 2001 From: Igor Grinberg Date: Tue, 10 Nov 2009 14:18:41 +0200 Subject: [ARM] pxa/cm-x300: add PWM backlight support Signed-off-by: Igor Grinberg Signed-off-by: Mike Rapoport Signed-off-by: Eric Miao diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index 6f4f475..8a0837e 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -110,6 +110,8 @@ config MACH_CM_X300 bool "CompuLab CM-X300 modules" select PXA3xx select CPU_PXA300 + select CPU_PXA310 + select HAVE_PWM config ARCH_GUMSTIX bool "Gumstix XScale 255 boards" diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c index d564d8e..d37cfa1 100644 --- a/arch/arm/mach-pxa/cm-x300.c +++ b/arch/arm/mach-pxa/cm-x300.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -50,6 +51,7 @@ #include #include "generic.h" +#include "devices.h" #define CM_X300_ETH_PHYS 0x08000010 @@ -160,6 +162,9 @@ static mfp_cfg_t cm_x3xx_mfp_cfg[] __initdata = { /* Standard I2C */ GPIO21_I2C_SCL, GPIO22_I2C_SDA, + + /* PWM Backlight */ + GPIO19_PWM2_OUT, }; static mfp_cfg_t cm_x3xx_rev_lt130_mfp_cfg[] __initdata = { @@ -290,6 +295,30 @@ static void __init cm_x300_init_lcd(void) static inline void cm_x300_init_lcd(void) {} #endif +#if defined(CONFIG_BACKLIGHT_PWM) || defined(CONFIG_BACKLIGHT_PWM_MODULE) +static struct platform_pwm_backlight_data cm_x300_backlight_data = { + .pwm_id = 2, + .max_brightness = 100, + .dft_brightness = 100, + .pwm_period_ns = 10000, +}; + +static struct platform_device cm_x300_backlight_device = { + .name = "pwm-backlight", + .dev = { + .parent = &pxa27x_device_pwm0.dev, + .platform_data = &cm_x300_backlight_data, + }, +}; + +static void cm_x300_init_bl(void) +{ + platform_device_register(&cm_x300_backlight_device); +} +#else +static inline void cm_x300_init_bl(void) {} +#endif + #if defined(CONFIG_SPI_GPIO) || defined(CONFIG_SPI_GPIO_MODULE) #define GPIO_LCD_BASE (144) #define GPIO_LCD_DIN (GPIO_LCD_BASE + 8) /* aux_gpio3_0 */ @@ -654,6 +683,7 @@ static void __init cm_x300_init(void) cm_x300_init_rtc(); cm_x300_init_ac97(); cm_x300_init_wi2wi(); + cm_x300_init_bl(); } static void __init cm_x300_fixup(struct machine_desc *mdesc, struct tag *tags, -- cgit v0.10.2 From a328e95b82c1b8483ae5ab2f809140664d7f6c92 Mon Sep 17 00:00:00 2001 From: Dave Hansen Date: Thu, 1 Oct 2009 15:43:32 -0700 Subject: leds: LED driver for Intel NAS SS4200 series (v5) This code is based on a driver that came in the "Open-source and GPL components" download here: http://downloadcenter.intel.com/SearchResult.aspx?lang=eng&ProductFamily=Server+Products&ProductLine=Intel%C2%AE+Storage+Systems&ProductProduct=Intel%C2%AE+Entry+Storage+System+SS4200-E&OSVersion=OS+Independent It was in a file called nasgpio.c inside of a second zip file called SS4200-E_Linux_SIO_Driver-v1.4.zip and is based on this updated to use the LED subsystem with the ioctl and hardware monitor support removed. I don't have any need for brightness control, and its code is *completely* separate from the on/off controls implemented here. If anyone else wants it, I'd be happy to look into adding it, but I don't care enough for now. Except for the probe routines, I rewrote most of it. I also Note that I don't have any hardware documentation except for the original driver. Thanks go to Arjan for his help in getting the original source for this released and for chasing down some licensing issues. Signed-off-by: Dave Hansen Signed-off-by: Richard Purdie diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index e4f599f..e481d3c 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -236,6 +236,15 @@ config LEDS_BD2802 This option enables support for BD2802GU RGB LED driver chips accessed via the I2C bus. +config LEDS_INTEL_SS4200 + tristate "LED driver for Intel NAS SS4200 series" + depends on LEDS_CLASS && PCI && DMI + help + This option enables support for the Intel SS4200 series of + Network Attached Storage servers. You may control the hard + drive or power LEDs on the front panel. Using this driver + can stop the front LED from blinking after startup. + comment "LED Triggers" config LEDS_TRIGGERS diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index 46d7270..12b7a20 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile @@ -29,6 +29,7 @@ obj-$(CONFIG_LEDS_DA903X) += leds-da903x.o obj-$(CONFIG_LEDS_WM831X_STATUS) += leds-wm831x-status.o obj-$(CONFIG_LEDS_WM8350) += leds-wm8350.o obj-$(CONFIG_LEDS_PWM) += leds-pwm.o +obj-$(CONFIG_LEDS_INTEL_SS4200) += leds-ss4200.o # LED SPI Drivers obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o diff --git a/drivers/leds/leds-ss4200.c b/drivers/leds/leds-ss4200.c new file mode 100644 index 0000000..0ec4ec3 --- /dev/null +++ b/drivers/leds/leds-ss4200.c @@ -0,0 +1,552 @@ +/* + * SS4200-E Hardware API + * Copyright (c) 2009, Intel Corporation. + * Copyright IBM Corporation, 2009 + * + * 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. + * + * Author: Dave Hansen + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +MODULE_AUTHOR("Rodney Girod , Dave Hansen "); +MODULE_DESCRIPTION("Intel NAS/Home Server ICH7 GPIO Driver"); +MODULE_LICENSE("GPL"); + +/* + * ICH7 LPC/GPIO PCI Config register offsets + */ +#define PMBASE 0x040 +#define GPIO_BASE 0x048 +#define GPIO_CTRL 0x04c +#define GPIO_EN 0x010 + +/* + * The ICH7 GPIO register block is 64 bytes in size. + */ +#define ICH7_GPIO_SIZE 64 + +/* + * Define register offsets within the ICH7 register block. + */ +#define GPIO_USE_SEL 0x000 +#define GP_IO_SEL 0x004 +#define GP_LVL 0x00c +#define GPO_BLINK 0x018 +#define GPI_INV 0x030 +#define GPIO_USE_SEL2 0x034 +#define GP_IO_SEL2 0x038 +#define GP_LVL2 0x03c + +/* + * PCI ID of the Intel ICH7 LPC Device within which the GPIO block lives. + */ +static struct pci_device_id ich7_lpc_pci_id[] = +{ + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_30) }, + { } /* NULL entry */ +}; + +MODULE_DEVICE_TABLE(pci, ich7_lpc_pci_id); + +static int __init ss4200_led_dmi_callback(const struct dmi_system_id *id) +{ + pr_info("detected '%s'\n", id->ident); + return 1; +} + +static unsigned int __initdata nodetect; +module_param_named(nodetect, nodetect, bool, 0); +MODULE_PARM_DESC(nodetect, "Skip DMI-based hardware detection"); + +/* + * struct nas_led_whitelist - List of known good models + * + * Contains the known good models this driver is compatible with. + * When adding a new model try to be as strict as possible. This + * makes it possible to keep the false positives (the model is + * detected as working, but in reality it is not) as low as + * possible. + */ +static struct dmi_system_id __initdata nas_led_whitelist[] = { + { + .callback = ss4200_led_dmi_callback, + .ident = "Intel SS4200-E", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Intel"), + DMI_MATCH(DMI_PRODUCT_NAME, "SS4200-E"), + DMI_MATCH(DMI_PRODUCT_VERSION, "1.00.00") + } + }, +}; + +/* + * Base I/O address assigned to the Power Management register block + */ +static u32 g_pm_io_base; + +/* + * Base I/O address assigned to the ICH7 GPIO register block + */ +static u32 nas_gpio_io_base; + +/* + * When we successfully register a region, we are returned a resource. + * We use these to identify which regions we need to release on our way + * back out. + */ +static struct resource *gp_gpio_resource; + +struct nasgpio_led { + char *name; + u32 gpio_bit; + struct led_classdev led_cdev; +}; + +/* + * gpio_bit(s) are the ICH7 GPIO bit assignments + */ +static struct nasgpio_led nasgpio_leds[] = { + { .name = "hdd1:blue:sata", .gpio_bit = 0 }, + { .name = "hdd1:amber:sata", .gpio_bit = 1 }, + { .name = "hdd2:blue:sata", .gpio_bit = 2 }, + { .name = "hdd2:amber:sata", .gpio_bit = 3 }, + { .name = "hdd3:blue:sata", .gpio_bit = 4 }, + { .name = "hdd3:amber:sata", .gpio_bit = 5 }, + { .name = "hdd4:blue:sata", .gpio_bit = 6 }, + { .name = "hdd4:amber:sata", .gpio_bit = 7 }, + { .name = "power:blue:power", .gpio_bit = 27}, + { .name = "power:amber:power", .gpio_bit = 28}, +}; + +#define NAS_RECOVERY 0x00000400 /* GPIO10 */ + +static struct nasgpio_led * +led_classdev_to_nasgpio_led(struct led_classdev *led_cdev) +{ + return container_of(led_cdev, struct nasgpio_led, led_cdev); +} + +static struct nasgpio_led *get_led_named(char *name) +{ + int i; + for (i = 0; i < ARRAY_SIZE(nasgpio_leds); i++) { + if (strcmp(nasgpio_leds[i].name, name)) + continue; + return &nasgpio_leds[i]; + } + return NULL; +} + +/* + * This protects access to the gpio ports. + */ +static DEFINE_SPINLOCK(nasgpio_gpio_lock); + +/* + * There are two gpio ports, one for blinking and the other + * for power. @port tells us if we're doing blinking or + * power control. + * + * Caller must hold nasgpio_gpio_lock + */ +static void __nasgpio_led_set_attr(struct led_classdev *led_cdev, + u32 port, u32 value) +{ + struct nasgpio_led *led = led_classdev_to_nasgpio_led(led_cdev); + u32 gpio_out; + + gpio_out = inl(nas_gpio_io_base + port); + if (value) + gpio_out |= (1<gpio_bit); + else + gpio_out &= ~(1<gpio_bit); + + outl(gpio_out, nas_gpio_io_base + port); +} + +static void nasgpio_led_set_attr(struct led_classdev *led_cdev, + u32 port, u32 value) +{ + spin_lock(&nasgpio_gpio_lock); + __nasgpio_led_set_attr(led_cdev, port, value); + spin_unlock(&nasgpio_gpio_lock); +} + +u32 nasgpio_led_get_attr(struct led_classdev *led_cdev, u32 port) +{ + struct nasgpio_led *led = led_classdev_to_nasgpio_led(led_cdev); + u32 gpio_in; + + spin_lock(&nasgpio_gpio_lock); + gpio_in = inl(nas_gpio_io_base + port); + spin_unlock(&nasgpio_gpio_lock); + if (gpio_in & (1<gpio_bit)) + return 1; + return 0; +} + +/* + * There is actual brightness control in the hardware, + * but it is via smbus commands and not implemented + * in this driver. + */ +static void nasgpio_led_set_brightness(struct led_classdev *led_cdev, + enum led_brightness brightness) +{ + u32 setting = 0; + if (brightness >= LED_HALF) + setting = 1; + /* + * Hold the lock across both operations. This ensures + * consistency so that both the "turn off blinking" + * and "turn light off" operations complete as a set. + */ + spin_lock(&nasgpio_gpio_lock); + /* + * LED class documentation asks that past blink state + * be disabled when brightness is turned to zero. + */ + if (brightness == 0) + __nasgpio_led_set_attr(led_cdev, GPO_BLINK, 0); + __nasgpio_led_set_attr(led_cdev, GP_LVL, setting); + spin_unlock(&nasgpio_gpio_lock); +} + +static int nasgpio_led_set_blink(struct led_classdev *led_cdev, + unsigned long *delay_on, + unsigned long *delay_off) +{ + u32 setting = 1; + if (!(*delay_on == 0 && *delay_off == 0) && + !(*delay_on == 500 && *delay_off == 500)) + return -EINVAL; + /* + * These are very approximate. + */ + *delay_on = 500; + *delay_off = 500; + + nasgpio_led_set_attr(led_cdev, GPO_BLINK, setting); + + return 0; +} + + +/* + * Initialize the ICH7 GPIO registers for NAS usage. The BIOS should have + * already taken care of this, but we will do so in a non destructive manner + * so that we have what we need whether the BIOS did it or not. + */ +static int __devinit ich7_gpio_init(struct device *dev) +{ + int i; + u32 config_data = 0; + u32 all_nas_led = 0; + + for (i = 0; i < ARRAY_SIZE(nasgpio_leds); i++) + all_nas_led |= (1<dev, + "ERROR: The LPC GPIO Block has not been enabled.\n"); + goto out; + } + + status = pci_read_config_dword(dev, GPIO_BASE, &nas_gpio_io_base); + if (0 > status) { + dev_info(&dev->dev, "Unable to read GPIOBASE.\n"); + goto out; + } + dev_dbg(&dev->dev, ": GPIOBASE = 0x%08x\n", nas_gpio_io_base); + nas_gpio_io_base &= 0x00000ffc0; + + /* + * Insure that we have exclusive access to the GPIO I/O address range. + */ + gp_gpio_resource = request_region(nas_gpio_io_base, ICH7_GPIO_SIZE, + KBUILD_MODNAME); + if (NULL == gp_gpio_resource) { + dev_info(&dev->dev, + "ERROR Unable to register GPIO I/O addresses.\n"); + status = -1; + goto out; + } + + /* + * Initialize the GPIO for NAS/Home Server Use + */ + ich7_gpio_init(&dev->dev); + +out: + if (status) { + ich7_lpc_cleanup(&dev->dev); + pci_disable_device(dev); + } + return status; +} + +static void ich7_lpc_remove(struct pci_dev *dev) +{ + ich7_lpc_cleanup(&dev->dev); + pci_disable_device(dev); +} + +/* + * pci_driver structure passed to the PCI modules + */ +static struct pci_driver nas_gpio_pci_driver = { + .name = KBUILD_MODNAME, + .id_table = ich7_lpc_pci_id, + .probe = ich7_lpc_probe, + .remove = ich7_lpc_remove, +}; + +static struct led_classdev *get_classdev_for_led_nr(int nr) +{ + struct nasgpio_led *nas_led = &nasgpio_leds[nr]; + struct led_classdev *led = &nas_led->led_cdev; + return led; +} + + +static void set_power_light_amber_noblink(void) +{ + struct nasgpio_led *amber = get_led_named("power:amber:power"); + struct nasgpio_led *blue = get_led_named("power:blue:power"); + + if (!amber || !blue) + return; + /* + * LED_OFF implies disabling future blinking + */ + pr_debug("setting blue off and amber on\n"); + + nasgpio_led_set_brightness(&blue->led_cdev, LED_OFF); + nasgpio_led_set_brightness(&amber->led_cdev, LED_FULL); +} + +static ssize_t nas_led_blink_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct led_classdev *led = dev_get_drvdata(dev); + int blinking = 0; + if (nasgpio_led_get_attr(led, GPO_BLINK)) + blinking = 1; + return sprintf(buf, "%u\n", blinking); +} + +static ssize_t nas_led_blink_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + int ret; + struct led_classdev *led = dev_get_drvdata(dev); + unsigned long blink_state; + + ret = strict_strtoul(buf, 10, &blink_state); + if (ret) + return ret; + + nasgpio_led_set_attr(led, GPO_BLINK, blink_state); + + return size; +} + +static DEVICE_ATTR(blink, 0644, nas_led_blink_show, nas_led_blink_store); + +static int register_nasgpio_led(int led_nr) +{ + int ret; + struct nasgpio_led *nas_led = &nasgpio_leds[led_nr]; + struct led_classdev *led = get_classdev_for_led_nr(led_nr); + + led->name = nas_led->name; + led->brightness = LED_OFF; + if (nasgpio_led_get_attr(led, GP_LVL)) + led->brightness = LED_FULL; + led->brightness_set = nasgpio_led_set_brightness; + led->blink_set = nasgpio_led_set_blink; + ret = led_classdev_register(&nas_gpio_pci_dev->dev, led); + if (ret) + return ret; + ret = device_create_file(led->dev, &dev_attr_blink); + if (ret) + led_classdev_unregister(led); + return ret; +} + +static void unregister_nasgpio_led(int led_nr) +{ + struct led_classdev *led = get_classdev_for_led_nr(led_nr); + led_classdev_unregister(led); + device_remove_file(led->dev, &dev_attr_blink); +} +/* + * module load/initialization + */ +static int __init nas_gpio_init(void) +{ + int i; + int ret = 0; + int nr_devices = 0; + + nr_devices = dmi_check_system(nas_led_whitelist); + if (nodetect) { + pr_info("skipping hardware autodetection\n"); + pr_info("Please send 'dmidecode' output to dave@sr71.net\n"); + nr_devices++; + } + + if (nr_devices <= 0) { + pr_info("no LED devices found\n"); + return -ENODEV; + } + + pr_info("registering PCI driver\n"); + ret = pci_register_driver(&nas_gpio_pci_driver); + if (ret) + return ret; + for (i = 0; i < ARRAY_SIZE(nasgpio_leds); i++) { + ret = register_nasgpio_led(i); + if (ret) + goto out_err; + } + /* + * When the system powers on, the BIOS leaves the power + * light blue and blinking. This will turn it solid + * amber once the driver is loaded. + */ + set_power_light_amber_noblink(); + return 0; +out_err: + for (; i >= 0; i--) + unregister_nasgpio_led(i); + pci_unregister_driver(&nas_gpio_pci_driver); + return ret; +} + +/* + * module unload + */ +static void __exit nas_gpio_exit(void) +{ + int i; + pr_info("Unregistering driver\n"); + for (i = 0; i < ARRAY_SIZE(nasgpio_leds); i++) + unregister_nasgpio_led(i); + pci_unregister_driver(&nas_gpio_pci_driver); +} + +module_init(nas_gpio_init); +module_exit(nas_gpio_exit); -- cgit v0.10.2 From 7f131cf3ed96c969d7b092bf629e25c3df50901e Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Mon, 5 Oct 2009 20:22:27 +0800 Subject: leds: leds-alix2c - take port address from MSR This makes the LEDs driver for ALIX2.C boards work with Coreboot by looking up the port address in the MSR rather than hard-coding it. The BIOS scan also needed some tweaks as the string in Coreboot differs from the one in the legacy BIOS. Successfully tested with both the legacy tinyBIOS as well as Coreboot v3. Signed-off-by: Daniel Mack Signed-off-by: Richard Purdie diff --git a/drivers/leds/leds-alix2.c b/drivers/leds/leds-alix2.c index 731d4ee..f59ffad 100644 --- a/drivers/leds/leds-alix2.c +++ b/drivers/leds/leds-alix2.c @@ -11,11 +11,24 @@ #include #include #include +#include static int force = 0; module_param(force, bool, 0444); MODULE_PARM_DESC(force, "Assume system has ALIX.2/ALIX.3 style LEDs"); +#define MSR_LBAR_GPIO 0x5140000C +#define CS5535_GPIO_SIZE 256 + +static u32 gpio_base; + +static struct pci_device_id divil_pci[] = { + { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_ISA) }, + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) }, + { } /* NULL entry */ +}; +MODULE_DEVICE_TABLE(pci, divil_pci); + struct alix_led { struct led_classdev cdev; unsigned short port; @@ -30,9 +43,9 @@ static void alix_led_set(struct led_classdev *led_cdev, container_of(led_cdev, struct alix_led, cdev); if (brightness) - outl(led_dev->on_value, led_dev->port); + outl(led_dev->on_value, gpio_base + led_dev->port); else - outl(led_dev->off_value, led_dev->port); + outl(led_dev->off_value, gpio_base + led_dev->port); } static struct alix_led alix_leds[] = { @@ -41,7 +54,7 @@ static struct alix_led alix_leds[] = { .name = "alix:1", .brightness_set = alix_led_set, }, - .port = 0x6100, + .port = 0x00, .on_value = 1 << 22, .off_value = 1 << 6, }, @@ -50,7 +63,7 @@ static struct alix_led alix_leds[] = { .name = "alix:2", .brightness_set = alix_led_set, }, - .port = 0x6180, + .port = 0x80, .on_value = 1 << 25, .off_value = 1 << 9, }, @@ -59,7 +72,7 @@ static struct alix_led alix_leds[] = { .name = "alix:3", .brightness_set = alix_led_set, }, - .port = 0x6180, + .port = 0x80, .on_value = 1 << 27, .off_value = 1 << 11, }, @@ -101,64 +114,104 @@ static struct platform_driver alix_led_driver = { }, }; -static int __init alix_present(void) +static int __init alix_present(unsigned long bios_phys, + const char *alix_sig, + size_t alix_sig_len) { - const unsigned long bios_phys = 0x000f0000; const size_t bios_len = 0x00010000; - const char alix_sig[] = "PC Engines ALIX."; - const size_t alix_sig_len = sizeof(alix_sig) - 1; - const char *bios_virt; const char *scan_end; const char *p; - int ret = 0; + char name[64]; if (force) { printk(KERN_NOTICE "%s: forced to skip BIOS test, " "assume system has ALIX.2 style LEDs\n", KBUILD_MODNAME); - ret = 1; - goto out; + return 1; } bios_virt = phys_to_virt(bios_phys); scan_end = bios_virt + bios_len - (alix_sig_len + 2); for (p = bios_virt; p < scan_end; p++) { const char *tail; + char *a; - if (memcmp(p, alix_sig, alix_sig_len) != 0) { + if (memcmp(p, alix_sig, alix_sig_len) != 0) continue; - } + + memcpy(name, p, sizeof(name)); + + /* remove the first \0 character from string */ + a = strchr(name, '\0'); + if (a) + *a = ' '; + + /* cut the string at a newline */ + a = strchr(name, '\r'); + if (a) + *a = '\0'; tail = p + alix_sig_len; - if ((tail[0] == '2' || tail[0] == '3') && tail[1] == '\0') { + if ((tail[0] == '2' || tail[0] == '3')) { printk(KERN_INFO "%s: system is recognized as \"%s\"\n", - KBUILD_MODNAME, p); - ret = 1; - break; + KBUILD_MODNAME, name); + return 1; } } -out: - return ret; + return 0; } static struct platform_device *pdev; -static int __init alix_led_init(void) +static int __init alix_pci_led_init(void) { - int ret; + u32 low, hi; - if (!alix_present()) { - ret = -ENODEV; - goto out; + if (pci_dev_present(divil_pci) == 0) { + printk(KERN_WARNING KBUILD_MODNAME": DIVIL not found\n"); + return -ENODEV; } - /* enable output on GPIO for LED 1,2,3 */ - outl(1 << 6, 0x6104); - outl(1 << 9, 0x6184); - outl(1 << 11, 0x6184); + /* Grab the GPIO I/O range */ + rdmsr(MSR_LBAR_GPIO, low, hi); + + /* Check the mask and whether GPIO is enabled (sanity check) */ + if (hi != 0x0000f001) { + printk(KERN_WARNING KBUILD_MODNAME": GPIO not enabled\n"); + return -ENODEV; + } + + /* Mask off the IO base address */ + gpio_base = low & 0x0000ff00; + + if (!request_region(gpio_base, CS5535_GPIO_SIZE, KBUILD_MODNAME)) { + printk(KERN_ERR KBUILD_MODNAME": can't allocate I/O for GPIO\n"); + return -ENODEV; + } + + /* Set GPIO function to output */ + outl(1 << 6, gpio_base + 0x04); + outl(1 << 9, gpio_base + 0x84); + outl(1 << 11, gpio_base + 0x84); + + return 0; +} + +static int __init alix_led_init(void) +{ + int ret = -ENODEV; + const char tinybios_sig[] = "PC Engines ALIX."; + const char coreboot_sig[] = "PC Engines\0ALIX."; + + if (alix_present(0xf0000, tinybios_sig, sizeof(tinybios_sig) - 1) || + alix_present(0x500, coreboot_sig, sizeof(coreboot_sig) - 1)) + ret = alix_pci_led_init(); + + if (ret < 0) + return ret; pdev = platform_device_register_simple(KBUILD_MODNAME, -1, NULL, 0); if (!IS_ERR(pdev)) { @@ -168,7 +221,6 @@ static int __init alix_led_init(void) } else ret = PTR_ERR(pdev); -out: return ret; } @@ -176,6 +228,7 @@ static void __exit alix_led_exit(void) { platform_device_unregister(pdev); platform_driver_unregister(&alix_led_driver); + release_region(gpio_base, CS5535_GPIO_SIZE); } module_init(alix_led_init); -- cgit v0.10.2 From 09a46db05b2e07484c08c638d7d6bda0523a13a6 Mon Sep 17 00:00:00 2001 From: Dave Hansen Date: Wed, 14 Oct 2009 09:20:47 -0700 Subject: leds-ss4200: Check pci_enable_device return pci_enable_result is defined using the __must_check macro but leds-ss4200 is not checking the return value. Signed-off-by: Javier Martinez Canillas Signed-off-by: Dave Hansen Signed-off-by: Richard Purdie diff --git a/drivers/leds/leds-ss4200.c b/drivers/leds/leds-ss4200.c index 0ec4ec3..c7f6347 100644 --- a/drivers/leds/leds-ss4200.c +++ b/drivers/leds/leds-ss4200.c @@ -344,10 +344,14 @@ static struct pci_dev *nas_gpio_pci_dev; static int __devinit ich7_lpc_probe(struct pci_dev *dev, const struct pci_device_id *id) { - int status = 0; + int status; u32 gc = 0; - pci_enable_device(dev); + status = pci_enable_device(dev); + if (status) { + dev_err(&dev->dev, "pci_enable_device failed\n"); + return; + } nas_gpio_pci_dev = dev; status = pci_read_config_dword(dev, PMBASE, &g_pm_io_base); -- cgit v0.10.2 From a8dd18feb68ef0c5d3ec02f7d198740ddd7e8fd3 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Thu, 15 Oct 2009 02:59:35 +0200 Subject: leds: Add driver for LT3593 controlled LEDs The LT3593 is a step-up DC/DC converter designed to drive up to ten white LEDs in series. The current flow can be set with a control pin. This driver controls any number of such devices connected on generic GPIOs and exports the function as as platform_driver. The gpio_led platform data struct definition is reused for this purpose. Successfully tested on a PXA embedded board. Signed-off-by: Daniel Mack Signed-off-by: Richard Purdie diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index e481d3c..e2b7a53 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -245,6 +245,14 @@ config LEDS_INTEL_SS4200 drive or power LEDs on the front panel. Using this driver can stop the front LED from blinking after startup. +config LEDS_LT3593 + tristate "LED driver for LT3593 controllers" + depends on LEDS_CLASS && GENERIC_GPIO + help + This option enables support for LEDs driven by a Linear Technology + LT3593 controller. This controller uses a special one-wire pulse + coding protocol to set the brightness. + comment "LED Triggers" config LEDS_TRIGGERS diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index 12b7a20..eb5a141 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile @@ -30,6 +30,7 @@ obj-$(CONFIG_LEDS_WM831X_STATUS) += leds-wm831x-status.o obj-$(CONFIG_LEDS_WM8350) += leds-wm8350.o obj-$(CONFIG_LEDS_PWM) += leds-pwm.o obj-$(CONFIG_LEDS_INTEL_SS4200) += leds-ss4200.o +obj-$(CONFIG_LEDS_LT3593) += leds-lt3593.o # LED SPI Drivers obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o diff --git a/drivers/leds/leds-lt3593.c b/drivers/leds/leds-lt3593.c new file mode 100644 index 0000000..fee40a8 --- /dev/null +++ b/drivers/leds/leds-lt3593.c @@ -0,0 +1,217 @@ +/* + * LEDs driver for LT3593 controllers + * + * See the datasheet at http://cds.linear.com/docs/Datasheet/3593f.pdf + * + * Copyright (c) 2009 Daniel Mack + * + * Based on leds-gpio.c, + * + * Copyright (C) 2007 8D Technologies inc. + * Raphael Assenat + * Copyright (C) 2008 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include + +struct lt3593_led_data { + struct led_classdev cdev; + unsigned gpio; + struct work_struct work; + u8 new_level; +}; + +static void lt3593_led_work(struct work_struct *work) +{ + int pulses; + struct lt3593_led_data *led_dat = + container_of(work, struct lt3593_led_data, work); + + /* + * The LT3593 resets its internal current level register to the maximum + * level on the first falling edge on the control pin. Each following + * falling edge decreases the current level by 625uA. Up to 32 pulses + * can be sent, so the maximum power reduction is 20mA. + * After a timeout of 128us, the value is taken from the register and + * applied is to the output driver. + */ + + if (led_dat->new_level == 0) { + gpio_set_value_cansleep(led_dat->gpio, 0); + return; + } + + pulses = 32 - (led_dat->new_level * 32) / 255; + + if (pulses == 0) { + gpio_set_value_cansleep(led_dat->gpio, 0); + mdelay(1); + gpio_set_value_cansleep(led_dat->gpio, 1); + return; + } + + gpio_set_value_cansleep(led_dat->gpio, 1); + + while (pulses--) { + gpio_set_value_cansleep(led_dat->gpio, 0); + udelay(1); + gpio_set_value_cansleep(led_dat->gpio, 1); + udelay(1); + } +} + +static void lt3593_led_set(struct led_classdev *led_cdev, + enum led_brightness value) +{ + struct lt3593_led_data *led_dat = + container_of(led_cdev, struct lt3593_led_data, cdev); + + led_dat->new_level = value; + schedule_work(&led_dat->work); +} + +static int __devinit create_lt3593_led(const struct gpio_led *template, + struct lt3593_led_data *led_dat, struct device *parent) +{ + int ret, state; + + /* skip leds on GPIOs that aren't available */ + if (!gpio_is_valid(template->gpio)) { + printk(KERN_INFO "%s: skipping unavailable LT3593 LED at gpio %d (%s)\n", + KBUILD_MODNAME, template->gpio, template->name); + return 0; + } + + ret = gpio_request(template->gpio, template->name); + if (ret < 0) + return ret; + + led_dat->cdev.name = template->name; + led_dat->cdev.default_trigger = template->default_trigger; + led_dat->gpio = template->gpio; + + led_dat->cdev.brightness_set = lt3593_led_set; + + state = (template->default_state == LEDS_GPIO_DEFSTATE_ON); + led_dat->cdev.brightness = state ? LED_FULL : LED_OFF; + + if (!template->retain_state_suspended) + led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME; + + ret = gpio_direction_output(led_dat->gpio, state); + if (ret < 0) + goto err; + + INIT_WORK(&led_dat->work, lt3593_led_work); + + ret = led_classdev_register(parent, &led_dat->cdev); + if (ret < 0) + goto err; + + printk(KERN_INFO "%s: registered LT3593 LED '%s' at GPIO %d\n", + KBUILD_MODNAME, template->name, template->gpio); + + return 0; + +err: + gpio_free(led_dat->gpio); + return ret; +} + +static void delete_lt3593_led(struct lt3593_led_data *led) +{ + if (!gpio_is_valid(led->gpio)) + return; + + led_classdev_unregister(&led->cdev); + cancel_work_sync(&led->work); + gpio_free(led->gpio); +} + +static int __devinit lt3593_led_probe(struct platform_device *pdev) +{ + struct gpio_led_platform_data *pdata = pdev->dev.platform_data; + struct lt3593_led_data *leds_data; + int i, ret = 0; + + if (!pdata) + return -EBUSY; + + leds_data = kzalloc(sizeof(struct lt3593_led_data) * pdata->num_leds, + GFP_KERNEL); + if (!leds_data) + return -ENOMEM; + + for (i = 0; i < pdata->num_leds; i++) { + ret = create_lt3593_led(&pdata->leds[i], &leds_data[i], + &pdev->dev); + if (ret < 0) + goto err; + } + + platform_set_drvdata(pdev, leds_data); + + return 0; + +err: + for (i = i - 1; i >= 0; i--) + delete_lt3593_led(&leds_data[i]); + + kfree(leds_data); + + return ret; +} + +static int __devexit lt3593_led_remove(struct platform_device *pdev) +{ + int i; + struct gpio_led_platform_data *pdata = pdev->dev.platform_data; + struct lt3593_led_data *leds_data; + + leds_data = platform_get_drvdata(pdev); + + for (i = 0; i < pdata->num_leds; i++) + delete_lt3593_led(&leds_data[i]); + + kfree(leds_data); + + return 0; +} + +static struct platform_driver lt3593_led_driver = { + .probe = lt3593_led_probe, + .remove = __devexit_p(lt3593_led_remove), + .driver = { + .name = "leds-lt3593", + .owner = THIS_MODULE, + }, +}; + +MODULE_ALIAS("platform:leds-lt3593"); + +static int __init lt3593_led_init(void) +{ + return platform_driver_register(<3593_led_driver); +} + +static void __exit lt3593_led_exit(void) +{ + platform_driver_unregister(<3593_led_driver); +} + +module_init(lt3593_led_init); +module_exit(lt3593_led_exit); + +MODULE_AUTHOR("Daniel Mack "); +MODULE_DESCRIPTION("LED driver for LT3593 controllers"); +MODULE_LICENSE("GPL"); -- cgit v0.10.2 From ed4a10b47ff1e4059157f33248a62d9551ced786 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Thu, 8 Oct 2009 04:00:19 -0400 Subject: leds: Add driver for ADP5520/ADP5501 MFD PMICs Signed-off-by: Michael Hennerich Signed-off-by: Bryan Wu Signed-off-by: Mike Frysinger Signed-off-by: Richard Purdie diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index e2b7a53..f12a996 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -253,6 +253,16 @@ config LEDS_LT3593 LT3593 controller. This controller uses a special one-wire pulse coding protocol to set the brightness. +config LEDS_ADP5520 + tristate "LED Support for ADP5520/ADP5501 PMIC" + depends on LEDS_CLASS && PMIC_ADP5520 + help + This option enables support for on-chip LED drivers found + on Analog Devices ADP5520/ADP5501 PMICs. + + To compile this driver as a module, choose M here: the module will + be called leds-adp5520. + comment "LED Triggers" config LEDS_TRIGGERS diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index eb5a141..176f0c6 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile @@ -31,6 +31,7 @@ obj-$(CONFIG_LEDS_WM8350) += leds-wm8350.o obj-$(CONFIG_LEDS_PWM) += leds-pwm.o obj-$(CONFIG_LEDS_INTEL_SS4200) += leds-ss4200.o obj-$(CONFIG_LEDS_LT3593) += leds-lt3593.o +obj-$(CONFIG_LEDS_ADP5520) += leds-adp5520.o # LED SPI Drivers obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o diff --git a/drivers/leds/leds-adp5520.c b/drivers/leds/leds-adp5520.c new file mode 100644 index 0000000..a8f3159 --- /dev/null +++ b/drivers/leds/leds-adp5520.c @@ -0,0 +1,230 @@ +/* + * LEDs driver for Analog Devices ADP5520/ADP5501 MFD PMICs + * + * Copyright 2009 Analog Devices Inc. + * + * Loosely derived from leds-da903x: + * Copyright (C) 2008 Compulab, Ltd. + * Mike Rapoport + * + * Copyright (C) 2006-2008 Marvell International Ltd. + * Eric Miao + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include + +struct adp5520_led { + struct led_classdev cdev; + struct work_struct work; + struct device *master; + enum led_brightness new_brightness; + int id; + int flags; +}; + +static void adp5520_led_work(struct work_struct *work) +{ + struct adp5520_led *led = container_of(work, struct adp5520_led, work); + adp5520_write(led->master, ADP5520_LED1_CURRENT + led->id - 1, + led->new_brightness >> 2); +} + +static void adp5520_led_set(struct led_classdev *led_cdev, + enum led_brightness value) +{ + struct adp5520_led *led; + + led = container_of(led_cdev, struct adp5520_led, cdev); + led->new_brightness = value; + schedule_work(&led->work); +} + +static int adp5520_led_setup(struct adp5520_led *led) +{ + struct device *dev = led->master; + int flags = led->flags; + int ret = 0; + + switch (led->id) { + case FLAG_ID_ADP5520_LED1_ADP5501_LED0: + ret |= adp5520_set_bits(dev, ADP5520_LED_TIME, + (flags >> ADP5520_FLAG_OFFT_SHIFT) & + ADP5520_FLAG_OFFT_MASK); + ret |= adp5520_set_bits(dev, ADP5520_LED_CONTROL, + ADP5520_LED1_EN); + break; + case FLAG_ID_ADP5520_LED2_ADP5501_LED1: + ret |= adp5520_set_bits(dev, ADP5520_LED_TIME, + ((flags >> ADP5520_FLAG_OFFT_SHIFT) & + ADP5520_FLAG_OFFT_MASK) << 2); + ret |= adp5520_clr_bits(dev, ADP5520_LED_CONTROL, + ADP5520_R3_MODE); + ret |= adp5520_set_bits(dev, ADP5520_LED_CONTROL, + ADP5520_LED2_EN); + break; + case FLAG_ID_ADP5520_LED3_ADP5501_LED2: + ret |= adp5520_set_bits(dev, ADP5520_LED_TIME, + ((flags >> ADP5520_FLAG_OFFT_SHIFT) & + ADP5520_FLAG_OFFT_MASK) << 4); + ret |= adp5520_clr_bits(dev, ADP5520_LED_CONTROL, + ADP5520_C3_MODE); + ret |= adp5520_set_bits(dev, ADP5520_LED_CONTROL, + ADP5520_LED3_EN); + break; + } + + return ret; +} + +static int __devinit adp5520_led_prepare(struct platform_device *pdev) +{ + struct adp5520_leds_platform_data *pdata = pdev->dev.platform_data; + struct device *dev = pdev->dev.parent; + int ret = 0; + + ret |= adp5520_write(dev, ADP5520_LED1_CURRENT, 0); + ret |= adp5520_write(dev, ADP5520_LED2_CURRENT, 0); + ret |= adp5520_write(dev, ADP5520_LED3_CURRENT, 0); + ret |= adp5520_write(dev, ADP5520_LED_TIME, pdata->led_on_time << 6); + ret |= adp5520_write(dev, ADP5520_LED_FADE, FADE_VAL(pdata->fade_in, + pdata->fade_out)); + + return ret; +} + +static int __devinit adp5520_led_probe(struct platform_device *pdev) +{ + struct adp5520_leds_platform_data *pdata = pdev->dev.platform_data; + struct adp5520_led *led, *led_dat; + struct led_info *cur_led; + int ret, i; + + if (pdata == NULL) { + dev_err(&pdev->dev, "missing platform data\n"); + return -ENODEV; + } + + if (pdata->num_leds > ADP5520_01_MAXLEDS) { + dev_err(&pdev->dev, "can't handle more than %d LEDS\n", + ADP5520_01_MAXLEDS); + return -EFAULT; + } + + led = kzalloc(sizeof(*led) * pdata->num_leds, GFP_KERNEL); + if (led == NULL) { + dev_err(&pdev->dev, "failed to alloc memory\n"); + return -ENOMEM; + } + + ret = adp5520_led_prepare(pdev); + + if (ret) { + dev_err(&pdev->dev, "failed to write\n"); + goto err_free; + } + + for (i = 0; i < pdata->num_leds; ++i) { + cur_led = &pdata->leds[i]; + led_dat = &led[i]; + + led_dat->cdev.name = cur_led->name; + led_dat->cdev.default_trigger = cur_led->default_trigger; + led_dat->cdev.brightness_set = adp5520_led_set; + led_dat->cdev.brightness = LED_OFF; + + if (cur_led->flags & ADP5520_FLAG_LED_MASK) + led_dat->flags = cur_led->flags; + else + led_dat->flags = i + 1; + + led_dat->id = led_dat->flags & ADP5520_FLAG_LED_MASK; + + led_dat->master = pdev->dev.parent; + led_dat->new_brightness = LED_OFF; + + INIT_WORK(&led_dat->work, adp5520_led_work); + + ret = led_classdev_register(led_dat->master, &led_dat->cdev); + if (ret) { + dev_err(&pdev->dev, "failed to register LED %d\n", + led_dat->id); + goto err; + } + + ret = adp5520_led_setup(led_dat); + if (ret) { + dev_err(&pdev->dev, "failed to write\n"); + i++; + goto err; + } + } + + platform_set_drvdata(pdev, led); + return 0; + +err: + if (i > 0) { + for (i = i - 1; i >= 0; i--) { + led_classdev_unregister(&led[i].cdev); + cancel_work_sync(&led[i].work); + } + } + +err_free: + kfree(led); + return ret; +} + +static int __devexit adp5520_led_remove(struct platform_device *pdev) +{ + struct adp5520_leds_platform_data *pdata = pdev->dev.platform_data; + struct adp5520_led *led; + int i; + + led = platform_get_drvdata(pdev); + + adp5520_clr_bits(led->master, ADP5520_LED_CONTROL, + ADP5520_LED1_EN | ADP5520_LED2_EN | ADP5520_LED3_EN); + + for (i = 0; i < pdata->num_leds; i++) { + led_classdev_unregister(&led[i].cdev); + cancel_work_sync(&led[i].work); + } + + kfree(led); + return 0; +} + +static struct platform_driver adp5520_led_driver = { + .driver = { + .name = "adp5520-led", + .owner = THIS_MODULE, + }, + .probe = adp5520_led_probe, + .remove = __devexit_p(adp5520_led_remove), +}; + +static int __init adp5520_led_init(void) +{ + return platform_driver_register(&adp5520_led_driver); +} +module_init(adp5520_led_init); + +static void __exit adp5520_led_exit(void) +{ + platform_driver_unregister(&adp5520_led_driver); +} +module_exit(adp5520_led_exit); + +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("LEDS ADP5520(01) Driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:adp5520-led"); -- cgit v0.10.2 From 6baddba4a40b4f4e37db051e84ac5e7cc454a19c Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sun, 20 Sep 2009 14:44:48 -0300 Subject: backlight/thinkpad-acpi: issue backlight class events Take advantage of the new events capabilities of the backlight class to notify userspace of backlight changes. Signed-off-by: Henrique de Moraes Holschuh Signed-off-by: Richard Purdie diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt index aafcaa6..f5056c7 100644 --- a/Documentation/laptops/thinkpad-acpi.txt +++ b/Documentation/laptops/thinkpad-acpi.txt @@ -460,6 +460,8 @@ event code Key Notes For Lenovo ThinkPads with a new BIOS, it has to be handled either by the ACPI OSI, or by userspace. + The driver does the right thing, + never mess with this. 0x1011 0x10 FN+END Brightness down. See brightness up for details. @@ -582,46 +584,15 @@ with hotkey_report_mode. Brightness hotkey notes: -These are the current sane choices for brightness key mapping in -thinkpad-acpi: +Don't mess with the brightness hotkeys in a Thinkpad. If you want +notifications for OSD, use the sysfs backlight class event support. -For IBM and Lenovo models *without* ACPI backlight control (the ones on -which thinkpad-acpi will autoload its backlight interface by default, -and on which ACPI video does not export a backlight interface): - -1. Don't enable or map the brightness hotkeys in thinkpad-acpi, as - these older firmware versions unfortunately won't respect the hotkey - mask for brightness keys anyway, and always reacts to them. This - usually work fine, unless X.org drivers are doing something to block - the BIOS. In that case, use (3) below. This is the default mode of - operation. - -2. Enable the hotkeys, but map them to something else that is NOT - KEY_BRIGHTNESS_UP/DOWN or any other keycode that would cause - userspace to try to change the backlight level, and use that as an - on-screen-display hint. - -3. IF AND ONLY IF X.org drivers find a way to block the firmware from - automatically changing the brightness, enable the hotkeys and map - them to KEY_BRIGHTNESS_UP and KEY_BRIGHTNESS_DOWN, and feed that to - something that calls xbacklight. thinkpad-acpi will not be able to - change brightness in that case either, so you should disable its - backlight interface. - -For Lenovo models *with* ACPI backlight control: - -1. Load up ACPI video and use that. ACPI video will report ACPI - events for brightness change keys. Do not mess with thinkpad-acpi - defaults in this case. thinkpad-acpi should not have anything to do - with backlight events in a scenario where ACPI video is loaded: - brightness hotkeys must be disabled, and the backlight interface is - to be kept disabled as well. This is the default mode of operation. - -2. Do *NOT* load up ACPI video, enable the hotkeys in thinkpad-acpi, - and map them to KEY_BRIGHTNESS_UP and KEY_BRIGHTNESS_DOWN. Process - these keys on userspace somehow (e.g. by calling xbacklight). - The driver will do this automatically if it detects that ACPI video - has been disabled. +The driver will issue KEY_BRIGHTNESS_UP and KEY_BRIGHTNESS_DOWN events +automatically for the cases were userspace has to do something to +implement brightness changes. When you override these events, you will +either fail to handle properly the ThinkPads that require explicit +action to change backlight brightness, or the ThinkPads that require +that no action be taken to work properly. Bluetooth @@ -1465,3 +1436,5 @@ Sysfs interface changelog: and it is always able to disable hot keys. Very old thinkpads are properly supported. hotkey_bios_mask is deprecated and marked for removal. + +0x020600: Marker for backlight change event support. diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index cf61d6a..758dc0b 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -22,7 +22,7 @@ */ #define TPACPI_VERSION "0.23" -#define TPACPI_SYSFS_VERSION 0x020500 +#define TPACPI_SYSFS_VERSION 0x020600 /* * Changelog: @@ -6092,6 +6092,12 @@ static int brightness_get(struct backlight_device *bd) return status & TP_EC_BACKLIGHT_LVLMSK; } +static void tpacpi_brightness_notify_change(void) +{ + backlight_force_update(ibm_backlight_device, + BACKLIGHT_UPDATE_HOTKEY); +} + static struct backlight_ops ibm_backlight_data = { .get_brightness = brightness_get, .update_status = brightness_update_status, @@ -6246,6 +6252,12 @@ static int __init brightness_init(struct ibm_init_struct *iibm) ibm_backlight_device->props.brightness = b & TP_EC_BACKLIGHT_LVLMSK; backlight_update_status(ibm_backlight_device); + vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT, + "brightness: registering brightness hotkeys " + "as change notification\n"); + tpacpi_hotkey_driver_mask_set(hotkey_driver_mask + | TP_ACPI_HKEY_BRGHTUP_MASK + | TP_ACPI_HKEY_BRGHTDWN_MASK);; return 0; } @@ -6322,6 +6334,9 @@ static int brightness_write(char *buf) * Doing it this way makes the syscall restartable in case of EINTR */ rc = brightness_set(level); + if (!rc && ibm_backlight_device) + backlight_force_update(ibm_backlight_device, + BACKLIGHT_UPDATE_SYSFS); return (rc == -EINTR)? -ERESTARTSYS : rc; } @@ -7721,6 +7736,13 @@ static struct ibm_struct fan_driver_data = { */ static void tpacpi_driver_event(const unsigned int hkey_event) { + if (ibm_backlight_device) { + switch (hkey_event) { + case TP_HKEY_EV_BRGHT_UP: + case TP_HKEY_EV_BRGHT_DOWN: + tpacpi_brightness_notify_change(); + } + } } -- cgit v0.10.2 From 9905a43b2d563e6f89e4c63c4278ada03f2ebb14 Mon Sep 17 00:00:00 2001 From: Emese Revfy Date: Mon, 14 Dec 2009 00:58:57 +0100 Subject: backlight: Constify struct backlight_ops Signed-off-by: Emese Revfy Signed-off-by: Richard Purdie diff --git a/drivers/video/backlight/adp5520_bl.c b/drivers/video/backlight/adp5520_bl.c index 4c10edecf..86d95c22 100644 --- a/drivers/video/backlight/adp5520_bl.c +++ b/drivers/video/backlight/adp5520_bl.c @@ -85,7 +85,7 @@ static int adp5520_bl_get_brightness(struct backlight_device *bl) return error ? data->current_brightness : reg_val; } -static struct backlight_ops adp5520_bl_ops = { +static const struct backlight_ops adp5520_bl_ops = { .update_status = adp5520_bl_update_status, .get_brightness = adp5520_bl_get_brightness, }; diff --git a/drivers/video/backlight/adx_bl.c b/drivers/video/backlight/adx_bl.c index 2c3bdfc..d769b0b 100644 --- a/drivers/video/backlight/adx_bl.c +++ b/drivers/video/backlight/adx_bl.c @@ -61,7 +61,7 @@ static int adx_backlight_check_fb(struct fb_info *fb) return 1; } -static struct backlight_ops adx_backlight_ops = { +static const struct backlight_ops adx_backlight_ops = { .options = 0, .update_status = adx_backlight_update_status, .get_brightness = adx_backlight_get_brightness, diff --git a/drivers/video/backlight/atmel-pwm-bl.c b/drivers/video/backlight/atmel-pwm-bl.c index 2cf7ba5..f625ffc 100644 --- a/drivers/video/backlight/atmel-pwm-bl.c +++ b/drivers/video/backlight/atmel-pwm-bl.c @@ -113,7 +113,7 @@ static int atmel_pwm_bl_init_pwm(struct atmel_pwm_bl *pwmbl) return pwm_channel_enable(&pwmbl->pwmc); } -static struct backlight_ops atmel_pwm_bl_ops = { +static const struct backlight_ops atmel_pwm_bl_ops = { .get_brightness = atmel_pwm_bl_get_intensity, .update_status = atmel_pwm_bl_set_intensity, }; diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c index 6615ac7..18829cf 100644 --- a/drivers/video/backlight/backlight.c +++ b/drivers/video/backlight/backlight.c @@ -269,7 +269,7 @@ EXPORT_SYMBOL(backlight_force_update); * ERR_PTR() or a pointer to the newly allocated device. */ struct backlight_device *backlight_device_register(const char *name, - struct device *parent, void *devdata, struct backlight_ops *ops) + struct device *parent, void *devdata, const struct backlight_ops *ops) { struct backlight_device *new_bd; int rc; diff --git a/drivers/video/backlight/corgi_lcd.c b/drivers/video/backlight/corgi_lcd.c index 9677494..b4bcf80 100644 --- a/drivers/video/backlight/corgi_lcd.c +++ b/drivers/video/backlight/corgi_lcd.c @@ -451,7 +451,7 @@ void corgi_lcd_limit_intensity(int limit) } EXPORT_SYMBOL(corgi_lcd_limit_intensity); -static struct backlight_ops corgi_bl_ops = { +static const struct backlight_ops corgi_bl_ops = { .get_brightness = corgi_bl_get_intensity, .update_status = corgi_bl_update_status, }; diff --git a/drivers/video/backlight/cr_bllcd.c b/drivers/video/backlight/cr_bllcd.c index b9fe62b..2914bf1 100644 --- a/drivers/video/backlight/cr_bllcd.c +++ b/drivers/video/backlight/cr_bllcd.c @@ -108,7 +108,7 @@ static int cr_backlight_get_intensity(struct backlight_device *bd) return intensity; } -static struct backlight_ops cr_backlight_ops = { +static const struct backlight_ops cr_backlight_ops = { .get_brightness = cr_backlight_get_intensity, .update_status = cr_backlight_set_intensity, }; diff --git a/drivers/video/backlight/da903x_bl.c b/drivers/video/backlight/da903x_bl.c index f2d76da..74cdc64 100644 --- a/drivers/video/backlight/da903x_bl.c +++ b/drivers/video/backlight/da903x_bl.c @@ -95,7 +95,7 @@ static int da903x_backlight_get_brightness(struct backlight_device *bl) return data->current_brightness; } -static struct backlight_ops da903x_backlight_ops = { +static const struct backlight_ops da903x_backlight_ops = { .update_status = da903x_backlight_update_status, .get_brightness = da903x_backlight_get_brightness, }; diff --git a/drivers/video/backlight/generic_bl.c b/drivers/video/backlight/generic_bl.c index 6d27f62..e6d348e 100644 --- a/drivers/video/backlight/generic_bl.c +++ b/drivers/video/backlight/generic_bl.c @@ -70,7 +70,7 @@ void corgibl_limit_intensity(int limit) } EXPORT_SYMBOL(corgibl_limit_intensity); -static struct backlight_ops genericbl_ops = { +static const struct backlight_ops genericbl_ops = { .options = BL_CORE_SUSPENDRESUME, .get_brightness = genericbl_get_intensity, .update_status = genericbl_send_intensity, diff --git a/drivers/video/backlight/hp680_bl.c b/drivers/video/backlight/hp680_bl.c index 7fb4eef..f7cc528 100644 --- a/drivers/video/backlight/hp680_bl.c +++ b/drivers/video/backlight/hp680_bl.c @@ -98,7 +98,7 @@ static int hp680bl_get_intensity(struct backlight_device *bd) return current_intensity; } -static struct backlight_ops hp680bl_ops = { +static const struct backlight_ops hp680bl_ops = { .get_brightness = hp680bl_get_intensity, .update_status = hp680bl_set_intensity, }; diff --git a/drivers/video/backlight/jornada720_bl.c b/drivers/video/backlight/jornada720_bl.c index 7aed256..db9071f 100644 --- a/drivers/video/backlight/jornada720_bl.c +++ b/drivers/video/backlight/jornada720_bl.c @@ -93,7 +93,7 @@ out: return ret; } -static struct backlight_ops jornada_bl_ops = { +static const struct backlight_ops jornada_bl_ops = { .get_brightness = jornada_bl_get_brightness, .update_status = jornada_bl_update_status, .options = BL_CORE_SUSPENDRESUME, diff --git a/drivers/video/backlight/kb3886_bl.c b/drivers/video/backlight/kb3886_bl.c index a38fda1..939e7b8 100644 --- a/drivers/video/backlight/kb3886_bl.c +++ b/drivers/video/backlight/kb3886_bl.c @@ -134,7 +134,7 @@ static int kb3886bl_get_intensity(struct backlight_device *bd) return kb3886bl_intensity; } -static struct backlight_ops kb3886bl_ops = { +static const struct backlight_ops kb3886bl_ops = { .get_brightness = kb3886bl_get_intensity, .update_status = kb3886bl_send_intensity, }; diff --git a/drivers/video/backlight/locomolcd.c b/drivers/video/backlight/locomolcd.c index 6b488b8..00a9591 100644 --- a/drivers/video/backlight/locomolcd.c +++ b/drivers/video/backlight/locomolcd.c @@ -141,7 +141,7 @@ static int locomolcd_get_intensity(struct backlight_device *bd) return current_intensity; } -static struct backlight_ops locomobl_data = { +static const struct backlight_ops locomobl_data = { .get_brightness = locomolcd_get_intensity, .update_status = locomolcd_set_intensity, }; diff --git a/drivers/video/backlight/mbp_nvidia_bl.c b/drivers/video/backlight/mbp_nvidia_bl.c index 9edb8d7..5812468 100644 --- a/drivers/video/backlight/mbp_nvidia_bl.c +++ b/drivers/video/backlight/mbp_nvidia_bl.c @@ -33,7 +33,7 @@ struct dmi_match_data { unsigned long iostart; unsigned long iolen; /* Backlight operations structure. */ - struct backlight_ops backlight_ops; + const struct backlight_ops backlight_ops; }; /* Module parameters. */ diff --git a/drivers/video/backlight/omap1_bl.c b/drivers/video/backlight/omap1_bl.c index 8693e5f..409ca96 100644 --- a/drivers/video/backlight/omap1_bl.c +++ b/drivers/video/backlight/omap1_bl.c @@ -125,7 +125,7 @@ static int omapbl_get_intensity(struct backlight_device *dev) return bl->current_intensity; } -static struct backlight_ops omapbl_ops = { +static const struct backlight_ops omapbl_ops = { .get_brightness = omapbl_get_intensity, .update_status = omapbl_update_status, }; diff --git a/drivers/video/backlight/progear_bl.c b/drivers/video/backlight/progear_bl.c index 9edaf24f..075786e 100644 --- a/drivers/video/backlight/progear_bl.c +++ b/drivers/video/backlight/progear_bl.c @@ -54,7 +54,7 @@ static int progearbl_get_intensity(struct backlight_device *bd) return intensity - HW_LEVEL_MIN; } -static struct backlight_ops progearbl_ops = { +static const struct backlight_ops progearbl_ops = { .get_brightness = progearbl_get_intensity, .update_status = progearbl_set_intensity, }; diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c index 8871662..df9e0b3 100644 --- a/drivers/video/backlight/pwm_bl.c +++ b/drivers/video/backlight/pwm_bl.c @@ -56,7 +56,7 @@ static int pwm_backlight_get_brightness(struct backlight_device *bl) return bl->props.brightness; } -static struct backlight_ops pwm_backlight_ops = { +static const struct backlight_ops pwm_backlight_ops = { .update_status = pwm_backlight_update_status, .get_brightness = pwm_backlight_get_brightness, }; diff --git a/drivers/video/backlight/tosa_bl.c b/drivers/video/backlight/tosa_bl.c index 43edbad..e14ce4d 100644 --- a/drivers/video/backlight/tosa_bl.c +++ b/drivers/video/backlight/tosa_bl.c @@ -72,7 +72,7 @@ static int tosa_bl_get_brightness(struct backlight_device *dev) return props->brightness; } -static struct backlight_ops bl_ops = { +static const struct backlight_ops bl_ops = { .get_brightness = tosa_bl_get_brightness, .update_status = tosa_bl_update_status, }; diff --git a/drivers/video/backlight/wm831x_bl.c b/drivers/video/backlight/wm831x_bl.c index 467bdb7..e32add3 100644 --- a/drivers/video/backlight/wm831x_bl.c +++ b/drivers/video/backlight/wm831x_bl.c @@ -112,7 +112,7 @@ static int wm831x_backlight_get_brightness(struct backlight_device *bl) return data->current_brightness; } -static struct backlight_ops wm831x_backlight_ops = { +static const struct backlight_ops wm831x_backlight_ops = { .options = BL_CORE_SUSPENDRESUME, .update_status = wm831x_backlight_update_status, .get_brightness = wm831x_backlight_get_brightness, diff --git a/include/linux/backlight.h b/include/linux/backlight.h index 0f5f578..8c4f884 100644 --- a/include/linux/backlight.h +++ b/include/linux/backlight.h @@ -36,18 +36,18 @@ struct backlight_device; struct fb_info; struct backlight_ops { - unsigned int options; + const unsigned int options; #define BL_CORE_SUSPENDRESUME (1 << 0) /* Notify the backlight driver some property has changed */ - int (*update_status)(struct backlight_device *); + int (* const update_status)(struct backlight_device *); /* Return the current backlight brightness (accounting for power, fb_blank etc.) */ - int (*get_brightness)(struct backlight_device *); + int (* const get_brightness)(struct backlight_device *); /* Check if given framebuffer device is the one bound to this backlight; return 0 if not, !=0 if it is. If NULL, backlight always matches the fb. */ - int (*check_fb)(struct fb_info *); + int (* const check_fb)(struct fb_info *); }; /* This structure defines all the properties of a backlight */ @@ -86,7 +86,7 @@ struct backlight_device { registered this device has been unloaded, and if class_get_devdata() points to something in the body of that driver, it is also invalid. */ struct mutex ops_lock; - struct backlight_ops *ops; + const struct backlight_ops *ops; /* The framebuffer notifier block */ struct notifier_block fb_notif; @@ -103,7 +103,7 @@ static inline void backlight_update_status(struct backlight_device *bd) } extern struct backlight_device *backlight_device_register(const char *name, - struct device *dev, void *devdata, struct backlight_ops *ops); + struct device *dev, void *devdata, const struct backlight_ops *ops); extern void backlight_device_unregister(struct backlight_device *bd); extern void backlight_force_update(struct backlight_device *bd, enum backlight_update_reason reason); -- cgit v0.10.2 From 75e874c698bf7aeed005acd74d0fb13c47124939 Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Wed, 16 Dec 2009 21:35:52 +0800 Subject: [ARM] pxa: fix no reference of cpu_is_pxa25x() in devices.c Signed-off-by: Eric Miao diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c index d4cc41d..8e10db1 100644 --- a/arch/arm/mach-pxa/devices.c +++ b/arch/arm/mach-pxa/devices.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include -- cgit v0.10.2 From 75b46c1321785c29cfbc4f839b6dc031428734ad Mon Sep 17 00:00:00 2001 From: Jon Smirl Date: Tue, 15 Dec 2009 20:53:44 -0500 Subject: ASoC: Fix disable of SPDIF on STAC9766 codec Change code so that switching to playing music through the analog output disables SPDIF out instead of disabling it when stream ends. Signed-off-by: Jon Smirl Acked-by: Mark Brown diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c index bbc72c2..81b8c9d 100644 --- a/sound/soc/codecs/stac9766.c +++ b/sound/soc/codecs/stac9766.c @@ -191,6 +191,7 @@ static int ac97_analog_prepare(struct snd_pcm_substream *substream, vra = stac9766_ac97_read(codec, AC97_EXTENDED_STATUS); vra |= 0x1; /* enable variable rate audio */ + vra &= ~0x4; /* disable SPDIF output */ stac9766_ac97_write(codec, AC97_EXTENDED_STATUS, vra); @@ -221,22 +222,6 @@ static int ac97_digital_prepare(struct snd_pcm_substream *substream, return stac9766_ac97_write(codec, reg, runtime->rate); } -static int ac97_digital_trigger(struct snd_pcm_substream *substream, - int cmd, struct snd_soc_dai *dai) -{ - struct snd_soc_codec *codec = dai->codec; - unsigned short vra; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_STOP: - vra = stac9766_ac97_read(codec, AC97_EXTENDED_STATUS); - vra &= !0x04; - stac9766_ac97_write(codec, AC97_EXTENDED_STATUS, vra); - break; - } - return 0; -} - static int stac9766_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { @@ -315,7 +300,6 @@ static struct snd_soc_dai_ops stac9766_dai_ops_analog = { static struct snd_soc_dai_ops stac9766_dai_ops_digital = { .prepare = ac97_digital_prepare, - .trigger = ac97_digital_trigger, }; struct snd_soc_dai stac9766_dai[] = { -- cgit v0.10.2 From 96b47b65594fe2365f73aede060cb5203561fed3 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 15 Dec 2009 17:50:00 +0100 Subject: drm/i915: fix order of fence release wrt flushing i915_gem_object_unbind had the ordering wrong. The other user, i915_gem_object_put_fence_reg already has the correct ordering. Results was usually corrupted pixmaps, especially garbled font glyphs after a suspend/resume (because this evicts everything). I'm still waiting for the feedback from the bug-reporters, but because this obviously fixes a bug (at least for me) I'm already submitting it. Bugzilla: http://bugs.freedesktop.org/show_bug.cgi?id=25406 Signed-off-by: Daniel Vetter Signed-off-by: Eric Anholt CC: stable@kernel.org diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 8c463cf..9e81a0d 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2021,9 +2021,6 @@ i915_gem_object_unbind(struct drm_gem_object *obj) /* blow away mappings if mapped through GTT */ i915_gem_release_mmap(obj); - if (obj_priv->fence_reg != I915_FENCE_REG_NONE) - i915_gem_clear_fence_reg(obj); - /* Move the object to the CPU domain to ensure that * any possible CPU writes while it's not in the GTT * are flushed when we go to remap it. This will @@ -2039,6 +2036,10 @@ i915_gem_object_unbind(struct drm_gem_object *obj) BUG_ON(obj_priv->active); + /* release the fence reg _after_ flushing */ + if (obj_priv->fence_reg != I915_FENCE_REG_NONE) + i915_gem_clear_fence_reg(obj); + if (obj_priv->agp_mem != NULL) { drm_unbind_agp(obj_priv->agp_mem); drm_free_agp(obj_priv->agp_mem, obj->size / PAGE_SIZE); -- cgit v0.10.2 From 11ba159288f1bfc1a475c994e598f5fe423fde9d Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Tue, 15 Dec 2009 13:55:24 -0500 Subject: drm/i915: Don't check for lid presence when detecting LVDS Checking for the presence of a lid in order to validate whether or not an LVDS display exists fails on some development platforms that implement a lid device but allow the LVDS to be disabled. The VBT is correctly updated, but Linux assumes that an LVDS is still present and lies to userspace. Remove the lid check and trust the VBT. Signed-off-by: Matthew Garrett Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 3118ce2..539d97e 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -854,65 +854,6 @@ static const struct dmi_system_id intel_no_lvds[] = { { } /* terminating entry */ }; -#ifdef CONFIG_ACPI -/* - * check_lid_device -- check whether @handle is an ACPI LID device. - * @handle: ACPI device handle - * @level : depth in the ACPI namespace tree - * @context: the number of LID device when we find the device - * @rv: a return value to fill if desired (Not use) - */ -static acpi_status -check_lid_device(acpi_handle handle, u32 level, void *context, - void **return_value) -{ - struct acpi_device *acpi_dev; - int *lid_present = context; - - acpi_dev = NULL; - /* Get the acpi device for device handle */ - if (acpi_bus_get_device(handle, &acpi_dev) || !acpi_dev) { - /* If there is no ACPI device for handle, return */ - return AE_OK; - } - - if (!strncmp(acpi_device_hid(acpi_dev), "PNP0C0D", 7)) - *lid_present = 1; - - return AE_OK; -} - -/** - * check whether there exists the ACPI LID device by enumerating the ACPI - * device tree. - */ -static int intel_lid_present(void) -{ - int lid_present = 0; - - if (acpi_disabled) { - /* If ACPI is disabled, there is no ACPI device tree to - * check, so assume the LID device would have been present. - */ - return 1; - } - - acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, - check_lid_device, NULL, &lid_present, NULL); - - return lid_present; -} -#else -static int intel_lid_present(void) -{ - /* In the absence of ACPI built in, assume that the LID device would - * have been present. - */ - return 1; -} -#endif - /** * intel_find_lvds_downclock - find the reduced downclock for LVDS in EDID * @dev: drm device @@ -1031,12 +972,8 @@ void intel_lvds_init(struct drm_device *dev) if (dmi_check_system(intel_no_lvds)) return; - /* - * Assume LVDS is present if there's an ACPI lid device or if the - * device is present in the VBT. - */ - if (!lvds_is_present_in_vbt(dev) && !intel_lid_present()) { - DRM_DEBUG_KMS("LVDS is not present in VBT and no lid detected\n"); + if (!lvds_is_present_in_vbt(dev)) { + DRM_DEBUG_KMS("LVDS is not present in VBT\n"); return; } -- cgit v0.10.2 From cbda12d77ea590082edb6d30bd342a67ebc459e0 Mon Sep 17 00:00:00 2001 From: Zhenyu Wang Date: Wed, 16 Dec 2009 13:36:10 +0800 Subject: drm/i915: implement new pm ops for i915 One problem in i915 hibernate with current legacy pci pm ops is that after we do freeze, we'll be forced to do resume once again, which re-init some resources and do modesetting again, that is unnecessary for hibernate. This patch trys to bypass that. We can't resolve this within legacy pm framework, but can do it easily with new pm ops. Suspend (S3) process has also been kept without change. Signed-off-by: Zhenyu Wang Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 2fa2178..6978a22 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -284,6 +284,52 @@ i915_pci_resume(struct pci_dev *pdev) return i915_resume(dev); } +static int +i915_pm_suspend(struct device *dev) +{ + return i915_pci_suspend(to_pci_dev(dev), PMSG_SUSPEND); +} + +static int +i915_pm_resume(struct device *dev) +{ + return i915_pci_resume(to_pci_dev(dev)); +} + +static int +i915_pm_freeze(struct device *dev) +{ + return i915_pci_suspend(to_pci_dev(dev), PMSG_FREEZE); +} + +static int +i915_pm_thaw(struct device *dev) +{ + /* thaw during hibernate, do nothing! */ + return 0; +} + +static int +i915_pm_poweroff(struct device *dev) +{ + return i915_pci_suspend(to_pci_dev(dev), PMSG_HIBERNATE); +} + +static int +i915_pm_restore(struct device *dev) +{ + return i915_pci_resume(to_pci_dev(dev)); +} + +const struct dev_pm_ops i915_pm_ops = { + .suspend = i915_pm_suspend, + .resume = i915_pm_resume, + .freeze = i915_pm_freeze, + .thaw = i915_pm_thaw, + .poweroff = i915_pm_poweroff, + .restore = i915_pm_restore, +}; + static struct vm_operations_struct i915_gem_vm_ops = { .fault = i915_gem_fault, .open = drm_gem_vm_open, @@ -303,8 +349,6 @@ static struct drm_driver driver = { .lastclose = i915_driver_lastclose, .preclose = i915_driver_preclose, .postclose = i915_driver_postclose, - .suspend = i915_suspend, - .resume = i915_resume, .device_is_agp = i915_driver_device_is_agp, .enable_vblank = i915_enable_vblank, .disable_vblank = i915_disable_vblank, @@ -344,10 +388,7 @@ static struct drm_driver driver = { .id_table = pciidlist, .probe = i915_pci_probe, .remove = i915_pci_remove, -#ifdef CONFIG_PM - .resume = i915_pci_resume, - .suspend = i915_pci_suspend, -#endif + .driver.pm = &i915_pm_ops, }, .name = DRIVER_NAME, -- cgit v0.10.2 From 0ad3dc3af8ba028368263b190a7a270f8d5cf5ae Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 4 Dec 2009 00:36:09 -0800 Subject: tc1100-wmi - switch to using attribute group Sysfs attribute group takes care of proper creation of a set of attributes and implements proper error unwinding so the driver does not have to do it. Signed-off-by: Dmitry Torokhov Signed-off-by: Len Brown diff --git a/drivers/platform/x86/tc1100-wmi.c b/drivers/platform/x86/tc1100-wmi.c index 4416600..0d53d51 100644 --- a/drivers/platform/x86/tc1100-wmi.c +++ b/drivers/platform/x86/tc1100-wmi.c @@ -183,30 +183,15 @@ static DEVICE_ATTR(value, S_IWUGO | S_IRUGO | S_IWUSR, \ show_set_bool(wireless, TC1100_INSTANCE_WIRELESS); show_set_bool(jogdial, TC1100_INSTANCE_JOGDIAL); -static void remove_fs(void) -{ - device_remove_file(&tc1100_device->dev, &dev_attr_wireless); - device_remove_file(&tc1100_device->dev, &dev_attr_jogdial); -} - -static int add_fs(void) -{ - int ret; - - ret = device_create_file(&tc1100_device->dev, &dev_attr_wireless); - if (ret) - goto add_sysfs_error; - - ret = device_create_file(&tc1100_device->dev, &dev_attr_jogdial); - if (ret) - goto add_sysfs_error; - - return ret; +static struct attribute *tc1100_attributes[] = { + &dev_attr_wireless.attr, + &dev_attr_jogdial.attr, + NULL +}; -add_sysfs_error: - remove_fs(); - return ret; -} +static struct attribute_group tc1100_attribute_group = { + .attrs = tc1100_attributes, +}; /* -------------------------------------------------------------------------- Driver Model @@ -214,16 +199,14 @@ add_sysfs_error: static int tc1100_probe(struct platform_device *device) { - int result = 0; - - result = add_fs(); - return result; + return sysfs_create_group(&device->dev.kobj, &tc1100_attribute_group); } static int tc1100_remove(struct platform_device *device) { - remove_fs(); + sysfs_remove_group(&device->dev.kobj, &tc1100_attribute_group); + return 0; } -- cgit v0.10.2 From 9634a627b330fcc7cdca25df4d7853ca9c7745de Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 4 Dec 2009 00:36:15 -0800 Subject: tc1100-wmi - add error handling for device registration Any of the platform API functions can fail; driver should be prepared to handle such failures. Also: - changed to platform_driver_probe() since the device is created right there with the driver; - added __devexit annotation to remove method; - fixed memory leak on module unload - named platform_device_del() is not enough to free platform device, need platform_device_unregister(). Signed-off-by: Dmitry Torokhov Signed-off-by: Len Brown diff --git a/drivers/platform/x86/tc1100-wmi.c b/drivers/platform/x86/tc1100-wmi.c index 0d53d51..fa2995b 100644 --- a/drivers/platform/x86/tc1100-wmi.c +++ b/drivers/platform/x86/tc1100-wmi.c @@ -47,22 +47,6 @@ MODULE_DESCRIPTION("HP Compaq TC1100 Tablet WMI Extras"); MODULE_LICENSE("GPL"); MODULE_ALIAS("wmi:C364AC71-36DB-495A-8494-B439D472A505"); -static int tc1100_probe(struct platform_device *device); -static int tc1100_remove(struct platform_device *device); -static int tc1100_suspend(struct platform_device *device, pm_message_t state); -static int tc1100_resume(struct platform_device *device); - -static struct platform_driver tc1100_driver = { - .driver = { - .name = "tc1100-wmi", - .owner = THIS_MODULE, - }, - .probe = tc1100_probe, - .remove = tc1100_remove, - .suspend = tc1100_suspend, - .resume = tc1100_resume, -}; - static struct platform_device *tc1100_device; struct tc1100_data { @@ -197,13 +181,13 @@ static struct attribute_group tc1100_attribute_group = { Driver Model -------------------------------------------------------------------------- */ -static int tc1100_probe(struct platform_device *device) +static int __init tc1100_probe(struct platform_device *device) { return sysfs_create_group(&device->dev.kobj, &tc1100_attribute_group); } -static int tc1100_remove(struct platform_device *device) +static int __devexit tc1100_remove(struct platform_device *device) { sysfs_remove_group(&device->dev.kobj, &tc1100_attribute_group); @@ -240,31 +224,49 @@ static int tc1100_resume(struct platform_device *dev) return ret; } +static struct platform_driver tc1100_driver = { + .driver = { + .name = "tc1100-wmi", + .owner = THIS_MODULE, + }, + .remove = __devexit_p(tc1100_remove), + .suspend = tc1100_suspend, + .resume = tc1100_resume, +}; + static int __init tc1100_init(void) { - int result = 0; + int error; if (!wmi_has_guid(GUID)) return -ENODEV; - result = platform_driver_register(&tc1100_driver); - if (result) - return result; - tc1100_device = platform_device_alloc("tc1100-wmi", -1); - platform_device_add(tc1100_device); + if (!tc1100_device) + return -ENOMEM; + + error = platform_device_add(tc1100_device); + if (error) + goto err_device_put; + + error = platform_driver_probe(&tc1100_driver, tc1100_probe); + if (error) + goto err_device_del; printk(TC1100_INFO "HP Compaq TC1100 Tablet WMI Extras loaded\n"); + return 0; - return result; + err_device_del: + platform_device_del(tc1100_device); + err_device_put: + platform_device_put(tc1100_device); + return error; } static void __exit tc1100_exit(void) { - platform_device_del(tc1100_device); + platform_device_unregister(tc1100_device); platform_driver_unregister(&tc1100_driver); - - printk(TC1100_INFO "HP Compaq TC1100 Tablet WMI Extras unloaded\n"); } module_init(tc1100_init); -- cgit v0.10.2 From 8e698a3c47887fe5aa5e2252c27bb6ff416a07e4 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 4 Dec 2009 00:36:20 -0800 Subject: tc1100-wmi - switch to using dev_pm_ops Also guard PM operations with CONFIG_PM. Signed-off-by: Dmitry Torokhov Signed-off-by: Len Brown diff --git a/drivers/platform/x86/tc1100-wmi.c b/drivers/platform/x86/tc1100-wmi.c index fa2995b..dd33b51 100644 --- a/drivers/platform/x86/tc1100-wmi.c +++ b/drivers/platform/x86/tc1100-wmi.c @@ -194,7 +194,8 @@ static int __devexit tc1100_remove(struct platform_device *device) return 0; } -static int tc1100_suspend(struct platform_device *dev, pm_message_t state) +#ifdef CONFIG_PM +static int tc1100_suspend(struct device *dev) { int ret; @@ -206,10 +207,10 @@ static int tc1100_suspend(struct platform_device *dev, pm_message_t state) if (ret) return ret; - return ret; + return 0; } -static int tc1100_resume(struct platform_device *dev) +static int tc1100_resume(struct device *dev) { int ret; @@ -221,17 +222,26 @@ static int tc1100_resume(struct platform_device *dev) if (ret) return ret; - return ret; + return 0; } +static const struct dev_pm_ops tc1100_pm_ops = { + .suspend = tc1100_suspend, + .resume = tc1100_resume, + .freeze = tc1100_suspend, + .restore = tc1100_resume, +}; +#endif + static struct platform_driver tc1100_driver = { .driver = { .name = "tc1100-wmi", .owner = THIS_MODULE, +#ifdef CONFIG_PM + .pm = &tc1100_pm_ops, +#endif }, .remove = __devexit_p(tc1100_remove), - .suspend = tc1100_suspend, - .resume = tc1100_resume, }; static int __init tc1100_init(void) -- cgit v0.10.2 From 933b0618d8b2a59c7a0742e43836544e02f1e9bd Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 16 Dec 2009 18:04:31 +0100 Subject: sched: Mark boot-cpu active before smp_init() A UP machine has 1 active cpu, not having the boot-cpu in the active map when starting the scheduler confuses things. Signed-off-by: Peter Zijlstra Cc: Mike Galbraith LKML-Reference: <20091216170517.423469527@chello.nl> Signed-off-by: Ingo Molnar diff --git a/init/main.c b/init/main.c index c3db4a9..dac44a9 100644 --- a/init/main.c +++ b/init/main.c @@ -369,12 +369,6 @@ static void __init smp_init(void) { unsigned int cpu; - /* - * Set up the current CPU as possible to migrate to. - * The other ones will be done by cpu_up/cpu_down() - */ - set_cpu_active(smp_processor_id(), true); - /* FIXME: This should be done in userspace --RR */ for_each_present_cpu(cpu) { if (num_online_cpus() >= setup_max_cpus) @@ -486,6 +480,7 @@ static void __init boot_cpu_init(void) int cpu = smp_processor_id(); /* Mark the boot cpu "present", "online" etc for SMP and UP case */ set_cpu_online(cpu, true); + set_cpu_active(cpu, true); set_cpu_present(cpu, true); set_cpu_possible(cpu, true); } -- cgit v0.10.2 From 9ee349ad6d326df3633d43f54202427295999c47 Mon Sep 17 00:00:00 2001 From: Xiaotian Feng Date: Wed, 16 Dec 2009 18:04:32 +0100 Subject: sched: Fix set_cpu_active() in cpu_down() Sachin found cpu hotplug test failures on powerpc, which made the kernel hang on his POWER box. The problem is that we fail to re-activate a cpu when a hot-unplug fails. Fix this by moving the de-activation into _cpu_down after doing the initial checks. Remove the synchronize_sched() calls and rely on those implied by rebuilding the sched domains using the new mask. Reported-by: Sachin Sant Signed-off-by: Xiaotian Feng Tested-by: Sachin Sant Signed-off-by: Peter Zijlstra Cc: Mike Galbraith LKML-Reference: <20091216170517.500272612@chello.nl> Signed-off-by: Ingo Molnar diff --git a/kernel/cpu.c b/kernel/cpu.c index 291ac58..1c8ddd6 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c @@ -209,6 +209,7 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen) return -ENOMEM; cpu_hotplug_begin(); + set_cpu_active(cpu, false); err = __raw_notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE | mod, hcpu, -1, &nr_calls); if (err == NOTIFY_BAD) { @@ -280,18 +281,6 @@ int __ref cpu_down(unsigned int cpu) goto out; } - set_cpu_active(cpu, false); - - /* - * Make sure the all cpus did the reschedule and are not - * using stale version of the cpu_active_mask. - * This is not strictly necessary becuase stop_machine() - * that we run down the line already provides the required - * synchronization. But it's really a side effect and we do not - * want to depend on the innards of the stop_machine here. - */ - synchronize_sched(); - err = _cpu_down(cpu, 0); out: @@ -382,19 +371,12 @@ int disable_nonboot_cpus(void) return error; cpu_maps_update_begin(); first_cpu = cpumask_first(cpu_online_mask); - /* We take down all of the non-boot CPUs in one shot to avoid races + /* + * We take down all of the non-boot CPUs in one shot to avoid races * with the userspace trying to use the CPU hotplug at the same time */ cpumask_clear(frozen_cpus); - for_each_online_cpu(cpu) { - if (cpu == first_cpu) - continue; - set_cpu_active(cpu, false); - } - - synchronize_sched(); - printk("Disabling non-boot CPUs ...\n"); for_each_online_cpu(cpu) { if (cpu == first_cpu) -- cgit v0.10.2 From e6c8fba7771563b2f3dfb96a78f36ec17e15bdf0 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 16 Dec 2009 18:04:33 +0100 Subject: sched: Fix task_hot() test order Make sure not to access sched_fair fields before verifying it is indeed a sched_fair task. Signed-off-by: Peter Zijlstra Cc: Mike Galbraith CC: stable@kernel.org LKML-Reference: <20091216170517.577998058@chello.nl> Signed-off-by: Ingo Molnar diff --git a/kernel/sched.c b/kernel/sched.c index 9c30858..1d8ca25 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -2046,6 +2046,9 @@ task_hot(struct task_struct *p, u64 now, struct sched_domain *sd) { s64 delta; + if (p->sched_class != &fair_sched_class) + return 0; + /* * Buddy candidates are cache hot: */ @@ -2054,9 +2057,6 @@ task_hot(struct task_struct *p, u64 now, struct sched_domain *sd) &p->se == cfs_rq_of(&p->se)->last)) return 1; - if (p->sched_class != &fair_sched_class) - return 0; - if (sysctl_sched_migration_cost == -1) return 1; if (sysctl_sched_migration_cost == 0) -- cgit v0.10.2 From e4f4288842ee12747e10c354d72be7d424c0b627 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 16 Dec 2009 18:04:34 +0100 Subject: sched: Select_task_rq_fair() must honour SD_LOAD_BALANCE We should skip !SD_LOAD_BALANCE domains. Signed-off-by: Peter Zijlstra Cc: Mike Galbraith LKML-Reference: <20091216170517.653578430@chello.nl> CC: stable@kernel.org Signed-off-by: Ingo Molnar diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index 5bedf6e..ec1d271 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c @@ -1429,6 +1429,9 @@ static int select_task_rq_fair(struct task_struct *p, int sd_flag, int wake_flag } for_each_domain(cpu, tmp) { + if (!(tmp->flags & SD_LOAD_BALANCE)) + continue; + /* * If power savings logic is enabled for a domain, see if we * are not overloaded, if so, don't balance wider. -- cgit v0.10.2 From 06b83b5fbea273672822b6ee93e16781046553ec Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 16 Dec 2009 18:04:35 +0100 Subject: sched: Use TASK_WAKING for fork wakups For later convenience use TASK_WAKING for fresh tasks. Signed-off-by: Peter Zijlstra Cc: Mike Galbraith LKML-Reference: <20091216170517.732561278@chello.nl> Signed-off-by: Ingo Molnar diff --git a/kernel/sched.c b/kernel/sched.c index 1d8ca25..1672823 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -2540,14 +2540,6 @@ static void __sched_fork(struct task_struct *p) #ifdef CONFIG_PREEMPT_NOTIFIERS INIT_HLIST_HEAD(&p->preempt_notifiers); #endif - - /* - * We mark the process as running here, but have not actually - * inserted it onto the runqueue yet. This guarantees that - * nobody will actually run it, and a signal or other external - * event cannot wake it up and insert it on the runqueue either. - */ - p->state = TASK_RUNNING; } /* @@ -2558,6 +2550,12 @@ void sched_fork(struct task_struct *p, int clone_flags) int cpu = get_cpu(); __sched_fork(p); + /* + * We mark the process as waking here. This guarantees that + * nobody will actually run it, and a signal or other external + * event cannot wake it up and insert it on the runqueue either. + */ + p->state = TASK_WAKING; /* * Revert to default priority/policy on fork if requested. @@ -2626,7 +2624,8 @@ void wake_up_new_task(struct task_struct *p, unsigned long clone_flags) struct rq *rq; rq = task_rq_lock(p, &flags); - BUG_ON(p->state != TASK_RUNNING); + BUG_ON(p->state != TASK_WAKING); + p->state = TASK_RUNNING; update_rq_clock(rq); activate_task(rq, p, 0); trace_sched_wakeup_new(rq, p, 1); @@ -6984,6 +6983,7 @@ void __cpuinit init_idle(struct task_struct *idle, int cpu) raw_spin_lock_irqsave(&rq->lock, flags); __sched_fork(idle); + idle->state = TASK_RUNNING; idle->se.exec_start = sched_clock(); cpumask_copy(&idle->cpus_allowed, cpumask_of(cpu)); -- cgit v0.10.2 From e2912009fb7b715728311b0d8fe327a1432b3f79 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 16 Dec 2009 18:04:36 +0100 Subject: sched: Ensure set_task_cpu() is never called on blocked tasks In order to clean up the set_task_cpu() rq dependencies we need to ensure it is never called on blocked tasks because such usage does not pair with consistent rq->lock usage. This puts the migration burden on ttwu(). Furthermore we need to close a race against changing ->cpus_allowed, since select_task_rq() runs with only preemption disabled. For sched_fork() this is safe because the child isn't in the tasklist yet, for wakeup we fix this by synchronizing set_cpus_allowed_ptr() against TASK_WAKING, which leaves sched_exec to be a problem This also closes a hole in (6ad4c1888 sched: Fix balance vs hotplug race) where ->select_task_rq() doesn't validate the result against the sched_domain/root_domain. Signed-off-by: Peter Zijlstra Cc: Mike Galbraith LKML-Reference: <20091216170517.807938893@chello.nl> Signed-off-by: Ingo Molnar diff --git a/kernel/sched.c b/kernel/sched.c index 1672823..33d7965 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -2018,22 +2018,15 @@ static inline void check_class_changed(struct rq *rq, struct task_struct *p, */ void kthread_bind(struct task_struct *p, unsigned int cpu) { - struct rq *rq = cpu_rq(cpu); - unsigned long flags; - /* Must have done schedule() in kthread() before we set_task_cpu */ if (!wait_task_inactive(p, TASK_UNINTERRUPTIBLE)) { WARN_ON(1); return; } - raw_spin_lock_irqsave(&rq->lock, flags); - update_rq_clock(rq); - set_task_cpu(p, cpu); p->cpus_allowed = cpumask_of_cpu(cpu); p->rt.nr_cpus_allowed = 1; p->flags |= PF_THREAD_BOUND; - raw_spin_unlock_irqrestore(&rq->lock, flags); } EXPORT_SYMBOL(kthread_bind); @@ -2074,6 +2067,14 @@ void set_task_cpu(struct task_struct *p, unsigned int new_cpu) struct cfs_rq *old_cfsrq = task_cfs_rq(p), *new_cfsrq = cpu_cfs_rq(old_cfsrq, new_cpu); +#ifdef CONFIG_SCHED_DEBUG + /* + * We should never call set_task_cpu() on a blocked task, + * ttwu() will sort out the placement. + */ + WARN_ON(p->state != TASK_RUNNING && p->state != TASK_WAKING); +#endif + trace_sched_migrate_task(p, new_cpu); if (old_cpu != new_cpu) { @@ -2107,13 +2108,10 @@ migrate_task(struct task_struct *p, int dest_cpu, struct migration_req *req) /* * If the task is not on a runqueue (and not running), then - * it is sufficient to simply update the task's cpu field. + * the next wake-up will properly place the task. */ - if (!p->se.on_rq && !task_running(rq, p)) { - update_rq_clock(rq); - set_task_cpu(p, dest_cpu); + if (!p->se.on_rq && !task_running(rq, p)) return 0; - } init_completion(&req->done); req->task = p; @@ -2319,10 +2317,42 @@ void task_oncpu_function_call(struct task_struct *p, } #ifdef CONFIG_SMP +/* + * Called from: + * + * - fork, @p is stable because it isn't on the tasklist yet + * + * - exec, @p is unstable XXX + * + * - wake-up, we serialize ->cpus_allowed against TASK_WAKING so + * we should be good. + */ static inline int select_task_rq(struct task_struct *p, int sd_flags, int wake_flags) { - return p->sched_class->select_task_rq(p, sd_flags, wake_flags); + int cpu = p->sched_class->select_task_rq(p, sd_flags, wake_flags); + + /* + * In order not to call set_task_cpu() on a blocking task we need + * to rely on ttwu() to place the task on a valid ->cpus_allowed + * cpu. + * + * Since this is common to all placement strategies, this lives here. + * + * [ this allows ->select_task() to simply return task_cpu(p) and + * not worry about this generic constraint ] + */ + if (unlikely(!cpumask_test_cpu(cpu, &p->cpus_allowed) || + !cpu_active(cpu))) { + + cpu = cpumask_any_and(&p->cpus_allowed, cpu_active_mask); + /* + * XXX: race against hot-plug modifying cpu_active_mask + */ + BUG_ON(cpu >= nr_cpu_ids); + } + + return cpu; } #endif @@ -7098,7 +7128,23 @@ int set_cpus_allowed_ptr(struct task_struct *p, const struct cpumask *new_mask) struct rq *rq; int ret = 0; + /* + * Since we rely on wake-ups to migrate sleeping tasks, don't change + * the ->cpus_allowed mask from under waking tasks, which would be + * possible when we change rq->lock in ttwu(), so synchronize against + * TASK_WAKING to avoid that. + */ +again: + while (p->state == TASK_WAKING) + cpu_relax(); + rq = task_rq_lock(p, &flags); + + if (p->state == TASK_WAKING) { + task_rq_unlock(rq, &flags); + goto again; + } + if (!cpumask_intersects(new_mask, cpu_active_mask)) { ret = -EINVAL; goto out; @@ -7154,7 +7200,7 @@ EXPORT_SYMBOL_GPL(set_cpus_allowed_ptr); static int __migrate_task(struct task_struct *p, int src_cpu, int dest_cpu) { struct rq *rq_dest, *rq_src; - int ret = 0, on_rq; + int ret = 0; if (unlikely(!cpu_active(dest_cpu))) return ret; @@ -7170,12 +7216,13 @@ static int __migrate_task(struct task_struct *p, int src_cpu, int dest_cpu) if (!cpumask_test_cpu(dest_cpu, &p->cpus_allowed)) goto fail; - on_rq = p->se.on_rq; - if (on_rq) + /* + * If we're not on a rq, the next wake-up will ensure we're + * placed properly. + */ + if (p->se.on_rq) { deactivate_task(rq_src, p, 0); - - set_task_cpu(p, dest_cpu); - if (on_rq) { + set_task_cpu(p, dest_cpu); activate_task(rq_dest, p, 0); check_preempt_curr(rq_dest, p, 0); } -- cgit v0.10.2 From 3802290628348674985d14914f9bfee7b9084548 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 16 Dec 2009 18:04:37 +0100 Subject: sched: Fix sched_exec() balancing Since we access ->cpus_allowed without holding rq->lock we need a retry loop to validate the result, this comes for near free when we merge sched_migrate_task() into sched_exec() since that already does the needed check. Signed-off-by: Peter Zijlstra Cc: Mike Galbraith LKML-Reference: <20091216170517.884743662@chello.nl> Signed-off-by: Ingo Molnar diff --git a/kernel/sched.c b/kernel/sched.c index 33d7965..63e55ac 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -2322,7 +2322,7 @@ void task_oncpu_function_call(struct task_struct *p, * * - fork, @p is stable because it isn't on the tasklist yet * - * - exec, @p is unstable XXX + * - exec, @p is unstable, retry loop * * - wake-up, we serialize ->cpus_allowed against TASK_WAKING so * we should be good. @@ -3132,21 +3132,36 @@ static void double_rq_unlock(struct rq *rq1, struct rq *rq2) } /* - * If dest_cpu is allowed for this process, migrate the task to it. - * This is accomplished by forcing the cpu_allowed mask to only - * allow dest_cpu, which will force the cpu onto dest_cpu. Then - * the cpu_allowed mask is restored. + * sched_exec - execve() is a valuable balancing opportunity, because at + * this point the task has the smallest effective memory and cache footprint. */ -static void sched_migrate_task(struct task_struct *p, int dest_cpu) +void sched_exec(void) { + struct task_struct *p = current; struct migration_req req; + int dest_cpu, this_cpu; unsigned long flags; struct rq *rq; +again: + this_cpu = get_cpu(); + dest_cpu = select_task_rq(p, SD_BALANCE_EXEC, 0); + if (dest_cpu == this_cpu) { + put_cpu(); + return; + } + rq = task_rq_lock(p, &flags); + put_cpu(); + + /* + * select_task_rq() can race against ->cpus_allowed + */ if (!cpumask_test_cpu(dest_cpu, &p->cpus_allowed) - || unlikely(!cpu_active(dest_cpu))) - goto out; + || unlikely(!cpu_active(dest_cpu))) { + task_rq_unlock(rq, &flags); + goto again; + } /* force the process onto the specified CPU */ if (migrate_task(p, dest_cpu, &req)) { @@ -3161,24 +3176,10 @@ static void sched_migrate_task(struct task_struct *p, int dest_cpu) return; } -out: task_rq_unlock(rq, &flags); } /* - * sched_exec - execve() is a valuable balancing opportunity, because at - * this point the task has the smallest effective memory and cache footprint. - */ -void sched_exec(void) -{ - int new_cpu, this_cpu = get_cpu(); - new_cpu = select_task_rq(current, SD_BALANCE_EXEC, 0); - put_cpu(); - if (new_cpu != this_cpu) - sched_migrate_task(current, new_cpu); -} - -/* * pull_task - move a task from a remote runqueue to the local runqueue. * Both runqueues must be locked. */ -- cgit v0.10.2 From 5da9a0fb673a0ea0a093862f95f6b89b3390c31e Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 16 Dec 2009 18:04:38 +0100 Subject: sched: Fix select_task_rq() vs hotplug issues Since select_task_rq() is now responsible for guaranteeing ->cpus_allowed and cpu_active_mask, we need to verify this. select_task_rq_rt() can blindly return smp_processor_id()/task_cpu() without checking the valid masks, select_task_rq_fair() can do the same in the rare case that all SD_flags are disabled. Signed-off-by: Peter Zijlstra Cc: Mike Galbraith LKML-Reference: <20091216170517.961475466@chello.nl> Signed-off-by: Ingo Molnar diff --git a/kernel/sched.c b/kernel/sched.c index 63e55ac..cc40bda 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -2317,6 +2317,43 @@ void task_oncpu_function_call(struct task_struct *p, } #ifdef CONFIG_SMP +static int select_fallback_rq(int cpu, struct task_struct *p) +{ + int dest_cpu; + const struct cpumask *nodemask = cpumask_of_node(cpu_to_node(cpu)); + + /* Look for allowed, online CPU in same node. */ + for_each_cpu_and(dest_cpu, nodemask, cpu_active_mask) + if (cpumask_test_cpu(dest_cpu, &p->cpus_allowed)) + return dest_cpu; + + /* Any allowed, online CPU? */ + dest_cpu = cpumask_any_and(&p->cpus_allowed, cpu_active_mask); + if (dest_cpu < nr_cpu_ids) + return dest_cpu; + + /* No more Mr. Nice Guy. */ + if (dest_cpu >= nr_cpu_ids) { + rcu_read_lock(); + cpuset_cpus_allowed_locked(p, &p->cpus_allowed); + rcu_read_unlock(); + dest_cpu = cpumask_any_and(cpu_active_mask, &p->cpus_allowed); + + /* + * Don't tell them about moving exiting tasks or + * kernel threads (both mm NULL), since they never + * leave kernel. + */ + if (p->mm && printk_ratelimit()) { + printk(KERN_INFO "process %d (%s) no " + "longer affine to cpu%d\n", + task_pid_nr(p), p->comm, cpu); + } + } + + return dest_cpu; +} + /* * Called from: * @@ -2343,14 +2380,8 @@ int select_task_rq(struct task_struct *p, int sd_flags, int wake_flags) * not worry about this generic constraint ] */ if (unlikely(!cpumask_test_cpu(cpu, &p->cpus_allowed) || - !cpu_active(cpu))) { - - cpu = cpumask_any_and(&p->cpus_allowed, cpu_active_mask); - /* - * XXX: race against hot-plug modifying cpu_active_mask - */ - BUG_ON(cpu >= nr_cpu_ids); - } + !cpu_active(cpu))) + cpu = select_fallback_rq(task_cpu(p), p); return cpu; } @@ -7319,36 +7350,10 @@ static int __migrate_task_irq(struct task_struct *p, int src_cpu, int dest_cpu) static void move_task_off_dead_cpu(int dead_cpu, struct task_struct *p) { int dest_cpu; - const struct cpumask *nodemask = cpumask_of_node(cpu_to_node(dead_cpu)); again: - /* Look for allowed, online CPU in same node. */ - for_each_cpu_and(dest_cpu, nodemask, cpu_active_mask) - if (cpumask_test_cpu(dest_cpu, &p->cpus_allowed)) - goto move; - - /* Any allowed, online CPU? */ - dest_cpu = cpumask_any_and(&p->cpus_allowed, cpu_active_mask); - if (dest_cpu < nr_cpu_ids) - goto move; - - /* No more Mr. Nice Guy. */ - if (dest_cpu >= nr_cpu_ids) { - cpuset_cpus_allowed_locked(p, &p->cpus_allowed); - dest_cpu = cpumask_any_and(cpu_active_mask, &p->cpus_allowed); - - /* - * Don't tell them about moving exiting tasks or - * kernel threads (both mm NULL), since they never - * leave kernel. - */ - if (p->mm && printk_ratelimit()) { - pr_info("process %d (%s) no longer affine to cpu%d\n", - task_pid_nr(p), p->comm, dead_cpu); - } - } + dest_cpu = select_fallback_rq(dead_cpu, p); -move: /* It can have affinity changed while we were choosing. */ if (unlikely(!__migrate_task_irq(p, dead_cpu, dest_cpu))) goto again; -- cgit v0.10.2 From 881232b70b195768a71cd74ff4b4e8ab9502997b Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 16 Dec 2009 18:04:39 +0100 Subject: sched: Move kthread_bind() back to kthread.c Since kthread_bind() lost its dependencies on sched.c, move it back where it came from. Signed-off-by: Peter Zijlstra Cc: Mike Galbraith LKML-Reference: <20091216170518.039524041@chello.nl> Signed-off-by: Ingo Molnar diff --git a/kernel/kthread.c b/kernel/kthread.c index ab7ae57..fbb6222 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c @@ -150,6 +150,29 @@ struct task_struct *kthread_create(int (*threadfn)(void *data), EXPORT_SYMBOL(kthread_create); /** + * kthread_bind - bind a just-created kthread to a cpu. + * @p: thread created by kthread_create(). + * @cpu: cpu (might not be online, must be possible) for @k to run on. + * + * Description: This function is equivalent to set_cpus_allowed(), + * except that @cpu doesn't need to be online, and the thread must be + * stopped (i.e., just returned from kthread_create()). + */ +void kthread_bind(struct task_struct *p, unsigned int cpu) +{ + /* Must have done schedule() in kthread() before we set_task_cpu */ + if (!wait_task_inactive(p, TASK_UNINTERRUPTIBLE)) { + WARN_ON(1); + return; + } + + p->cpus_allowed = cpumask_of_cpu(cpu); + p->rt.nr_cpus_allowed = 1; + p->flags |= PF_THREAD_BOUND; +} +EXPORT_SYMBOL(kthread_bind); + +/** * kthread_stop - stop a thread created by kthread_create(). * @k: thread created by kthread_create(). * diff --git a/kernel/sched.c b/kernel/sched.c index cc40bda..297dc44 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -2004,32 +2004,6 @@ static inline void check_class_changed(struct rq *rq, struct task_struct *p, p->sched_class->prio_changed(rq, p, oldprio, running); } -/** - * kthread_bind - bind a just-created kthread to a cpu. - * @p: thread created by kthread_create(). - * @cpu: cpu (might not be online, must be possible) for @k to run on. - * - * Description: This function is equivalent to set_cpus_allowed(), - * except that @cpu doesn't need to be online, and the thread must be - * stopped (i.e., just returned from kthread_create()). - * - * Function lives here instead of kthread.c because it messes with - * scheduler internals which require locking. - */ -void kthread_bind(struct task_struct *p, unsigned int cpu) -{ - /* Must have done schedule() in kthread() before we set_task_cpu */ - if (!wait_task_inactive(p, TASK_UNINTERRUPTIBLE)) { - WARN_ON(1); - return; - } - - p->cpus_allowed = cpumask_of_cpu(cpu); - p->rt.nr_cpus_allowed = 1; - p->flags |= PF_THREAD_BOUND; -} -EXPORT_SYMBOL(kthread_bind); - #ifdef CONFIG_SMP /* * Is this task likely cache-hot: -- cgit v0.10.2 From efbbd05a595343a413964ad85a2ad359b7b7efbd Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 16 Dec 2009 18:04:40 +0100 Subject: sched: Add pre and post wakeup hooks As will be apparent in the next patch, we need a pre wakeup hook for sched_fair task migration, hence rename the post wakeup hook and one pre wakeup. Signed-off-by: Peter Zijlstra Cc: Mike Galbraith LKML-Reference: <20091216170518.114746117@chello.nl> Signed-off-by: Ingo Molnar diff --git a/include/linux/sched.h b/include/linux/sched.h index 5c858f3..2c9fa1c 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1091,7 +1091,8 @@ struct sched_class { enum cpu_idle_type idle); void (*pre_schedule) (struct rq *this_rq, struct task_struct *task); void (*post_schedule) (struct rq *this_rq); - void (*task_wake_up) (struct rq *this_rq, struct task_struct *task); + void (*task_waking) (struct rq *this_rq, struct task_struct *task); + void (*task_woken) (struct rq *this_rq, struct task_struct *task); void (*set_cpus_allowed)(struct task_struct *p, const struct cpumask *newmask); diff --git a/kernel/sched.c b/kernel/sched.c index 297dc44..6c571bd 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -2412,6 +2412,10 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state, if (task_contributes_to_load(p)) rq->nr_uninterruptible--; p->state = TASK_WAKING; + + if (p->sched_class->task_waking) + p->sched_class->task_waking(rq, p); + __task_rq_unlock(rq); cpu = select_task_rq(p, SD_BALANCE_WAKE, wake_flags); @@ -2475,8 +2479,8 @@ out_running: p->state = TASK_RUNNING; #ifdef CONFIG_SMP - if (p->sched_class->task_wake_up) - p->sched_class->task_wake_up(rq, p); + if (p->sched_class->task_woken) + p->sched_class->task_woken(rq, p); if (unlikely(rq->idle_stamp)) { u64 delta = rq->clock - rq->idle_stamp; @@ -2666,8 +2670,8 @@ void wake_up_new_task(struct task_struct *p, unsigned long clone_flags) trace_sched_wakeup_new(rq, p, 1); check_preempt_curr(rq, p, WF_FORK); #ifdef CONFIG_SMP - if (p->sched_class->task_wake_up) - p->sched_class->task_wake_up(rq, p); + if (p->sched_class->task_woken) + p->sched_class->task_woken(rq, p); #endif task_rq_unlock(rq, &flags); } diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c index d2ea282..f48328a 100644 --- a/kernel/sched_rt.c +++ b/kernel/sched_rt.c @@ -1472,7 +1472,7 @@ static void post_schedule_rt(struct rq *rq) * If we are not running and we are not going to reschedule soon, we should * try to push tasks away now */ -static void task_wake_up_rt(struct rq *rq, struct task_struct *p) +static void task_woken_rt(struct rq *rq, struct task_struct *p) { if (!task_running(rq, p) && !test_tsk_need_resched(rq->curr) && @@ -1753,7 +1753,7 @@ static const struct sched_class rt_sched_class = { .rq_offline = rq_offline_rt, .pre_schedule = pre_schedule_rt, .post_schedule = post_schedule_rt, - .task_wake_up = task_wake_up_rt, + .task_woken = task_woken_rt, .switched_from = switched_from_rt, #endif -- cgit v0.10.2 From 88ec22d3edb72b261f8628226cd543589a6d5e1b Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 16 Dec 2009 18:04:41 +0100 Subject: sched: Remove the cfs_rq dependency from set_task_cpu() In order to remove the cfs_rq dependency from set_task_cpu() we need to ensure the task is cfs_rq invariant for all callsites. The simple approach is to substract cfs_rq->min_vruntime from se->vruntime on dequeue, and add cfs_rq->min_vruntime on enqueue. However, this has the downside of breaking FAIR_SLEEPERS since we loose the old vruntime as we only maintain the relative position. To solve this, we observe that we only migrate runnable tasks, we do this using deactivate_task(.sleep=0) and activate_task(.wakeup=0), therefore we can restrain the min_vruntime invariance to that state. The only other case is wakeup balancing, since we want to maintain the old vruntime we cannot make it relative on dequeue, but since we don't migrate inactive tasks, we can do so right before we activate it again. This is where we need the new pre-wakeup hook, we need to call this while still holding the old rq->lock. We could fold it into ->select_task_rq(), but since that has multiple callsites and would obfuscate the locking requirements, that seems like a fudge. This leaves the fork() case, simply make sure that ->task_fork() leaves the ->vruntime in a relative state. This covers all cases where set_task_cpu() gets called, and ensures it sees a relative vruntime. Signed-off-by: Peter Zijlstra Cc: Mike Galbraith LKML-Reference: <20091216170518.191697025@chello.nl> Signed-off-by: Ingo Molnar diff --git a/include/linux/sched.h b/include/linux/sched.h index 2c9fa1c..973b2b8 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1116,7 +1116,7 @@ struct sched_class { struct task_struct *task); #ifdef CONFIG_FAIR_GROUP_SCHED - void (*moved_group) (struct task_struct *p); + void (*moved_group) (struct task_struct *p, int on_rq); #endif }; diff --git a/kernel/sched.c b/kernel/sched.c index 6c571bd..f92ce63 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -2038,8 +2038,6 @@ task_hot(struct task_struct *p, u64 now, struct sched_domain *sd) void set_task_cpu(struct task_struct *p, unsigned int new_cpu) { int old_cpu = task_cpu(p); - struct cfs_rq *old_cfsrq = task_cfs_rq(p), - *new_cfsrq = cpu_cfs_rq(old_cfsrq, new_cpu); #ifdef CONFIG_SCHED_DEBUG /* @@ -2056,8 +2054,6 @@ void set_task_cpu(struct task_struct *p, unsigned int new_cpu) perf_sw_event(PERF_COUNT_SW_CPU_MIGRATIONS, 1, 1, NULL, 0); } - p->se.vruntime -= old_cfsrq->min_vruntime - - new_cfsrq->min_vruntime; __set_task_cpu(p, new_cpu); } @@ -10102,7 +10098,7 @@ void sched_move_task(struct task_struct *tsk) #ifdef CONFIG_FAIR_GROUP_SCHED if (tsk->sched_class->moved_group) - tsk->sched_class->moved_group(tsk); + tsk->sched_class->moved_group(tsk, on_rq); #endif if (unlikely(running)) diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index ec1d271..42ac3c9 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c @@ -510,6 +510,7 @@ __update_curr(struct cfs_rq *cfs_rq, struct sched_entity *curr, curr->sum_exec_runtime += delta_exec; schedstat_add(cfs_rq, exec_clock, delta_exec); delta_exec_weighted = calc_delta_fair(delta_exec, curr); + curr->vruntime += delta_exec_weighted; update_min_vruntime(cfs_rq); } @@ -765,16 +766,26 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial) se->vruntime = vruntime; } +#define ENQUEUE_WAKEUP 1 +#define ENQUEUE_MIGRATE 2 + static void -enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int wakeup) +enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags) { /* + * Update the normalized vruntime before updating min_vruntime + * through callig update_curr(). + */ + if (!(flags & ENQUEUE_WAKEUP) || (flags & ENQUEUE_MIGRATE)) + se->vruntime += cfs_rq->min_vruntime; + + /* * Update run-time statistics of the 'current'. */ update_curr(cfs_rq); account_entity_enqueue(cfs_rq, se); - if (wakeup) { + if (flags & ENQUEUE_WAKEUP) { place_entity(cfs_rq, se, 0); enqueue_sleeper(cfs_rq, se); } @@ -828,6 +839,14 @@ dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int sleep) __dequeue_entity(cfs_rq, se); account_entity_dequeue(cfs_rq, se); update_min_vruntime(cfs_rq); + + /* + * Normalize the entity after updating the min_vruntime because the + * update can refer to the ->curr item and we need to reflect this + * movement in our normalized position. + */ + if (!sleep) + se->vruntime -= cfs_rq->min_vruntime; } /* @@ -1038,13 +1057,19 @@ static void enqueue_task_fair(struct rq *rq, struct task_struct *p, int wakeup) { struct cfs_rq *cfs_rq; struct sched_entity *se = &p->se; + int flags = 0; + + if (wakeup) + flags |= ENQUEUE_WAKEUP; + if (p->state == TASK_WAKING) + flags |= ENQUEUE_MIGRATE; for_each_sched_entity(se) { if (se->on_rq) break; cfs_rq = cfs_rq_of(se); - enqueue_entity(cfs_rq, se, wakeup); - wakeup = 1; + enqueue_entity(cfs_rq, se, flags); + flags = ENQUEUE_WAKEUP; } hrtick_update(rq); @@ -1120,6 +1145,14 @@ static void yield_task_fair(struct rq *rq) #ifdef CONFIG_SMP +static void task_waking_fair(struct rq *rq, struct task_struct *p) +{ + struct sched_entity *se = &p->se; + struct cfs_rq *cfs_rq = cfs_rq_of(se); + + se->vruntime -= cfs_rq->min_vruntime; +} + #ifdef CONFIG_FAIR_GROUP_SCHED /* * effective_load() calculates the load change as seen from the root_task_group @@ -1978,6 +2011,8 @@ static void task_fork_fair(struct task_struct *p) resched_task(rq->curr); } + se->vruntime -= cfs_rq->min_vruntime; + raw_spin_unlock_irqrestore(&rq->lock, flags); } @@ -2031,12 +2066,13 @@ static void set_curr_task_fair(struct rq *rq) } #ifdef CONFIG_FAIR_GROUP_SCHED -static void moved_group_fair(struct task_struct *p) +static void moved_group_fair(struct task_struct *p, int on_rq) { struct cfs_rq *cfs_rq = task_cfs_rq(p); update_curr(cfs_rq); - place_entity(cfs_rq, &p->se, 1); + if (!on_rq) + place_entity(cfs_rq, &p->se, 1); } #endif @@ -2076,6 +2112,8 @@ static const struct sched_class fair_sched_class = { .move_one_task = move_one_task_fair, .rq_online = rq_online_fair, .rq_offline = rq_offline_fair, + + .task_waking = task_waking_fair, #endif .set_curr_task = set_curr_task_fair, -- cgit v0.10.2 From 738d2be4301007f054541c5c4bf7fb6a361c9b3a Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 16 Dec 2009 18:04:42 +0100 Subject: sched: Simplify set_task_cpu() Rearrange code a bit now that its a simpler function. Signed-off-by: Peter Zijlstra Cc: Mike Galbraith LKML-Reference: <20091216170518.269101883@chello.nl> Signed-off-by: Ingo Molnar diff --git a/kernel/sched.c b/kernel/sched.c index f92ce63..8a2bfd3 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -2034,11 +2034,8 @@ task_hot(struct task_struct *p, u64 now, struct sched_domain *sd) return delta < (s64)sysctl_sched_migration_cost; } - void set_task_cpu(struct task_struct *p, unsigned int new_cpu) { - int old_cpu = task_cpu(p); - #ifdef CONFIG_SCHED_DEBUG /* * We should never call set_task_cpu() on a blocked task, @@ -2049,11 +2046,11 @@ void set_task_cpu(struct task_struct *p, unsigned int new_cpu) trace_sched_migrate_task(p, new_cpu); - if (old_cpu != new_cpu) { - p->se.nr_migrations++; - perf_sw_event(PERF_COUNT_SW_CPU_MIGRATIONS, - 1, 1, NULL, 0); - } + if (task_cpu(p) == new_cpu) + return; + + p->se.nr_migrations++; + perf_sw_event(PERF_COUNT_SW_CPU_MIGRATIONS, 1, 1, NULL, 0); __set_task_cpu(p, new_cpu); } -- cgit v0.10.2 From 4297a462f455e38f08976df7b16c849614a287da Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Wed, 16 Dec 2009 16:28:03 +0100 Subject: dma: at_hdmac: correct incompatible type for argument 1 of 'spin_lock_bh' Correct a typo error in locking calls. Cc: Signed-off-by: Nicolas Ferre Signed-off-by: Dan Williams diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index 7585c41..c558fa1 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c @@ -815,7 +815,7 @@ atc_is_tx_complete(struct dma_chan *chan, dev_vdbg(chan2dev(chan), "is_tx_complete: %d (d%d, u%d)\n", cookie, done ? *done : 0, used ? *used : 0); - spin_lock_bh(atchan->lock); + spin_lock_bh(&atchan->lock); last_complete = atchan->completed_cookie; last_used = chan->cookie; @@ -830,7 +830,7 @@ atc_is_tx_complete(struct dma_chan *chan, ret = dma_async_is_complete(cookie, last_complete, last_used); } - spin_unlock_bh(atchan->lock); + spin_unlock_bh(&atchan->lock); if (done) *done = last_complete; -- cgit v0.10.2 From 15293df82bd1c15196e7cb336130c243e9a41806 Mon Sep 17 00:00:00 2001 From: Detlef Riekenberg Date: Thu, 10 Dec 2009 13:55:48 +0100 Subject: vgaarbiter: fix a typo in the vgaarbiter Documentation I detected a typo, while reading "Documentation/vgaarbiter.txt". Fix the 'fieldd' mispelling. Signed-off-by: Detlef Riekenberg Signed-off-by: Jesse Barnes diff --git a/Documentation/vgaarbiter.txt b/Documentation/vgaarbiter.txt index 987f9b0..43a9b06 100644 --- a/Documentation/vgaarbiter.txt +++ b/Documentation/vgaarbiter.txt @@ -103,7 +103,7 @@ I.2 libpciaccess ---------------- To use the vga arbiter char device it was implemented an API inside the -libpciaccess library. One fieldd was added to struct pci_device (each device +libpciaccess library. One field was added to struct pci_device (each device on the system): /* the type of resource decoded by the device */ -- cgit v0.10.2 From d93626e861eaab387950ec34346961013ba28d5e Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 16 Dec 2009 20:06:36 +0000 Subject: [ARM] Update mach-types Signed-off-by: Russell King diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types index 07b976d..c3a74ce 100644 --- a/arch/arm/tools/mach-types +++ b/arch/arm/tools/mach-types @@ -12,7 +12,7 @@ # # http://www.arm.linux.org.uk/developer/machines/?action=new # -# Last update: Wed Nov 25 22:14:58 2009 +# Last update: Wed Dec 16 20:06:34 2009 # # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number # @@ -1776,6 +1776,7 @@ cybook3 MACH_CYBOOK3 CYBOOK3 1784 wdg002 MACH_WDG002 WDG002 1785 sg560adsl MACH_SG560ADSL SG560ADSL 1786 nextio_n2800_ica MACH_NEXTIO_N2800_ICA NEXTIO_N2800_ICA 1787 +dove_db MACH_DOVE_DB DOVE_DB 1788 marvell_newdb MACH_MARVELL_NEWDB MARVELL_NEWDB 1789 vandihud MACH_VANDIHUD VANDIHUD 1790 magx_e8 MACH_MAGX_E8 MAGX_E8 1791 @@ -2536,3 +2537,44 @@ c3ax03 MACH_C3AX03 C3AX03 2549 mxt_td60 MACH_MXT_TD60 MXT_TD60 2550 esyx MACH_ESYX ESYX 2551 bulldog MACH_BULLDOG BULLDOG 2553 +derell_me2000 MACH_DERELL_ME2000 DERELL_ME2000 2554 +bcmring_base MACH_BCMRING_BASE BCMRING_BASE 2555 +bcmring_evm MACH_BCMRING_EVM BCMRING_EVM 2556 +bcmring_evm_jazz MACH_BCMRING_EVM_JAZZ BCMRING_EVM_JAZZ 2557 +bcmring_sp MACH_BCMRING_SP BCMRING_SP 2558 +bcmring_sv MACH_BCMRING_SV BCMRING_SV 2559 +bcmring_sv_jazz MACH_BCMRING_SV_JAZZ BCMRING_SV_JAZZ 2560 +bcmring_tablet MACH_BCMRING_TABLET BCMRING_TABLET 2561 +bcmring_vp MACH_BCMRING_VP BCMRING_VP 2562 +bcmring_evm_seikor MACH_BCMRING_EVM_SEIKOR BCMRING_EVM_SEIKOR 2563 +bcmring_sp_wqvga MACH_BCMRING_SP_WQVGA BCMRING_SP_WQVGA 2564 +bcmring_custom MACH_BCMRING_CUSTOM BCMRING_CUSTOM 2565 +acer_s200 MACH_ACER_S200 ACER_S200 2566 +bt270 MACH_BT270 BT270 2567 +iseo MACH_ISEO ISEO 2568 +cezanne MACH_CEZANNE CEZANNE 2569 +lucca MACH_LUCCA LUCCA 2570 +supersmart MACH_SUPERSMART SUPERSMART 2571 +magnolia2 MACH_MAGNOLIA2 MAGNOLIA2 2573 +emxx MACH_EMXX EMXX 2574 +outlaw MACH_OUTLAW OUTLAW 2575 +riot_bei2 MACH_RIOT_BEI2 RIOT_BEI2 2576 +riot_vox MACH_RIOT_VOX RIOT_VOX 2577 +riot_x37 MACH_RIOT_X37 RIOT_X37 2578 +mega25mx MACH_MEGA25MX MEGA25MX 2579 +benzina2 MACH_BENZINA2 BENZINA2 2580 +ignite MACH_IGNITE IGNITE 2581 +foggia MACH_FOGGIA FOGGIA 2582 +arezzo MACH_AREZZO AREZZO 2583 +leica_skywalker MACH_LEICA_SKYWALKER LEICA_SKYWALKER 2584 +jacinto2_jamr MACH_JACINTO2_JAMR JACINTO2_JAMR 2585 +gts_nova MACH_GTS_NOVA GTS_NOVA 2586 +p3600 MACH_P3600 P3600 2587 +dlt2 MACH_DLT2 DLT2 2588 +df3120 MACH_DF3120 DF3120 2589 +ecucore_9g20 MACH_ECUCORE_9G20 ECUCORE_9G20 2590 +nautel_lpc3240 MACH_NAUTEL_LPC3240 NAUTEL_LPC3240 2591 +glacier MACH_GLACIER GLACIER 2592 +phrazer_bulldog MACH_PHRAZER_BULLDOG PHRAZER_BULLDOG 2593 +omap3_bulldog MACH_OMAP3_BULLDOG OMAP3_BULLDOG 2594 +pca101 MACH_PCA101 PCA101 2595 -- cgit v0.10.2 From a7a5ac58df0832daf7774b083c33032a7d26c792 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 15 Dec 2009 21:11:21 +0100 Subject: PCMCIA: fix pxa2xx_lubbock modular build error Commit d0d26c33b63c7ec10c3fdf9c7ce0aa035f0b3200 broke the driver by propagating a pointer to the platform_device where a pointer to the generic device was expected, leading to a spectacular crash... Signed-off-by: Marc Zyngier Acked-by: Dominik Brodowski Acked-by: Eric Miao Signed-off-by: Russell King diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c index 3aabf1e..76e640b 100644 --- a/drivers/pcmcia/pxa2xx_base.c +++ b/drivers/pcmcia/pxa2xx_base.c @@ -291,7 +291,7 @@ static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev) skt->nr = ops->first + i; skt->ops = ops; skt->socket.owner = ops->owner; - skt->socket.dev.parent = dev; + skt->socket.dev.parent = &dev->dev; skt->socket.pci_irq = NO_IRQ; ret = pxa2xx_drv_pcmcia_add_one(skt); @@ -304,8 +304,8 @@ static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev) soc_pcmcia_remove_one(&sinfo->skt[i]); kfree(sinfo); } else { - pxa2xx_configure_sockets(dev); - dev_set_drvdata(dev, sinfo); + pxa2xx_configure_sockets(&dev->dev); + dev_set_drvdata(&dev->dev, sinfo); } return ret; -- cgit v0.10.2 From 3c57e89b467d1db6fda74d5c97112c8b9466dd97 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Wed, 16 Dec 2009 21:38:25 +0100 Subject: hwmon: New driver for AMD Family 10h/11h CPUs This adds a driver for the internal temperature sensor of AMD Family 10h and 11h CPUs. Signed-off-by: Clemens Ladisch Signed-off-by: Jean Delvare diff --git a/Documentation/hwmon/k10temp b/Documentation/hwmon/k10temp new file mode 100644 index 0000000..a7a18d4 --- /dev/null +++ b/Documentation/hwmon/k10temp @@ -0,0 +1,60 @@ +Kernel driver k10temp +===================== + +Supported chips: +* AMD Family 10h processors: + Socket F: Quad-Core/Six-Core/Embedded Opteron + Socket AM2+: Opteron, Phenom (II) X3/X4 + Socket AM3: Quad-Core Opteron, Athlon/Phenom II X2/X3/X4, Sempron II + Socket S1G3: Athlon II, Sempron, Turion II +* AMD Family 11h processors: + Socket S1G2: Athlon (X2), Sempron (X2), Turion X2 (Ultra) + + Prefix: 'k10temp' + Addresses scanned: PCI space + Datasheets: + BIOS and Kernel Developer's Guide (BKDG) For AMD Family 10h Processors: + http://support.amd.com/us/Processor_TechDocs/31116.pdf + BIOS and Kernel Developer's Guide (BKDG) for AMD Family 11h Processors: + http://support.amd.com/us/Processor_TechDocs/41256.pdf + Revision Guide for AMD Family 10h Processors: + http://support.amd.com/us/Processor_TechDocs/41322.pdf + Revision Guide for AMD Family 11h Processors: + http://support.amd.com/us/Processor_TechDocs/41788.pdf + AMD Family 11h Processor Power and Thermal Data Sheet for Notebooks: + http://support.amd.com/us/Processor_TechDocs/43373.pdf + AMD Family 10h Server and Workstation Processor Power and Thermal Data Sheet: + http://support.amd.com/us/Processor_TechDocs/43374.pdf + AMD Family 10h Desktop Processor Power and Thermal Data Sheet: + http://support.amd.com/us/Processor_TechDocs/43375.pdf + +Author: Clemens Ladisch + +Description +----------- + +This driver permits reading of the internal temperature sensor of AMD +Family 10h and 11h processors. + +All these processors have a sensor, but on older revisions of Family 10h +processors, the sensor may return inconsistent values (erratum 319). The +driver will refuse to load on these revisions unless you specify the +"force=1" module parameter. + +There is one temperature measurement value, available as temp1_input in +sysfs. It is measured in degrees Celsius with a resolution of 1/8th degree. +Please note that it is defined as a relative value; to quote the AMD manual: + + Tctl is the processor temperature control value, used by the platform to + control cooling systems. Tctl is a non-physical temperature on an + arbitrary scale measured in degrees. It does _not_ represent an actual + physical temperature like die or case temperature. Instead, it specifies + the processor temperature relative to the point at which the system must + supply the maximum cooling for the processor's specified maximum case + temperature and maximum thermal power dissipation. + +The maximum value for Tctl is available in the file temp1_max. + +If the BIOS has enabled hardware temperature control, the threshold at +which the processor will throttle itself to avoid damage is available in +temp1_crit and temp1_crit_hyst. diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 95ccbe3..665947f 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -228,6 +228,18 @@ config SENSORS_K8TEMP This driver can also be built as a module. If so, the module will be called k8temp. +config SENSORS_K10TEMP + tristate "AMD Phenom/Sempron/Turion/Opteron temperature sensor" + depends on X86 && PCI + help + If you say yes here you get support for the temperature + sensor(s) inside your CPU. Supported are later revisions of + the AMD Family 10h and all revisions of the AMD Family 11h + microarchitectures. + + This driver can also be built as a module. If so, the module + will be called k10temp. + config SENSORS_AMS tristate "Apple Motion Sensor driver" depends on PPC_PMAC && !PPC64 && INPUT && ((ADB_PMU && I2C = y) || (ADB_PMU && !I2C) || I2C) && EXPERIMENTAL diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 33c2ee1..da84a6a 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -53,6 +53,7 @@ obj-$(CONFIG_SENSORS_IBMAEM) += ibmaem.o obj-$(CONFIG_SENSORS_IBMPEX) += ibmpex.o obj-$(CONFIG_SENSORS_IT87) += it87.o obj-$(CONFIG_SENSORS_K8TEMP) += k8temp.o +obj-$(CONFIG_SENSORS_K10TEMP) += k10temp.o obj-$(CONFIG_SENSORS_LIS3LV02D) += lis3lv02d.o hp_accel.o obj-$(CONFIG_SENSORS_LIS3_SPI) += lis3lv02d.o lis3lv02d_spi.o obj-$(CONFIG_SENSORS_LM63) += lm63.o diff --git a/drivers/hwmon/k10temp.c b/drivers/hwmon/k10temp.c new file mode 100644 index 0000000..d8a26d1 --- /dev/null +++ b/drivers/hwmon/k10temp.c @@ -0,0 +1,197 @@ +/* + * k10temp.c - AMD Family 10h/11h processor hardware monitoring + * + * Copyright (c) 2009 Clemens Ladisch + * + * + * This driver is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License; either + * version 2 of the License, or (at your option) any later version. + * + * This driver 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 driver; if not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +MODULE_DESCRIPTION("AMD Family 10h/11h CPU core temperature monitor"); +MODULE_AUTHOR("Clemens Ladisch "); +MODULE_LICENSE("GPL"); + +static bool force; +module_param(force, bool, 0444); +MODULE_PARM_DESC(force, "force loading on processors with erratum 319"); + +#define REG_HARDWARE_THERMAL_CONTROL 0x64 +#define HTC_ENABLE 0x00000001 + +#define REG_REPORTED_TEMPERATURE 0xa4 + +#define REG_NORTHBRIDGE_CAPABILITIES 0xe8 +#define NB_CAP_HTC 0x00000400 + +static ssize_t show_temp(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u32 regval; + + pci_read_config_dword(to_pci_dev(dev), + REG_REPORTED_TEMPERATURE, ®val); + return sprintf(buf, "%u\n", (regval >> 21) * 125); +} + +static ssize_t show_temp_max(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", 70 * 1000); +} + +static ssize_t show_temp_crit(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + int show_hyst = attr->index; + u32 regval; + int value; + + pci_read_config_dword(to_pci_dev(dev), + REG_HARDWARE_THERMAL_CONTROL, ®val); + value = ((regval >> 16) & 0x7f) * 500 + 52000; + if (show_hyst) + value -= ((regval >> 24) & 0xf) * 500; + return sprintf(buf, "%d\n", value); +} + +static ssize_t show_name(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "k10temp\n"); +} + +static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL); +static DEVICE_ATTR(temp1_max, S_IRUGO, show_temp_max, NULL); +static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, show_temp_crit, NULL, 0); +static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IRUGO, show_temp_crit, NULL, 1); +static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); + +static bool __devinit has_erratum_319(void) +{ + /* + * Erratum 319: The thermal sensor of older Family 10h processors + * (B steppings) may be unreliable. + */ + return boot_cpu_data.x86 == 0x10 && boot_cpu_data.x86_model <= 2; +} + +static int __devinit k10temp_probe(struct pci_dev *pdev, + const struct pci_device_id *id) +{ + struct device *hwmon_dev; + u32 reg_caps, reg_htc; + int err; + + if (has_erratum_319() && !force) { + dev_err(&pdev->dev, + "unreliable CPU thermal sensor; monitoring disabled\n"); + err = -ENODEV; + goto exit; + } + + err = device_create_file(&pdev->dev, &dev_attr_temp1_input); + if (err) + goto exit; + err = device_create_file(&pdev->dev, &dev_attr_temp1_max); + if (err) + goto exit_remove; + + pci_read_config_dword(pdev, REG_NORTHBRIDGE_CAPABILITIES, ®_caps); + pci_read_config_dword(pdev, REG_HARDWARE_THERMAL_CONTROL, ®_htc); + if ((reg_caps & NB_CAP_HTC) && (reg_htc & HTC_ENABLE)) { + err = device_create_file(&pdev->dev, + &sensor_dev_attr_temp1_crit.dev_attr); + if (err) + goto exit_remove; + err = device_create_file(&pdev->dev, + &sensor_dev_attr_temp1_crit_hyst.dev_attr); + if (err) + goto exit_remove; + } + + err = device_create_file(&pdev->dev, &dev_attr_name); + if (err) + goto exit_remove; + + hwmon_dev = hwmon_device_register(&pdev->dev); + if (IS_ERR(hwmon_dev)) { + err = PTR_ERR(hwmon_dev); + goto exit_remove; + } + dev_set_drvdata(&pdev->dev, hwmon_dev); + + if (has_erratum_319() && force) + dev_warn(&pdev->dev, + "unreliable CPU thermal sensor; check erratum 319\n"); + return 0; + +exit_remove: + device_remove_file(&pdev->dev, &dev_attr_name); + device_remove_file(&pdev->dev, &dev_attr_temp1_input); + device_remove_file(&pdev->dev, &dev_attr_temp1_max); + device_remove_file(&pdev->dev, + &sensor_dev_attr_temp1_crit.dev_attr); + device_remove_file(&pdev->dev, + &sensor_dev_attr_temp1_crit_hyst.dev_attr); +exit: + return err; +} + +static void __devexit k10temp_remove(struct pci_dev *pdev) +{ + hwmon_device_unregister(dev_get_drvdata(&pdev->dev)); + device_remove_file(&pdev->dev, &dev_attr_name); + device_remove_file(&pdev->dev, &dev_attr_temp1_input); + device_remove_file(&pdev->dev, &dev_attr_temp1_max); + device_remove_file(&pdev->dev, + &sensor_dev_attr_temp1_crit.dev_attr); + device_remove_file(&pdev->dev, + &sensor_dev_attr_temp1_crit_hyst.dev_attr); + dev_set_drvdata(&pdev->dev, NULL); +} + +static struct pci_device_id k10temp_id_table[] = { + { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_10H_NB_MISC) }, + { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_11H_NB_MISC) }, + {} +}; +MODULE_DEVICE_TABLE(pci, k10temp_id_table); + +static struct pci_driver k10temp_driver = { + .name = "k10temp", + .id_table = k10temp_id_table, + .probe = k10temp_probe, + .remove = __devexit_p(k10temp_remove), +}; + +static int __init k10temp_init(void) +{ + return pci_register_driver(&k10temp_driver); +} + +static void __exit k10temp_exit(void) +{ + pci_unregister_driver(&k10temp_driver); +} + +module_init(k10temp_init) +module_exit(k10temp_exit) -- cgit v0.10.2 From a0e92d70f35b5fd7da8ec2160cda78b98e2113bc Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Dec 2009 21:38:26 +0100 Subject: hwmon: (smsc47m1) Only request I/O ports we really use The I/O area of the SMSC LPC47M1xx chips which we use, gives access to a lot of registers, some of which are related to fan speed monitoring and control, but many are not. At the moment, the smsc47m1 driver requests the whole I/O port range. This could easily result in resource conflicts with either ACPI or other drivers. Request only the I/O ports we really use, to prevent such conflicts. Signed-off-by: Jean Delvare Tested-by: Sean Fidler diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c index 8ad50fd..bfef223 100644 --- a/drivers/hwmon/smsc47m1.c +++ b/drivers/hwmon/smsc47m1.c @@ -481,13 +481,94 @@ static int __init smsc47m1_find(unsigned short *addr, return 0; } +#define CHECK 1 +#define REQUEST 2 +#define RELEASE 3 + +/* + * This function can be used to: + * - test for resource conflicts with ACPI + * - request the resources + * - release the resources + * We only allocate the I/O ports we really need, to minimize the risk of + * conflicts with ACPI or with other drivers. + */ +static int smsc47m1_handle_resources(unsigned short address, enum chips type, + int action, struct device *dev) +{ + static const u8 ports_m1[] = { + /* register, region length */ + 0x04, 1, + 0x33, 4, + 0x56, 7, + }; + + static const u8 ports_m2[] = { + /* register, region length */ + 0x04, 1, + 0x09, 1, + 0x2c, 2, + 0x35, 4, + 0x56, 7, + 0x69, 4, + }; + + int i, ports_size, err; + const u8 *ports; + + switch (type) { + case smsc47m1: + default: + ports = ports_m1; + ports_size = ARRAY_SIZE(ports_m1); + break; + case smsc47m2: + ports = ports_m2; + ports_size = ARRAY_SIZE(ports_m2); + break; + } + + for (i = 0; i + 1 < ports_size; i += 2) { + unsigned short start = address + ports[i]; + unsigned short len = ports[i + 1]; + + switch (action) { + case CHECK: + /* Only check for conflicts */ + err = acpi_check_region(start, len, DRVNAME); + if (err) + return err; + break; + case REQUEST: + /* Request the resources */ + if (!request_region(start, len, DRVNAME)) { + dev_err(dev, "Region 0x%hx-0x%hx already in " + "use!\n", start, start + len); + + /* Undo all requests */ + for (i -= 2; i >= 0; i -= 2) + release_region(address + ports[i], + ports[i + 1]); + return -EBUSY; + } + break; + case RELEASE: + /* Release the resources */ + release_region(start, len); + break; + } + } + + return 0; +} + static int __devinit smsc47m1_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct smsc47m1_sio_data *sio_data = dev->platform_data; struct smsc47m1_data *data; struct resource *res; - int err = 0; + int err; int fan1, fan2, fan3, pwm1, pwm2, pwm3; static const char *names[] = { @@ -496,12 +577,10 @@ static int __devinit smsc47m1_probe(struct platform_device *pdev) }; res = platform_get_resource(pdev, IORESOURCE_IO, 0); - if (!request_region(res->start, SMSC_EXTENT, DRVNAME)) { - dev_err(dev, "Region 0x%lx-0x%lx already in use!\n", - (unsigned long)res->start, - (unsigned long)res->end); - return -EBUSY; - } + err = smsc47m1_handle_resources(res->start, sio_data->type, + REQUEST, dev); + if (err < 0) + return err; if (!(data = kzalloc(sizeof(struct smsc47m1_data), GFP_KERNEL))) { err = -ENOMEM; @@ -637,7 +716,7 @@ error_free: platform_set_drvdata(pdev, NULL); kfree(data); error_release: - release_region(res->start, SMSC_EXTENT); + smsc47m1_handle_resources(res->start, sio_data->type, RELEASE, dev); return err; } @@ -650,7 +729,7 @@ static int __devexit smsc47m1_remove(struct platform_device *pdev) sysfs_remove_group(&pdev->dev.kobj, &smsc47m1_group); res = platform_get_resource(pdev, IORESOURCE_IO, 0); - release_region(res->start, SMSC_EXTENT); + smsc47m1_handle_resources(res->start, data->type, RELEASE, &pdev->dev); platform_set_drvdata(pdev, NULL); kfree(data); @@ -717,7 +796,7 @@ static int __init smsc47m1_device_add(unsigned short address, }; int err; - err = acpi_check_resource_conflict(&res); + err = smsc47m1_handle_resources(address, sio_data->type, CHECK, NULL); if (err) goto exit; -- cgit v0.10.2 From 3ecf44b312758d10be20539b06b2df5d77d59cdb Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Dec 2009 21:38:26 +0100 Subject: hwmon: (smsc47m1) Fail module loading on error If an error occurs during probing, there's no point in keeping the module in memory. Better fail the module loading early to make the problem more visible. Signed-off-by: Jean Delvare Tested-by: Sean Fidler diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c index bfef223..92cca51 100644 --- a/drivers/hwmon/smsc47m1.c +++ b/drivers/hwmon/smsc47m1.c @@ -139,8 +139,7 @@ struct smsc47m1_sio_data { }; -static int smsc47m1_probe(struct platform_device *pdev); -static int __devexit smsc47m1_remove(struct platform_device *pdev); +static int __exit smsc47m1_remove(struct platform_device *pdev); static struct smsc47m1_data *smsc47m1_update_device(struct device *dev, int init); @@ -160,8 +159,7 @@ static struct platform_driver smsc47m1_driver = { .owner = THIS_MODULE, .name = DRVNAME, }, - .probe = smsc47m1_probe, - .remove = __devexit_p(smsc47m1_remove), + .remove = __exit_p(smsc47m1_remove), }; static ssize_t get_fan(struct device *dev, struct device_attribute @@ -562,7 +560,7 @@ static int smsc47m1_handle_resources(unsigned short address, enum chips type, return 0; } -static int __devinit smsc47m1_probe(struct platform_device *pdev) +static int __init smsc47m1_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct smsc47m1_sio_data *sio_data = dev->platform_data; @@ -720,7 +718,7 @@ error_release: return err; } -static int __devexit smsc47m1_remove(struct platform_device *pdev) +static int __exit smsc47m1_remove(struct platform_device *pdev) { struct smsc47m1_data *data = platform_get_drvdata(pdev); struct resource *res; @@ -845,27 +843,27 @@ static int __init sm_smsc47m1_init(void) if (smsc47m1_find(&address, &sio_data)) return -ENODEV; - err = platform_driver_register(&smsc47m1_driver); + /* Sets global pdev as a side effect */ + err = smsc47m1_device_add(address, &sio_data); if (err) goto exit; - /* Sets global pdev as a side effect */ - err = smsc47m1_device_add(address, &sio_data); + err = platform_driver_probe(&smsc47m1_driver, smsc47m1_probe); if (err) - goto exit_driver; + goto exit_device; return 0; -exit_driver: - platform_driver_unregister(&smsc47m1_driver); +exit_device: + platform_device_unregister(pdev); exit: return err; } static void __exit sm_smsc47m1_exit(void) { - platform_device_unregister(pdev); platform_driver_unregister(&smsc47m1_driver); + platform_device_unregister(pdev); } MODULE_AUTHOR("Mark D. Studebaker "); -- cgit v0.10.2 From fa0bff02239abdad446effef22e5db281cf3d562 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Dec 2009 21:38:27 +0100 Subject: hwmon: (smsc47m1) Enable device if needed If the address is set but the device isn't enabled, attempt to enable it. If it won't work for any reason (resource conflict, no function enabled) the initial state is restored. The initial state is also restored on module unloading. Signed-off-by: Jean Delvare Tested-by: Sean Fidler diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c index 92cca51..9ca9781 100644 --- a/drivers/hwmon/smsc47m1.c +++ b/drivers/hwmon/smsc47m1.c @@ -136,6 +136,7 @@ struct smsc47m1_data { struct smsc47m1_sio_data { enum chips type; + u8 activate; /* Remember initial device state */ }; @@ -468,17 +469,38 @@ static int __init smsc47m1_find(unsigned short *addr, superio_select(); *addr = (superio_inb(SUPERIO_REG_BASE) << 8) | superio_inb(SUPERIO_REG_BASE + 1); - val = superio_inb(SUPERIO_REG_ACT); - if (*addr == 0 || (val & 0x01) == 0) { - pr_info(DRVNAME ": Device is disabled, will not use\n"); + if (*addr == 0) { + pr_info(DRVNAME ": Device address not set, will not use\n"); superio_exit(); return -ENODEV; } + /* Enable only if address is set (needed at least on the + * Compaq Presario S4000NX) */ + sio_data->activate = superio_inb(SUPERIO_REG_ACT); + if ((sio_data->activate & 0x01) == 0) { + pr_info(DRVNAME ": Enabling device\n"); + superio_outb(SUPERIO_REG_ACT, sio_data->activate | 0x01); + } + superio_exit(); return 0; } +/* Restore device to its initial state */ +static void __init smsc47m1_restore(const struct smsc47m1_sio_data *sio_data) +{ + if ((sio_data->activate & 0x01) == 0) { + superio_enter(); + superio_select(); + + pr_info(DRVNAME ": Disabling device\n"); + superio_outb(SUPERIO_REG_ACT, sio_data->activate); + + superio_exit(); + } +} + #define CHECK 1 #define REQUEST 2 #define RELEASE 3 @@ -856,6 +878,7 @@ static int __init sm_smsc47m1_init(void) exit_device: platform_device_unregister(pdev); + smsc47m1_restore(&sio_data); exit: return err; } @@ -863,6 +886,7 @@ exit: static void __exit sm_smsc47m1_exit(void) { platform_driver_unregister(&smsc47m1_driver); + smsc47m1_restore(pdev->dev.platform_data); platform_device_unregister(pdev); } -- cgit v0.10.2 From 70c38772aef27b01dc236fb4016261c3828df6aa Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Wed, 16 Dec 2009 21:38:28 +0100 Subject: hwmon: Add driver for VIA CPU core temperature This is a driver for the on-die digital temperature sensor of VIA's recent CPU models. [JD: Misc clean-ups.] Signed-off-by: Harald Welte Cc: Juerg Haefliger Signed-off-by: Jean Delvare Tested-by: Adam Nielsen diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 665947f..be8eead 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -822,6 +822,14 @@ config SENSORS_TMP421 This driver can also be built as a module. If so, the module will be called tmp421. +config SENSORS_VIA_CPUTEMP + tristate "VIA CPU temperature sensor" + depends on X86 + help + If you say yes here you get support for the temperature + sensor inside your CPU. Supported are all known variants of + the VIA C7 and Nano. + config SENSORS_VIA686A tristate "VIA686A" depends on PCI diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index da84a6a..312b7c3 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -88,6 +88,7 @@ obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o obj-$(CONFIG_SENSORS_THMC50) += thmc50.o obj-$(CONFIG_SENSORS_TMP401) += tmp401.o obj-$(CONFIG_SENSORS_TMP421) += tmp421.o +obj-$(CONFIG_SENSORS_VIA_CPUTEMP)+= via-cputemp.o obj-$(CONFIG_SENSORS_VIA686A) += via686a.o obj-$(CONFIG_SENSORS_VT1211) += vt1211.o obj-$(CONFIG_SENSORS_VT8231) += vt8231.o diff --git a/drivers/hwmon/via-cputemp.c b/drivers/hwmon/via-cputemp.c new file mode 100644 index 0000000..7442cf7 --- /dev/null +++ b/drivers/hwmon/via-cputemp.c @@ -0,0 +1,356 @@ +/* + * via-cputemp.c - Driver for VIA CPU core temperature monitoring + * Copyright (C) 2009 VIA Technologies, Inc. + * + * based on existing coretemp.c, which is + * + * Copyright (C) 2007 Rudolf Marek + * + * 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 Street, Fifth Floor, Boston, MA + * 02110-1301 USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRVNAME "via_cputemp" + +enum { SHOW_TEMP, SHOW_LABEL, SHOW_NAME } SHOW; + +/* + * Functions declaration + */ + +struct via_cputemp_data { + struct device *hwmon_dev; + const char *name; + u32 id; + u32 msr; +}; + +/* + * Sysfs stuff + */ + +static ssize_t show_name(struct device *dev, struct device_attribute + *devattr, char *buf) +{ + int ret; + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct via_cputemp_data *data = dev_get_drvdata(dev); + + if (attr->index == SHOW_NAME) + ret = sprintf(buf, "%s\n", data->name); + else /* show label */ + ret = sprintf(buf, "Core %d\n", data->id); + return ret; +} + +static ssize_t show_temp(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + struct via_cputemp_data *data = dev_get_drvdata(dev); + u32 eax, edx; + int err; + + err = rdmsr_safe_on_cpu(data->id, data->msr, &eax, &edx); + if (err) + return -EAGAIN; + + return sprintf(buf, "%lu\n", ((unsigned long)eax & 0xffffff) * 1000); +} + +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, + SHOW_TEMP); +static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, show_name, NULL, SHOW_LABEL); +static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, SHOW_NAME); + +static struct attribute *via_cputemp_attributes[] = { + &sensor_dev_attr_name.dev_attr.attr, + &sensor_dev_attr_temp1_label.dev_attr.attr, + &sensor_dev_attr_temp1_input.dev_attr.attr, + NULL +}; + +static const struct attribute_group via_cputemp_group = { + .attrs = via_cputemp_attributes, +}; + +static int __devinit via_cputemp_probe(struct platform_device *pdev) +{ + struct via_cputemp_data *data; + struct cpuinfo_x86 *c = &cpu_data(pdev->id); + int err; + u32 eax, edx; + + data = kzalloc(sizeof(struct via_cputemp_data), GFP_KERNEL); + if (!data) { + err = -ENOMEM; + dev_err(&pdev->dev, "Out of memory\n"); + goto exit; + } + + data->id = pdev->id; + data->name = "via_cputemp"; + + switch (c->x86_model) { + case 0xA: + /* C7 A */ + case 0xD: + /* C7 D */ + data->msr = 0x1169; + break; + case 0xF: + /* Nano */ + data->msr = 0x1423; + break; + default: + err = -ENODEV; + goto exit_free; + } + + /* test if we can access the TEMPERATURE MSR */ + err = rdmsr_safe_on_cpu(data->id, data->msr, &eax, &edx); + if (err) { + dev_err(&pdev->dev, + "Unable to access TEMPERATURE MSR, giving up\n"); + goto exit_free; + } + + platform_set_drvdata(pdev, data); + + err = sysfs_create_group(&pdev->dev.kobj, &via_cputemp_group); + if (err) + goto exit_free; + + data->hwmon_dev = hwmon_device_register(&pdev->dev); + if (IS_ERR(data->hwmon_dev)) { + err = PTR_ERR(data->hwmon_dev); + dev_err(&pdev->dev, "Class registration failed (%d)\n", + err); + goto exit_remove; + } + + return 0; + +exit_remove: + sysfs_remove_group(&pdev->dev.kobj, &via_cputemp_group); +exit_free: + platform_set_drvdata(pdev, NULL); + kfree(data); +exit: + return err; +} + +static int __devexit via_cputemp_remove(struct platform_device *pdev) +{ + struct via_cputemp_data *data = platform_get_drvdata(pdev); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&pdev->dev.kobj, &via_cputemp_group); + platform_set_drvdata(pdev, NULL); + kfree(data); + return 0; +} + +static struct platform_driver via_cputemp_driver = { + .driver = { + .owner = THIS_MODULE, + .name = DRVNAME, + }, + .probe = via_cputemp_probe, + .remove = __devexit_p(via_cputemp_remove), +}; + +struct pdev_entry { + struct list_head list; + struct platform_device *pdev; + unsigned int cpu; +}; + +static LIST_HEAD(pdev_list); +static DEFINE_MUTEX(pdev_list_mutex); + +static int __cpuinit via_cputemp_device_add(unsigned int cpu) +{ + int err; + struct platform_device *pdev; + struct pdev_entry *pdev_entry; + + pdev = platform_device_alloc(DRVNAME, cpu); + if (!pdev) { + err = -ENOMEM; + printk(KERN_ERR DRVNAME ": Device allocation failed\n"); + goto exit; + } + + pdev_entry = kzalloc(sizeof(struct pdev_entry), GFP_KERNEL); + if (!pdev_entry) { + err = -ENOMEM; + goto exit_device_put; + } + + err = platform_device_add(pdev); + if (err) { + printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n", + err); + goto exit_device_free; + } + + pdev_entry->pdev = pdev; + pdev_entry->cpu = cpu; + mutex_lock(&pdev_list_mutex); + list_add_tail(&pdev_entry->list, &pdev_list); + mutex_unlock(&pdev_list_mutex); + + return 0; + +exit_device_free: + kfree(pdev_entry); +exit_device_put: + platform_device_put(pdev); +exit: + return err; +} + +#ifdef CONFIG_HOTPLUG_CPU +static void via_cputemp_device_remove(unsigned int cpu) +{ + struct pdev_entry *p, *n; + mutex_lock(&pdev_list_mutex); + list_for_each_entry_safe(p, n, &pdev_list, list) { + if (p->cpu == cpu) { + platform_device_unregister(p->pdev); + list_del(&p->list); + kfree(p); + } + } + mutex_unlock(&pdev_list_mutex); +} + +static int __cpuinit via_cputemp_cpu_callback(struct notifier_block *nfb, + unsigned long action, void *hcpu) +{ + unsigned int cpu = (unsigned long) hcpu; + + switch (action) { + case CPU_ONLINE: + case CPU_DOWN_FAILED: + via_cputemp_device_add(cpu); + break; + case CPU_DOWN_PREPARE: + via_cputemp_device_remove(cpu); + break; + } + return NOTIFY_OK; +} + +static struct notifier_block via_cputemp_cpu_notifier __refdata = { + .notifier_call = via_cputemp_cpu_callback, +}; +#endif /* !CONFIG_HOTPLUG_CPU */ + +static int __init via_cputemp_init(void) +{ + int i, err; + struct pdev_entry *p, *n; + + if (cpu_data(0).x86_vendor != X86_VENDOR_CENTAUR) { + printk(KERN_DEBUG DRVNAME ": Not a VIA CPU\n"); + err = -ENODEV; + goto exit; + } + + err = platform_driver_register(&via_cputemp_driver); + if (err) + goto exit; + + for_each_online_cpu(i) { + struct cpuinfo_x86 *c = &cpu_data(i); + + if (c->x86 != 6) + continue; + + if (c->x86_model < 0x0a) + continue; + + if (c->x86_model > 0x0f) { + printk(KERN_WARNING DRVNAME ": Unknown CPU " + "model 0x%x\n", c->x86_model); + continue; + } + + err = via_cputemp_device_add(i); + if (err) + goto exit_devices_unreg; + } + if (list_empty(&pdev_list)) { + err = -ENODEV; + goto exit_driver_unreg; + } + +#ifdef CONFIG_HOTPLUG_CPU + register_hotcpu_notifier(&via_cputemp_cpu_notifier); +#endif + return 0; + +exit_devices_unreg: + mutex_lock(&pdev_list_mutex); + list_for_each_entry_safe(p, n, &pdev_list, list) { + platform_device_unregister(p->pdev); + list_del(&p->list); + kfree(p); + } + mutex_unlock(&pdev_list_mutex); +exit_driver_unreg: + platform_driver_unregister(&via_cputemp_driver); +exit: + return err; +} + +static void __exit via_cputemp_exit(void) +{ + struct pdev_entry *p, *n; +#ifdef CONFIG_HOTPLUG_CPU + unregister_hotcpu_notifier(&via_cputemp_cpu_notifier); +#endif + mutex_lock(&pdev_list_mutex); + list_for_each_entry_safe(p, n, &pdev_list, list) { + platform_device_unregister(p->pdev); + list_del(&p->list); + kfree(p); + } + mutex_unlock(&pdev_list_mutex); + platform_driver_unregister(&via_cputemp_driver); +} + +MODULE_AUTHOR("Harald Welte "); +MODULE_DESCRIPTION("VIA CPU temperature monitor"); +MODULE_LICENSE("GPL"); + +module_init(via_cputemp_init) +module_exit(via_cputemp_exit) -- cgit v0.10.2 From 4235f684b66d6f00d2cd8849c884cf8f8b57ecad Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 16 Dec 2009 21:38:28 +0100 Subject: hwmon: (sht15) Off-by-one error in array index + incorrect constants Fix an off-by-one error in array index + incorrect constants. Signed-off-by: Christoph Walser Signed-off-by: Jonathan Cameron Signed-off-by: Jean Delvare diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c index ebe38b6..864a371 100644 --- a/drivers/hwmon/sht15.c +++ b/drivers/hwmon/sht15.c @@ -305,7 +305,7 @@ static inline int sht15_calc_temp(struct sht15_data *data) int d1 = 0; int i; - for (i = 1; i < ARRAY_SIZE(temppoints) - 1; i++) + for (i = 1; i < ARRAY_SIZE(temppoints); i++) /* Find pointer to interpolate */ if (data->supply_uV > temppoints[i - 1].vdd) { d1 = (data->supply_uV/1000 - temppoints[i - 1].vdd) @@ -332,12 +332,12 @@ static inline int sht15_calc_humid(struct sht15_data *data) const int c1 = -4; const int c2 = 40500; /* x 10 ^ -6 */ - const int c3 = 2800; /* x10 ^ -9 */ + const int c3 = -2800; /* x10 ^ -9 */ RHlinear = c1*1000 + c2 * data->val_humid/1000 + (data->val_humid * data->val_humid * c3)/1000000; - return (temp - 25000) * (10000 + 800 * data->val_humid) + return (temp - 25000) * (10000 + 80 * data->val_humid) / 1000000 + RHlinear; } -- cgit v0.10.2 From c46c0e9188685c0276b4c0adf9fb7e903937e35b Mon Sep 17 00:00:00 2001 From: Christian Schulte Date: Wed, 16 Dec 2009 21:38:29 +0100 Subject: hwmon: (w83627hf) Fix for "No such device" The commit b72656dbc491484765776a16eeb55ef2e90efea6 introduced a bug leading to the w83627hf_find function no longer finding any chips. Signed-off-by: Christian Schulte Signed-off-by: Jean Delvare diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c index b257c72..38e2805 100644 --- a/drivers/hwmon/w83627hf.c +++ b/drivers/hwmon/w83627hf.c @@ -1135,6 +1135,7 @@ static int __init w83627hf_find(int sioaddr, unsigned short *addr, "W83687THF", }; + sio_data->sioaddr = sioaddr; superio_enter(sio_data); val = force_id ? force_id : superio_inb(sio_data, DEVID); switch (val) { @@ -1177,7 +1178,6 @@ static int __init w83627hf_find(int sioaddr, unsigned short *addr, } err = 0; - sio_data->sioaddr = sioaddr; pr_info(DRVNAME ": Found %s chip at %#x\n", names[sio_data->type], *addr); -- cgit v0.10.2 From c76f782cb3cfffc1fd4233e11f3116655fa0fcd2 Mon Sep 17 00:00:00 2001 From: Thomas Weber Date: Tue, 15 Dec 2009 10:38:05 -0800 Subject: USB ehci: replace mach header with plat Replace the mach/usb.h with plat/usb.h Cc: linux-usb-devel@lists.sourceforge.net Signed-off-by: Thomas Weber Acked-by: Felipe Balbi Acked-by: Greg Kroah-Hartman Signed-off-by: Tony Lindgren diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index 12f1ad2..74d07f4 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c @@ -37,7 +37,7 @@ #include #include #include -#include +#include /* * OMAP USBHOST Register addresses: VIRTUAL ADDRESSES -- cgit v0.10.2 From ebeb53e1e1f11a51d8a93843a437f516e3528bfa Mon Sep 17 00:00:00 2001 From: Balaji T K Date: Tue, 15 Dec 2009 20:09:02 +0530 Subject: mfd: twl: fix twl4030 rename for remaining driver, board files Recent drivers/mfd/twl4030* renames to twl broke compile for various boards as the series was missing a patch to change the board-*.c files. This patch renames include twl4030.h to include twl.h and also renames twl4030_i2c_ routines. Signed-off-by: Balaji T K Acked-by: Mark Brown Reviewed-by: Felipe Balbi Cc: Samuel Ortiz Signed-off-by: Tony Lindgren diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c index 1591aae..2626a9f 100644 --- a/arch/arm/mach-omap2/board-cm-t35.c +++ b/arch/arm/mach-omap2/board-cm-t35.c @@ -29,7 +29,7 @@ #include #include -#include +#include #include #include diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c index 44239e3..117b8fd 100644 --- a/arch/arm/mach-omap2/board-igep0020.c +++ b/arch/arm/mach-omap2/board-igep0020.c @@ -19,7 +19,7 @@ #include #include -#include +#include #include #include diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c index 18913e9..34de178 100644 --- a/arch/arm/mach-omap2/board-omap3evm.c +++ b/arch/arm/mach-omap2/board-omap3evm.c @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include diff --git a/arch/arm/mach-omap2/board-omap3touchbook.c b/arch/arm/mach-omap2/board-omap3touchbook.c index c9e5ebb..fe3d22c 100644 --- a/arch/arm/mach-omap2/board-omap3touchbook.c +++ b/arch/arm/mach-omap2/board-omap3touchbook.c @@ -34,7 +34,7 @@ #include #include -#include +#include #include #include diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c index 17f3c91..acafdbc 100644 --- a/arch/arm/mach-omap2/board-rx51-peripherals.c +++ b/arch/arm/mach-omap2/board-rx51-peripherals.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c index 258794d..8dd277c 100755 --- a/arch/arm/mach-omap2/board-zoom-peripherals.c +++ b/arch/arm/mach-omap2/board-zoom-peripherals.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/video/omap/lcd_ldp.c b/drivers/video/omap/lcd_ldp.c index 5bb7f6f..0f5952c 100644 --- a/drivers/video/omap/lcd_ldp.c +++ b/drivers/video/omap/lcd_ldp.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include @@ -59,7 +59,7 @@ #define TWL4030_VPLL2_DEV_GRP 0x33 #define TWL4030_VPLL2_DEDICATED 0x36 -#define t2_out(c, r, v) twl4030_i2c_write_u8(c, r, v) +#define t2_out(c, r, v) twl_i2c_write_u8(c, r, v) static int ldp_panel_init(struct lcd_panel *panel, diff --git a/drivers/video/omap/lcd_omap2evm.c b/drivers/video/omap/lcd_omap2evm.c index 006c2fe..7e7a65c 100644 --- a/drivers/video/omap/lcd_omap2evm.c +++ b/drivers/video/omap/lcd_omap2evm.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include @@ -61,9 +61,9 @@ static int omap2evm_panel_init(struct lcd_panel *panel, gpio_direction_output(LCD_PANEL_LR, 1); gpio_direction_output(LCD_PANEL_UD, 1); - twl4030_i2c_write_u8(TWL4030_MODULE_LED, 0x11, TWL_LED_LEDEN); - twl4030_i2c_write_u8(TWL4030_MODULE_PWMA, 0x01, TWL_PWMA_PWMAON); - twl4030_i2c_write_u8(TWL4030_MODULE_PWMA, 0x02, TWL_PWMA_PWMAOFF); + twl_i2c_write_u8(TWL4030_MODULE_LED, 0x11, TWL_LED_LEDEN); + twl_i2c_write_u8(TWL4030_MODULE_PWMA, 0x01, TWL_PWMA_PWMAON); + twl_i2c_write_u8(TWL4030_MODULE_PWMA, 0x02, TWL_PWMA_PWMAOFF); bklight_level = 100; return 0; @@ -101,7 +101,7 @@ static int omap2evm_bklight_setlevel(struct lcd_panel *panel, u8 c; if ((level >= 0) && (level <= 100)) { c = (125 * (100 - level)) / 100 + 2; - twl4030_i2c_write_u8(TWL4030_MODULE_PWMA, c, TWL_PWMA_PWMAOFF); + twl_i2c_write_u8(TWL4030_MODULE_PWMA, c, TWL_PWMA_PWMAOFF); bklight_level = level; } return 0; diff --git a/drivers/video/omap/lcd_omap3beagle.c b/drivers/video/omap/lcd_omap3beagle.c index fc503d8..ca75cc2 100644 --- a/drivers/video/omap/lcd_omap3beagle.c +++ b/drivers/video/omap/lcd_omap3beagle.c @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/video/omap/lcd_omap3evm.c b/drivers/video/omap/lcd_omap3evm.c index ae2edc4..06840da 100644 --- a/drivers/video/omap/lcd_omap3evm.c +++ b/drivers/video/omap/lcd_omap3evm.c @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include @@ -63,9 +63,9 @@ static int omap3evm_panel_init(struct lcd_panel *panel, gpio_direction_output(LCD_PANEL_LR, 1); gpio_direction_output(LCD_PANEL_UD, 1); - twl4030_i2c_write_u8(TWL4030_MODULE_LED, 0x11, TWL_LED_LEDEN); - twl4030_i2c_write_u8(TWL4030_MODULE_PWMA, 0x01, TWL_PWMA_PWMAON); - twl4030_i2c_write_u8(TWL4030_MODULE_PWMA, 0x02, TWL_PWMA_PWMAOFF); + twl_i2c_write_u8(TWL4030_MODULE_LED, 0x11, TWL_LED_LEDEN); + twl_i2c_write_u8(TWL4030_MODULE_PWMA, 0x01, TWL_PWMA_PWMAON); + twl_i2c_write_u8(TWL4030_MODULE_PWMA, 0x02, TWL_PWMA_PWMAOFF); bklight_level = 100; return 0; @@ -102,7 +102,7 @@ static int omap3evm_bklight_setlevel(struct lcd_panel *panel, u8 c; if ((level >= 0) && (level <= 100)) { c = (125 * (100 - level)) / 100 + 2; - twl4030_i2c_write_u8(TWL4030_MODULE_PWMA, c, TWL_PWMA_PWMAOFF); + twl_i2c_write_u8(TWL4030_MODULE_PWMA, c, TWL_PWMA_PWMAOFF); bklight_level = level; } return 0; diff --git a/drivers/video/omap/lcd_overo.c b/drivers/video/omap/lcd_overo.c index 56ee192..564933f 100644 --- a/drivers/video/omap/lcd_overo.c +++ b/drivers/video/omap/lcd_overo.c @@ -21,7 +21,7 @@ #include #include -#include +#include #include #include diff --git a/sound/soc/omap/sdp3430.c b/sound/soc/omap/sdp3430.c index c071f96..3c85c0f 100644 --- a/sound/soc/omap/sdp3430.c +++ b/sound/soc/omap/sdp3430.c @@ -24,7 +24,7 @@ #include #include -#include +#include #include #include #include @@ -321,11 +321,11 @@ static int __init sdp3430_soc_init(void) *(unsigned int *)sdp3430_dai[1].cpu_dai->private_data = 2; /* McBSP3 */ /* Set TWL4030 GPIO6 as EXTMUTE signal */ - twl4030_i2c_read_u8(TWL4030_MODULE_INTBR, &pin_mux, + twl_i2c_read_u8(TWL4030_MODULE_INTBR, &pin_mux, TWL4030_INTBR_PMBR1); pin_mux &= ~TWL4030_GPIO6_PWM0_MUTE(0x03); pin_mux |= TWL4030_GPIO6_PWM0_MUTE(0x02); - twl4030_i2c_write_u8(TWL4030_MODULE_INTBR, pin_mux, + twl_i2c_write_u8(TWL4030_MODULE_INTBR, pin_mux, TWL4030_INTBR_PMBR1); ret = platform_device_add(sdp3430_snd_device); -- cgit v0.10.2 From f2eeeae06a41d4f9c90f8382cc0ef1d35888d09a Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Mon, 14 Dec 2009 13:59:18 +0000 Subject: OMAP3: serial - fix bug introduced in Commit f62349ee9788b1d94c55eb6c291d74a1f69bdd9e had side effect that causes kernel to oops when we are suspending to ram: # echo mem > /sys/power/state WARNING: at kernel/irq/manage.c:858 __free_irq+0x90/0x174() Trying to free already-free IRQ 72 Modules linked in: Backtrace: [] (dump_backtrace+0x0/0x110) from [] (dump_stack+0x18/0x1c) r7:dfd4be08 r6:c009505c r5:c03fbfd1 r4:0000035a [] (dump_stack+0x0/0x1c) from [] (warn_slowpath_common+0x50/0x68) [] (warn_slowpath_common+0x0/0x68) from [] (warn_slowpath_fmt+0x30) r7:c0474afc r6:00000048 r5:00000000 r4:c0474ac0 [] (warn_slowpath_fmt+0x0/0x38) from [] (__free_irq+0x90/0x174) r3:00000048 r2:c03fc0ef [] (__free_irq+0x0/0x174) from [] (free_irq+0x44/0x64) [] (free_irq+0x0/0x64) from [] (omap_uart_enable_irqs+0x4c/0x90) r7:c034d58c r6:00000003 r5:00000000 r4:c0463028 [] (omap_uart_enable_irqs+0x0/0x90) from [] (omap3_pm_begin+0x1c/0) r5:00000003 r4:00000000 [] (omap3_pm_begin+0x0/0x28) from [] (suspend_devices_and_enter+0x) [] (suspend_devices_and_enter+0x0/0x1dc) from [] (enter_state+0xe8) r5:c03f7f46 r4:00000000 [] (enter_state+0x0/0x140) from [] (state_store+0x9c/0xc4) r7:c034d58c r6:00000003 r5:00000003 r4:c03f7f46 [] (state_store+0x0/0xc4) from [] (kobj_attr_store+0x20/0x24) [] (kobj_attr_store+0x0/0x24) from [] (sysfs_write_file+0x114/0x14) [] (sysfs_write_file+0x0/0x148) from [] (vfs_write+0xb8/0x164) [] (vfs_write+0x0/0x164) from [] (sys_write+0x44/0x70) r8:4001f000 r7:00000004 r6:df81bd00 r5:00000000 r4:00000000 [] (sys_write+0x0/0x70) from [] (ret_fast_syscall+0x0/0x38) r8:c002f204 r7:00000004 r6:401fa5e8 r5:4001f000 r4:00000004 This is due the fact that uart_list list was populated in omap_serial_early_init() and omap_uart_enable_irqs() went through this list even when serial idle wasn't enabled for all uarts. This patch moves the code that populates the uart_list and enables uart clocks into omap_serial_init_port(). Signed-off-by: Mika Westerberg Signed-off-by: Kevin Hilman Signed-off-by: Tony Lindgren diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 39b797b..19805a7 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -640,12 +640,9 @@ void __init omap_serial_early_init(void) uart->num = i; p->private_data = uart; uart->p = p; - list_add_tail(&uart->node, &uart_list); if (cpu_is_omap44xx()) p->irq += 32; - - omap_uart_enable_clocks(uart); } } @@ -673,9 +670,13 @@ void __init omap_serial_init_port(int port) pdev = &uart->pdev; dev = &pdev->dev; + omap_uart_enable_clocks(uart); + omap_uart_reset(uart); omap_uart_idle_init(uart); + list_add_tail(&uart->node, &uart_list); + if (WARN_ON(platform_device_register(pdev))) return; -- cgit v0.10.2 From a3cb5195f6db58dbebd8a31b877ddce082c9b63d Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Fri, 11 Dec 2009 09:26:10 +0800 Subject: drm/i915: Add MALATA PC-81005 to ACPI LID quirk list The MALATA PC-81005 laptop always reports that the LID status is closed and we can't use it reliabily for LVDS detection. So add this box into the quirk list. https://bugs.freedesktop.org/show_bug.cgi?id=25523 Signed-off-by: Zhao Yakui Review-by: Jesse Barnes Tested-by: Hector Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 539d97e..b3188a0 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -608,6 +608,13 @@ static const struct dmi_system_id bad_lid_status[] = { DMI_MATCH(DMI_PRODUCT_NAME, "Aspire one"), }, }, + { + .ident = "PC-81005", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "MALATA"), + DMI_MATCH(DMI_PRODUCT_NAME, "PC-81005"), + }, + }, { } }; -- cgit v0.10.2 From a2565377a5c31e25c77c7cabaf6752abe9a2d83a Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Fri, 11 Dec 2009 09:26:11 +0800 Subject: drm/i915: Update LVDS connector status when receiving ACPI LID event Dirk reports that nothing is displayed on LVDS when using ubuntu 9.1 after close/reopen the LID. And I also reproduce this issue on another laptop. After some tests and debug, it seems that it is related with that the LVDS status is not updated in time in course of suspend/resume. Now the LID state is used to check whether the LVDS is connected or disconnected. And when the LID is closed, it means that the LVDS is disconnected. When it is reopened, it means that the LVDS is connected. At the same time on some distributions the LID event is also used to put the system into suspend state. When the LID is closed, the system will enter the suspend state. When the LID is reopened, the system will be resumed. In such case when the LID is closed, user-space script will receive the LID notification event and detect the LVDS as disconnected. Then the system will enter the suspended state. When the LID is reopened, the system will be resumed. As the LVDS status is not updated in course of resume, it will cause that the LVDS connector is marked as unused and disabled. After the resume is finished,user-space script will try to configure the display mode for LVDS. But unfortunately as the LVDS status is not updated in time and it is still marked as disconnected, the LVDS and its corresponding CRTC will be disabled again in the function of drm_helper_disable_unused_functions after changing mode for LVDS. So we had better check and update the status of LVDS connector after receiving the LID notication event. Then after the system is resumed from suspended state, we can set the display mode for LVDS correctly. Signed-off-by: Zhao Yakui Reported-by: Dirk Hohndel Reviewed-by: Jesse Barnes CC: stable@kernel.org Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index fbecac7..25c1047 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -561,6 +561,7 @@ typedef struct drm_i915_private { u16 orig_clock; int child_dev_num; struct child_device_config *child_dev; + struct drm_connector *int_lvds_connector; } drm_i915_private_t; /** driver private structure attached to each drm_gem_object */ diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index b3188a0..f4b4aa2 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -686,7 +686,14 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val, struct drm_i915_private *dev_priv = container_of(nb, struct drm_i915_private, lid_notifier); struct drm_device *dev = dev_priv->dev; + struct drm_connector *connector = dev_priv->int_lvds_connector; + /* + * check and update the status of LVDS connector after receiving + * the LID nofication event. + */ + if (connector) + connector->status = connector->funcs->detect(connector); if (!acpi_lid_open()) { dev_priv->modeset_on_lid = 1; return NOTIFY_OK; @@ -1124,6 +1131,8 @@ out: DRM_DEBUG_KMS("lid notifier registration failed\n"); dev_priv->lid_notifier.notifier_call = NULL; } + /* keep the LVDS connector */ + dev_priv->int_lvds_connector = connector; drm_sysfs_connector_add(connector); return; -- cgit v0.10.2 From dc1a94ae1749d14c55f8b54e9d92bd89df82d51a Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 29 Nov 2009 16:35:54 +0100 Subject: PCI/PM: Propagate wake-up enable for PCIe devices too Having read the PM part of the PCIe 2.0 specification more carefully I think that it was a mistake to restrict the wake-up enable propagation to non-PCIe devices, because if we do not request control of the root ports' PME registers via OSC, PCIe PME is supposed to be handled by the platform, just like the non-PCIe PME. Even if we do that, the wake-up propagation is done to allow the devices to wake up the system from sleep states which involves the platform anyway, so it won't hurt. Signed-off-by: Rafael J. Wysocki Signed-off-by: Jesse Barnes diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index cc617dd..7e28295 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -112,11 +112,7 @@ static bool acpi_pci_can_wakeup(struct pci_dev *dev) static void acpi_pci_propagate_wakeup_enable(struct pci_bus *bus, bool enable) { while (bus->parent) { - struct pci_dev *bridge = bus->self; - int ret; - - ret = acpi_pm_device_sleep_wake(&bridge->dev, enable); - if (!ret || pci_is_pcie(bridge)) + if (!acpi_pm_device_sleep_wake(&bus->self->dev, enable)) return; bus = bus->parent; } @@ -131,9 +127,7 @@ static int acpi_pci_sleep_wake(struct pci_dev *dev, bool enable) if (acpi_pci_can_wakeup(dev)) return acpi_pm_device_sleep_wake(&dev->dev, enable); - if (!pci_is_pcie(dev)) - acpi_pci_propagate_wakeup_enable(dev->bus, enable); - + acpi_pci_propagate_wakeup_enable(dev->bus, enable); return 0; } -- cgit v0.10.2 From 2820f333e3b4ad96590093efbed7b3400bcf492b Mon Sep 17 00:00:00 2001 From: Csaba Henk Date: Tue, 15 Dec 2009 17:55:25 +0530 Subject: PCI: Handle case when no pci device can provide cache line size hint Prior to this patch, if pci_read_config_byte(dev, PCI_CACHE_LINE_SIZE, ...) returns 0 for all dev, pci_cache_line_size ends up set to zero (instead of pci_dfl_cache_line_size). This patch ensures the pci_cache_line_size = pci_dfl_cache_line_size setting in the above scenario. This happens in case of a kvm-88 guest (where, consequently, the rtl8139 NIC failed to initialize). Acked-by: Tejun Heo Signed-off-by: Csaba Henk Signed-off-by: Jesse Barnes diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 7cfa7c3..f70f4e2 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -2629,7 +2629,7 @@ static int __init pci_apply_final_quirks(void) if (!pci_cache_line_size) { printk(KERN_DEBUG "PCI: CLS %u bytes, default %u\n", cls << 2, pci_dfl_cache_line_size << 2); - pci_cache_line_size = cls; + pci_cache_line_size = cls ? cls : pci_dfl_cache_line_size; } return 0; -- cgit v0.10.2 From b9c3b266411d27f1a6466c19d146d08db576bfea Mon Sep 17 00:00:00 2001 From: Dexuan Cui Date: Mon, 7 Dec 2009 13:03:21 +0800 Subject: PCI: support device-specific reset methods Add a new type of quirk for resetting devices at pci_dev_reset time. This is necessary to handle device with nonstandard reset procedures, especially useful for guest drivers. Signed-off-by: Yu Zhao Signed-off-by: Dexuan Cui Signed-off-by: Jesse Barnes diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 0bc27e0..6011d06 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -2284,6 +2284,21 @@ static int pci_parent_bus_reset(struct pci_dev *dev, int probe) return 0; } +static int pci_dev_specific_reset(struct pci_dev *dev, int probe) +{ + struct pci_dev_reset_methods *i; + + for (i = pci_dev_reset_methods; i->reset; i++) { + if ((i->vendor == dev->vendor || + i->vendor == (u16)PCI_ANY_ID) && + (i->device == dev->device || + i->device == (u16)PCI_ANY_ID)) + return i->reset(dev, probe); + } + + return -ENOTTY; +} + static int pci_dev_reset(struct pci_dev *dev, int probe) { int rc; @@ -2296,6 +2311,10 @@ static int pci_dev_reset(struct pci_dev *dev, int probe) down(&dev->dev.sem); } + rc = pci_dev_specific_reset(dev, probe); + if (rc != -ENOTTY) + goto done; + rc = pcie_flr(dev, probe); if (rc != -ENOTTY) goto done; diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 33ed8e0..709eaa4 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -313,4 +313,12 @@ static inline int pci_resource_alignment(struct pci_dev *dev, extern void pci_enable_acs(struct pci_dev *dev); +struct pci_dev_reset_methods { + u16 vendor; + u16 device; + int (*reset)(struct pci_dev *dev, int probe); +}; + +extern struct pci_dev_reset_methods pci_dev_reset_methods[]; + #endif /* DRIVERS_PCI_H */ diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index f70f4e2..86c9177 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -2636,6 +2636,15 @@ static int __init pci_apply_final_quirks(void) } fs_initcall_sync(pci_apply_final_quirks); + +/* + * Followings are device-specific reset methods which can be used to + * reset a single function if other methods (e.g. FLR, PM D0->D3) are + * not available. + */ +struct pci_dev_reset_methods pci_dev_reset_methods[] = { + { 0 } +}; #else void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) {} #endif -- cgit v0.10.2 From aeb30016fec3378c543cae33654c2144277fe674 Mon Sep 17 00:00:00 2001 From: Dexuan Cui Date: Mon, 7 Dec 2009 13:03:22 +0800 Subject: PCI: add Intel USB specific reset method Handle device specific reset requirements (i.e. vendor reg for reset along with appropriate timeout). Signed-off-by: Yu Zhao Signed-off-by: Dexuan Cui Signed-off-by: Jesse Barnes diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 86c9177..cf96776 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -2642,7 +2642,31 @@ fs_initcall_sync(pci_apply_final_quirks); * reset a single function if other methods (e.g. FLR, PM D0->D3) are * not available. */ +static int reset_intel_generic_dev(struct pci_dev *dev, int probe) +{ + int pos; + + /* only implement PCI_CLASS_SERIAL_USB at present */ + if (dev->class == PCI_CLASS_SERIAL_USB) { + pos = pci_find_capability(dev, PCI_CAP_ID_VNDR); + if (!pos) + return -ENOTTY; + + if (probe) + return 0; + + pci_write_config_byte(dev, pos + 0x4, 1); + msleep(100); + + return 0; + } else { + return -ENOTTY; + } +} + struct pci_dev_reset_methods pci_dev_reset_methods[] = { + { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, + reset_intel_generic_dev }, { 0 } }; #else -- cgit v0.10.2 From c763e7b58f71833e6cb7b05493eb1adda4811b08 Mon Sep 17 00:00:00 2001 From: Dexuan Cui Date: Mon, 7 Dec 2009 13:03:23 +0800 Subject: PCI: add Intel 82599 Virtual Function specific reset method Handle device specific timeout and use FLR. Signed-off-by: Yu Zhao Signed-off-by: Dexuan Cui Signed-off-by: Jesse Barnes diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index cf96776..8726698 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -2664,7 +2664,29 @@ static int reset_intel_generic_dev(struct pci_dev *dev, int probe) } } +static int reset_intel_82599_sfp_virtfn(struct pci_dev *dev, int probe) +{ + int pos; + + pos = pci_find_capability(dev, PCI_CAP_ID_EXP); + if (!pos) + return -ENOTTY; + + if (probe) + return 0; + + pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, + PCI_EXP_DEVCTL_BCR_FLR); + msleep(100); + + return 0; +} + +#define PCI_DEVICE_ID_INTEL_82599_SFP_VF 0x10ed + struct pci_dev_reset_methods pci_dev_reset_methods[] = { + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82599_SFP_VF, + reset_intel_82599_sfp_virtfn }, { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, reset_intel_generic_dev }, { 0 } -- cgit v0.10.2 From 5714868812b563ba8816c1d974f4f07c76941c30 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 15 Dec 2009 10:19:50 +0900 Subject: PCI: fix section mismatch on update_res() Remark update_res from __init to __devinit as it is called also from __devinit functions. This patch removes the following warning message: WARNING: vmlinux.o(.devinit.text+0x774a): Section mismatch in reference from the function pci_root_bus_res() to the function .init.text:update_res() The function __devinit pci_root_bus_res() references a function __init update_res(). If update_res is only used by pci_root_bus_res then annotate update_res with a matching annotation. Signed-off-by: Jiri Slaby Cc: Aristeu Sergio Cc: Jesse Barnes Cc: linux-pci@vger.kernel.org Cc: x86@kernel.org Signed-off-by: Hidetoshi Seto Signed-off-by: Jesse Barnes diff --git a/arch/x86/pci/bus_numa.c b/arch/x86/pci/bus_numa.c index 145df00..f939d60 100644 --- a/arch/x86/pci/bus_numa.c +++ b/arch/x86/pci/bus_numa.c @@ -51,7 +51,7 @@ void x86_pci_root_bus_res_quirks(struct pci_bus *b) } } -void __init update_res(struct pci_root_info *info, size_t start, +void __devinit update_res(struct pci_root_info *info, size_t start, size_t end, unsigned long flags, int merge) { int i; -- cgit v0.10.2 From 45e829ea412760d2404d7dfc42528df46aedbf62 Mon Sep 17 00:00:00 2001 From: Stefan Assmann Date: Thu, 3 Dec 2009 06:49:24 -0500 Subject: PCI: change PCI nomenclature in drivers/pci/ (comment changes) Changing occurrences of variants of PCI-X and PCIe to the PCI-SIG terms listed in the "Trademark and Logo Usage Guidelines". http://www.pcisig.com/developers/procedures/logos/Trademark_and_Logo_Usage_Guidelines_updated_112206.pdf Patch is limited to drivers/pci/ and changes concern comments only. Signed-off-by: Stefan Assmann Signed-off-by: Jesse Barnes diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h index bd588eb..8e210cd7 100644 --- a/drivers/pci/hotplug/shpchp.h +++ b/drivers/pci/hotplug/shpchp.h @@ -121,7 +121,7 @@ struct controller { #define PCI_DEVICE_ID_AMD_GOLAM_7450 0x7450 #define PCI_DEVICE_ID_AMD_POGO_7458 0x7458 -/* AMD PCIX bridge registers */ +/* AMD PCI-X bridge registers */ #define PCIX_MEM_BASE_LIMIT_OFFSET 0x1C #define PCIX_MISCII_OFFSET 0x48 #define PCIX_MISC_BRIDGE_ERRORS_OFFSET 0x80 diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index 8d61594..25e15d5 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c @@ -304,7 +304,7 @@ struct device_domain_info { int segment; /* PCI domain */ u8 bus; /* PCI bus number */ u8 devfn; /* PCI devfn number */ - struct pci_dev *dev; /* it's NULL for PCIE-to-PCI bridge */ + struct pci_dev *dev; /* it's NULL for PCIe-to-PCI bridge */ struct intel_iommu *iommu; /* IOMMU used by this device */ struct dmar_domain *domain; /* pointer to domain */ }; @@ -1611,7 +1611,7 @@ domain_context_mapping(struct dmar_domain *domain, struct pci_dev *pdev, return ret; parent = parent->bus->self; } - if (pci_is_pcie(tmp)) /* this is a PCIE-to-PCI bridge */ + if (pci_is_pcie(tmp)) /* this is a PCIe-to-PCI bridge */ return domain_context_mapping_one(domain, pci_domain_nr(tmp->subordinate), tmp->subordinate->number, 0, @@ -3319,7 +3319,7 @@ static void iommu_detach_dependent_devices(struct intel_iommu *iommu, parent->devfn); parent = parent->bus->self; } - if (pci_is_pcie(tmp)) /* this is a PCIE-to-PCI bridge */ + if (pci_is_pcie(tmp)) /* this is a PCIe-to-PCI bridge */ iommu_detach_dev(iommu, tmp->subordinate->number, 0); else /* this is a legacy PCI bridge */ diff --git a/drivers/pci/intr_remapping.c b/drivers/pci/intr_remapping.c index 1487bf2..c26caf1 100644 --- a/drivers/pci/intr_remapping.c +++ b/drivers/pci/intr_remapping.c @@ -528,7 +528,7 @@ int set_msi_sid(struct irte *irte, struct pci_dev *dev) bridge = pci_find_upstream_pcie_bridge(dev); if (bridge) { - if (pci_is_pcie(bridge))/* this is a PCIE-to-PCI/PCIX bridge */ + if (pci_is_pcie(bridge))/* this is a PCIe-to-PCI/PCIX bridge */ set_irte_sid(irte, SVT_VERIFY_BUS, SQ_ALL_16, (bridge->bus->number << 8) | dev->bus->number); else /* this is a legacy PCI bridge */ diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 6011d06..d50522b 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1153,11 +1153,11 @@ pci_disable_device(struct pci_dev *dev) /** * pcibios_set_pcie_reset_state - set reset state for device dev - * @dev: the PCI-E device reset + * @dev: the PCIe device reset * @state: Reset state to enter into * * - * Sets the PCI-E reset state for the device. This is the default + * Sets the PCIe reset state for the device. This is the default * implementation. Architecture implementations can override this. */ int __attribute__ ((weak)) pcibios_set_pcie_reset_state(struct pci_dev *dev, @@ -1168,7 +1168,7 @@ int __attribute__ ((weak)) pcibios_set_pcie_reset_state(struct pci_dev *dev, /** * pci_set_pcie_reset_state - set reset state for device dev - * @dev: the PCI-E device reset + * @dev: the PCIe device reset * @state: Reset state to enter into * * diff --git a/drivers/pci/pcie/aer/aer_inject.c b/drivers/pci/pcie/aer/aer_inject.c index 7fcd5331..0cae0f2 100644 --- a/drivers/pci/pcie/aer/aer_inject.c +++ b/drivers/pci/pcie/aer/aer_inject.c @@ -1,7 +1,7 @@ /* - * PCIE AER software error injection support. + * PCIe AER software error injection support. * - * Debuging PCIE AER code is quite difficult because it is hard to + * Debuging PCIe AER code is quite difficult because it is hard to * trigger various real hardware errors. Software based error * injection can fake almost all kinds of errors with the help of a * user space helper tool aer-inject, which can be gotten from: diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c index 97a3459..21f215f 100644 --- a/drivers/pci/pcie/aer/aerdrv.c +++ b/drivers/pci/pcie/aer/aerdrv.c @@ -155,7 +155,7 @@ static struct aer_rpc *aer_alloc_rpc(struct pcie_device *dev) mutex_init(&rpc->rpc_mutex); init_waitqueue_head(&rpc->wait_release); - /* Use PCIE bus function to store rpc into PCIE device */ + /* Use PCIe bus function to store rpc into PCIe device */ set_service_data(dev, rpc); return rpc; diff --git a/drivers/pci/pcie/aer/aerdrv_acpi.c b/drivers/pci/pcie/aer/aerdrv_acpi.c index 8edb2f3..0481408 100644 --- a/drivers/pci/pcie/aer/aerdrv_acpi.c +++ b/drivers/pci/pcie/aer/aerdrv_acpi.c @@ -24,7 +24,7 @@ * * @return: Zero on success. Nonzero otherwise. * - * Invoked when PCIE bus loads AER service driver. To avoid conflict with + * Invoked when PCIe bus loads AER service driver. To avoid conflict with * BIOS AER support requires BIOS to yield AER control to OS native driver. **/ int aer_osc_setup(struct pcie_device *pciedev) diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index ae672ca..c843a79 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c @@ -587,7 +587,7 @@ static void handle_error_source(struct pcie_device *aerdev, * aer_enable_rootport - enable Root Port's interrupts when receiving messages * @rpc: pointer to a Root Port data structure * - * Invoked when PCIE bus loads AER service driver. + * Invoked when PCIe bus loads AER service driver. */ void aer_enable_rootport(struct aer_rpc *rpc) { @@ -597,7 +597,7 @@ void aer_enable_rootport(struct aer_rpc *rpc) u32 reg32; pos = pci_pcie_cap(pdev); - /* Clear PCIE Capability's Device Status */ + /* Clear PCIe Capability's Device Status */ pci_read_config_word(pdev, pos+PCI_EXP_DEVSTA, ®16); pci_write_config_word(pdev, pos+PCI_EXP_DEVSTA, reg16); @@ -631,7 +631,7 @@ void aer_enable_rootport(struct aer_rpc *rpc) * disable_root_aer - disable Root Port's interrupts when receiving messages * @rpc: pointer to a Root Port data structure * - * Invoked when PCIE bus unloads AER service driver. + * Invoked when PCIe bus unloads AER service driver. */ static void disable_root_aer(struct aer_rpc *rpc) { diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 5a01fc7..be53d98 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c @@ -1,6 +1,6 @@ /* * File: drivers/pci/pcie/aspm.c - * Enabling PCIE link L0s/L1 state and Clock Power Management + * Enabling PCIe link L0s/L1 state and Clock Power Management * * Copyright (C) 2007 Intel * Copyright (C) Zhang Yanmin (yanmin.zhang@intel.com) @@ -499,7 +499,7 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev) int pos; u32 reg32; /* - * Some functions in a slot might not all be PCIE functions, + * Some functions in a slot might not all be PCIe functions, * very strange. Disable ASPM for the whole slot */ list_for_each_entry(child, &pdev->subordinate->devices, bus_list) { diff --git a/drivers/pci/search.c b/drivers/pci/search.c index 6dae871..4a471dc 100644 --- a/drivers/pci/search.c +++ b/drivers/pci/search.c @@ -15,9 +15,9 @@ DECLARE_RWSEM(pci_bus_sem); /* - * find the upstream PCIE-to-PCI bridge of a PCI device + * find the upstream PCIe-to-PCI bridge of a PCI device * if the device is PCIE, return NULL - * if the device isn't connected to a PCIE bridge (that is its parent is a + * if the device isn't connected to a PCIe bridge (that is its parent is a * legacy PCI bridge and the bridge is directly connected to bus 0), return its * parent */ @@ -37,7 +37,7 @@ pci_find_upstream_pcie_bridge(struct pci_dev *pdev) tmp = pdev; continue; } - /* PCI device should connect to a PCIE bridge */ + /* PCI device should connect to a PCIe bridge */ if (pdev->pcie_type != PCI_EXP_TYPE_PCI_BRIDGE) { /* Busted hardware? */ WARN_ON_ONCE(1); -- cgit v0.10.2 From 7e8af37a9a71b479f58d2fd5f0ddaa6780c51f11 Mon Sep 17 00:00:00 2001 From: Stefan Assmann Date: Thu, 3 Dec 2009 18:00:10 +0100 Subject: PCI: change PCI nomenclature in drivers/pci/ (non-comment changes) Changing occurrences of variants of PCI-X and PCIe to the PCI-SIG terms listed in the "Trademark and Logo Usage Guidelines". http://www.pcisig.com/developers/procedures/logos/Trademark_and_Logo_Usage_Guidelines_updated_112206.pdf Patch is limited to drivers/pci/ and changes concern non-comment parts or anything that might be visible to the user. Signed-off-by: Stefan Assmann Signed-off-by: Jesse Barnes diff --git a/drivers/pci/pcie/aer/Kconfig.debug b/drivers/pci/pcie/aer/Kconfig.debug index b8c925c..9142949 100644 --- a/drivers/pci/pcie/aer/Kconfig.debug +++ b/drivers/pci/pcie/aer/Kconfig.debug @@ -3,14 +3,14 @@ # config PCIEAER_INJECT - tristate "PCIE AER error injector support" + tristate "PCIe AER error injector support" depends on PCIEAER default n help This enables PCI Express Root Port Advanced Error Reporting (AER) software error injector. - Debuging PCIE AER code is quite difficult because it is hard + Debugging PCIe AER code is quite difficult because it is hard to trigger various real hardware errors. Software based error injection can fake almost all kinds of errors with the help of a user space helper tool aer-inject, which can be diff --git a/drivers/pci/pcie/aer/aer_inject.c b/drivers/pci/pcie/aer/aer_inject.c index 0cae0f2..797d478 100644 --- a/drivers/pci/pcie/aer/aer_inject.c +++ b/drivers/pci/pcie/aer/aer_inject.c @@ -484,5 +484,5 @@ static void __exit aer_inject_exit(void) module_init(aer_inject_init); module_exit(aer_inject_exit); -MODULE_DESCRIPTION("PCIE AER software error injector"); +MODULE_DESCRIPTION("PCIe AER software error injector"); MODULE_LICENSE("GPL"); diff --git a/drivers/pci/pcie/aer/aerdrv_errprint.c b/drivers/pci/pcie/aer/aerdrv_errprint.c index 44acde7..9d3e4c8 100644 --- a/drivers/pci/pcie/aer/aerdrv_errprint.c +++ b/drivers/pci/pcie/aer/aerdrv_errprint.c @@ -184,7 +184,7 @@ void aer_print_error(struct pci_dev *dev, struct aer_err_info *info) if (info->status == 0) { AER_PR(info, dev, - "PCIE Bus Error: severity=%s, type=Unaccessible, " + "PCIe Bus Error: severity=%s, type=Unaccessible, " "id=%04x(Unregistered Agent ID)\n", aer_error_severity_string[info->severity], id); } else { @@ -194,7 +194,7 @@ void aer_print_error(struct pci_dev *dev, struct aer_err_info *info) agent = AER_GET_AGENT(info->severity, info->status); AER_PR(info, dev, - "PCIE Bus Error: severity=%s, type=%s, id=%04x(%s)\n", + "PCIe Bus Error: severity=%s, type=%s, id=%04x(%s)\n", aer_error_severity_string[info->severity], aer_error_layer[layer], id, aer_agent_string[agent]); diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index a49452e..34d6517 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c @@ -24,7 +24,7 @@ */ #define DRIVER_VERSION "v1.0" #define DRIVER_AUTHOR "tom.l.nguyen@intel.com" -#define DRIVER_DESC "PCIE Port Bus Driver" +#define DRIVER_DESC "PCIe Port Bus Driver" MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From 49ae35f2dd1ff78ee88d5f8a38d0af63c3ad9f71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Wed, 16 Dec 2009 15:16:15 -0500 Subject: drm/i915: Move PCI IDs into i915 driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The old include/drm/drm_pciids.h used to be generated from the libdrm git repo. We don't use that anymore so just use a local list in the driver like everybody else. Signed-off-by: Kristian Høgsberg Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 6978a22..b6ec949 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -33,7 +33,6 @@ #include "i915_drm.h" #include "i915_drv.h" -#include "drm_pciids.h" #include #include "drm_crtc_helper.h" @@ -48,8 +47,47 @@ module_param_named(powersave, i915_powersave, int, 0400); static struct drm_driver driver; +#define INTEL_VGA_DEVICE(id) { \ + .class = PCI_CLASS_DISPLAY_VGA << 8, \ + .class_mask = 0xffff00, \ + .vendor = 0x8086, \ + .device = id, \ + .subvendor = PCI_ANY_ID, \ + .subdevice = PCI_ANY_ID, \ + .driver_data = 0 } + static struct pci_device_id pciidlist[] = { - i915_PCI_IDS + INTEL_VGA_DEVICE(0x3577), + INTEL_VGA_DEVICE(0x2562), + INTEL_VGA_DEVICE(0x3582), + INTEL_VGA_DEVICE(0x2572), + INTEL_VGA_DEVICE(0x2582), + INTEL_VGA_DEVICE(0x258a), + INTEL_VGA_DEVICE(0x2592), + INTEL_VGA_DEVICE(0x2772), + INTEL_VGA_DEVICE(0x27a2), + INTEL_VGA_DEVICE(0x27ae), + INTEL_VGA_DEVICE(0x2972), + INTEL_VGA_DEVICE(0x2982), + INTEL_VGA_DEVICE(0x2992), + INTEL_VGA_DEVICE(0x29a2), + INTEL_VGA_DEVICE(0x29b2), + INTEL_VGA_DEVICE(0x29c2), + INTEL_VGA_DEVICE(0x29d2), + INTEL_VGA_DEVICE(0x2a02), + INTEL_VGA_DEVICE(0x2a12), + INTEL_VGA_DEVICE(0x2a42), + INTEL_VGA_DEVICE(0x2e02), + INTEL_VGA_DEVICE(0x2e12), + INTEL_VGA_DEVICE(0x2e22), + INTEL_VGA_DEVICE(0x2e32), + INTEL_VGA_DEVICE(0x2e42), + INTEL_VGA_DEVICE(0xa001), + INTEL_VGA_DEVICE(0xa011), + INTEL_VGA_DEVICE(0x35e8), + INTEL_VGA_DEVICE(0x0042), + INTEL_VGA_DEVICE(0x0046), + {0, 0, 0} }; #if defined(CONFIG_DRM_I915_KMS) -- cgit v0.10.2 From cfdf1fa23f4074c9f8766dc67a928bbf680b1ac9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Wed, 16 Dec 2009 15:16:16 -0500 Subject: drm/i915: Implement IS_* macros using static tables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of using the IS_I9XX etc macros that expand to a ton of comparisons, use new struct intel_device_info to capture the capabilities of the different chipsets. The drm_i915_private struct will be initialized to point to the device info that correspond to the actual device and this way, testing for a specific capability is just a matter of checking a bit field. Signed-off-by: Kristian Høgsberg Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 701bfea..549e46c 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1360,7 +1360,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) { struct drm_i915_private *dev_priv = dev->dev_private; resource_size_t base, size; - int ret = 0, mmio_bar = IS_I9XX(dev) ? 0 : 1; + int ret = 0, mmio_bar; uint32_t agp_size, prealloc_size, prealloc_start; /* i915 has 4 more counters */ @@ -1376,8 +1376,10 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) dev->dev_private = (void *)dev_priv; dev_priv->dev = dev; + dev_priv->info = (struct intel_device_info *) flags; /* Add register map (needed for suspend/resume) */ + mmio_bar = IS_I9XX(dev) ? 0 : 1; base = drm_get_resource_start(dev, mmio_bar); size = drm_get_resource_len(dev, mmio_bar); diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index b6ec949..1b256de 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -47,46 +47,122 @@ module_param_named(powersave, i915_powersave, int, 0400); static struct drm_driver driver; -#define INTEL_VGA_DEVICE(id) { \ +#define INTEL_VGA_DEVICE(id, info) { \ .class = PCI_CLASS_DISPLAY_VGA << 8, \ .class_mask = 0xffff00, \ .vendor = 0x8086, \ .device = id, \ .subvendor = PCI_ANY_ID, \ .subdevice = PCI_ANY_ID, \ - .driver_data = 0 } - -static struct pci_device_id pciidlist[] = { - INTEL_VGA_DEVICE(0x3577), - INTEL_VGA_DEVICE(0x2562), - INTEL_VGA_DEVICE(0x3582), - INTEL_VGA_DEVICE(0x2572), - INTEL_VGA_DEVICE(0x2582), - INTEL_VGA_DEVICE(0x258a), - INTEL_VGA_DEVICE(0x2592), - INTEL_VGA_DEVICE(0x2772), - INTEL_VGA_DEVICE(0x27a2), - INTEL_VGA_DEVICE(0x27ae), - INTEL_VGA_DEVICE(0x2972), - INTEL_VGA_DEVICE(0x2982), - INTEL_VGA_DEVICE(0x2992), - INTEL_VGA_DEVICE(0x29a2), - INTEL_VGA_DEVICE(0x29b2), - INTEL_VGA_DEVICE(0x29c2), - INTEL_VGA_DEVICE(0x29d2), - INTEL_VGA_DEVICE(0x2a02), - INTEL_VGA_DEVICE(0x2a12), - INTEL_VGA_DEVICE(0x2a42), - INTEL_VGA_DEVICE(0x2e02), - INTEL_VGA_DEVICE(0x2e12), - INTEL_VGA_DEVICE(0x2e22), - INTEL_VGA_DEVICE(0x2e32), - INTEL_VGA_DEVICE(0x2e42), - INTEL_VGA_DEVICE(0xa001), - INTEL_VGA_DEVICE(0xa011), - INTEL_VGA_DEVICE(0x35e8), - INTEL_VGA_DEVICE(0x0042), - INTEL_VGA_DEVICE(0x0046), + .driver_data = (unsigned long) info } + +const static struct intel_device_info intel_i830_info = { + .is_i8xx = 1, .is_mobile = 1, +}; + +const static struct intel_device_info intel_845g_info = { + .is_i8xx = 1, +}; + +const static struct intel_device_info intel_i85x_info = { + .is_i8xx = 1, .is_mobile = 1, +}; + +const static struct intel_device_info intel_i865g_info = { + .is_i8xx = 1, +}; + +const static struct intel_device_info intel_i915g_info = { + .is_i915g = 1, .is_i9xx = 1, +}; +const static struct intel_device_info intel_i915gm_info = { + .is_i9xx = 1, .is_mobile = 1, .has_fbc = 1, +}; +const static struct intel_device_info intel_i945g_info = { + .is_i9xx = 1, .has_hotplug = 1, +}; +const static struct intel_device_info intel_i945gm_info = { + .is_i945gm = 1, .is_i9xx = 1, .is_mobile = 1, .has_fbc = 1, + .has_hotplug = 1, +}; + +const static struct intel_device_info intel_i965g_info = { + .is_i965g = 1, .is_i9xx = 1, .has_hotplug = 1, +}; + +const static struct intel_device_info intel_i965gm_info = { + .is_i965g = 1, .is_mobile = 1, .is_i965gm = 1, .is_i9xx = 1, + .is_mobile = 1, .has_fbc = 1, .has_rc6 = 1, + .has_hotplug = 1, +}; + +const static struct intel_device_info intel_g33_info = { + .is_g33 = 1, .is_i9xx = 1, .need_gfx_hws = 1, + .has_hotplug = 1, +}; + +const static struct intel_device_info intel_g45_info = { + .is_i965g = 1, .is_g4x = 1, .is_i9xx = 1, .need_gfx_hws = 1, + .has_pipe_cxsr = 1, + .has_hotplug = 1, +}; + +const static struct intel_device_info intel_gm45_info = { + .is_i965g = 1, .is_mobile = 1, .is_g4x = 1, .is_i9xx = 1, + .is_mobile = 1, .need_gfx_hws = 1, .has_fbc = 1, .has_rc6 = 1, + .has_pipe_cxsr = 1, + .has_hotplug = 1, +}; + +const static struct intel_device_info intel_pineview_info = { + .is_g33 = 1, .is_pineview = 1, .is_mobile = 1, .is_i9xx = 1, + .has_pipe_cxsr = 1, + .has_hotplug = 1, +}; + +const static struct intel_device_info intel_ironlake_d_info = { + .is_ironlake = 1, .is_i965g = 1, .is_i9xx = 1, .need_gfx_hws = 1, + .has_pipe_cxsr = 1, + .has_hotplug = 1, +}; + +const static struct intel_device_info intel_ironlake_m_info = { + .is_ironlake = 1, .is_mobile = 1, .is_i965g = 1, .is_i9xx = 1, + .need_gfx_hws = 1, .has_rc6 = 1, + .has_hotplug = 1, +}; + +const static struct pci_device_id pciidlist[] = { + INTEL_VGA_DEVICE(0x3577, &intel_i830_info), + INTEL_VGA_DEVICE(0x2562, &intel_845g_info), + INTEL_VGA_DEVICE(0x3582, &intel_i85x_info), + INTEL_VGA_DEVICE(0x35e8, &intel_i85x_info), + INTEL_VGA_DEVICE(0x2572, &intel_i865g_info), + INTEL_VGA_DEVICE(0x2582, &intel_i915g_info), + INTEL_VGA_DEVICE(0x258a, &intel_i915g_info), + INTEL_VGA_DEVICE(0x2592, &intel_i915gm_info), + INTEL_VGA_DEVICE(0x2772, &intel_i945g_info), + INTEL_VGA_DEVICE(0x27a2, &intel_i945gm_info), + INTEL_VGA_DEVICE(0x27ae, &intel_i945gm_info), + INTEL_VGA_DEVICE(0x2972, &intel_i965g_info), + INTEL_VGA_DEVICE(0x2982, &intel_i965g_info), + INTEL_VGA_DEVICE(0x2992, &intel_i965g_info), + INTEL_VGA_DEVICE(0x29a2, &intel_i965g_info), + INTEL_VGA_DEVICE(0x29b2, &intel_g33_info), + INTEL_VGA_DEVICE(0x29c2, &intel_g33_info), + INTEL_VGA_DEVICE(0x29d2, &intel_g33_info), + INTEL_VGA_DEVICE(0x2a02, &intel_i965gm_info), + INTEL_VGA_DEVICE(0x2a12, &intel_i965gm_info), + INTEL_VGA_DEVICE(0x2a42, &intel_gm45_info), + INTEL_VGA_DEVICE(0x2e02, &intel_g45_info), + INTEL_VGA_DEVICE(0x2e12, &intel_g45_info), + INTEL_VGA_DEVICE(0x2e22, &intel_g45_info), + INTEL_VGA_DEVICE(0x2e32, &intel_g45_info), + INTEL_VGA_DEVICE(0x2e42, &intel_g45_info), + INTEL_VGA_DEVICE(0xa001, &intel_pineview_info), + INTEL_VGA_DEVICE(0xa011, &intel_pineview_info), + INTEL_VGA_DEVICE(0x0042, &intel_ironlake_d_info), + INTEL_VGA_DEVICE(0x0046, &intel_ironlake_m_info), {0, 0, 0} }; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 25c1047..0d24e03 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -172,9 +172,30 @@ struct drm_i915_display_funcs { struct intel_overlay; +struct intel_device_info { + u8 is_mobile : 1; + u8 is_i8xx : 1; + u8 is_i915g : 1; + u8 is_i9xx : 1; + u8 is_i945gm : 1; + u8 is_i965g : 1; + u8 is_i965gm : 1; + u8 is_g33 : 1; + u8 need_gfx_hws : 1; + u8 is_g4x : 1; + u8 is_pineview : 1; + u8 is_ironlake : 1; + u8 has_fbc : 1; + u8 has_rc6 : 1; + u8 has_pipe_cxsr : 1; + u8 has_hotplug : 1; +}; + typedef struct drm_i915_private { struct drm_device *dev; + const struct intel_device_info *info; + int has_gem; void __iomem *regs; @@ -983,67 +1004,33 @@ extern void g4x_disable_fbc(struct drm_device *dev); extern int i915_wrap_ring(struct drm_device * dev); extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); -#define IS_I830(dev) ((dev)->pci_device == 0x3577) -#define IS_845G(dev) ((dev)->pci_device == 0x2562) -#define IS_I85X(dev) ((dev)->pci_device == 0x3582) -#define IS_I865G(dev) ((dev)->pci_device == 0x2572) -#define IS_I8XX(dev) (IS_I830(dev) || IS_845G(dev) || IS_I85X(dev) || IS_I865G(dev)) - -#define IS_I915G(dev) ((dev)->pci_device == 0x2582 || (dev)->pci_device == 0x258a) -#define IS_I915GM(dev) ((dev)->pci_device == 0x2592) -#define IS_I945G(dev) ((dev)->pci_device == 0x2772) -#define IS_I945GM(dev) ((dev)->pci_device == 0x27A2 ||\ - (dev)->pci_device == 0x27AE) -#define IS_I965G(dev) ((dev)->pci_device == 0x2972 || \ - (dev)->pci_device == 0x2982 || \ - (dev)->pci_device == 0x2992 || \ - (dev)->pci_device == 0x29A2 || \ - (dev)->pci_device == 0x2A02 || \ - (dev)->pci_device == 0x2A12 || \ - (dev)->pci_device == 0x2A42 || \ - (dev)->pci_device == 0x2E02 || \ - (dev)->pci_device == 0x2E12 || \ - (dev)->pci_device == 0x2E22 || \ - (dev)->pci_device == 0x2E32 || \ - (dev)->pci_device == 0x2E42 || \ - (dev)->pci_device == 0x0042 || \ - (dev)->pci_device == 0x0046) - -#define IS_I965GM(dev) ((dev)->pci_device == 0x2A02 || \ - (dev)->pci_device == 0x2A12) - -#define IS_GM45(dev) ((dev)->pci_device == 0x2A42) - -#define IS_G4X(dev) ((dev)->pci_device == 0x2E02 || \ - (dev)->pci_device == 0x2E12 || \ - (dev)->pci_device == 0x2E22 || \ - (dev)->pci_device == 0x2E32 || \ - (dev)->pci_device == 0x2E42 || \ - IS_GM45(dev)) - -#define IS_PINEVIEW_G(dev) ((dev)->pci_device == 0xa001) -#define IS_PINEVIEW_M(dev) ((dev)->pci_device == 0xa011) -#define IS_PINEVIEW(dev) (IS_PINEVIEW_G(dev) || IS_PINEVIEW_M(dev)) - -#define IS_G33(dev) ((dev)->pci_device == 0x29C2 || \ - (dev)->pci_device == 0x29B2 || \ - (dev)->pci_device == 0x29D2 || \ - (IS_PINEVIEW(dev))) - +#define INTEL_INFO(dev) (((struct drm_i915_private *) (dev)->dev_private)->info) + +#define IS_I830(dev) ((dev)->pci_device == 0x3577) +#define IS_845G(dev) ((dev)->pci_device == 0x2562) +#define IS_I85X(dev) ((dev)->pci_device == 0x3582) +#define IS_I865G(dev) ((dev)->pci_device == 0x2572) +#define IS_I8XX(dev) (INTEL_INFO(dev)->is_i8xx) +#define IS_I915G(dev) (INTEL_INFO(dev)->is_i915g) +#define IS_I915GM(dev) ((dev)->pci_device == 0x2592) +#define IS_I945G(dev) ((dev)->pci_device == 0x2772) +#define IS_I945GM(dev) (INTEL_INFO(dev)->is_i945gm) +#define IS_I965G(dev) (INTEL_INFO(dev)->is_i965g) +#define IS_I965GM(dev) (INTEL_INFO(dev)->is_i965gm) +#define IS_GM45(dev) ((dev)->pci_device == 0x2A42) +#define IS_G4X(dev) (INTEL_INFO(dev)->is_g4x) +#define IS_PINEVIEW_G(dev) ((dev)->pci_device == 0xa001) +#define IS_PINEVIEW_M(dev) ((dev)->pci_device == 0xa011) +#define IS_PINEVIEW(dev) (INTEL_INFO(dev)->is_pineview) +#define IS_G33(dev) (INTEL_INFO(dev)->is_g33) #define IS_IRONLAKE_D(dev) ((dev)->pci_device == 0x0042) #define IS_IRONLAKE_M(dev) ((dev)->pci_device == 0x0046) -#define IS_IRONLAKE(dev) (IS_IRONLAKE_D(dev) || IS_IRONLAKE_M(dev)) - -#define IS_I9XX(dev) (IS_I915G(dev) || IS_I915GM(dev) || IS_I945G(dev) || \ - IS_I945GM(dev) || IS_I965G(dev) || IS_G33(dev) || \ - IS_IRONLAKE(dev)) +#define IS_IRONLAKE(dev) (INTEL_INFO(dev)->is_ironlake) +#define IS_I9XX(dev) (INTEL_INFO(dev)->is_i9xx) +#define IS_MOBILE(dev) (INTEL_INFO(dev)->is_mobile) -#define IS_MOBILE(dev) (IS_I830(dev) || IS_I85X(dev) || IS_I915GM(dev) || \ - IS_I945GM(dev) || IS_I965GM(dev) || IS_GM45(dev) || \ - IS_PINEVIEW(dev) || IS_IRONLAKE_M(dev)) +#define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws) -#define I915_NEED_GFX_HWS(dev) (IS_G33(dev) || IS_GM45(dev) || IS_G4X(dev) || \ - IS_IRONLAKE(dev)) /* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte * rows, which changed the alignment requirements and fence programming. */ @@ -1055,17 +1042,14 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); #define SUPPORTS_EDP(dev) (IS_IRONLAKE_M(dev)) #define SUPPORTS_TV(dev) (IS_I9XX(dev) && IS_MOBILE(dev) && \ !IS_IRONLAKE(dev) && !IS_PINEVIEW(dev)) -#define I915_HAS_HOTPLUG(dev) (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev) || IS_I965G(dev)) +#define I915_HAS_HOTPLUG(dev) (INTEL_INFO(dev)->has_hotplug) /* dsparb controlled by hw only */ #define DSPARB_HWCONTROL(dev) (IS_G4X(dev) || IS_IRONLAKE(dev)) #define HAS_FW_BLC(dev) (IS_I9XX(dev) || IS_G4X(dev) || IS_IRONLAKE(dev)) -#define HAS_PIPE_CXSR(dev) (IS_G4X(dev) || IS_IRONLAKE(dev)) -#define I915_HAS_FBC(dev) (IS_MOBILE(dev) && \ - (IS_I9XX(dev) || IS_GM45(dev)) && \ - !IS_PINEVIEW(dev) && \ - !IS_IRONLAKE(dev)) -#define I915_HAS_RC6(dev) (IS_I965GM(dev) || IS_GM45(dev) || IS_IRONLAKE_M(dev)) +#define HAS_PIPE_CXSR(dev) (INTEL_INFO(dev)->has_pipe_cxsr) +#define I915_HAS_FBC(dev) (INTEL_INFO(dev)->has_fbc) +#define I915_HAS_RC6(dev) (INTEL_INFO(dev)->has_rc6) #define PRIMARY_RINGBUFFER_SIZE (128*1024) -- cgit v0.10.2 From b295d1b6e3e3f240d27cbe556d33ff5eb54721a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Wed, 16 Dec 2009 15:16:17 -0500 Subject: drm/i915: Track whether cursor needs physical address in intel_device_info MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Kristian Høgsberg Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 549e46c..28d99b8 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1200,14 +1200,6 @@ static int i915_load_modeset_init(struct drm_device *dev, dev->mode_config.fb_base = drm_get_resource_start(dev, fb_bar) & 0xff000000; - if (IS_MOBILE(dev) || IS_I9XX(dev)) - dev_priv->cursor_needs_physical = true; - else - dev_priv->cursor_needs_physical = false; - - if (IS_I965G(dev) || IS_G33(dev)) - dev_priv->cursor_needs_physical = false; - /* Basic memrange allocator for stolen space (aka vram) */ drm_mm_init(&dev_priv->vram, 0, prealloc_size); DRM_INFO("set up %ldM of stolen space\n", prealloc_size / (1024*1024)); diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 1b256de..a0a2cad 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -57,7 +57,7 @@ static struct drm_driver driver; .driver_data = (unsigned long) info } const static struct intel_device_info intel_i830_info = { - .is_i8xx = 1, .is_mobile = 1, + .is_i8xx = 1, .is_mobile = 1, .cursor_needs_physical = 1, }; const static struct intel_device_info intel_845g_info = { @@ -65,7 +65,7 @@ const static struct intel_device_info intel_845g_info = { }; const static struct intel_device_info intel_i85x_info = { - .is_i8xx = 1, .is_mobile = 1, + .is_i8xx = 1, .is_mobile = 1, .cursor_needs_physical = 1, }; const static struct intel_device_info intel_i865g_info = { @@ -73,17 +73,18 @@ const static struct intel_device_info intel_i865g_info = { }; const static struct intel_device_info intel_i915g_info = { - .is_i915g = 1, .is_i9xx = 1, + .is_i915g = 1, .is_i9xx = 1, .cursor_needs_physical = 1, }; const static struct intel_device_info intel_i915gm_info = { .is_i9xx = 1, .is_mobile = 1, .has_fbc = 1, + .cursor_needs_physical = 1, }; const static struct intel_device_info intel_i945g_info = { - .is_i9xx = 1, .has_hotplug = 1, + .is_i9xx = 1, .has_hotplug = 1, .cursor_needs_physical = 1, }; const static struct intel_device_info intel_i945gm_info = { .is_i945gm = 1, .is_i9xx = 1, .is_mobile = 1, .has_fbc = 1, - .has_hotplug = 1, + .has_hotplug = 1, .cursor_needs_physical = 1, }; const static struct intel_device_info intel_i965g_info = { diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 0d24e03..9a05f1a 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -189,6 +189,7 @@ struct intel_device_info { u8 has_rc6 : 1; u8 has_pipe_cxsr : 1; u8 has_hotplug : 1; + u8 cursor_needs_physical : 1; }; typedef struct drm_i915_private { @@ -253,8 +254,6 @@ typedef struct drm_i915_private { int hangcheck_count; uint32_t last_acthd; - bool cursor_needs_physical; - struct drm_mm vram; unsigned long cfb_size; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 52cd9b0..ef9c613 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3385,7 +3385,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, /* we only need to pin inside GTT if cursor is non-phy */ mutex_lock(&dev->struct_mutex); - if (!dev_priv->cursor_needs_physical) { + if (!dev_priv->info->cursor_needs_physical) { ret = i915_gem_object_pin(bo, PAGE_SIZE); if (ret) { DRM_ERROR("failed to pin cursor bo\n"); @@ -3420,7 +3420,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, I915_WRITE(base, addr); if (intel_crtc->cursor_bo) { - if (dev_priv->cursor_needs_physical) { + if (dev_priv->info->cursor_needs_physical) { if (intel_crtc->cursor_bo != bo) i915_gem_detach_phys_object(dev, intel_crtc->cursor_bo); } else -- cgit v0.10.2 From b01f2c3a4a37d09a47ad73ccbb46d554d21cfeb0 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Fri, 11 Dec 2009 11:07:17 -0800 Subject: drm/i915: only enable hotplug for detected outputs This patch changes around our hotplug enable code a bit to only enable it for ports we actually detect and initialize. This prevents problems with stuck or spurious interrupts on outputs that aren't actually wired up, and is generally more correct. Fixes FDO bug #23183. Signed-off-by: Jesse Barnes Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 28d99b8..e3e5d50 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1249,6 +1249,8 @@ static int i915_load_modeset_init(struct drm_device *dev, if (ret) goto destroy_ringbuffer; + intel_modeset_init(dev); + ret = drm_irq_install(dev); if (ret) goto destroy_ringbuffer; @@ -1263,8 +1265,6 @@ static int i915_load_modeset_init(struct drm_device *dev, I915_WRITE(INSTPM, (1 << 5) | (1 << 21)); - intel_modeset_init(dev); - drm_helper_initial_config(dev); return 0; diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 85f4c5d..1733eea 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1084,6 +1084,10 @@ void i915_driver_irq_preinstall(struct drm_device * dev) (void) I915_READ(IER); } +/* + * Must be called after intel_modeset_init or hotplug interrupts won't be + * enabled correctly. + */ int i915_driver_irq_postinstall(struct drm_device *dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; @@ -1106,19 +1110,23 @@ int i915_driver_irq_postinstall(struct drm_device *dev) if (I915_HAS_HOTPLUG(dev)) { u32 hotplug_en = I915_READ(PORT_HOTPLUG_EN); - /* Leave other bits alone */ - hotplug_en |= HOTPLUG_EN_MASK; + /* Note HDMI and DP share bits */ + if (dev_priv->hotplug_supported_mask & HDMIB_HOTPLUG_INT_STATUS) + hotplug_en |= HDMIB_HOTPLUG_INT_EN; + if (dev_priv->hotplug_supported_mask & HDMIC_HOTPLUG_INT_STATUS) + hotplug_en |= HDMIC_HOTPLUG_INT_EN; + if (dev_priv->hotplug_supported_mask & HDMID_HOTPLUG_INT_STATUS) + hotplug_en |= HDMID_HOTPLUG_INT_EN; + if (dev_priv->hotplug_supported_mask & SDVOC_HOTPLUG_INT_STATUS) + hotplug_en |= SDVOC_HOTPLUG_INT_EN; + if (dev_priv->hotplug_supported_mask & SDVOB_HOTPLUG_INT_STATUS) + hotplug_en |= SDVOB_HOTPLUG_INT_EN; + if (dev_priv->hotplug_supported_mask & CRT_HOTPLUG_INT_STATUS) + hotplug_en |= CRT_HOTPLUG_INT_EN; + /* Ignore TV since it's buggy */ + I915_WRITE(PORT_HOTPLUG_EN, hotplug_en); - dev_priv->hotplug_supported_mask = CRT_HOTPLUG_INT_STATUS | - TV_HOTPLUG_INT_STATUS | SDVOC_HOTPLUG_INT_STATUS | - SDVOB_HOTPLUG_INT_STATUS; - if (IS_G4X(dev)) { - dev_priv->hotplug_supported_mask |= - HDMIB_HOTPLUG_INT_STATUS | - HDMIC_HOTPLUG_INT_STATUS | - HDMID_HOTPLUG_INT_STATUS; - } /* Enable in IER... */ enable_mask |= I915_DISPLAY_PORT_INTERRUPT; /* and unmask in IMR */ diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 974b3cf..f79b133 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -879,13 +879,6 @@ #define CRT_HOTPLUG_DETECT_VOLTAGE_475MV (1 << 2) #define CRT_HOTPLUG_MASK (0x3fc) /* Bits 9-2 */ #define CRT_FORCE_HOTPLUG_MASK 0xfffffe1f -#define HOTPLUG_EN_MASK (HDMIB_HOTPLUG_INT_EN | \ - HDMIC_HOTPLUG_INT_EN | \ - HDMID_HOTPLUG_INT_EN | \ - SDVOB_HOTPLUG_INT_EN | \ - SDVOC_HOTPLUG_INT_EN | \ - CRT_HOTPLUG_INT_EN) - #define PORT_HOTPLUG_STAT 0x61114 #define HDMIB_HOTPLUG_INT_STATUS (1 << 29) diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 9f3d3e5..ddefc87 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -548,4 +548,6 @@ void intel_crt_init(struct drm_device *dev) drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs); drm_sysfs_connector_add(connector); + + dev_priv->hotplug_supported_mask |= CRT_HOTPLUG_INT_STATUS; } diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index ef9c613..c21dede 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4400,29 +4400,43 @@ static void intel_setup_outputs(struct drm_device *dev) bool found = false; if (I915_READ(SDVOB) & SDVO_DETECTED) { + DRM_DEBUG_KMS("probing SDVOB\n"); found = intel_sdvo_init(dev, SDVOB); - if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) + if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) { + DRM_DEBUG_KMS("probing HDMI on SDVOB\n"); intel_hdmi_init(dev, SDVOB); + } - if (!found && SUPPORTS_INTEGRATED_DP(dev)) + if (!found && SUPPORTS_INTEGRATED_DP(dev)) { + DRM_DEBUG_KMS("probing DP_B\n"); intel_dp_init(dev, DP_B); + } } /* Before G4X SDVOC doesn't have its own detect register */ - if (I915_READ(SDVOB) & SDVO_DETECTED) + if (I915_READ(SDVOB) & SDVO_DETECTED) { + DRM_DEBUG_KMS("probing SDVOC\n"); found = intel_sdvo_init(dev, SDVOC); + } if (!found && (I915_READ(SDVOC) & SDVO_DETECTED)) { - if (SUPPORTS_INTEGRATED_HDMI(dev)) + if (SUPPORTS_INTEGRATED_HDMI(dev)) { + DRM_DEBUG_KMS("probing HDMI on SDVOC\n"); intel_hdmi_init(dev, SDVOC); - if (SUPPORTS_INTEGRATED_DP(dev)) + } + if (SUPPORTS_INTEGRATED_DP(dev)) { + DRM_DEBUG_KMS("probing DP_C\n"); intel_dp_init(dev, DP_C); + } } - if (SUPPORTS_INTEGRATED_DP(dev) && (I915_READ(DP_D) & DP_DETECTED)) + if (SUPPORTS_INTEGRATED_DP(dev) && + (I915_READ(DP_D) & DP_DETECTED)) { + DRM_DEBUG_KMS("probing DP_D\n"); intel_dp_init(dev, DP_D); + } } else if (IS_I8XX(dev)) intel_dvo_init(dev); diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 4e7aa8b..1349d9f 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1402,14 +1402,20 @@ intel_dp_init(struct drm_device *dev, int output_reg) break; case DP_B: case PCH_DP_B: + dev_priv->hotplug_supported_mask |= + HDMIB_HOTPLUG_INT_STATUS; name = "DPDDC-B"; break; case DP_C: case PCH_DP_C: + dev_priv->hotplug_supported_mask |= + HDMIC_HOTPLUG_INT_STATUS; name = "DPDDC-C"; break; case DP_D: case PCH_DP_D: + dev_priv->hotplug_supported_mask |= + HDMID_HOTPLUG_INT_STATUS; name = "DPDDC-D"; break; } diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index f04dbbe..0643194 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -303,21 +303,26 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) if (sdvox_reg == SDVOB) { intel_output->clone_mask = (1 << INTEL_HDMIB_CLONE_BIT); intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "HDMIB"); + dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS; } else if (sdvox_reg == SDVOC) { intel_output->clone_mask = (1 << INTEL_HDMIC_CLONE_BIT); intel_output->ddc_bus = intel_i2c_create(dev, GPIOD, "HDMIC"); + dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS; } else if (sdvox_reg == HDMIB) { intel_output->clone_mask = (1 << INTEL_HDMID_CLONE_BIT); intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOE, "HDMIB"); + dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS; } else if (sdvox_reg == HDMIC) { intel_output->clone_mask = (1 << INTEL_HDMIE_CLONE_BIT); intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOD, "HDMIC"); + dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS; } else if (sdvox_reg == HDMID) { intel_output->clone_mask = (1 << INTEL_HDMIF_CLONE_BIT); intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOF, "HDMID"); + dev_priv->hotplug_supported_mask |= HDMID_HOTPLUG_INT_STATUS; } if (!intel_output->ddc_bus) goto err_connector; diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 24a3dc9..de5144c 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -2662,6 +2662,7 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector) bool intel_sdvo_init(struct drm_device *dev, int output_device) { + struct drm_i915_private *dev_priv = dev->dev_private; struct drm_connector *connector; struct intel_output *intel_output; struct intel_sdvo_priv *sdvo_priv; @@ -2708,10 +2709,12 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS"); sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA, "SDVOB/VGA DDC BUS"); + dev_priv->hotplug_supported_mask |= SDVOB_HOTPLUG_INT_STATUS; } else { intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS"); sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA, "SDVOC/VGA DDC BUS"); + dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS; } if (intel_output->ddc_bus == NULL) diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index 552ec11..1d5b9b7 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c @@ -1840,6 +1840,8 @@ intel_tv_init(struct drm_device *dev) drm_connector_attach_property(connector, dev->mode_config.tv_bottom_margin_property, tv_priv->margin[TV_MARGIN_BOTTOM]); + + dev_priv->hotplug_supported_mask |= TV_HOTPLUG_INT_STATUS; out: drm_sysfs_connector_add(connector); } -- cgit v0.10.2 From fa1cc7b5a5c4171dfdcac855428295340ccf87ec Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Tue, 15 Dec 2009 15:05:12 -0800 Subject: keys: PTR_ERR return of wrong pointer in keyctl_get_security() Return the PTR_ERR of the correct pointer. Signed-off-by: Roel Kluin Signed-off-by: Andrew Morton Acked-by: David Howells Signed-off-by: James Morris diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index 06ec722..5f830bc 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c @@ -1194,7 +1194,7 @@ long keyctl_get_security(key_serial_t keyid, * have the authorisation token handy */ instkey = key_get_instantiation_authkey(keyid); if (IS_ERR(instkey)) - return PTR_ERR(key_ref); + return PTR_ERR(instkey); key_put(instkey); key_ref = lookup_user_key(keyid, KEY_LOOKUP_PARTIAL, 0); -- cgit v0.10.2 From dd880fbe8e4792d1185a5101dc751f49eab0a509 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 15 Dec 2009 15:05:12 -0800 Subject: security/min_addr.c: make init_mmap_min_addr() static init_mmap_min_addr() is a pure_initcall and should be static. Signed-off-by: H Hartley Sweeten Signed-off-by: Andrew Morton Signed-off-by: James Morris diff --git a/security/min_addr.c b/security/min_addr.c index fc43c9d..e86f297 100644 --- a/security/min_addr.c +++ b/security/min_addr.c @@ -43,7 +43,7 @@ int mmap_min_addr_handler(struct ctl_table *table, int write, return ret; } -int __init init_mmap_min_addr(void) +static int __init init_mmap_min_addr(void) { update_mmap_min_addr(); -- cgit v0.10.2 From 6e1415467614e854fee660ff6648bd10fa976e95 Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 15 Dec 2009 19:27:45 +0000 Subject: NOMMU: Optimise away the {dac_,}mmap_min_addr tests In NOMMU mode clamp dac_mmap_min_addr to zero to cause the tests on it to be skipped by the compiler. We do this as the minimum mmap address doesn't make any sense in NOMMU mode. mmap_min_addr and round_hint_to_min() can be discarded entirely in NOMMU mode. Signed-off-by: David Howells Acked-by: Eric Paris Signed-off-by: James Morris diff --git a/include/linux/security.h b/include/linux/security.h index 466cbad..2c627d3 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -95,8 +95,13 @@ struct seq_file; extern int cap_netlink_send(struct sock *sk, struct sk_buff *skb); extern int cap_netlink_recv(struct sk_buff *skb, int cap); +#ifdef CONFIG_MMU extern unsigned long mmap_min_addr; extern unsigned long dac_mmap_min_addr; +#else +#define dac_mmap_min_addr 0UL +#endif + /* * Values used in the task_security_ops calls */ @@ -121,6 +126,7 @@ struct request_sock; #define LSM_UNSAFE_PTRACE 2 #define LSM_UNSAFE_PTRACE_CAP 4 +#ifdef CONFIG_MMU /* * If a hint addr is less than mmap_min_addr change hint to be as * low as possible but still greater than mmap_min_addr @@ -135,6 +141,7 @@ static inline unsigned long round_hint_to_min(unsigned long hint) } extern int mmap_min_addr_handler(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos); +#endif #ifdef CONFIG_SECURITY diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 45e4bef..856a24e 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -1214,6 +1214,7 @@ static struct ctl_table vm_table[] = { .proc_handler = proc_dointvec_jiffies, }, #endif +#ifdef CONFIG_MMU { .procname = "mmap_min_addr", .data = &dac_mmap_min_addr, @@ -1221,6 +1222,7 @@ static struct ctl_table vm_table[] = { .mode = 0644, .proc_handler = mmap_min_addr_handler, }, +#endif #ifdef CONFIG_NUMA { .procname = "numa_zonelist_order", diff --git a/mm/Kconfig b/mm/Kconfig index 43ea8c3..ee9f3e0 100644 --- a/mm/Kconfig +++ b/mm/Kconfig @@ -221,6 +221,7 @@ config KSM config DEFAULT_MMAP_MIN_ADDR int "Low address space to protect from user allocation" + depends on MMU default 4096 help This is the portion of low virtual memory which should be protected diff --git a/security/Makefile b/security/Makefile index bb44e35..da20a19 100644 --- a/security/Makefile +++ b/security/Makefile @@ -8,7 +8,8 @@ subdir-$(CONFIG_SECURITY_SMACK) += smack subdir-$(CONFIG_SECURITY_TOMOYO) += tomoyo # always enable default capabilities -obj-y += commoncap.o min_addr.o +obj-y += commoncap.o +obj-$(CONFIG_MMU) += min_addr.o # Object file lists obj-$(CONFIG_SECURITY) += security.o capability.o -- cgit v0.10.2 From 47376ceba54600cec4dd9e7c4fe8b98e4269633a Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Wed, 16 Dec 2009 23:25:50 +0100 Subject: reiserfs: Fix reiserfs lock <-> inode mutex dependency inversion The reiserfs lock -> inode mutex dependency gets inverted when we relax the lock while walking to the tree. To fix this, use a specialized version of reiserfs_mutex_lock_safe that takes care of mutex subclasses. Then we can grab the inode mutex with I_MUTEX_XATTR subclass without any reiserfs lock dependency. This fixes the following report: [ INFO: possible circular locking dependency detected ] 2.6.32-06793-gf405425-dirty #2 ------------------------------------------------------- mv/18566 is trying to acquire lock: (&REISERFS_SB(s)->lock){+.+.+.}, at: [] reiserfs_write_lock+0x28= /0x40 but task is already holding lock: (&sb->s_type->i_mutex_key#5/3){+.+.+.}, at: [] reiserfs_for_each_xattr+0x10c/0x380 which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #1 (&sb->s_type->i_mutex_key#5/3){+.+.+.}: [] validate_chain+0xa23/0xf70 [] __lock_acquire+0x4e5/0xa70 [] lock_acquire+0x7a/0xa0 [] mutex_lock_nested+0x5f/0x2b0 [] reiserfs_for_each_xattr+0x84/0x380 [] reiserfs_delete_xattrs+0x15/0x50 [] reiserfs_delete_inode+0x8f/0x140 [] generic_delete_inode+0x9c/0x150 [] generic_drop_inode+0x3d/0x60 [] iput+0x47/0x50 [] do_unlinkat+0xdb/0x160 [] sys_unlink+0x10/0x20 [] sysenter_do_call+0x12/0x36 -> #0 (&REISERFS_SB(s)->lock){+.+.+.}: [] validate_chain+0xf68/0xf70 [] __lock_acquire+0x4e5/0xa70 [] lock_acquire+0x7a/0xa0 [] mutex_lock_nested+0x5f/0x2b0 [] reiserfs_write_lock+0x28/0x40 [] search_by_key+0x1f7b/0x21b0 [] search_by_entry_key+0x1f/0x3b0 [] reiserfs_find_entry+0x77/0x400 [] reiserfs_lookup+0x85/0x130 [] __lookup_hash+0xb4/0x110 [] lookup_one_len+0xb3/0x100 [] reiserfs_for_each_xattr+0x120/0x380 [] reiserfs_delete_xattrs+0x15/0x50 [] reiserfs_delete_inode+0x8f/0x140 [] generic_delete_inode+0x9c/0x150 [] generic_drop_inode+0x3d/0x60 [] iput+0x47/0x50 [] dentry_iput+0x6f/0xf0 [] d_kill+0x24/0x50 [] dput+0x5b/0x120 [] sys_renameat+0x1b9/0x230 [] sys_rename+0x28/0x30 [] sysenter_do_call+0x12/0x36 other info that might help us debug this: 2 locks held by mv/18566: #0: (&sb->s_type->i_mutex_key#5/1){+.+.+.}, at: [] lock_rename+0xcc/0xd0 #1: (&sb->s_type->i_mutex_key#5/3){+.+.+.}, at: [] reiserfs_for_each_xattr+0x10c/0x380 stack backtrace: Pid: 18566, comm: mv Tainted: G C 2.6.32-06793-gf405425-dirty #2 Call Trace: [] ? printk+0x18/0x1e [] print_circular_bug+0xc0/0xd0 [] validate_chain+0xf68/0xf70 [] ? trace_hardirqs_off+0xb/0x10 [] __lock_acquire+0x4e5/0xa70 [] lock_acquire+0x7a/0xa0 [] ? reiserfs_write_lock+0x28/0x40 [] mutex_lock_nested+0x5f/0x2b0 [] ? reiserfs_write_lock+0x28/0x40 [] ? reiserfs_write_lock+0x28/0x40 [] ? schedule+0x27a/0x440 [] reiserfs_write_lock+0x28/0x40 [] search_by_key+0x1f7b/0x21b0 [] ? __lock_acquire+0x506/0xa70 [] ? lock_release_non_nested+0x1e7/0x340 [] ? reiserfs_write_lock+0x28/0x40 [] ? trace_hardirqs_on_caller+0x124/0x170 [] ? trace_hardirqs_on+0xb/0x10 [] ? T.316+0x15/0x1a0 [] ? sched_clock_cpu+0x9d/0x100 [] search_by_entry_key+0x1f/0x3b0 [] ? __mutex_unlock_slowpath+0x9a/0x120 [] ? trace_hardirqs_on_caller+0x124/0x170 [] reiserfs_find_entry+0x77/0x400 [] reiserfs_lookup+0x85/0x130 [] ? sched_clock_cpu+0x9d/0x100 [] __lookup_hash+0xb4/0x110 [] lookup_one_len+0xb3/0x100 [] reiserfs_for_each_xattr+0x120/0x380 [] ? delete_one_xattr+0x0/0x1c0 [] ? math_error+0x22/0x150 [] ? reiserfs_write_lock+0x28/0x40 [] reiserfs_delete_xattrs+0x15/0x50 [] ? reiserfs_write_lock+0x28/0x40 [] reiserfs_delete_inode+0x8f/0x140 [] ? generic_delete_inode+0x5f/0x150 [] ? reiserfs_delete_inode+0x0/0x140 [] generic_delete_inode+0x9c/0x150 [] generic_drop_inode+0x3d/0x60 [] iput+0x47/0x50 [] dentry_iput+0x6f/0xf0 [] d_kill+0x24/0x50 [] dput+0x5b/0x120 [] sys_renameat+0x1b9/0x230 [] ? sched_clock_cpu+0x9d/0x100 [] ? trace_hardirqs_off+0xb/0x10 [] ? cpu_clock+0x4e/0x60 [] ? do_page_fault+0x155/0x370 [] ? up_read+0x16/0x30 [] ? do_page_fault+0x155/0x370 [] sys_rename+0x28/0x30 [] sysenter_do_call+0x12/0x36 Reported-by: Alexander Beregalov Signed-off-by: Frederic Weisbecker Cc: Chris Mason Cc: Ingo Molnar Cc: Thomas Gleixner diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index 58aa8e7..8891cd8 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c @@ -243,7 +243,8 @@ static int reiserfs_for_each_xattr(struct inode *inode, goto out_dir; } - mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_XATTR); + reiserfs_mutex_lock_nested_safe(&dir->d_inode->i_mutex, I_MUTEX_XATTR, + inode->i_sb); buf.xadir = dir; err = reiserfs_readdir_dentry(dir, &buf, fill_with_dentries, &pos); while ((err == 0 || err == -ENOSPC) && buf.count) { diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h index a05b4a2..4351b49 100644 --- a/include/linux/reiserfs_fs.h +++ b/include/linux/reiserfs_fs.h @@ -97,6 +97,15 @@ static inline void reiserfs_mutex_lock_safe(struct mutex *m, reiserfs_write_lock(s); } +static inline void +reiserfs_mutex_lock_nested_safe(struct mutex *m, unsigned int subclass, + struct super_block *s) +{ + reiserfs_write_unlock(s); + mutex_lock_nested(m, subclass); + reiserfs_write_lock(s); +} + /* * When we schedule, we usually want to also release the write lock, * according to the previous bkl based locking scheme of reiserfs. -- cgit v0.10.2 From a00ae4d21b2fa9379914f270ffffd8d3bec55430 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 13 Dec 2009 20:21:34 +0100 Subject: Keys: KEYCTL_SESSION_TO_PARENT needs TIF_NOTIFY_RESUME architecture support As of commit ee18d64c1f632043a02e6f5ba5e045bb26a5465f ("KEYS: Add a keyctl to install a process's session keyring on its parent [try #6]"), CONFIG_KEYS=y fails to build on architectures that haven't implemented TIF_NOTIFY_RESUME yet: security/keys/keyctl.c: In function 'keyctl_session_to_parent': security/keys/keyctl.c:1312: error: 'TIF_NOTIFY_RESUME' undeclared (first use in this function) security/keys/keyctl.c:1312: error: (Each undeclared identifier is reported only once security/keys/keyctl.c:1312: error: for each function it appears in.) Make KEYCTL_SESSION_TO_PARENT depend on TIF_NOTIFY_RESUME until m68k, and xtensa have implemented it. Signed-off-by: Geert Uytterhoeven Signed-off-by: James Morris Acked-by: Mike Frysinger diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index 5f830bc..e9c2e7c5 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c @@ -1236,6 +1236,7 @@ long keyctl_get_security(key_serial_t keyid, */ long keyctl_session_to_parent(void) { +#ifdef TIF_NOTIFY_RESUME struct task_struct *me, *parent; const struct cred *mycred, *pcred; struct cred *cred, *oldcred; @@ -1326,6 +1327,15 @@ not_permitted: error_keyring: key_ref_put(keyring_r); return ret; + +#else /* !TIF_NOTIFY_RESUME */ + /* + * To be removed when TIF_NOTIFY_RESUME has been implemented on + * m68k/xtensa + */ +#warning TIF_NOTIFY_RESUME not implemented + return -EOPNOTSUPP; +#endif /* !TIF_NOTIFY_RESUME */ } /*****************************************************************************/ -- cgit v0.10.2 From 9d260ebc09a0ad6b5c73e17676df42c7bc75ff64 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Wed, 16 Dec 2009 15:43:55 +0100 Subject: x86, amd: Get multi-node CPU info from NodeId MSR instead of PCI config space Use NodeId MSR to get NodeId and number of nodes per processor. Signed-off-by: Andreas Herrmann LKML-Reference: <20091216144355.GB28798@alberich.amd.com> Signed-off-by: H. Peter Anvin diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h index 613700f..637e1ec 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h @@ -153,6 +153,7 @@ #define X86_FEATURE_SSE5 (6*32+11) /* SSE-5 */ #define X86_FEATURE_SKINIT (6*32+12) /* SKINIT/STGI instructions */ #define X86_FEATURE_WDT (6*32+13) /* Watchdog timer */ +#define X86_FEATURE_NODEID_MSR (6*32+19) /* NodeId MSR */ /* * Auxiliary flags: Linux defined - For features scattered in various diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index ac98d29..1cd58cd 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -124,6 +124,7 @@ #define FAM10H_MMIO_CONF_BUSRANGE_SHIFT 2 #define FAM10H_MMIO_CONF_BASE_MASK 0xfffffff #define FAM10H_MMIO_CONF_BASE_SHIFT 20 +#define MSR_FAM10H_NODE_ID 0xc001100c /* K8 MSRs */ #define MSR_K8_TOP_MEM1 0xc001001a diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index 8dc3ea1..e485825 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -254,59 +254,36 @@ static int __cpuinit nearby_node(int apicid) /* * Fixup core topology information for AMD multi-node processors. - * Assumption 1: Number of cores in each internal node is the same. - * Assumption 2: Mixed systems with both single-node and dual-node - * processors are not supported. + * Assumption: Number of cores in each internal node is the same. */ #ifdef CONFIG_X86_HT static void __cpuinit amd_fixup_dcm(struct cpuinfo_x86 *c) { -#ifdef CONFIG_PCI - u32 t, cpn; - u8 n, n_id; + unsigned long long value; + u32 nodes, cores_per_node; int cpu = smp_processor_id(); + if (!cpu_has(c, X86_FEATURE_NODEID_MSR)) + return; + /* fixup topology information only once for a core */ if (cpu_has(c, X86_FEATURE_AMD_DCM)) return; - /* check for multi-node processor on boot cpu */ - t = read_pci_config(0, 24, 3, 0xe8); - if (!(t & (1 << 29))) + rdmsrl(MSR_FAM10H_NODE_ID, value); + + nodes = ((value >> 3) & 7) + 1; + if (nodes == 1) return; set_cpu_cap(c, X86_FEATURE_AMD_DCM); + cores_per_node = c->x86_max_cores / nodes; - /* cores per node: each internal node has half the number of cores */ - cpn = c->x86_max_cores >> 1; + /* store NodeID, use llc_shared_map to store sibling info */ + per_cpu(cpu_llc_id, cpu) = value & 7; - /* even-numbered NB_id of this dual-node processor */ - n = c->phys_proc_id << 1; - - /* - * determine internal node id and assign cores fifty-fifty to - * each node of the dual-node processor - */ - t = read_pci_config(0, 24 + n, 3, 0xe8); - n = (t>>30) & 0x3; - if (n == 0) { - if (c->cpu_core_id < cpn) - n_id = 0; - else - n_id = 1; - } else { - if (c->cpu_core_id < cpn) - n_id = 1; - else - n_id = 0; - } - - /* compute entire NodeID, use llc_shared_map to store sibling info */ - per_cpu(cpu_llc_id, cpu) = (c->phys_proc_id << 1) + n_id; - - /* fixup core id to be in range from 0 to cpn */ - c->cpu_core_id = c->cpu_core_id % cpn; -#endif + /* fixup core id to be in range from 0 to (cores_per_node - 1) */ + c->cpu_core_id = c->cpu_core_id % cores_per_node; } #endif -- cgit v0.10.2 From 6ede31e03084ee084bcee073ef3d1136f68d0906 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Thu, 17 Dec 2009 00:16:25 +0100 Subject: x86, msr: msrs_alloc/free for CONFIG_SMP=n Randy Dunlap reported the following build error: "When CONFIG_SMP=n, CONFIG_X86_MSR=m: ERROR: "msrs_free" [drivers/edac/amd64_edac_mod.ko] undefined! ERROR: "msrs_alloc" [drivers/edac/amd64_edac_mod.ko] undefined!" This is due to the fact that is conditioned on CONFIG_SMP and in the UP case we have only the stubs in the header. Fork off SMP functionality into a new file (msr-smp.c) and build msrs_{alloc,free} unconditionally. Reported-by: Randy Dunlap Cc: H. Peter Anvin Signed-off-by: Borislav Petkov LKML-Reference: <20091216231625.GD27228@liondog.tnic> Signed-off-by: H. Peter Anvin diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h index cf985aa..c5bc4c2 100644 --- a/arch/x86/include/asm/msr.h +++ b/arch/x86/include/asm/msr.h @@ -27,6 +27,18 @@ struct msr { }; }; +struct msr_info { + u32 msr_no; + struct msr reg; + struct msr *msrs; + int err; +}; + +struct msr_regs_info { + u32 *regs; + int err; +}; + static inline unsigned long long native_read_tscp(unsigned int *aux) { unsigned long low, high; diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index a2d6472..706be8bf 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile @@ -14,7 +14,7 @@ $(obj)/inat.o: $(obj)/inat-tables.c clean-files := inat-tables.c -obj-$(CONFIG_SMP) := msr.o +obj-$(CONFIG_SMP) += msr-smp.o lib-y := delay.o lib-y += thunk_$(BITS).o @@ -22,7 +22,7 @@ lib-y += usercopy_$(BITS).o getuser.o putuser.o lib-y += memcpy_$(BITS).o lib-y += insn.o inat.o -obj-y += msr-reg.o msr-reg-export.o +obj-y += msr.o msr-reg.o msr-reg-export.o ifeq ($(CONFIG_X86_32),y) obj-y += atomic64_32.o diff --git a/arch/x86/lib/msr-smp.c b/arch/x86/lib/msr-smp.c new file mode 100644 index 0000000..a6b1b86 --- /dev/null +++ b/arch/x86/lib/msr-smp.c @@ -0,0 +1,204 @@ +#include +#include +#include +#include + +static void __rdmsr_on_cpu(void *info) +{ + struct msr_info *rv = info; + struct msr *reg; + int this_cpu = raw_smp_processor_id(); + + if (rv->msrs) + reg = per_cpu_ptr(rv->msrs, this_cpu); + else + reg = &rv->reg; + + rdmsr(rv->msr_no, reg->l, reg->h); +} + +static void __wrmsr_on_cpu(void *info) +{ + struct msr_info *rv = info; + struct msr *reg; + int this_cpu = raw_smp_processor_id(); + + if (rv->msrs) + reg = per_cpu_ptr(rv->msrs, this_cpu); + else + reg = &rv->reg; + + wrmsr(rv->msr_no, reg->l, reg->h); +} + +int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h) +{ + int err; + struct msr_info rv; + + memset(&rv, 0, sizeof(rv)); + + rv.msr_no = msr_no; + err = smp_call_function_single(cpu, __rdmsr_on_cpu, &rv, 1); + *l = rv.reg.l; + *h = rv.reg.h; + + return err; +} +EXPORT_SYMBOL(rdmsr_on_cpu); + +int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h) +{ + int err; + struct msr_info rv; + + memset(&rv, 0, sizeof(rv)); + + rv.msr_no = msr_no; + rv.reg.l = l; + rv.reg.h = h; + err = smp_call_function_single(cpu, __wrmsr_on_cpu, &rv, 1); + + return err; +} +EXPORT_SYMBOL(wrmsr_on_cpu); + +static void __rwmsr_on_cpus(const struct cpumask *mask, u32 msr_no, + struct msr *msrs, + void (*msr_func) (void *info)) +{ + struct msr_info rv; + int this_cpu; + + memset(&rv, 0, sizeof(rv)); + + rv.msrs = msrs; + rv.msr_no = msr_no; + + this_cpu = get_cpu(); + + if (cpumask_test_cpu(this_cpu, mask)) + msr_func(&rv); + + smp_call_function_many(mask, msr_func, &rv, 1); + put_cpu(); +} + +/* rdmsr on a bunch of CPUs + * + * @mask: which CPUs + * @msr_no: which MSR + * @msrs: array of MSR values + * + */ +void rdmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs) +{ + __rwmsr_on_cpus(mask, msr_no, msrs, __rdmsr_on_cpu); +} +EXPORT_SYMBOL(rdmsr_on_cpus); + +/* + * wrmsr on a bunch of CPUs + * + * @mask: which CPUs + * @msr_no: which MSR + * @msrs: array of MSR values + * + */ +void wrmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs) +{ + __rwmsr_on_cpus(mask, msr_no, msrs, __wrmsr_on_cpu); +} +EXPORT_SYMBOL(wrmsr_on_cpus); + +/* These "safe" variants are slower and should be used when the target MSR + may not actually exist. */ +static void __rdmsr_safe_on_cpu(void *info) +{ + struct msr_info *rv = info; + + rv->err = rdmsr_safe(rv->msr_no, &rv->reg.l, &rv->reg.h); +} + +static void __wrmsr_safe_on_cpu(void *info) +{ + struct msr_info *rv = info; + + rv->err = wrmsr_safe(rv->msr_no, rv->reg.l, rv->reg.h); +} + +int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h) +{ + int err; + struct msr_info rv; + + memset(&rv, 0, sizeof(rv)); + + rv.msr_no = msr_no; + err = smp_call_function_single(cpu, __rdmsr_safe_on_cpu, &rv, 1); + *l = rv.reg.l; + *h = rv.reg.h; + + return err ? err : rv.err; +} +EXPORT_SYMBOL(rdmsr_safe_on_cpu); + +int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h) +{ + int err; + struct msr_info rv; + + memset(&rv, 0, sizeof(rv)); + + rv.msr_no = msr_no; + rv.reg.l = l; + rv.reg.h = h; + err = smp_call_function_single(cpu, __wrmsr_safe_on_cpu, &rv, 1); + + return err ? err : rv.err; +} +EXPORT_SYMBOL(wrmsr_safe_on_cpu); + +/* + * These variants are significantly slower, but allows control over + * the entire 32-bit GPR set. + */ +static void __rdmsr_safe_regs_on_cpu(void *info) +{ + struct msr_regs_info *rv = info; + + rv->err = rdmsr_safe_regs(rv->regs); +} + +static void __wrmsr_safe_regs_on_cpu(void *info) +{ + struct msr_regs_info *rv = info; + + rv->err = wrmsr_safe_regs(rv->regs); +} + +int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 *regs) +{ + int err; + struct msr_regs_info rv; + + rv.regs = regs; + rv.err = -EIO; + err = smp_call_function_single(cpu, __rdmsr_safe_regs_on_cpu, &rv, 1); + + return err ? err : rv.err; +} +EXPORT_SYMBOL(rdmsr_safe_regs_on_cpu); + +int wrmsr_safe_regs_on_cpu(unsigned int cpu, u32 *regs) +{ + int err; + struct msr_regs_info rv; + + rv.regs = regs; + rv.err = -EIO; + err = smp_call_function_single(cpu, __wrmsr_safe_regs_on_cpu, &rv, 1); + + return err ? err : rv.err; +} +EXPORT_SYMBOL(wrmsr_safe_regs_on_cpu); diff --git a/arch/x86/lib/msr.c b/arch/x86/lib/msr.c index 8728341..8f8eebd 100644 --- a/arch/x86/lib/msr.c +++ b/arch/x86/lib/msr.c @@ -1,123 +1,7 @@ #include #include -#include #include -struct msr_info { - u32 msr_no; - struct msr reg; - struct msr *msrs; - int err; -}; - -static void __rdmsr_on_cpu(void *info) -{ - struct msr_info *rv = info; - struct msr *reg; - int this_cpu = raw_smp_processor_id(); - - if (rv->msrs) - reg = per_cpu_ptr(rv->msrs, this_cpu); - else - reg = &rv->reg; - - rdmsr(rv->msr_no, reg->l, reg->h); -} - -static void __wrmsr_on_cpu(void *info) -{ - struct msr_info *rv = info; - struct msr *reg; - int this_cpu = raw_smp_processor_id(); - - if (rv->msrs) - reg = per_cpu_ptr(rv->msrs, this_cpu); - else - reg = &rv->reg; - - wrmsr(rv->msr_no, reg->l, reg->h); -} - -int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h) -{ - int err; - struct msr_info rv; - - memset(&rv, 0, sizeof(rv)); - - rv.msr_no = msr_no; - err = smp_call_function_single(cpu, __rdmsr_on_cpu, &rv, 1); - *l = rv.reg.l; - *h = rv.reg.h; - - return err; -} -EXPORT_SYMBOL(rdmsr_on_cpu); - -int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h) -{ - int err; - struct msr_info rv; - - memset(&rv, 0, sizeof(rv)); - - rv.msr_no = msr_no; - rv.reg.l = l; - rv.reg.h = h; - err = smp_call_function_single(cpu, __wrmsr_on_cpu, &rv, 1); - - return err; -} -EXPORT_SYMBOL(wrmsr_on_cpu); - -static void __rwmsr_on_cpus(const struct cpumask *mask, u32 msr_no, - struct msr *msrs, - void (*msr_func) (void *info)) -{ - struct msr_info rv; - int this_cpu; - - memset(&rv, 0, sizeof(rv)); - - rv.msrs = msrs; - rv.msr_no = msr_no; - - this_cpu = get_cpu(); - - if (cpumask_test_cpu(this_cpu, mask)) - msr_func(&rv); - - smp_call_function_many(mask, msr_func, &rv, 1); - put_cpu(); -} - -/* rdmsr on a bunch of CPUs - * - * @mask: which CPUs - * @msr_no: which MSR - * @msrs: array of MSR values - * - */ -void rdmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs) -{ - __rwmsr_on_cpus(mask, msr_no, msrs, __rdmsr_on_cpu); -} -EXPORT_SYMBOL(rdmsr_on_cpus); - -/* - * wrmsr on a bunch of CPUs - * - * @mask: which CPUs - * @msr_no: which MSR - * @msrs: array of MSR values - * - */ -void wrmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs) -{ - __rwmsr_on_cpus(mask, msr_no, msrs, __wrmsr_on_cpu); -} -EXPORT_SYMBOL(wrmsr_on_cpus); - struct msr *msrs_alloc(void) { struct msr *msrs = NULL; @@ -137,100 +21,3 @@ void msrs_free(struct msr *msrs) free_percpu(msrs); } EXPORT_SYMBOL(msrs_free); - -/* These "safe" variants are slower and should be used when the target MSR - may not actually exist. */ -static void __rdmsr_safe_on_cpu(void *info) -{ - struct msr_info *rv = info; - - rv->err = rdmsr_safe(rv->msr_no, &rv->reg.l, &rv->reg.h); -} - -static void __wrmsr_safe_on_cpu(void *info) -{ - struct msr_info *rv = info; - - rv->err = wrmsr_safe(rv->msr_no, rv->reg.l, rv->reg.h); -} - -int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h) -{ - int err; - struct msr_info rv; - - memset(&rv, 0, sizeof(rv)); - - rv.msr_no = msr_no; - err = smp_call_function_single(cpu, __rdmsr_safe_on_cpu, &rv, 1); - *l = rv.reg.l; - *h = rv.reg.h; - - return err ? err : rv.err; -} -EXPORT_SYMBOL(rdmsr_safe_on_cpu); - -int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h) -{ - int err; - struct msr_info rv; - - memset(&rv, 0, sizeof(rv)); - - rv.msr_no = msr_no; - rv.reg.l = l; - rv.reg.h = h; - err = smp_call_function_single(cpu, __wrmsr_safe_on_cpu, &rv, 1); - - return err ? err : rv.err; -} -EXPORT_SYMBOL(wrmsr_safe_on_cpu); - -/* - * These variants are significantly slower, but allows control over - * the entire 32-bit GPR set. - */ -struct msr_regs_info { - u32 *regs; - int err; -}; - -static void __rdmsr_safe_regs_on_cpu(void *info) -{ - struct msr_regs_info *rv = info; - - rv->err = rdmsr_safe_regs(rv->regs); -} - -static void __wrmsr_safe_regs_on_cpu(void *info) -{ - struct msr_regs_info *rv = info; - - rv->err = wrmsr_safe_regs(rv->regs); -} - -int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 *regs) -{ - int err; - struct msr_regs_info rv; - - rv.regs = regs; - rv.err = -EIO; - err = smp_call_function_single(cpu, __rdmsr_safe_regs_on_cpu, &rv, 1); - - return err ? err : rv.err; -} -EXPORT_SYMBOL(rdmsr_safe_regs_on_cpu); - -int wrmsr_safe_regs_on_cpu(unsigned int cpu, u32 *regs) -{ - int err; - struct msr_regs_info rv; - - rv.regs = regs; - rv.err = -EIO; - err = smp_call_function_single(cpu, __wrmsr_safe_regs_on_cpu, &rv, 1); - - return err ? err : rv.err; -} -EXPORT_SYMBOL(wrmsr_safe_regs_on_cpu); -- cgit v0.10.2 From cf1e367ee84e02ac349ad0858eb65e8a6a511c8b Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Thu, 17 Dec 2009 11:15:42 +1100 Subject: timers: Remove duplicate setting of new_base in __mod_timer() new_base is set using per_cpu(tvec_bases, cpu) after selecting the desired value of cpu immediately below so this line is a unnecessary. Signed-off-by: Simon Horman LKML-Reference: <20091217001542.GD25317@verge.net.au> Signed-off-by: Thomas Gleixner diff --git a/kernel/timer.c b/kernel/timer.c index 5db5a8d..15533b7 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -656,8 +656,6 @@ __mod_timer(struct timer_list *timer, unsigned long expires, debug_activate(timer, expires); - new_base = __get_cpu_var(tvec_bases); - cpu = smp_processor_id(); #if defined(CONFIG_NO_HZ) && defined(CONFIG_SMP) -- cgit v0.10.2 From 45a94d7cd45ed991914011919e7d40eb6d2546d1 Mon Sep 17 00:00:00 2001 From: Suresh Siddha Date: Wed, 16 Dec 2009 16:25:42 -0800 Subject: x86, cpuid: Add "volatile" to asm in native_cpuid() xsave_cntxt_init() does something like: cpuid(0xd, ..); // find out what features FP/SSE/.. etc are supported xsetbv(); // enable the features known to OS cpuid(0xd, ..); // find out the size of the context for features enabled Depending on what features get enabled in xsetbv(), value of the cpuid.eax=0xd.ecx=0.ebx changes correspondingly (representing the size of the context that is enabled). As we don't have volatile keyword for native_cpuid(), gcc 4.1.2 optimizes away the second cpuid and the kernel continues to use the cpuid information obtained before xsetbv(), ultimately leading to kernel crash on processors supporting more state than the legacy FP/SSE. Add "volatile" for native_cpuid(). Signed-off-by: Suresh Siddha LKML-Reference: <1261009542.2745.55.camel@sbs-t61.sc.intel.com> Cc: stable@kernel.org Signed-off-by: H. Peter Anvin diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 6f8ec1c..fc801ba 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -181,7 +181,7 @@ static inline void native_cpuid(unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx) { /* ecx is often an input as well as an output. */ - asm("cpuid" + asm volatile("cpuid" : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), -- cgit v0.10.2 From 329962503692b42d8088f31584e42d52db179d52 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Tue, 15 Dec 2009 17:59:02 -0800 Subject: x86: Fix checking of SRAT when node 0 ram is not from 0 Found one system that boot from socket1 instead of socket0, SRAT get rejected... [ 0.000000] SRAT: Node 1 PXM 0 0-a0000 [ 0.000000] SRAT: Node 1 PXM 0 100000-80000000 [ 0.000000] SRAT: Node 1 PXM 0 100000000-2080000000 [ 0.000000] SRAT: Node 0 PXM 1 2080000000-4080000000 [ 0.000000] SRAT: Node 2 PXM 2 4080000000-6080000000 [ 0.000000] SRAT: Node 3 PXM 3 6080000000-8080000000 [ 0.000000] SRAT: Node 4 PXM 4 8080000000-a080000000 [ 0.000000] SRAT: Node 5 PXM 5 a080000000-c080000000 [ 0.000000] SRAT: Node 6 PXM 6 c080000000-e080000000 [ 0.000000] SRAT: Node 7 PXM 7 e080000000-10080000000 ... [ 0.000000] NUMA: Allocated memnodemap from 500000 - 701040 [ 0.000000] NUMA: Using 20 for the hash shift. [ 0.000000] Adding active range (0, 0x2080000, 0x4080000) 0 entries of 3200 used [ 0.000000] Adding active range (1, 0x0, 0x96) 1 entries of 3200 used [ 0.000000] Adding active range (1, 0x100, 0x7f750) 2 entries of 3200 used [ 0.000000] Adding active range (1, 0x100000, 0x2080000) 3 entries of 3200 used [ 0.000000] Adding active range (2, 0x4080000, 0x6080000) 4 entries of 3200 used [ 0.000000] Adding active range (3, 0x6080000, 0x8080000) 5 entries of 3200 used [ 0.000000] Adding active range (4, 0x8080000, 0xa080000) 6 entries of 3200 used [ 0.000000] Adding active range (5, 0xa080000, 0xc080000) 7 entries of 3200 used [ 0.000000] Adding active range (6, 0xc080000, 0xe080000) 8 entries of 3200 used [ 0.000000] Adding active range (7, 0xe080000, 0x10080000) 9 entries of 3200 used [ 0.000000] SRAT: PXMs only cover 917504MB of your 1048566MB e820 RAM. Not used. [ 0.000000] SRAT: SRAT not used. the early_node_map is not sorted because node0 with non zero start come first. so try to sort it right away after all regions are registered. also fixs refression by 8716273c (x86: Export srat physical topology) -v2: make it more solid to handle cross node case like node0 [0,4g), [8,12g) and node1 [4g, 8g), [12g, 16g) -v3: update comments. Reported-and-tested-by: Jens Axboe Signed-off-by: Yinghai Lu LKML-Reference: <4B2579D2.3010201@kernel.org> Signed-off-by: H. Peter Anvin diff --git a/arch/x86/mm/srat_32.c b/arch/x86/mm/srat_32.c index 6f8aa33..9324f13 100644 --- a/arch/x86/mm/srat_32.c +++ b/arch/x86/mm/srat_32.c @@ -267,6 +267,8 @@ int __init get_memcfg_from_srat(void) e820_register_active_regions(chunk->nid, chunk->start_pfn, min(chunk->end_pfn, max_pfn)); } + /* for out of order entries in SRAT */ + sort_node_map(); for_each_online_node(nid) { unsigned long start = node_start_pfn[nid]; diff --git a/arch/x86/mm/srat_64.c b/arch/x86/mm/srat_64.c index d890754..a271241 100644 --- a/arch/x86/mm/srat_64.c +++ b/arch/x86/mm/srat_64.c @@ -317,7 +317,7 @@ static int __init nodes_cover_memory(const struct bootnode *nodes) unsigned long s = nodes[i].start >> PAGE_SHIFT; unsigned long e = nodes[i].end >> PAGE_SHIFT; pxmram += e - s; - pxmram -= absent_pages_in_range(s, e); + pxmram -= __absent_pages_in_range(i, s, e); if ((long)pxmram < 0) pxmram = 0; } @@ -373,6 +373,8 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end) for_each_node_mask(i, nodes_parsed) e820_register_active_regions(i, nodes[i].start >> PAGE_SHIFT, nodes[i].end >> PAGE_SHIFT); + /* for out of order entries in SRAT */ + sort_node_map(); if (!nodes_cover_memory(nodes)) { bad_srat(); return -1; diff --git a/include/linux/mm.h b/include/linux/mm.h index 24c3956..20a2036 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1022,6 +1022,9 @@ extern void add_active_range(unsigned int nid, unsigned long start_pfn, extern void remove_active_range(unsigned int nid, unsigned long start_pfn, unsigned long end_pfn); extern void remove_all_active_ranges(void); +void sort_node_map(void); +unsigned long __absent_pages_in_range(int nid, unsigned long start_pfn, + unsigned long end_pfn); extern unsigned long absent_pages_in_range(unsigned long start_pfn, unsigned long end_pfn); extern void get_pfn_range_for_nid(unsigned int nid, diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 2bc2ac6..873c863 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -3573,7 +3573,7 @@ static unsigned long __meminit zone_spanned_pages_in_node(int nid, * Return the number of holes in a range on a node. If nid is MAX_NUMNODES, * then all holes in the requested range will be accounted for. */ -static unsigned long __meminit __absent_pages_in_range(int nid, +unsigned long __meminit __absent_pages_in_range(int nid, unsigned long range_start_pfn, unsigned long range_end_pfn) { @@ -4102,7 +4102,7 @@ static int __init cmp_node_active_region(const void *a, const void *b) } /* sort the node_map by start_pfn */ -static void __init sort_node_map(void) +void __init sort_node_map(void) { sort(early_node_map, (size_t)nr_nodemap_entries, sizeof(struct node_active_region), -- cgit v0.10.2 From 6a1e008a0915f502eb026fb995ea3e49d5b017f7 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Tue, 15 Dec 2009 17:59:03 -0800 Subject: x86: Increase MAX_EARLY_RES; insufficient on 32-bit NUMA Due to recent changes wakeup and mptable, we run out of early reservations on 32-bit NUMA. Thus, adjust the available number. Signed-off-by: Yinghai Lu LKML-Reference: <4B22D754.2020706@kernel.org> Signed-off-by: H. Peter Anvin diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index f50447d..05ed7ab 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c @@ -724,7 +724,7 @@ core_initcall(e820_mark_nvs_memory); /* * Early reserved memory areas. */ -#define MAX_EARLY_RES 20 +#define MAX_EARLY_RES 32 struct early_res { u64 start, end; -- cgit v0.10.2 From f6325e30ebd6fc870315b017a5d4a6ab15bf790b Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 17 Dec 2009 11:43:08 -0600 Subject: cpumask: use cpu_online in kernel/perf_event.c Also, we want to check against nr_cpu_ids, not num_possible_cpus(). The latter works, but the correct bounds check is < nr_cpu_ids. Signed-off-by: Rusty Russell To: Thomas Gleixner diff --git a/kernel/perf_event.c b/kernel/perf_event.c index 8ab8698..97d1a3d 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c @@ -1614,7 +1614,7 @@ static struct perf_event_context *find_get_context(pid_t pid, int cpu) * offline CPU and activate it when the CPU comes up, but * that's for later. */ - if (!cpu_isset(cpu, cpu_online_map)) + if (!cpu_online(cpu)) return ERR_PTR(-ENODEV); cpuctx = &per_cpu(perf_cpu_context, cpu); -- cgit v0.10.2 From 58463c1fe25f7c4183f30f06a5a86cb6cd9d8231 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 17 Dec 2009 11:43:12 -0600 Subject: cpumask: avoid deprecated function in mm/slab.c These days we use cpumask_empty() which takes a pointer. Signed-off-by: Rusty Russell Acked-by: Christoph Lameter diff --git a/mm/slab.c b/mm/slab.c index 3f48229..7560eb0 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -1132,7 +1132,7 @@ static void __cpuinit cpuup_canceled(long cpu) if (nc) free_block(cachep, nc->entry, nc->avail, node); - if (!cpus_empty(*mask)) { + if (!cpumask_empty(mask)) { spin_unlock_irq(&l3->list_lock); goto free_array_cache; } -- cgit v0.10.2 From 6957177f5c3c0e51b9e90a1d7fadb3177a333949 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 17 Dec 2009 11:43:14 -0600 Subject: cpumask: use modern cpumask style in drivers/scsi/fcoe/fcoe.c Signed-off-by: Rusty Russell Cc: "James E.J. Bottomley" Cc: Robert Love Cc: Chris Leech Cc: linux-scsi@vger.kernel.org diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index a30ffaa..51c24b3 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c @@ -1231,7 +1231,7 @@ int fcoe_rcv(struct sk_buff *skb, struct net_device *netdev, "CPU.\n"); spin_unlock_bh(&fps->fcoe_rx_list.lock); - cpu = first_cpu(cpu_online_map); + cpu = cpumask_first(cpu_online_mask); fps = &per_cpu(fcoe_percpu, cpu); spin_lock_bh(&fps->fcoe_rx_list.lock); if (!fps->thread) { -- cgit v0.10.2 From cc216b86e51e9ab22265ea9591769c9ee235e1e4 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 17 Dec 2009 11:43:24 -0600 Subject: cpumask: convert drivers/idle/i7300_idle.c to cpumask_var_t Fairly simple transformation: 1) cpumask_t -> cpumask_var_t and alloc_cpumask_var/free_cpumask_var (which are a NOOP unless CONFIG_CPUMASK_OFFSTACK=y). 2) cpu_set -> cpumask_set_cpu 3) cpus_weight -> cpumask_weight 4) cpu_clear -> cpumask_clear_cpu Signed-off-by: Rusty Russell To: Andy Henroid diff --git a/drivers/idle/i7300_idle.c b/drivers/idle/i7300_idle.c index 1f20a04..dd25300 100644 --- a/drivers/idle/i7300_idle.c +++ b/drivers/idle/i7300_idle.c @@ -81,7 +81,7 @@ static u8 i7300_idle_thrtctl_saved; static u8 i7300_idle_thrtlow_saved; static u32 i7300_idle_mc_saved; -static cpumask_t idle_cpumask; +static cpumask_var_t idle_cpumask; static ktime_t start_ktime; static unsigned long avg_idle_us; @@ -459,9 +459,9 @@ static int i7300_idle_notifier(struct notifier_block *nb, unsigned long val, spin_lock_irqsave(&i7300_idle_lock, flags); if (val == IDLE_START) { - cpu_set(smp_processor_id(), idle_cpumask); + cpumask_set_cpu(smp_processor_id(), idle_cpumask); - if (cpus_weight(idle_cpumask) != num_online_cpus()) + if (cpumask_weight(idle_cpumask) != num_online_cpus()) goto end; now_ktime = ktime_get(); @@ -478,8 +478,8 @@ static int i7300_idle_notifier(struct notifier_block *nb, unsigned long val, i7300_idle_ioat_start(); } else if (val == IDLE_END) { - cpu_clear(smp_processor_id(), idle_cpumask); - if (cpus_weight(idle_cpumask) == (num_online_cpus() - 1)) { + cpumask_clear_cpu(smp_processor_id(), idle_cpumask); + if (cpumask_weight(idle_cpumask) == (num_online_cpus() - 1)) { /* First CPU coming out of idle */ u64 idle_duration_us; @@ -553,7 +553,6 @@ struct debugfs_file_info { static int __init i7300_idle_init(void) { spin_lock_init(&i7300_idle_lock); - cpus_clear(idle_cpumask); total_us = 0; if (i7300_idle_platform_probe(&fbd_dev, &ioat_dev, forceload)) @@ -565,6 +564,9 @@ static int __init i7300_idle_init(void) if (i7300_idle_ioat_init()) return -ENODEV; + if (!zalloc_cpumask_var(&idle_cpumask, GFP_KERNEL)) + return -ENOMEM; + debugfs_dir = debugfs_create_dir("i7300_idle", NULL); if (debugfs_dir) { int i = 0; @@ -589,6 +591,7 @@ static int __init i7300_idle_init(void) static void __exit i7300_idle_exit(void) { idle_notifier_unregister(&i7300_idle_nb); + free_cpumask_var(idle_cpumask); if (debugfs_dir) { int i = 0; -- cgit v0.10.2 From 62ac12795095dc959649c66ace78708e7ac52477 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 17 Dec 2009 11:43:26 -0600 Subject: cpumask: avoid dereferencing struct cpumask struct cpumask will be undefined soon with CONFIG_CPUMASK_OFFSTACK=y, to avoid them being declared on the stack. cpumask_bits() does what we want here (of course, this code is crap). Signed-off-by: Rusty Russell To: Thomas Gleixner diff --git a/kernel/time/timer_list.c b/kernel/time/timer_list.c index 2826563..bdfb8dd 100644 --- a/kernel/time/timer_list.c +++ b/kernel/time/timer_list.c @@ -237,10 +237,10 @@ static void timer_list_show_tickdevices(struct seq_file *m) #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST print_tickdevice(m, tick_get_broadcast_device(), -1); SEQ_printf(m, "tick_broadcast_mask: %08lx\n", - tick_get_broadcast_mask()->bits[0]); + cpumask_bits(tick_get_broadcast_mask())[0]); #ifdef CONFIG_TICK_ONESHOT SEQ_printf(m, "tick_broadcast_oneshot_mask: %08lx\n", - tick_get_broadcast_oneshot_mask()->bits[0]); + cpumask_bits(tick_get_broadcast_oneshot_mask())[0]); #endif SEQ_printf(m, "\n"); #endif -- cgit v0.10.2 From 4251417484a1775ba5cbfe38c67e6d5af9615de4 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 17 Dec 2009 11:43:29 -0600 Subject: cpumask: don't recommend set_cpus_allowed hack in Documentation/cpu-hotplug.txt Signed-off-by: Rusty Russell Cc: Gautham R Shenoy Cc: Ashok Raj diff --git a/Documentation/cpu-hotplug.txt b/Documentation/cpu-hotplug.txt index 4d4a644b..a99d703 100644 --- a/Documentation/cpu-hotplug.txt +++ b/Documentation/cpu-hotplug.txt @@ -315,41 +315,26 @@ A: The following are what is required for CPU hotplug infrastructure to work Q: I need to ensure that a particular cpu is not removed when there is some work specific to this cpu is in progress. -A: First switch the current thread context to preferred cpu +A: There are two ways. If your code can be run in interrupt context, use + smp_call_function_single(), otherwise use work_on_cpu(). Note that + work_on_cpu() is slow, and can fail due to out of memory: int my_func_on_cpu(int cpu) { - cpumask_t saved_mask, new_mask = CPU_MASK_NONE; - int curr_cpu, err = 0; - - saved_mask = current->cpus_allowed; - cpu_set(cpu, new_mask); - err = set_cpus_allowed(current, new_mask); - - if (err) - return err; - - /* - * If we got scheduled out just after the return from - * set_cpus_allowed() before running the work, this ensures - * we stay locked. - */ - curr_cpu = get_cpu(); - - if (curr_cpu != cpu) { - err = -EAGAIN; - goto ret; - } else { - /* - * Do work : But cant sleep, since get_cpu() disables preempt - */ - } - ret: - put_cpu(); - set_cpus_allowed(current, saved_mask); - return err; - } - + int err; + get_online_cpus(); + if (!cpu_online(cpu)) + err = -EINVAL; + else +#if NEEDS_BLOCKING + err = work_on_cpu(cpu, __my_func_on_cpu, NULL); +#else + smp_call_function_single(cpu, __my_func_on_cpu, &err, + true); +#endif + put_online_cpus(); + return err; + } Q: How do we determine how many CPUs are available for hotplug. A: There is no clear spec defined way from ACPI that can give us that -- cgit v0.10.2 From a4636818f8e0991f32d9528f39cf4f3d6a7d30a3 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 17 Dec 2009 11:43:29 -0600 Subject: cpumask: rename tsk_cpumask to tsk_cpus_allowed Noone uses this wrapper yet, and Ingo asked that it be kept consistent with current task_struct usage. (One user crept in via linux-next: fixed) Signed-off-by: Rusty Russell Cc: Tejun Heo diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c index a9df944..f125e5c 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c @@ -1136,7 +1136,7 @@ static int powernowk8_target(struct cpufreq_policy *pol, if (!alloc_cpumask_var(&oldmask, GFP_KERNEL)) return -ENOMEM; - cpumask_copy(oldmask, tsk_cpumask(current)); + cpumask_copy(oldmask, tsk_cpus_allowed(current)); set_cpus_allowed_ptr(current, cpumask_of(pol->cpu)); if (smp_processor_id() != pol->cpu) { diff --git a/include/linux/sched.h b/include/linux/sched.h index 244c287..4d7adb2 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1555,7 +1555,7 @@ struct task_struct { }; /* Future-safe accessor for struct task_struct's cpus_allowed. */ -#define tsk_cpumask(tsk) (&(tsk)->cpus_allowed) +#define tsk_cpus_allowed(tsk) (&(tsk)->cpus_allowed) /* * Priority of a process goes from 0..MAX_PRIO-1, valid RT -- cgit v0.10.2 From 1b93b3c3e94be2605759735a89fc935ba5f58dcf Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Wed, 14 Oct 2009 18:12:16 +0800 Subject: MIPS: Add support for GZIP / BZIP2 / LZMA compressed kernel images This patch helps to generate smaller kernel images for linux-MIPS, Here is the effect when using lzma: $ ls -sh vmlinux 7.1M vmlinux $ ls -sh vmlinuz 1.5M vmlinuz Have tested the 32bit kernel on Qemu/Malta and 64bit kernel on FuLoong Mini PC. both of them work well. and also, tested by Alexander Clouter on an AR7 based Linksys WAG54Gv2, and by Manuel Lauss on an Alchemy board. This -v2 version incorporate the feedback from Ralf, and add the following changes: 1. add .ecoff, .bin, .erec format support 2. only enable it and the debug source code for the machines we tested 3. a dozen of fixups and cleanups and if you want to enable it for your board, please try to select SYS_SUPPORTS_ZBOOT for it, and if the board have an 16550 compatible uart, you can select SYS_SUPPORTS_ZBOOT_UART16550 directly. and then sending the relative patches to Ralf. Tested-by: Manuel Lauss Tested-by: Alexander Clouter Signed-off-by: Wu Zhangjin Signed-off-by: Ralf Baechle diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index fd7620f..f6f3b99 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -22,6 +22,7 @@ choice config MACH_ALCHEMY bool "Alchemy processor based machines" + select SYS_SUPPORTS_ZBOOT config AR7 bool "Texas Instruments AR7" @@ -36,6 +37,7 @@ config AR7 select SYS_HAS_EARLY_PRINTK select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_LITTLE_ENDIAN + select SYS_SUPPORTS_ZBOOT_UART16550 select GENERIC_GPIO select GCD select VLYNQ @@ -192,6 +194,7 @@ config LASAT config MACH_LOONGSON bool "Loongson family of machines" + select SYS_SUPPORTS_ZBOOT_UART16550 help This enables the support of Loongson family of machines. @@ -233,6 +236,7 @@ config MIPS_MALTA select SYS_SUPPORTS_MIPS_CMP select SYS_SUPPORTS_MULTITHREADING select SYS_SUPPORTS_SMARTMIPS + select SYS_SUPPORTS_ZBOOT help This enables support for the MIPS Technologies Malta evaluation board. @@ -1294,6 +1298,16 @@ config CPU_CAVIUM_OCTEON endchoice +config SYS_SUPPORTS_ZBOOT + bool + select HAVE_KERNEL_GZIP + select HAVE_KERNEL_BZIP2 + select HAVE_KERNEL_LZMA + +config SYS_SUPPORTS_ZBOOT_UART16550 + bool + select SYS_SUPPORTS_ZBOOT + config CPU_LOONGSON2 bool select CPU_SUPPORTS_32BIT_KERNEL diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 77f5021..ba04782 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -69,6 +69,7 @@ endif all-$(CONFIG_BOOT_ELF32) := $(vmlinux-32) all-$(CONFIG_BOOT_ELF64) := $(vmlinux-64) +all-$(CONFIG_SYS_SUPPORTS_ZBOOT)+= vmlinuz # # GCC uses -G 0 -mabicalls -fpic as default. We don't want PIC in the kernel @@ -331,7 +332,7 @@ load-$(CONFIG_LEMOTE_FULOONG2E) +=0xffffffff80100000 core-$(CONFIG_MIPS_MALTA) += arch/mips/mti-malta/ cflags-$(CONFIG_MIPS_MALTA) += -I$(srctree)/arch/mips/include/asm/mach-malta load-$(CONFIG_MIPS_MALTA) += 0xffffffff80100000 -all-$(CONFIG_MIPS_MALTA) := vmlinux.bin +all-$(CONFIG_MIPS_MALTA) := vmlinuz.bin # # MIPS SIM @@ -581,7 +582,7 @@ load-$(CONFIG_SNI_RM) += 0xffffffff80600000 else load-$(CONFIG_SNI_RM) += 0xffffffff80030000 endif -all-$(CONFIG_SNI_RM) := vmlinux.ecoff +all-$(CONFIG_SNI_RM) := vmlinuz.ecoff # # Common TXx9 @@ -699,9 +700,23 @@ vmlinux.64: vmlinux $(OBJCOPY) -O $(64bit-bfd) $(OBJCOPYFLAGS) $< $@ makeboot =$(Q)$(MAKE) $(build)=arch/mips/boot VMLINUX=$(vmlinux-32) $(1) +makezboot =$(Q)$(MAKE) $(build)=arch/mips/boot/compressed \ + VMLINUX_LOAD_ADDRESS=$(load-y) 32bit-bfd=$(32bit-bfd) $(1) all: $(all-y) +vmlinuz: vmlinux FORCE + +@$(call makezboot,$@) + +vmlinuz.bin: vmlinux + +@$(call makezboot,$@) + +vmlinuz.ecoff: vmlinux + +@$(call makezboot,$@) + +vmlinuz.srec: vmlinux + +@$(call makezboot,$@) + vmlinux.bin: $(vmlinux-32) +@$(call makeboot,$@) @@ -726,11 +741,13 @@ endif install: $(Q)install -D -m 755 vmlinux $(INSTALL_PATH)/vmlinux-$(KERNELRELEASE) + $(Q)install -D -m 755 vmlinuz $(INSTALL_PATH)/vmlinuz-$(KERNELRELEASE) $(Q)install -D -m 644 .config $(INSTALL_PATH)/config-$(KERNELRELEASE) $(Q)install -D -m 644 System.map $(INSTALL_PATH)/System.map-$(KERNELRELEASE) archclean: @$(MAKE) $(clean)=arch/mips/boot + @$(MAKE) $(clean)=arch/mips/boot/compressed @$(MAKE) $(clean)=arch/mips/lasat define archhelp @@ -738,10 +755,18 @@ define archhelp echo ' vmlinux.ecoff - ECOFF boot image' echo ' vmlinux.bin - Raw binary boot image' echo ' vmlinux.srec - SREC boot image' + echo ' vmlinuz - Compressed boot(zboot) image' + echo ' vmlinuz.ecoff - ECOFF zboot image' + echo ' vmlinuz.bin - Raw binary zboot image' + echo ' vmlinuz.srec - SREC zboot image' echo echo ' These will be default as apropriate for a configured platform.' endef CLEAN_FILES += vmlinux.32 \ vmlinux.64 \ - vmlinux.ecoff + vmlinux.ecoff \ + vmlinuz \ + vmlinuz.ecoff \ + vmlinuz.bin \ + vmlinuz.srec diff --git a/arch/mips/boot/compressed/Makefile b/arch/mips/boot/compressed/Makefile new file mode 100644 index 0000000..e27f40b --- /dev/null +++ b/arch/mips/boot/compressed/Makefile @@ -0,0 +1,100 @@ +# +# This file is subject to the terms and conditions of the GNU General Public +# License. +# +# Adapted for MIPS Pete Popov, Dan Malek +# +# Copyright (C) 1994 by Linus Torvalds +# Adapted for PowerPC by Gary Thomas +# modified by Cort (cort@cs.nmt.edu) +# +# Copyright (C) 2009 Lemote Inc. & DSLab, Lanzhou University +# Author: Wu Zhangjin +# + +# compressed kernel load addr: VMLINUZ_LOAD_ADDRESS > VMLINUX_LOAD_ADDRESS + VMLINUX_SIZE +VMLINUX_SIZE := $(shell wc -c $(objtree)/$(KBUILD_IMAGE) 2>/dev/null | cut -d' ' -f1) +VMLINUX_SIZE := $(shell [ -n "$(VMLINUX_SIZE)" ] && echo $$(($(VMLINUX_SIZE) + (65536 - $(VMLINUX_SIZE) % 65536)))) +VMLINUZ_LOAD_ADDRESS := 0x$(shell [ -n "$(VMLINUX_SIZE)" ] && printf %x $$(($(VMLINUX_LOAD_ADDRESS) + $(VMLINUX_SIZE)))) + +# set the default size of the mallocing area for decompressing +BOOT_HEAP_SIZE := 0x400000 + +# Disable Function Tracer +KBUILD_CFLAGS := $(shell echo $(KBUILD_CFLAGS) | sed -e "s/-pg//") + +KBUILD_CFLAGS := $(LINUXINCLUDE) $(KBUILD_CFLAGS) -D__KERNEL__ \ + -DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) -D"VMLINUX_LOAD_ADDRESS_ULL=$(VMLINUX_LOAD_ADDRESS)ull" \ + +KBUILD_AFLAGS := $(LINUXINCLUDE) $(KBUILD_AFLAGS) -D__ASSEMBLY__ \ + -DKERNEL_ENTRY=0x$(shell $(NM) $(objtree)/$(KBUILD_IMAGE) 2>/dev/null | grep " kernel_entry" | cut -f1 -d \ ) \ + -DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) + +obj-y := $(obj)/head.o $(obj)/decompress.o $(obj)/dbg.o + +obj-$(CONFIG_SYS_SUPPORTS_ZBOOT_UART16550) += $(obj)/uart-16550.o + +OBJCOPYFLAGS_vmlinux.bin := $(OBJCOPYFLAGS) -O binary -R .comment -S +$(obj)/vmlinux.bin: $(KBUILD_IMAGE) + $(call if_changed,objcopy) + +suffix_$(CONFIG_KERNEL_GZIP) = gz +suffix_$(CONFIG_KERNEL_BZIP2) = bz2 +suffix_$(CONFIG_KERNEL_LZMA) = lzma +tool_$(CONFIG_KERNEL_GZIP) = gzip +tool_$(CONFIG_KERNEL_BZIP2) = bzip2 +tool_$(CONFIG_KERNEL_LZMA) = lzma +$(obj)/vmlinux.$(suffix_y): $(obj)/vmlinux.bin + $(call if_changed,$(tool_y)) + +$(obj)/piggy.o: $(obj)/vmlinux.$(suffix_y) $(obj)/dummy.o + $(Q)$(OBJCOPY) $(OBJCOPYFLAGS) \ + --add-section=.image=$< \ + --set-section-flags=.image=contents,alloc,load,readonly,data \ + $(obj)/dummy.o $@ + +LDFLAGS_vmlinuz := $(LDFLAGS) -Ttext $(VMLINUZ_LOAD_ADDRESS) -T +vmlinuz: $(src)/ld.script $(obj-y) $(obj)/piggy.o + $(call if_changed,ld) + $(Q)$(OBJCOPY) $(OBJCOPYFLAGS) -R .comment -R .stab -R .stabstr -R .initrd -R .sysmap $@ + +# +# Some DECstations need all possible sections of an ECOFF executable +# +ifdef CONFIG_MACH_DECSTATION + E2EFLAGS = -a +else + E2EFLAGS = +endif + +# elf2ecoff can only handle 32bit image + +ifdef CONFIG_32BIT + VMLINUZ = vmlinuz +else + VMLINUZ = vmlinuz.32 +endif + +vmlinuz.32: vmlinuz + $(Q)$(OBJCOPY) -O $(32bit-bfd) $(OBJCOPYFLAGS) $< $@ + +vmlinuz.ecoff: $(obj)/../elf2ecoff $(VMLINUZ) + $(Q)$(obj)/../elf2ecoff $(VMLINUZ) vmlinuz.ecoff $(E2EFLAGS) + +$(obj)/../elf2ecoff: $(src)/../elf2ecoff.c + $(Q)$(HOSTCC) -o $@ $^ + +drop-sections = .reginfo .mdebug .comment .note .pdr .options .MIPS.options +strip-flags = $(addprefix --remove-section=,$(drop-sections)) + +OBJCOPYFLAGS_vmlinuz.bin := $(OBJCOPYFLAGS) -O binary $(strip-flags) +vmlinuz.bin: vmlinuz + $(call if_changed,objcopy) + +OBJCOPYFLAGS_vmlinuz.srec := $(OBJCOPYFLAGS) -S -O srec $(strip-flags) +vmlinuz.srec: vmlinuz + $(call if_changed,objcopy) + +clean: +clean-files += *.o \ + vmlinu* diff --git a/arch/mips/boot/compressed/dbg.c b/arch/mips/boot/compressed/dbg.c new file mode 100644 index 0000000..ff4dc7a --- /dev/null +++ b/arch/mips/boot/compressed/dbg.c @@ -0,0 +1,37 @@ +/* + * MIPS-specific debug support for pre-boot environment + * + * NOTE: putc() is board specific, if your board have a 16550 compatible uart, + * please select SYS_SUPPORTS_ZBOOT_UART16550 for your machine. othewise, you + * need to implement your own putc(). + */ + +#include +#include + +void __attribute__ ((weak)) putc(char c) +{ +} + +void puts(const char *s) +{ + char c; + while ((c = *s++) != '\0') { + putc(c); + if (c == '\n') + putc('\r'); + } +} + +void puthex(unsigned long long val) +{ + + unsigned char buf[10]; + int i; + for (i = 7; i >= 0; i--) { + buf[i] = "0123456789ABCDEF"[val & 0x0F]; + val >>= 4; + } + buf[8] = '\0'; + puts(buf); +} diff --git a/arch/mips/boot/compressed/decompress.c b/arch/mips/boot/compressed/decompress.c new file mode 100644 index 0000000..67330c2 --- /dev/null +++ b/arch/mips/boot/compressed/decompress.c @@ -0,0 +1,126 @@ +/* + * Misc. bootloader code for many machines. + * + * Copyright 2001 MontaVista Software Inc. + * Author: Matt Porter Derived from + * arch/ppc/boot/prep/misc.c + * + * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology + * Author: Wu Zhangjin + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include + +#include + +/* These two variables specify the free mem region + * that can be used for temporary malloc area + */ +unsigned long free_mem_ptr; +unsigned long free_mem_end_ptr; +char *zimage_start; + +/* The linker tells us where the image is. */ +extern unsigned char __image_begin, __image_end; +extern unsigned char __ramdisk_begin, __ramdisk_end; +unsigned long initrd_size; + +/* debug interfaces */ +extern void puts(const char *s); +extern void puthex(unsigned long long val); + +void error(char *x) +{ + puts("\n\n"); + puts(x); + puts("\n\n -- System halted"); + + while (1) + ; /* Halt */ +} + +/* activate the code for pre-boot environment */ +#define STATIC static + +#ifdef CONFIG_KERNEL_GZIP +void *memcpy(void *dest, const void *src, size_t n) +{ + int i; + const char *s = src; + char *d = dest; + + for (i = 0; i < n; i++) + d[i] = s[i]; + return dest; +} +#include "../../../../lib/decompress_inflate.c" +#endif + +#ifdef CONFIG_KERNEL_BZIP2 +void *memset(void *s, int c, size_t n) +{ + int i; + char *ss = s; + + for (i = 0; i < n; i++) + ss[i] = c; + return s; +} +#include "../../../../lib/decompress_bunzip2.c" +#endif + +#ifdef CONFIG_KERNEL_LZMA +#include "../../../../lib/decompress_unlzma.c" +#endif + +void decompress_kernel(unsigned long boot_heap_start) +{ + int zimage_size; + + /* + * We link ourself to an arbitrary low address. When we run, we + * relocate outself to that address. __image_beign points to + * the part of the image where the zImage is. -- Tom + */ + zimage_start = (char *)(unsigned long)(&__image_begin); + zimage_size = (unsigned long)(&__image_end) - + (unsigned long)(&__image_begin); + + /* + * The zImage and initrd will be between start and _end, so they've + * already been moved once. We're good to go now. -- Tom + */ + puts("zimage at: "); + puthex((unsigned long)zimage_start); + puts(" "); + puthex((unsigned long)(zimage_size + zimage_start)); + puts("\n"); + + if (initrd_size) { + puts("initrd at: "); + puthex((unsigned long)(&__ramdisk_begin)); + puts(" "); + puthex((unsigned long)(&__ramdisk_end)); + puts("\n"); + } + + /* this area are prepared for mallocing when decompressing */ + free_mem_ptr = boot_heap_start; + free_mem_end_ptr = boot_heap_start + BOOT_HEAP_SIZE; + + /* Display standard Linux/MIPS boot prompt for kernel args */ + puts("Uncompressing Linux at load address "); + puthex(VMLINUX_LOAD_ADDRESS_ULL); + puts("\n"); + /* Decompress the kernel with according algorithm */ + decompress(zimage_start, zimage_size, 0, 0, + (void *)VMLINUX_LOAD_ADDRESS_ULL, 0, error); + /* FIXME: is there a need to flush cache here? */ + puts("Now, booting the kernel...\n"); +} diff --git a/arch/mips/boot/compressed/dummy.c b/arch/mips/boot/compressed/dummy.c new file mode 100644 index 0000000..31dbf45 --- /dev/null +++ b/arch/mips/boot/compressed/dummy.c @@ -0,0 +1,4 @@ +int main(void) +{ + return 0; +} diff --git a/arch/mips/boot/compressed/head.S b/arch/mips/boot/compressed/head.S new file mode 100644 index 0000000..4e65a84 --- /dev/null +++ b/arch/mips/boot/compressed/head.S @@ -0,0 +1,56 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1994, 1995 Waldorf Electronics + * Written by Ralf Baechle and Andreas Busse + * Copyright (C) 1995 - 1999 Ralf Baechle + * Copyright (C) 1996 Paul M. Antoine + * Modified for DECStation and hence R3000 support by Paul M. Antoine + * Further modifications by David S. Miller and Harald Koerfgen + * Copyright (C) 1999 Silicon Graphics, Inc. + */ + +#include +#include + + .set noreorder + .cprestore + LEAF(start) +start: + /* Save boot rom start args */ + move s0, a0 + move s1, a1 + move s2, a2 + move s3, a3 + + /* Clear BSS */ + PTR_LA a0, _edata + PTR_LA a2, _end +1: sw zero, 0(a0) + bne a2, a0, 1b + addiu a0, a0, 4 + + PTR_LA a0, (.heap) /* heap address */ + PTR_LA sp, (.stack + 8192) /* stack address */ + + PTR_LA ra, 2f + PTR_LA k0, decompress_kernel + jr k0 + nop +2: + move a0, s0 + move a1, s1 + move a2, s2 + move a3, s3 + PTR_LI k0, KERNEL_ENTRY + jr k0 + nop +3: + b 3b + nop + END(start) + + .comm .heap,BOOT_HEAP_SIZE,4 + .comm .stack,4096*2,4 diff --git a/arch/mips/boot/compressed/ld.script b/arch/mips/boot/compressed/ld.script new file mode 100644 index 0000000..29e9f4c --- /dev/null +++ b/arch/mips/boot/compressed/ld.script @@ -0,0 +1,150 @@ +OUTPUT_ARCH(mips) +ENTRY(start) +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + .init : { *(.init) } =0 + .text : + { + _ftext = . ; + *(.text) + *(.rodata) + *(.rodata1) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + } =0 + .kstrtab : { *(.kstrtab) } + + . = ALIGN(16); /* Exception table */ + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + __start___dbe_table = .; /* Exception table for data bus errors */ + __dbe_table : { *(__dbe_table) } + __stop___dbe_table = .; + + __start___ksymtab = .; /* Kernel symbol table */ + __ksymtab : { *(__ksymtab) } + __stop___ksymtab = .; + + _etext = .; + + . = ALIGN(8192); + .data.init_task : { *(.data.init_task) } + + /* Startup code */ + . = ALIGN(4096); + __init_begin = .; + .text.init : { *(.text.init) } + .data.init : { *(.data.init) } + . = ALIGN(16); + __setup_start = .; + .setup.init : { *(.setup.init) } + __setup_end = .; + __initcall_start = .; + .initcall.init : { *(.initcall.init) } + __initcall_end = .; + . = ALIGN(4096); /* Align double page for init_task_union */ + __init_end = .; + + . = ALIGN(4096); + .data.page_aligned : { *(.data.idt) } + + . = ALIGN(32); + .data.cacheline_aligned : { *(.data.cacheline_aligned) } + + .fini : { *(.fini) } =0 + .reginfo : { *(.reginfo) } + /* Adjust the address for the data segment. We want to adjust up to + the same address within the page on the next page up. It would + be more correct to do this: + . = .; + The current expression does not correctly handle the case of a + text segment ending precisely at the end of a page; it causes the + data segment to skip a page. The above expression does not have + this problem, but it will currently (2/95) cause BFD to allocate + a single segment, combining both text and data, for this case. + This will prevent the text segment from being shared among + multiple executions of the program; I think that is more + important than losing a page of the virtual address space (note + that no actual memory is lost; the page which is skipped can not + be referenced). */ + . = .; + .data : + { + _fdata = . ; + *(.data) + + /* Put the compressed image here, so bss is on the end. */ + __image_begin = .; + *(.image) + __image_end = .; + /* Align the initial ramdisk image (INITRD) on page boundaries. */ + . = ALIGN(4096); + __ramdisk_begin = .; + *(.initrd) + __ramdisk_end = .; + . = ALIGN(4096); + + CONSTRUCTORS + } + .data1 : { *(.data1) } + _gp = . + 0x8000; + .lit8 : { *(.lit8) } + .lit4 : { *(.lit4) } + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + .got : { *(.got.plt) *(.got) } + .dynamic : { *(.dynamic) } + /* We want the small data sections together, so single-instruction offsets + can access them all, and initialized data all before uninitialized, so + we can shorten the on-disk segment size. */ + .sdata : { *(.sdata) } + . = ALIGN(4); + _edata = .; + PROVIDE (edata = .); + + __bss_start = .; + _fbss = .; + .sbss : { *(.sbss) *(.scommon) } + .bss : + { + *(.dynbss) + *(.bss) + *(COMMON) + . = ALIGN(4); + _end = . ; + PROVIDE (end = .); + } + + /* Sections to be discarded */ + /DISCARD/ : + { + *(.text.exit) + *(.data.exit) + *(.exitcall.exit) + } + + /* This is the MIPS specific mdebug section. */ + .mdebug : { *(.mdebug) } + /* These are needed for ELF backends which have not yet been + converted to the new style linker. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + /* DWARF debug sections. + Symbols in the .debug DWARF section are relative to the beginning of the + section so we begin .debug at 0. It's not clear yet what needs to happen + for the others. */ + .debug 0 : { *(.debug) } + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_sfnames 0 : { *(.debug_sfnames) } + .line 0 : { *(.line) } + /* These must appear regardless of . */ + .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) } + .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) } + .comment : { *(.comment) } + .note : { *(.note) } +} diff --git a/arch/mips/boot/compressed/uart-16550.c b/arch/mips/boot/compressed/uart-16550.c new file mode 100644 index 0000000..c9caaf4 --- /dev/null +++ b/arch/mips/boot/compressed/uart-16550.c @@ -0,0 +1,43 @@ +/* + * 16550 compatible uart based serial debug support for zboot + */ + +#include +#include +#include + +#include + +#if defined(CONFIG_MACH_LOONGSON) || defined(CONFIG_MIPS_MALTA) +#define UART_BASE 0x1fd003f8 +#define PORT(offset) (CKSEG1ADDR(UART_BASE) + (offset)) +#endif + +#ifdef CONFIG_AR7 +#include +#define PORT(offset) (CKSEG1ADDR(AR7_REGS_UART0) + (4 * offset)) +#endif + +#ifndef PORT +#error please define the serial port address for your own machine +#endif + +static inline unsigned int serial_in(int offset) +{ + return *((char *)PORT(offset)); +} + +static inline void serial_out(int offset, int value) +{ + *((char *)PORT(offset)) = value; +} + +void putc(char c) +{ + int timeout = 1024; + + while (((serial_in(UART_LSR) & UART_LSR_THRE) == 0) && (timeout-- > 0)) + ; + + serial_out(UART_TX, c); +} -- cgit v0.10.2 From cb6edd45f04152d91d598c0aadadbb3ac673d07b Mon Sep 17 00:00:00 2001 From: Dmitri Vorobiev Date: Tue, 13 Oct 2009 22:37:01 +0300 Subject: MIPS: IP22: Remove an unused function Nobody is using the ARCS-specific prom_getcmdline(), so let's remove it. Signed-off-by: Dmitri Vorobiev Signed-off-by: Ralf Baechle diff --git a/arch/mips/fw/arc/cmdline.c b/arch/mips/fw/arc/cmdline.c index 4ca4eef..5c8603c8 100644 --- a/arch/mips/fw/arc/cmdline.c +++ b/arch/mips/fw/arc/cmdline.c @@ -16,11 +16,6 @@ #undef DEBUG_CMDLINE -char * __init prom_getcmdline(void) -{ - return arcs_cmdline; -} - static char *ignored[] = { "ConsoleIn=", "ConsoleOut=", diff --git a/arch/mips/include/asm/sgialib.h b/arch/mips/include/asm/sgialib.h index bfce5c7..63741ca 100644 --- a/arch/mips/include/asm/sgialib.h +++ b/arch/mips/include/asm/sgialib.h @@ -85,8 +85,7 @@ extern void prom_identify_arch(void); extern PCHAR ArcGetEnvironmentVariable(PCHAR name); extern LONG ArcSetEnvironmentVariable(PCHAR name, PCHAR value); -/* ARCS command line acquisition and parsing. */ -extern char *prom_getcmdline(void); +/* ARCS command line parsing. */ extern void prom_init_cmdline(void); /* Acquiring info about the current time, etc. */ -- cgit v0.10.2 From 7580c9c3938f45b0d889728d5533cb46b0322a85 Mon Sep 17 00:00:00 2001 From: Dmitri Vorobiev Date: Tue, 13 Oct 2009 23:43:24 +0300 Subject: MIPS: Replace all usages of CL_SIZE by COMMAND_LINE_SIZE The MIPS-specific macro CL_SIZE is merely aliasing the macro COMMAND_LINE_SIZE. Other architectures use the latter; also, COMMAND_LINE_SIZE is documented in kernel-parameters.txt, so let's use it, and remove the alias. Signed-off-by: Dmitri Vorobiev Signed-off-by: Ralf Baechle diff --git a/arch/mips/bcm47xx/prom.c b/arch/mips/bcm47xx/prom.c index fb284c3..c51405e 100644 --- a/arch/mips/bcm47xx/prom.c +++ b/arch/mips/bcm47xx/prom.c @@ -100,11 +100,11 @@ static __init void prom_init_console(void) static __init void prom_init_cmdline(void) { - static char buf[CL_SIZE] __initdata; + static char buf[COMMAND_LINE_SIZE] __initdata; /* Get the kernel command line from CFE */ - if (cfe_getenv("LINUX_CMDLINE", buf, CL_SIZE) >= 0) { - buf[CL_SIZE-1] = 0; + if (cfe_getenv("LINUX_CMDLINE", buf, COMMAND_LINE_SIZE) >= 0) { + buf[COMMAND_LINE_SIZE - 1] = 0; strcpy(arcs_cmdline, buf); } @@ -112,13 +112,13 @@ static __init void prom_init_cmdline(void) * as CFE is not available anymore later in the boot process. */ if ((strstr(arcs_cmdline, "console=")) == NULL) { /* Try to read the default serial port used by CFE */ - if ((cfe_getenv("BOOT_CONSOLE", buf, CL_SIZE) < 0) + if ((cfe_getenv("BOOT_CONSOLE", buf, COMMAND_LINE_SIZE) < 0) || (strncmp("uart", buf, 4))) /* Default to uart0 */ strcpy(buf, "uart0"); /* Compute the new command line */ - snprintf(arcs_cmdline, CL_SIZE, "%s console=ttyS%c,115200", + snprintf(arcs_cmdline, COMMAND_LINE_SIZE, "%s console=ttyS%c,115200", arcs_cmdline, buf[4]); } } diff --git a/arch/mips/include/asm/bootinfo.h b/arch/mips/include/asm/bootinfo.h index f5dfaf6..07d4115 100644 --- a/arch/mips/include/asm/bootinfo.h +++ b/arch/mips/include/asm/bootinfo.h @@ -69,8 +69,6 @@ #define MACH_DEXXON_GDIUM2F10 5 #define MACH_LOONGSON_END 6 -#define CL_SIZE COMMAND_LINE_SIZE - extern char *system_type; const char *get_system_type(void); @@ -107,7 +105,7 @@ extern void free_init_pages(const char *what, /* * Initial kernel command line, usually setup by prom_init() */ -extern char arcs_cmdline[CL_SIZE]; +extern char arcs_cmdline[COMMAND_LINE_SIZE]; /* * Registers a0, a1, a3 and a4 as passed to the kernel entry by firmware diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index 2b290d7..fd138c9 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -58,8 +58,8 @@ EXPORT_SYMBOL(mips_machtype); struct boot_mem_map boot_mem_map; -static char command_line[CL_SIZE]; - char arcs_cmdline[CL_SIZE]=CONFIG_CMDLINE; +static char command_line[COMMAND_LINE_SIZE]; + char arcs_cmdline[COMMAND_LINE_SIZE] = CONFIG_CMDLINE; /* * mips_io_port_base is the begin of the address space to which x86 style diff --git a/arch/mips/lasat/prom.c b/arch/mips/lasat/prom.c index 6acc6cb..20fde19 100644 --- a/arch/mips/lasat/prom.c +++ b/arch/mips/lasat/prom.c @@ -100,8 +100,8 @@ void __init prom_init(void) /* Get the command line */ if (argc > 0) { - strncpy(arcs_cmdline, argv[0], CL_SIZE-1); - arcs_cmdline[CL_SIZE-1] = '\0'; + strncpy(arcs_cmdline, argv[0], COMMAND_LINE_SIZE-1); + arcs_cmdline[COMMAND_LINE_SIZE-1] = '\0'; } /* Set the I/O base address */ diff --git a/arch/mips/mti-malta/malta-memory.c b/arch/mips/mti-malta/malta-memory.c index 9035c64..b27419c 100644 --- a/arch/mips/mti-malta/malta-memory.c +++ b/arch/mips/mti-malta/malta-memory.c @@ -55,7 +55,7 @@ static struct prom_pmemblock * __init prom_getmdesc(void) char *memsize_str; unsigned int memsize; char *ptr; - static char cmdline[CL_SIZE] __initdata; + static char cmdline[COMMAND_LINE_SIZE] __initdata; /* otherwise look in the environment */ memsize_str = prom_getenv("memsize"); diff --git a/arch/mips/rb532/prom.c b/arch/mips/rb532/prom.c index ad5bd10..d7c26d0 100644 --- a/arch/mips/rb532/prom.c +++ b/arch/mips/rb532/prom.c @@ -69,7 +69,7 @@ static inline unsigned long tag2ul(char *arg, const char *tag) void __init prom_setup_cmdline(void) { - static char cmd_line[CL_SIZE] __initdata; + static char cmd_line[COMMAND_LINE_SIZE] __initdata; char *cp, *board; int prom_argc; char **prom_argv, **prom_envp; @@ -115,7 +115,7 @@ void __init prom_setup_cmdline(void) strcpy(cp, arcs_cmdline); cp += strlen(arcs_cmdline); } - cmd_line[CL_SIZE-1] = '\0'; + cmd_line[COMMAND_LINE_SIZE - 1] = '\0'; strcpy(arcs_cmdline, cmd_line); } diff --git a/arch/mips/sibyte/common/cfe.c b/arch/mips/sibyte/common/cfe.c index eb5396c..6343011 100644 --- a/arch/mips/sibyte/common/cfe.c +++ b/arch/mips/sibyte/common/cfe.c @@ -287,7 +287,7 @@ void __init prom_init(void) * boot console */ cfe_cons_handle = cfe_getstdhandle(CFE_STDHANDLE_CONSOLE); - if (cfe_getenv("LINUX_CMDLINE", arcs_cmdline, CL_SIZE) < 0) { + if (cfe_getenv("LINUX_CMDLINE", arcs_cmdline, COMMAND_LINE_SIZE) < 0) { if (argc >= 0) { /* The loader should have set the command line */ /* too early for panic to do any good */ @@ -318,7 +318,7 @@ void __init prom_init(void) #endif /* CONFIG_BLK_DEV_INITRD */ /* Not sure this is needed, but it's the safe way. */ - arcs_cmdline[CL_SIZE-1] = 0; + arcs_cmdline[COMMAND_LINE_SIZE-1] = 0; prom_meminit(); diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c index d66802e..06e801c 100644 --- a/arch/mips/txx9/generic/setup.c +++ b/arch/mips/txx9/generic/setup.c @@ -160,7 +160,7 @@ static void __init prom_init_cmdline(void) int argc; int *argv32; int i; /* Always ignore the "-c" at argv[0] */ - static char builtin[CL_SIZE] __initdata; + static char builtin[COMMAND_LINE_SIZE] __initdata; if (fw_arg0 >= CKSEG0 || fw_arg1 < CKSEG0) { /* @@ -315,7 +315,7 @@ static inline void txx9_cache_fixup(void) static void __init preprocess_cmdline(void) { - static char cmdline[CL_SIZE] __initdata; + static char cmdline[COMMAND_LINE_SIZE] __initdata; char *s; strcpy(cmdline, arcs_cmdline); -- cgit v0.10.2 From 362e696428590f7d0a5d0971a2d04b0372a761b8 Mon Sep 17 00:00:00 2001 From: David Daney Date: Fri, 26 Jun 2009 09:01:43 -0700 Subject: MIPS: Reorder operations in stackframe.h for better scheduling Reorder PT ops to avoid pipeline stalls. Signed-off-by: David Daney Signed-off-by: Ralf Baechle diff --git a/arch/mips/include/asm/stackframe.h b/arch/mips/include/asm/stackframe.h index db0fa7b..dd7e220 100644 --- a/arch/mips/include/asm/stackframe.h +++ b/arch/mips/include/asm/stackframe.h @@ -51,9 +51,6 @@ LONG_S v1, PT_ACX(sp) #else mfhi v1 - LONG_S v1, PT_HI(sp) - mflo v1 - LONG_S v1, PT_LO(sp) #endif #ifdef CONFIG_32BIT LONG_S $8, PT_R8(sp) @@ -62,10 +59,17 @@ LONG_S $10, PT_R10(sp) LONG_S $11, PT_R11(sp) LONG_S $12, PT_R12(sp) +#ifndef CONFIG_CPU_HAS_SMARTMIPS + LONG_S v1, PT_HI(sp) + mflo v1 +#endif LONG_S $13, PT_R13(sp) LONG_S $14, PT_R14(sp) LONG_S $15, PT_R15(sp) LONG_S $24, PT_R24(sp) +#ifndef CONFIG_CPU_HAS_SMARTMIPS + LONG_S v1, PT_LO(sp) +#endif .endm .macro SAVE_STATIC @@ -166,7 +170,6 @@ LONG_S $0, PT_R0(sp) mfc0 v1, CP0_STATUS LONG_S $2, PT_R2(sp) - LONG_S v1, PT_STATUS(sp) #ifdef CONFIG_MIPS_MT_SMTC /* * Ideally, these instructions would be shuffled in @@ -178,20 +181,21 @@ LONG_S v1, PT_TCSTATUS(sp) #endif /* CONFIG_MIPS_MT_SMTC */ LONG_S $4, PT_R4(sp) - mfc0 v1, CP0_CAUSE LONG_S $5, PT_R5(sp) - LONG_S v1, PT_CAUSE(sp) + LONG_S v1, PT_STATUS(sp) + mfc0 v1, CP0_CAUSE LONG_S $6, PT_R6(sp) - MFC0 v1, CP0_EPC LONG_S $7, PT_R7(sp) + LONG_S v1, PT_CAUSE(sp) + MFC0 v1, CP0_EPC #ifdef CONFIG_64BIT LONG_S $8, PT_R8(sp) LONG_S $9, PT_R9(sp) #endif - LONG_S v1, PT_EPC(sp) LONG_S $25, PT_R25(sp) LONG_S $28, PT_R28(sp) LONG_S $31, PT_R31(sp) + LONG_S v1, PT_EPC(sp) ori $28, sp, _THREAD_MASK xori $28, _THREAD_MASK #ifdef CONFIG_CPU_CAVIUM_OCTEON -- cgit v0.10.2 From 0f7e64a3941fef0a5735da5184f3ccc0d234b580 Mon Sep 17 00:00:00 2001 From: David Daney Date: Wed, 14 Oct 2009 12:04:37 -0700 Subject: MIPS: Octeon: Add platform device for MDIO buses. Signed-off-by: David Daney Signed-off-by: Ralf Baechle diff --git a/arch/mips/cavium-octeon/octeon-platform.c b/arch/mips/cavium-octeon/octeon-platform.c index be711dd..febfdd7 100644 --- a/arch/mips/cavium-octeon/octeon-platform.c +++ b/arch/mips/cavium-octeon/octeon-platform.c @@ -159,6 +159,36 @@ out: } device_initcall(octeon_rng_device_init); +/* Octeon SMI/MDIO interface. */ +static int __init octeon_mdiobus_device_init(void) +{ + struct platform_device *pd; + int ret = 0; + + if (octeon_is_simulation()) + return 0; /* No mdio in the simulator. */ + + /* The bus number is the platform_device id. */ + pd = platform_device_alloc("mdio-octeon", 0); + if (!pd) { + ret = -ENOMEM; + goto out; + } + + ret = platform_device_add(pd); + if (ret) + goto fail; + + return ret; +fail: + platform_device_put(pd); + +out: + return ret; + +} +device_initcall(octeon_mdiobus_device_init); + MODULE_AUTHOR("David Daney "); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Platform driver for Octeon SOC"); -- cgit v0.10.2 From 25d967b72a92d72b6e0263a0337dfc940bd6c044 Mon Sep 17 00:00:00 2001 From: David Daney Date: Wed, 14 Oct 2009 12:04:38 -0700 Subject: NET: Add driver for Octeon MDIO buses. The Octeon SOC has two types of Ethernet ports, each type with its own driver. However, the PHYs for all the ports are controlled by a common MDIO bus. Because the mdio driver is not associated with a particular driver, but is instead a system level resource, we create s stand-alone driver for it. As for the driver, we put the register definitions in arch/mips/include/asm/octeon where most of the other Octeon register definitions live. This is a platform driver with the platform device for "mdio-octeon" being registered in the platform startup code. Signed-off-by: David Daney Acked-by: David S. Miller Signed-off-by: Ralf Baechle diff --git a/arch/mips/include/asm/octeon/cvmx-smix-defs.h b/arch/mips/include/asm/octeon/cvmx-smix-defs.h new file mode 100644 index 0000000..9ae45fc --- /dev/null +++ b/arch/mips/include/asm/octeon/cvmx-smix-defs.h @@ -0,0 +1,178 @@ +/***********************license start*************** + * Author: Cavium Networks + * + * Contact: support@caviumnetworks.com + * This file is part of the OCTEON SDK + * + * Copyright (c) 2003-2008 Cavium Networks + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, Version 2, as + * published by the Free Software Foundation. + * + * This file is distributed in the hope that it will be useful, but + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or + * NONINFRINGEMENT. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * or visit http://www.gnu.org/licenses/. + * + * This file may also be available under a different license from Cavium. + * Contact Cavium Networks for more information + ***********************license end**************************************/ + +#ifndef __CVMX_SMIX_DEFS_H__ +#define __CVMX_SMIX_DEFS_H__ + +#define CVMX_SMIX_CLK(offset) \ + CVMX_ADD_IO_SEG(0x0001180000001818ull + (((offset) & 1) * 256)) +#define CVMX_SMIX_CMD(offset) \ + CVMX_ADD_IO_SEG(0x0001180000001800ull + (((offset) & 1) * 256)) +#define CVMX_SMIX_EN(offset) \ + CVMX_ADD_IO_SEG(0x0001180000001820ull + (((offset) & 1) * 256)) +#define CVMX_SMIX_RD_DAT(offset) \ + CVMX_ADD_IO_SEG(0x0001180000001810ull + (((offset) & 1) * 256)) +#define CVMX_SMIX_WR_DAT(offset) \ + CVMX_ADD_IO_SEG(0x0001180000001808ull + (((offset) & 1) * 256)) + +union cvmx_smix_clk { + uint64_t u64; + struct cvmx_smix_clk_s { + uint64_t reserved_25_63:39; + uint64_t mode:1; + uint64_t reserved_21_23:3; + uint64_t sample_hi:5; + uint64_t sample_mode:1; + uint64_t reserved_14_14:1; + uint64_t clk_idle:1; + uint64_t preamble:1; + uint64_t sample:4; + uint64_t phase:8; + } s; + struct cvmx_smix_clk_cn30xx { + uint64_t reserved_21_63:43; + uint64_t sample_hi:5; + uint64_t reserved_14_15:2; + uint64_t clk_idle:1; + uint64_t preamble:1; + uint64_t sample:4; + uint64_t phase:8; + } cn30xx; + struct cvmx_smix_clk_cn30xx cn31xx; + struct cvmx_smix_clk_cn30xx cn38xx; + struct cvmx_smix_clk_cn30xx cn38xxp2; + struct cvmx_smix_clk_cn50xx { + uint64_t reserved_25_63:39; + uint64_t mode:1; + uint64_t reserved_21_23:3; + uint64_t sample_hi:5; + uint64_t reserved_14_15:2; + uint64_t clk_idle:1; + uint64_t preamble:1; + uint64_t sample:4; + uint64_t phase:8; + } cn50xx; + struct cvmx_smix_clk_s cn52xx; + struct cvmx_smix_clk_cn50xx cn52xxp1; + struct cvmx_smix_clk_s cn56xx; + struct cvmx_smix_clk_cn50xx cn56xxp1; + struct cvmx_smix_clk_cn30xx cn58xx; + struct cvmx_smix_clk_cn30xx cn58xxp1; +}; + +union cvmx_smix_cmd { + uint64_t u64; + struct cvmx_smix_cmd_s { + uint64_t reserved_18_63:46; + uint64_t phy_op:2; + uint64_t reserved_13_15:3; + uint64_t phy_adr:5; + uint64_t reserved_5_7:3; + uint64_t reg_adr:5; + } s; + struct cvmx_smix_cmd_cn30xx { + uint64_t reserved_17_63:47; + uint64_t phy_op:1; + uint64_t reserved_13_15:3; + uint64_t phy_adr:5; + uint64_t reserved_5_7:3; + uint64_t reg_adr:5; + } cn30xx; + struct cvmx_smix_cmd_cn30xx cn31xx; + struct cvmx_smix_cmd_cn30xx cn38xx; + struct cvmx_smix_cmd_cn30xx cn38xxp2; + struct cvmx_smix_cmd_s cn50xx; + struct cvmx_smix_cmd_s cn52xx; + struct cvmx_smix_cmd_s cn52xxp1; + struct cvmx_smix_cmd_s cn56xx; + struct cvmx_smix_cmd_s cn56xxp1; + struct cvmx_smix_cmd_cn30xx cn58xx; + struct cvmx_smix_cmd_cn30xx cn58xxp1; +}; + +union cvmx_smix_en { + uint64_t u64; + struct cvmx_smix_en_s { + uint64_t reserved_1_63:63; + uint64_t en:1; + } s; + struct cvmx_smix_en_s cn30xx; + struct cvmx_smix_en_s cn31xx; + struct cvmx_smix_en_s cn38xx; + struct cvmx_smix_en_s cn38xxp2; + struct cvmx_smix_en_s cn50xx; + struct cvmx_smix_en_s cn52xx; + struct cvmx_smix_en_s cn52xxp1; + struct cvmx_smix_en_s cn56xx; + struct cvmx_smix_en_s cn56xxp1; + struct cvmx_smix_en_s cn58xx; + struct cvmx_smix_en_s cn58xxp1; +}; + +union cvmx_smix_rd_dat { + uint64_t u64; + struct cvmx_smix_rd_dat_s { + uint64_t reserved_18_63:46; + uint64_t pending:1; + uint64_t val:1; + uint64_t dat:16; + } s; + struct cvmx_smix_rd_dat_s cn30xx; + struct cvmx_smix_rd_dat_s cn31xx; + struct cvmx_smix_rd_dat_s cn38xx; + struct cvmx_smix_rd_dat_s cn38xxp2; + struct cvmx_smix_rd_dat_s cn50xx; + struct cvmx_smix_rd_dat_s cn52xx; + struct cvmx_smix_rd_dat_s cn52xxp1; + struct cvmx_smix_rd_dat_s cn56xx; + struct cvmx_smix_rd_dat_s cn56xxp1; + struct cvmx_smix_rd_dat_s cn58xx; + struct cvmx_smix_rd_dat_s cn58xxp1; +}; + +union cvmx_smix_wr_dat { + uint64_t u64; + struct cvmx_smix_wr_dat_s { + uint64_t reserved_18_63:46; + uint64_t pending:1; + uint64_t val:1; + uint64_t dat:16; + } s; + struct cvmx_smix_wr_dat_s cn30xx; + struct cvmx_smix_wr_dat_s cn31xx; + struct cvmx_smix_wr_dat_s cn38xx; + struct cvmx_smix_wr_dat_s cn38xxp2; + struct cvmx_smix_wr_dat_s cn50xx; + struct cvmx_smix_wr_dat_s cn52xx; + struct cvmx_smix_wr_dat_s cn52xxp1; + struct cvmx_smix_wr_dat_s cn56xx; + struct cvmx_smix_wr_dat_s cn56xxp1; + struct cvmx_smix_wr_dat_s cn58xx; + struct cvmx_smix_wr_dat_s cn58xxp1; +}; + +#endif diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index d5d8e1c..fc5938ba 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig @@ -115,4 +115,15 @@ config MDIO_GPIO To compile this driver as a module, choose M here: the module will be called mdio-gpio. +config MDIO_OCTEON + tristate "Support for MDIO buses on Octeon SOCs" + depends on CPU_CAVIUM_OCTEON + default y + help + + This module provides a driver for the Octeon MDIO busses. + It is required by the Octeon Ethernet device drivers. + + If in doubt, say Y. + endif # PHYLIB diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile index edfaac4..1342585 100644 --- a/drivers/net/phy/Makefile +++ b/drivers/net/phy/Makefile @@ -20,3 +20,4 @@ obj-$(CONFIG_MDIO_BITBANG) += mdio-bitbang.o obj-$(CONFIG_MDIO_GPIO) += mdio-gpio.o obj-$(CONFIG_NATIONAL_PHY) += national.o obj-$(CONFIG_STE10XP) += ste10Xp.o +obj-$(CONFIG_MDIO_OCTEON) += mdio-octeon.o diff --git a/drivers/net/phy/mdio-octeon.c b/drivers/net/phy/mdio-octeon.c new file mode 100644 index 0000000..61a4461 --- /dev/null +++ b/drivers/net/phy/mdio-octeon.c @@ -0,0 +1,180 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2009 Cavium Networks + */ + +#include +#include +#include +#include + +#include +#include + +#define DRV_VERSION "1.0" +#define DRV_DESCRIPTION "Cavium Networks Octeon SMI/MDIO driver" + +struct octeon_mdiobus { + struct mii_bus *mii_bus; + int unit; + int phy_irq[PHY_MAX_ADDR]; +}; + +static int octeon_mdiobus_read(struct mii_bus *bus, int phy_id, int regnum) +{ + struct octeon_mdiobus *p = bus->priv; + union cvmx_smix_cmd smi_cmd; + union cvmx_smix_rd_dat smi_rd; + int timeout = 1000; + + smi_cmd.u64 = 0; + smi_cmd.s.phy_op = 1; /* MDIO_CLAUSE_22_READ */ + smi_cmd.s.phy_adr = phy_id; + smi_cmd.s.reg_adr = regnum; + cvmx_write_csr(CVMX_SMIX_CMD(p->unit), smi_cmd.u64); + + do { + /* + * Wait 1000 clocks so we don't saturate the RSL bus + * doing reads. + */ + cvmx_wait(1000); + smi_rd.u64 = cvmx_read_csr(CVMX_SMIX_RD_DAT(p->unit)); + } while (smi_rd.s.pending && --timeout); + + if (smi_rd.s.val) + return smi_rd.s.dat; + else + return -EIO; +} + +static int octeon_mdiobus_write(struct mii_bus *bus, int phy_id, + int regnum, u16 val) +{ + struct octeon_mdiobus *p = bus->priv; + union cvmx_smix_cmd smi_cmd; + union cvmx_smix_wr_dat smi_wr; + int timeout = 1000; + + smi_wr.u64 = 0; + smi_wr.s.dat = val; + cvmx_write_csr(CVMX_SMIX_WR_DAT(p->unit), smi_wr.u64); + + smi_cmd.u64 = 0; + smi_cmd.s.phy_op = 0; /* MDIO_CLAUSE_22_WRITE */ + smi_cmd.s.phy_adr = phy_id; + smi_cmd.s.reg_adr = regnum; + cvmx_write_csr(CVMX_SMIX_CMD(p->unit), smi_cmd.u64); + + do { + /* + * Wait 1000 clocks so we don't saturate the RSL bus + * doing reads. + */ + cvmx_wait(1000); + smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(p->unit)); + } while (smi_wr.s.pending && --timeout); + + if (timeout <= 0) + return -EIO; + + return 0; +} + +static int __init octeon_mdiobus_probe(struct platform_device *pdev) +{ + struct octeon_mdiobus *bus; + int i; + int err = -ENOENT; + + bus = devm_kzalloc(&pdev->dev, sizeof(*bus), GFP_KERNEL); + if (!bus) + return -ENOMEM; + + /* The platform_device id is our unit number. */ + bus->unit = pdev->id; + + bus->mii_bus = mdiobus_alloc(); + + if (!bus->mii_bus) + goto err; + + /* + * Standard Octeon evaluation boards don't support phy + * interrupts, we need to poll. + */ + for (i = 0; i < PHY_MAX_ADDR; i++) + bus->phy_irq[i] = PHY_POLL; + + bus->mii_bus->priv = bus; + bus->mii_bus->irq = bus->phy_irq; + bus->mii_bus->name = "mdio-octeon"; + snprintf(bus->mii_bus->id, MII_BUS_ID_SIZE, "%x", bus->unit); + bus->mii_bus->parent = &pdev->dev; + + bus->mii_bus->read = octeon_mdiobus_read; + bus->mii_bus->write = octeon_mdiobus_write; + + dev_set_drvdata(&pdev->dev, bus); + + err = mdiobus_register(bus->mii_bus); + if (err) + goto err_register; + + dev_info(&pdev->dev, "Version " DRV_VERSION "\n"); + + return 0; +err_register: + mdiobus_free(bus->mii_bus); + +err: + devm_kfree(&pdev->dev, bus); + return err; +} + +static int __exit octeon_mdiobus_remove(struct platform_device *pdev) +{ + struct octeon_mdiobus *bus; + + bus = dev_get_drvdata(&pdev->dev); + + mdiobus_unregister(bus->mii_bus); + mdiobus_free(bus->mii_bus); + return 0; +} + +static struct platform_driver octeon_mdiobus_driver = { + .driver = { + .name = "mdio-octeon", + .owner = THIS_MODULE, + }, + .probe = octeon_mdiobus_probe, + .remove = __exit_p(octeon_mdiobus_remove), +}; + +void octeon_mdiobus_force_mod_depencency(void) +{ + /* Let ethernet drivers force us to be loaded. */ +} +EXPORT_SYMBOL(octeon_mdiobus_force_mod_depencency); + +static int __init octeon_mdiobus_mod_init(void) +{ + return platform_driver_register(&octeon_mdiobus_driver); +} + +static void __exit octeon_mdiobus_mod_exit(void) +{ + platform_driver_unregister(&octeon_mdiobus_driver); +} + +module_init(octeon_mdiobus_mod_init); +module_exit(octeon_mdiobus_mod_exit); + +MODULE_DESCRIPTION(DRV_DESCRIPTION); +MODULE_VERSION(DRV_VERSION); +MODULE_AUTHOR("David Daney"); +MODULE_LICENSE("GPL"); -- cgit v0.10.2 From 24479d9f4650faf09f6f18fb32251ff7d399cb75 Mon Sep 17 00:00:00 2001 From: David Daney Date: Wed, 14 Oct 2009 12:04:39 -0700 Subject: MIPS: Octeon: Add platform devices MGMT Ethernet ports. Signed-off-by: David Daney Signed-off-by: Ralf Baechle diff --git a/arch/mips/cavium-octeon/octeon-platform.c b/arch/mips/cavium-octeon/octeon-platform.c index febfdd7..cfdb4c2 100644 --- a/arch/mips/cavium-octeon/octeon-platform.c +++ b/arch/mips/cavium-octeon/octeon-platform.c @@ -189,6 +189,64 @@ out: } device_initcall(octeon_mdiobus_device_init); +/* Octeon mgmt port Ethernet interface. */ +static int __init octeon_mgmt_device_init(void) +{ + struct platform_device *pd; + int ret = 0; + int port, num_ports; + + struct resource mgmt_port_resource = { + .flags = IORESOURCE_IRQ, + .start = -1, + .end = -1 + }; + + if (!OCTEON_IS_MODEL(OCTEON_CN56XX) && !OCTEON_IS_MODEL(OCTEON_CN52XX)) + return 0; + + if (OCTEON_IS_MODEL(OCTEON_CN56XX)) + num_ports = 1; + else + num_ports = 2; + + for (port = 0; port < num_ports; port++) { + pd = platform_device_alloc("octeon_mgmt", port); + if (!pd) { + ret = -ENOMEM; + goto out; + } + switch (port) { + case 0: + mgmt_port_resource.start = OCTEON_IRQ_MII0; + break; + case 1: + mgmt_port_resource.start = OCTEON_IRQ_MII1; + break; + default: + BUG(); + } + mgmt_port_resource.end = mgmt_port_resource.start; + + ret = platform_device_add_resources(pd, &mgmt_port_resource, 1); + + if (ret) + goto fail; + + ret = platform_device_add(pd); + if (ret) + goto fail; + } + return ret; +fail: + platform_device_put(pd); + +out: + return ret; + +} +device_initcall(octeon_mgmt_device_init); + MODULE_AUTHOR("David Daney "); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Platform driver for Octeon SOC"); -- cgit v0.10.2 From a7187a2ffcdedf6d8fd13c4a1250874071892347 Mon Sep 17 00:00:00 2001 From: David Daney Date: Wed, 14 Oct 2009 12:04:40 -0700 Subject: MIPS: Octeon: Add register definitions for MGMT Ethernet driver. Signed-off-by: David Daney Signed-off-by: Ralf Baechle diff --git a/arch/mips/include/asm/octeon/cvmx-agl-defs.h b/arch/mips/include/asm/octeon/cvmx-agl-defs.h new file mode 100644 index 0000000..ec94b9a --- /dev/null +++ b/arch/mips/include/asm/octeon/cvmx-agl-defs.h @@ -0,0 +1,1194 @@ +/***********************license start*************** + * Author: Cavium Networks + * + * Contact: support@caviumnetworks.com + * This file is part of the OCTEON SDK + * + * Copyright (c) 2003-2008 Cavium Networks + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, Version 2, as + * published by the Free Software Foundation. + * + * This file is distributed in the hope that it will be useful, but + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or + * NONINFRINGEMENT. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * or visit http://www.gnu.org/licenses/. + * + * This file may also be available under a different license from Cavium. + * Contact Cavium Networks for more information + ***********************license end**************************************/ + +#ifndef __CVMX_AGL_DEFS_H__ +#define __CVMX_AGL_DEFS_H__ + +#define CVMX_AGL_GMX_BAD_REG \ + CVMX_ADD_IO_SEG(0x00011800E0000518ull) +#define CVMX_AGL_GMX_BIST \ + CVMX_ADD_IO_SEG(0x00011800E0000400ull) +#define CVMX_AGL_GMX_DRV_CTL \ + CVMX_ADD_IO_SEG(0x00011800E00007F0ull) +#define CVMX_AGL_GMX_INF_MODE \ + CVMX_ADD_IO_SEG(0x00011800E00007F8ull) +#define CVMX_AGL_GMX_PRTX_CFG(offset) \ + CVMX_ADD_IO_SEG(0x00011800E0000010ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_RXX_ADR_CAM0(offset) \ + CVMX_ADD_IO_SEG(0x00011800E0000180ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_RXX_ADR_CAM1(offset) \ + CVMX_ADD_IO_SEG(0x00011800E0000188ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_RXX_ADR_CAM2(offset) \ + CVMX_ADD_IO_SEG(0x00011800E0000190ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_RXX_ADR_CAM3(offset) \ + CVMX_ADD_IO_SEG(0x00011800E0000198ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_RXX_ADR_CAM4(offset) \ + CVMX_ADD_IO_SEG(0x00011800E00001A0ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_RXX_ADR_CAM5(offset) \ + CVMX_ADD_IO_SEG(0x00011800E00001A8ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_RXX_ADR_CAM_EN(offset) \ + CVMX_ADD_IO_SEG(0x00011800E0000108ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_RXX_ADR_CTL(offset) \ + CVMX_ADD_IO_SEG(0x00011800E0000100ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_RXX_DECISION(offset) \ + CVMX_ADD_IO_SEG(0x00011800E0000040ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_RXX_FRM_CHK(offset) \ + CVMX_ADD_IO_SEG(0x00011800E0000020ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_RXX_FRM_CTL(offset) \ + CVMX_ADD_IO_SEG(0x00011800E0000018ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_RXX_FRM_MAX(offset) \ + CVMX_ADD_IO_SEG(0x00011800E0000030ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_RXX_FRM_MIN(offset) \ + CVMX_ADD_IO_SEG(0x00011800E0000028ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_RXX_IFG(offset) \ + CVMX_ADD_IO_SEG(0x00011800E0000058ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_RXX_INT_EN(offset) \ + CVMX_ADD_IO_SEG(0x00011800E0000008ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_RXX_INT_REG(offset) \ + CVMX_ADD_IO_SEG(0x00011800E0000000ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_RXX_JABBER(offset) \ + CVMX_ADD_IO_SEG(0x00011800E0000038ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_RXX_PAUSE_DROP_TIME(offset) \ + CVMX_ADD_IO_SEG(0x00011800E0000068ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_RXX_STATS_CTL(offset) \ + CVMX_ADD_IO_SEG(0x00011800E0000050ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_RXX_STATS_OCTS(offset) \ + CVMX_ADD_IO_SEG(0x00011800E0000088ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_RXX_STATS_OCTS_CTL(offset) \ + CVMX_ADD_IO_SEG(0x00011800E0000098ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_RXX_STATS_OCTS_DMAC(offset) \ + CVMX_ADD_IO_SEG(0x00011800E00000A8ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_RXX_STATS_OCTS_DRP(offset) \ + CVMX_ADD_IO_SEG(0x00011800E00000B8ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_RXX_STATS_PKTS(offset) \ + CVMX_ADD_IO_SEG(0x00011800E0000080ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_RXX_STATS_PKTS_BAD(offset) \ + CVMX_ADD_IO_SEG(0x00011800E00000C0ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_RXX_STATS_PKTS_CTL(offset) \ + CVMX_ADD_IO_SEG(0x00011800E0000090ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_RXX_STATS_PKTS_DMAC(offset) \ + CVMX_ADD_IO_SEG(0x00011800E00000A0ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_RXX_STATS_PKTS_DRP(offset) \ + CVMX_ADD_IO_SEG(0x00011800E00000B0ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_RXX_UDD_SKP(offset) \ + CVMX_ADD_IO_SEG(0x00011800E0000048ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_RX_BP_DROPX(offset) \ + CVMX_ADD_IO_SEG(0x00011800E0000420ull + (((offset) & 1) * 8)) +#define CVMX_AGL_GMX_RX_BP_OFFX(offset) \ + CVMX_ADD_IO_SEG(0x00011800E0000460ull + (((offset) & 1) * 8)) +#define CVMX_AGL_GMX_RX_BP_ONX(offset) \ + CVMX_ADD_IO_SEG(0x00011800E0000440ull + (((offset) & 1) * 8)) +#define CVMX_AGL_GMX_RX_PRT_INFO \ + CVMX_ADD_IO_SEG(0x00011800E00004E8ull) +#define CVMX_AGL_GMX_RX_TX_STATUS \ + CVMX_ADD_IO_SEG(0x00011800E00007E8ull) +#define CVMX_AGL_GMX_SMACX(offset) \ + CVMX_ADD_IO_SEG(0x00011800E0000230ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_STAT_BP \ + CVMX_ADD_IO_SEG(0x00011800E0000520ull) +#define CVMX_AGL_GMX_TXX_APPEND(offset) \ + CVMX_ADD_IO_SEG(0x00011800E0000218ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_TXX_CTL(offset) \ + CVMX_ADD_IO_SEG(0x00011800E0000270ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_TXX_MIN_PKT(offset) \ + CVMX_ADD_IO_SEG(0x00011800E0000240ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_TXX_PAUSE_PKT_INTERVAL(offset) \ + CVMX_ADD_IO_SEG(0x00011800E0000248ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_TXX_PAUSE_PKT_TIME(offset) \ + CVMX_ADD_IO_SEG(0x00011800E0000238ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_TXX_PAUSE_TOGO(offset) \ + CVMX_ADD_IO_SEG(0x00011800E0000258ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_TXX_PAUSE_ZERO(offset) \ + CVMX_ADD_IO_SEG(0x00011800E0000260ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_TXX_SOFT_PAUSE(offset) \ + CVMX_ADD_IO_SEG(0x00011800E0000250ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_TXX_STAT0(offset) \ + CVMX_ADD_IO_SEG(0x00011800E0000280ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_TXX_STAT1(offset) \ + CVMX_ADD_IO_SEG(0x00011800E0000288ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_TXX_STAT2(offset) \ + CVMX_ADD_IO_SEG(0x00011800E0000290ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_TXX_STAT3(offset) \ + CVMX_ADD_IO_SEG(0x00011800E0000298ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_TXX_STAT4(offset) \ + CVMX_ADD_IO_SEG(0x00011800E00002A0ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_TXX_STAT5(offset) \ + CVMX_ADD_IO_SEG(0x00011800E00002A8ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_TXX_STAT6(offset) \ + CVMX_ADD_IO_SEG(0x00011800E00002B0ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_TXX_STAT7(offset) \ + CVMX_ADD_IO_SEG(0x00011800E00002B8ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_TXX_STAT8(offset) \ + CVMX_ADD_IO_SEG(0x00011800E00002C0ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_TXX_STAT9(offset) \ + CVMX_ADD_IO_SEG(0x00011800E00002C8ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_TXX_STATS_CTL(offset) \ + CVMX_ADD_IO_SEG(0x00011800E0000268ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_TXX_THRESH(offset) \ + CVMX_ADD_IO_SEG(0x00011800E0000210ull + (((offset) & 1) * 2048)) +#define CVMX_AGL_GMX_TX_BP \ + CVMX_ADD_IO_SEG(0x00011800E00004D0ull) +#define CVMX_AGL_GMX_TX_COL_ATTEMPT \ + CVMX_ADD_IO_SEG(0x00011800E0000498ull) +#define CVMX_AGL_GMX_TX_IFG \ + CVMX_ADD_IO_SEG(0x00011800E0000488ull) +#define CVMX_AGL_GMX_TX_INT_EN \ + CVMX_ADD_IO_SEG(0x00011800E0000508ull) +#define CVMX_AGL_GMX_TX_INT_REG \ + CVMX_ADD_IO_SEG(0x00011800E0000500ull) +#define CVMX_AGL_GMX_TX_JAM \ + CVMX_ADD_IO_SEG(0x00011800E0000490ull) +#define CVMX_AGL_GMX_TX_LFSR \ + CVMX_ADD_IO_SEG(0x00011800E00004F8ull) +#define CVMX_AGL_GMX_TX_OVR_BP \ + CVMX_ADD_IO_SEG(0x00011800E00004C8ull) +#define CVMX_AGL_GMX_TX_PAUSE_PKT_DMAC \ + CVMX_ADD_IO_SEG(0x00011800E00004A0ull) +#define CVMX_AGL_GMX_TX_PAUSE_PKT_TYPE \ + CVMX_ADD_IO_SEG(0x00011800E00004A8ull) + +union cvmx_agl_gmx_bad_reg { + uint64_t u64; + struct cvmx_agl_gmx_bad_reg_s { + uint64_t reserved_38_63:26; + uint64_t txpsh1:1; + uint64_t txpop1:1; + uint64_t ovrflw1:1; + uint64_t txpsh:1; + uint64_t txpop:1; + uint64_t ovrflw:1; + uint64_t reserved_27_31:5; + uint64_t statovr:1; + uint64_t reserved_23_25:3; + uint64_t loststat:1; + uint64_t reserved_4_21:18; + uint64_t out_ovr:2; + uint64_t reserved_0_1:2; + } s; + struct cvmx_agl_gmx_bad_reg_s cn52xx; + struct cvmx_agl_gmx_bad_reg_s cn52xxp1; + struct cvmx_agl_gmx_bad_reg_cn56xx { + uint64_t reserved_35_63:29; + uint64_t txpsh:1; + uint64_t txpop:1; + uint64_t ovrflw:1; + uint64_t reserved_27_31:5; + uint64_t statovr:1; + uint64_t reserved_23_25:3; + uint64_t loststat:1; + uint64_t reserved_3_21:19; + uint64_t out_ovr:1; + uint64_t reserved_0_1:2; + } cn56xx; + struct cvmx_agl_gmx_bad_reg_cn56xx cn56xxp1; +}; + +union cvmx_agl_gmx_bist { + uint64_t u64; + struct cvmx_agl_gmx_bist_s { + uint64_t reserved_10_63:54; + uint64_t status:10; + } s; + struct cvmx_agl_gmx_bist_s cn52xx; + struct cvmx_agl_gmx_bist_s cn52xxp1; + struct cvmx_agl_gmx_bist_s cn56xx; + struct cvmx_agl_gmx_bist_s cn56xxp1; +}; + +union cvmx_agl_gmx_drv_ctl { + uint64_t u64; + struct cvmx_agl_gmx_drv_ctl_s { + uint64_t reserved_49_63:15; + uint64_t byp_en1:1; + uint64_t reserved_45_47:3; + uint64_t pctl1:5; + uint64_t reserved_37_39:3; + uint64_t nctl1:5; + uint64_t reserved_17_31:15; + uint64_t byp_en:1; + uint64_t reserved_13_15:3; + uint64_t pctl:5; + uint64_t reserved_5_7:3; + uint64_t nctl:5; + } s; + struct cvmx_agl_gmx_drv_ctl_s cn52xx; + struct cvmx_agl_gmx_drv_ctl_s cn52xxp1; + struct cvmx_agl_gmx_drv_ctl_cn56xx { + uint64_t reserved_17_63:47; + uint64_t byp_en:1; + uint64_t reserved_13_15:3; + uint64_t pctl:5; + uint64_t reserved_5_7:3; + uint64_t nctl:5; + } cn56xx; + struct cvmx_agl_gmx_drv_ctl_cn56xx cn56xxp1; +}; + +union cvmx_agl_gmx_inf_mode { + uint64_t u64; + struct cvmx_agl_gmx_inf_mode_s { + uint64_t reserved_2_63:62; + uint64_t en:1; + uint64_t reserved_0_0:1; + } s; + struct cvmx_agl_gmx_inf_mode_s cn52xx; + struct cvmx_agl_gmx_inf_mode_s cn52xxp1; + struct cvmx_agl_gmx_inf_mode_s cn56xx; + struct cvmx_agl_gmx_inf_mode_s cn56xxp1; +}; + +union cvmx_agl_gmx_prtx_cfg { + uint64_t u64; + struct cvmx_agl_gmx_prtx_cfg_s { + uint64_t reserved_6_63:58; + uint64_t tx_en:1; + uint64_t rx_en:1; + uint64_t slottime:1; + uint64_t duplex:1; + uint64_t speed:1; + uint64_t en:1; + } s; + struct cvmx_agl_gmx_prtx_cfg_s cn52xx; + struct cvmx_agl_gmx_prtx_cfg_s cn52xxp1; + struct cvmx_agl_gmx_prtx_cfg_s cn56xx; + struct cvmx_agl_gmx_prtx_cfg_s cn56xxp1; +}; + +union cvmx_agl_gmx_rxx_adr_cam0 { + uint64_t u64; + struct cvmx_agl_gmx_rxx_adr_cam0_s { + uint64_t adr:64; + } s; + struct cvmx_agl_gmx_rxx_adr_cam0_s cn52xx; + struct cvmx_agl_gmx_rxx_adr_cam0_s cn52xxp1; + struct cvmx_agl_gmx_rxx_adr_cam0_s cn56xx; + struct cvmx_agl_gmx_rxx_adr_cam0_s cn56xxp1; +}; + +union cvmx_agl_gmx_rxx_adr_cam1 { + uint64_t u64; + struct cvmx_agl_gmx_rxx_adr_cam1_s { + uint64_t adr:64; + } s; + struct cvmx_agl_gmx_rxx_adr_cam1_s cn52xx; + struct cvmx_agl_gmx_rxx_adr_cam1_s cn52xxp1; + struct cvmx_agl_gmx_rxx_adr_cam1_s cn56xx; + struct cvmx_agl_gmx_rxx_adr_cam1_s cn56xxp1; +}; + +union cvmx_agl_gmx_rxx_adr_cam2 { + uint64_t u64; + struct cvmx_agl_gmx_rxx_adr_cam2_s { + uint64_t adr:64; + } s; + struct cvmx_agl_gmx_rxx_adr_cam2_s cn52xx; + struct cvmx_agl_gmx_rxx_adr_cam2_s cn52xxp1; + struct cvmx_agl_gmx_rxx_adr_cam2_s cn56xx; + struct cvmx_agl_gmx_rxx_adr_cam2_s cn56xxp1; +}; + +union cvmx_agl_gmx_rxx_adr_cam3 { + uint64_t u64; + struct cvmx_agl_gmx_rxx_adr_cam3_s { + uint64_t adr:64; + } s; + struct cvmx_agl_gmx_rxx_adr_cam3_s cn52xx; + struct cvmx_agl_gmx_rxx_adr_cam3_s cn52xxp1; + struct cvmx_agl_gmx_rxx_adr_cam3_s cn56xx; + struct cvmx_agl_gmx_rxx_adr_cam3_s cn56xxp1; +}; + +union cvmx_agl_gmx_rxx_adr_cam4 { + uint64_t u64; + struct cvmx_agl_gmx_rxx_adr_cam4_s { + uint64_t adr:64; + } s; + struct cvmx_agl_gmx_rxx_adr_cam4_s cn52xx; + struct cvmx_agl_gmx_rxx_adr_cam4_s cn52xxp1; + struct cvmx_agl_gmx_rxx_adr_cam4_s cn56xx; + struct cvmx_agl_gmx_rxx_adr_cam4_s cn56xxp1; +}; + +union cvmx_agl_gmx_rxx_adr_cam5 { + uint64_t u64; + struct cvmx_agl_gmx_rxx_adr_cam5_s { + uint64_t adr:64; + } s; + struct cvmx_agl_gmx_rxx_adr_cam5_s cn52xx; + struct cvmx_agl_gmx_rxx_adr_cam5_s cn52xxp1; + struct cvmx_agl_gmx_rxx_adr_cam5_s cn56xx; + struct cvmx_agl_gmx_rxx_adr_cam5_s cn56xxp1; +}; + +union cvmx_agl_gmx_rxx_adr_cam_en { + uint64_t u64; + struct cvmx_agl_gmx_rxx_adr_cam_en_s { + uint64_t reserved_8_63:56; + uint64_t en:8; + } s; + struct cvmx_agl_gmx_rxx_adr_cam_en_s cn52xx; + struct cvmx_agl_gmx_rxx_adr_cam_en_s cn52xxp1; + struct cvmx_agl_gmx_rxx_adr_cam_en_s cn56xx; + struct cvmx_agl_gmx_rxx_adr_cam_en_s cn56xxp1; +}; + +union cvmx_agl_gmx_rxx_adr_ctl { + uint64_t u64; + struct cvmx_agl_gmx_rxx_adr_ctl_s { + uint64_t reserved_4_63:60; + uint64_t cam_mode:1; + uint64_t mcst:2; + uint64_t bcst:1; + } s; + struct cvmx_agl_gmx_rxx_adr_ctl_s cn52xx; + struct cvmx_agl_gmx_rxx_adr_ctl_s cn52xxp1; + struct cvmx_agl_gmx_rxx_adr_ctl_s cn56xx; + struct cvmx_agl_gmx_rxx_adr_ctl_s cn56xxp1; +}; + +union cvmx_agl_gmx_rxx_decision { + uint64_t u64; + struct cvmx_agl_gmx_rxx_decision_s { + uint64_t reserved_5_63:59; + uint64_t cnt:5; + } s; + struct cvmx_agl_gmx_rxx_decision_s cn52xx; + struct cvmx_agl_gmx_rxx_decision_s cn52xxp1; + struct cvmx_agl_gmx_rxx_decision_s cn56xx; + struct cvmx_agl_gmx_rxx_decision_s cn56xxp1; +}; + +union cvmx_agl_gmx_rxx_frm_chk { + uint64_t u64; + struct cvmx_agl_gmx_rxx_frm_chk_s { + uint64_t reserved_9_63:55; + uint64_t skperr:1; + uint64_t rcverr:1; + uint64_t lenerr:1; + uint64_t alnerr:1; + uint64_t fcserr:1; + uint64_t jabber:1; + uint64_t maxerr:1; + uint64_t reserved_1_1:1; + uint64_t minerr:1; + } s; + struct cvmx_agl_gmx_rxx_frm_chk_s cn52xx; + struct cvmx_agl_gmx_rxx_frm_chk_s cn52xxp1; + struct cvmx_agl_gmx_rxx_frm_chk_s cn56xx; + struct cvmx_agl_gmx_rxx_frm_chk_s cn56xxp1; +}; + +union cvmx_agl_gmx_rxx_frm_ctl { + uint64_t u64; + struct cvmx_agl_gmx_rxx_frm_ctl_s { + uint64_t reserved_10_63:54; + uint64_t pre_align:1; + uint64_t pad_len:1; + uint64_t vlan_len:1; + uint64_t pre_free:1; + uint64_t ctl_smac:1; + uint64_t ctl_mcst:1; + uint64_t ctl_bck:1; + uint64_t ctl_drp:1; + uint64_t pre_strp:1; + uint64_t pre_chk:1; + } s; + struct cvmx_agl_gmx_rxx_frm_ctl_s cn52xx; + struct cvmx_agl_gmx_rxx_frm_ctl_s cn52xxp1; + struct cvmx_agl_gmx_rxx_frm_ctl_s cn56xx; + struct cvmx_agl_gmx_rxx_frm_ctl_s cn56xxp1; +}; + +union cvmx_agl_gmx_rxx_frm_max { + uint64_t u64; + struct cvmx_agl_gmx_rxx_frm_max_s { + uint64_t reserved_16_63:48; + uint64_t len:16; + } s; + struct cvmx_agl_gmx_rxx_frm_max_s cn52xx; + struct cvmx_agl_gmx_rxx_frm_max_s cn52xxp1; + struct cvmx_agl_gmx_rxx_frm_max_s cn56xx; + struct cvmx_agl_gmx_rxx_frm_max_s cn56xxp1; +}; + +union cvmx_agl_gmx_rxx_frm_min { + uint64_t u64; + struct cvmx_agl_gmx_rxx_frm_min_s { + uint64_t reserved_16_63:48; + uint64_t len:16; + } s; + struct cvmx_agl_gmx_rxx_frm_min_s cn52xx; + struct cvmx_agl_gmx_rxx_frm_min_s cn52xxp1; + struct cvmx_agl_gmx_rxx_frm_min_s cn56xx; + struct cvmx_agl_gmx_rxx_frm_min_s cn56xxp1; +}; + +union cvmx_agl_gmx_rxx_ifg { + uint64_t u64; + struct cvmx_agl_gmx_rxx_ifg_s { + uint64_t reserved_4_63:60; + uint64_t ifg:4; + } s; + struct cvmx_agl_gmx_rxx_ifg_s cn52xx; + struct cvmx_agl_gmx_rxx_ifg_s cn52xxp1; + struct cvmx_agl_gmx_rxx_ifg_s cn56xx; + struct cvmx_agl_gmx_rxx_ifg_s cn56xxp1; +}; + +union cvmx_agl_gmx_rxx_int_en { + uint64_t u64; + struct cvmx_agl_gmx_rxx_int_en_s { + uint64_t reserved_20_63:44; + uint64_t pause_drp:1; + uint64_t reserved_16_18:3; + uint64_t ifgerr:1; + uint64_t coldet:1; + uint64_t falerr:1; + uint64_t rsverr:1; + uint64_t pcterr:1; + uint64_t ovrerr:1; + uint64_t reserved_9_9:1; + uint64_t skperr:1; + uint64_t rcverr:1; + uint64_t lenerr:1; + uint64_t alnerr:1; + uint64_t fcserr:1; + uint64_t jabber:1; + uint64_t maxerr:1; + uint64_t reserved_1_1:1; + uint64_t minerr:1; + } s; + struct cvmx_agl_gmx_rxx_int_en_s cn52xx; + struct cvmx_agl_gmx_rxx_int_en_s cn52xxp1; + struct cvmx_agl_gmx_rxx_int_en_s cn56xx; + struct cvmx_agl_gmx_rxx_int_en_s cn56xxp1; +}; + +union cvmx_agl_gmx_rxx_int_reg { + uint64_t u64; + struct cvmx_agl_gmx_rxx_int_reg_s { + uint64_t reserved_20_63:44; + uint64_t pause_drp:1; + uint64_t reserved_16_18:3; + uint64_t ifgerr:1; + uint64_t coldet:1; + uint64_t falerr:1; + uint64_t rsverr:1; + uint64_t pcterr:1; + uint64_t ovrerr:1; + uint64_t reserved_9_9:1; + uint64_t skperr:1; + uint64_t rcverr:1; + uint64_t lenerr:1; + uint64_t alnerr:1; + uint64_t fcserr:1; + uint64_t jabber:1; + uint64_t maxerr:1; + uint64_t reserved_1_1:1; + uint64_t minerr:1; + } s; + struct cvmx_agl_gmx_rxx_int_reg_s cn52xx; + struct cvmx_agl_gmx_rxx_int_reg_s cn52xxp1; + struct cvmx_agl_gmx_rxx_int_reg_s cn56xx; + struct cvmx_agl_gmx_rxx_int_reg_s cn56xxp1; +}; + +union cvmx_agl_gmx_rxx_jabber { + uint64_t u64; + struct cvmx_agl_gmx_rxx_jabber_s { + uint64_t reserved_16_63:48; + uint64_t cnt:16; + } s; + struct cvmx_agl_gmx_rxx_jabber_s cn52xx; + struct cvmx_agl_gmx_rxx_jabber_s cn52xxp1; + struct cvmx_agl_gmx_rxx_jabber_s cn56xx; + struct cvmx_agl_gmx_rxx_jabber_s cn56xxp1; +}; + +union cvmx_agl_gmx_rxx_pause_drop_time { + uint64_t u64; + struct cvmx_agl_gmx_rxx_pause_drop_time_s { + uint64_t reserved_16_63:48; + uint64_t status:16; + } s; + struct cvmx_agl_gmx_rxx_pause_drop_time_s cn52xx; + struct cvmx_agl_gmx_rxx_pause_drop_time_s cn52xxp1; + struct cvmx_agl_gmx_rxx_pause_drop_time_s cn56xx; + struct cvmx_agl_gmx_rxx_pause_drop_time_s cn56xxp1; +}; + +union cvmx_agl_gmx_rxx_stats_ctl { + uint64_t u64; + struct cvmx_agl_gmx_rxx_stats_ctl_s { + uint64_t reserved_1_63:63; + uint64_t rd_clr:1; + } s; + struct cvmx_agl_gmx_rxx_stats_ctl_s cn52xx; + struct cvmx_agl_gmx_rxx_stats_ctl_s cn52xxp1; + struct cvmx_agl_gmx_rxx_stats_ctl_s cn56xx; + struct cvmx_agl_gmx_rxx_stats_ctl_s cn56xxp1; +}; + +union cvmx_agl_gmx_rxx_stats_octs { + uint64_t u64; + struct cvmx_agl_gmx_rxx_stats_octs_s { + uint64_t reserved_48_63:16; + uint64_t cnt:48; + } s; + struct cvmx_agl_gmx_rxx_stats_octs_s cn52xx; + struct cvmx_agl_gmx_rxx_stats_octs_s cn52xxp1; + struct cvmx_agl_gmx_rxx_stats_octs_s cn56xx; + struct cvmx_agl_gmx_rxx_stats_octs_s cn56xxp1; +}; + +union cvmx_agl_gmx_rxx_stats_octs_ctl { + uint64_t u64; + struct cvmx_agl_gmx_rxx_stats_octs_ctl_s { + uint64_t reserved_48_63:16; + uint64_t cnt:48; + } s; + struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn52xx; + struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn52xxp1; + struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn56xx; + struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn56xxp1; +}; + +union cvmx_agl_gmx_rxx_stats_octs_dmac { + uint64_t u64; + struct cvmx_agl_gmx_rxx_stats_octs_dmac_s { + uint64_t reserved_48_63:16; + uint64_t cnt:48; + } s; + struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn52xx; + struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn52xxp1; + struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn56xx; + struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn56xxp1; +}; + +union cvmx_agl_gmx_rxx_stats_octs_drp { + uint64_t u64; + struct cvmx_agl_gmx_rxx_stats_octs_drp_s { + uint64_t reserved_48_63:16; + uint64_t cnt:48; + } s; + struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn52xx; + struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn52xxp1; + struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn56xx; + struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn56xxp1; +}; + +union cvmx_agl_gmx_rxx_stats_pkts { + uint64_t u64; + struct cvmx_agl_gmx_rxx_stats_pkts_s { + uint64_t reserved_32_63:32; + uint64_t cnt:32; + } s; + struct cvmx_agl_gmx_rxx_stats_pkts_s cn52xx; + struct cvmx_agl_gmx_rxx_stats_pkts_s cn52xxp1; + struct cvmx_agl_gmx_rxx_stats_pkts_s cn56xx; + struct cvmx_agl_gmx_rxx_stats_pkts_s cn56xxp1; +}; + +union cvmx_agl_gmx_rxx_stats_pkts_bad { + uint64_t u64; + struct cvmx_agl_gmx_rxx_stats_pkts_bad_s { + uint64_t reserved_32_63:32; + uint64_t cnt:32; + } s; + struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn52xx; + struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn52xxp1; + struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn56xx; + struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn56xxp1; +}; + +union cvmx_agl_gmx_rxx_stats_pkts_ctl { + uint64_t u64; + struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s { + uint64_t reserved_32_63:32; + uint64_t cnt:32; + } s; + struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn52xx; + struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn52xxp1; + struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn56xx; + struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn56xxp1; +}; + +union cvmx_agl_gmx_rxx_stats_pkts_dmac { + uint64_t u64; + struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s { + uint64_t reserved_32_63:32; + uint64_t cnt:32; + } s; + struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn52xx; + struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn52xxp1; + struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn56xx; + struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn56xxp1; +}; + +union cvmx_agl_gmx_rxx_stats_pkts_drp { + uint64_t u64; + struct cvmx_agl_gmx_rxx_stats_pkts_drp_s { + uint64_t reserved_32_63:32; + uint64_t cnt:32; + } s; + struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn52xx; + struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn52xxp1; + struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn56xx; + struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn56xxp1; +}; + +union cvmx_agl_gmx_rxx_udd_skp { + uint64_t u64; + struct cvmx_agl_gmx_rxx_udd_skp_s { + uint64_t reserved_9_63:55; + uint64_t fcssel:1; + uint64_t reserved_7_7:1; + uint64_t len:7; + } s; + struct cvmx_agl_gmx_rxx_udd_skp_s cn52xx; + struct cvmx_agl_gmx_rxx_udd_skp_s cn52xxp1; + struct cvmx_agl_gmx_rxx_udd_skp_s cn56xx; + struct cvmx_agl_gmx_rxx_udd_skp_s cn56xxp1; +}; + +union cvmx_agl_gmx_rx_bp_dropx { + uint64_t u64; + struct cvmx_agl_gmx_rx_bp_dropx_s { + uint64_t reserved_6_63:58; + uint64_t mark:6; + } s; + struct cvmx_agl_gmx_rx_bp_dropx_s cn52xx; + struct cvmx_agl_gmx_rx_bp_dropx_s cn52xxp1; + struct cvmx_agl_gmx_rx_bp_dropx_s cn56xx; + struct cvmx_agl_gmx_rx_bp_dropx_s cn56xxp1; +}; + +union cvmx_agl_gmx_rx_bp_offx { + uint64_t u64; + struct cvmx_agl_gmx_rx_bp_offx_s { + uint64_t reserved_6_63:58; + uint64_t mark:6; + } s; + struct cvmx_agl_gmx_rx_bp_offx_s cn52xx; + struct cvmx_agl_gmx_rx_bp_offx_s cn52xxp1; + struct cvmx_agl_gmx_rx_bp_offx_s cn56xx; + struct cvmx_agl_gmx_rx_bp_offx_s cn56xxp1; +}; + +union cvmx_agl_gmx_rx_bp_onx { + uint64_t u64; + struct cvmx_agl_gmx_rx_bp_onx_s { + uint64_t reserved_9_63:55; + uint64_t mark:9; + } s; + struct cvmx_agl_gmx_rx_bp_onx_s cn52xx; + struct cvmx_agl_gmx_rx_bp_onx_s cn52xxp1; + struct cvmx_agl_gmx_rx_bp_onx_s cn56xx; + struct cvmx_agl_gmx_rx_bp_onx_s cn56xxp1; +}; + +union cvmx_agl_gmx_rx_prt_info { + uint64_t u64; + struct cvmx_agl_gmx_rx_prt_info_s { + uint64_t reserved_18_63:46; + uint64_t drop:2; + uint64_t reserved_2_15:14; + uint64_t commit:2; + } s; + struct cvmx_agl_gmx_rx_prt_info_s cn52xx; + struct cvmx_agl_gmx_rx_prt_info_s cn52xxp1; + struct cvmx_agl_gmx_rx_prt_info_cn56xx { + uint64_t reserved_17_63:47; + uint64_t drop:1; + uint64_t reserved_1_15:15; + uint64_t commit:1; + } cn56xx; + struct cvmx_agl_gmx_rx_prt_info_cn56xx cn56xxp1; +}; + +union cvmx_agl_gmx_rx_tx_status { + uint64_t u64; + struct cvmx_agl_gmx_rx_tx_status_s { + uint64_t reserved_6_63:58; + uint64_t tx:2; + uint64_t reserved_2_3:2; + uint64_t rx:2; + } s; + struct cvmx_agl_gmx_rx_tx_status_s cn52xx; + struct cvmx_agl_gmx_rx_tx_status_s cn52xxp1; + struct cvmx_agl_gmx_rx_tx_status_cn56xx { + uint64_t reserved_5_63:59; + uint64_t tx:1; + uint64_t reserved_1_3:3; + uint64_t rx:1; + } cn56xx; + struct cvmx_agl_gmx_rx_tx_status_cn56xx cn56xxp1; +}; + +union cvmx_agl_gmx_smacx { + uint64_t u64; + struct cvmx_agl_gmx_smacx_s { + uint64_t reserved_48_63:16; + uint64_t smac:48; + } s; + struct cvmx_agl_gmx_smacx_s cn52xx; + struct cvmx_agl_gmx_smacx_s cn52xxp1; + struct cvmx_agl_gmx_smacx_s cn56xx; + struct cvmx_agl_gmx_smacx_s cn56xxp1; +}; + +union cvmx_agl_gmx_stat_bp { + uint64_t u64; + struct cvmx_agl_gmx_stat_bp_s { + uint64_t reserved_17_63:47; + uint64_t bp:1; + uint64_t cnt:16; + } s; + struct cvmx_agl_gmx_stat_bp_s cn52xx; + struct cvmx_agl_gmx_stat_bp_s cn52xxp1; + struct cvmx_agl_gmx_stat_bp_s cn56xx; + struct cvmx_agl_gmx_stat_bp_s cn56xxp1; +}; + +union cvmx_agl_gmx_txx_append { + uint64_t u64; + struct cvmx_agl_gmx_txx_append_s { + uint64_t reserved_4_63:60; + uint64_t force_fcs:1; + uint64_t fcs:1; + uint64_t pad:1; + uint64_t preamble:1; + } s; + struct cvmx_agl_gmx_txx_append_s cn52xx; + struct cvmx_agl_gmx_txx_append_s cn52xxp1; + struct cvmx_agl_gmx_txx_append_s cn56xx; + struct cvmx_agl_gmx_txx_append_s cn56xxp1; +}; + +union cvmx_agl_gmx_txx_ctl { + uint64_t u64; + struct cvmx_agl_gmx_txx_ctl_s { + uint64_t reserved_2_63:62; + uint64_t xsdef_en:1; + uint64_t xscol_en:1; + } s; + struct cvmx_agl_gmx_txx_ctl_s cn52xx; + struct cvmx_agl_gmx_txx_ctl_s cn52xxp1; + struct cvmx_agl_gmx_txx_ctl_s cn56xx; + struct cvmx_agl_gmx_txx_ctl_s cn56xxp1; +}; + +union cvmx_agl_gmx_txx_min_pkt { + uint64_t u64; + struct cvmx_agl_gmx_txx_min_pkt_s { + uint64_t reserved_8_63:56; + uint64_t min_size:8; + } s; + struct cvmx_agl_gmx_txx_min_pkt_s cn52xx; + struct cvmx_agl_gmx_txx_min_pkt_s cn52xxp1; + struct cvmx_agl_gmx_txx_min_pkt_s cn56xx; + struct cvmx_agl_gmx_txx_min_pkt_s cn56xxp1; +}; + +union cvmx_agl_gmx_txx_pause_pkt_interval { + uint64_t u64; + struct cvmx_agl_gmx_txx_pause_pkt_interval_s { + uint64_t reserved_16_63:48; + uint64_t interval:16; + } s; + struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn52xx; + struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn52xxp1; + struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn56xx; + struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn56xxp1; +}; + +union cvmx_agl_gmx_txx_pause_pkt_time { + uint64_t u64; + struct cvmx_agl_gmx_txx_pause_pkt_time_s { + uint64_t reserved_16_63:48; + uint64_t time:16; + } s; + struct cvmx_agl_gmx_txx_pause_pkt_time_s cn52xx; + struct cvmx_agl_gmx_txx_pause_pkt_time_s cn52xxp1; + struct cvmx_agl_gmx_txx_pause_pkt_time_s cn56xx; + struct cvmx_agl_gmx_txx_pause_pkt_time_s cn56xxp1; +}; + +union cvmx_agl_gmx_txx_pause_togo { + uint64_t u64; + struct cvmx_agl_gmx_txx_pause_togo_s { + uint64_t reserved_16_63:48; + uint64_t time:16; + } s; + struct cvmx_agl_gmx_txx_pause_togo_s cn52xx; + struct cvmx_agl_gmx_txx_pause_togo_s cn52xxp1; + struct cvmx_agl_gmx_txx_pause_togo_s cn56xx; + struct cvmx_agl_gmx_txx_pause_togo_s cn56xxp1; +}; + +union cvmx_agl_gmx_txx_pause_zero { + uint64_t u64; + struct cvmx_agl_gmx_txx_pause_zero_s { + uint64_t reserved_1_63:63; + uint64_t send:1; + } s; + struct cvmx_agl_gmx_txx_pause_zero_s cn52xx; + struct cvmx_agl_gmx_txx_pause_zero_s cn52xxp1; + struct cvmx_agl_gmx_txx_pause_zero_s cn56xx; + struct cvmx_agl_gmx_txx_pause_zero_s cn56xxp1; +}; + +union cvmx_agl_gmx_txx_soft_pause { + uint64_t u64; + struct cvmx_agl_gmx_txx_soft_pause_s { + uint64_t reserved_16_63:48; + uint64_t time:16; + } s; + struct cvmx_agl_gmx_txx_soft_pause_s cn52xx; + struct cvmx_agl_gmx_txx_soft_pause_s cn52xxp1; + struct cvmx_agl_gmx_txx_soft_pause_s cn56xx; + struct cvmx_agl_gmx_txx_soft_pause_s cn56xxp1; +}; + +union cvmx_agl_gmx_txx_stat0 { + uint64_t u64; + struct cvmx_agl_gmx_txx_stat0_s { + uint64_t xsdef:32; + uint64_t xscol:32; + } s; + struct cvmx_agl_gmx_txx_stat0_s cn52xx; + struct cvmx_agl_gmx_txx_stat0_s cn52xxp1; + struct cvmx_agl_gmx_txx_stat0_s cn56xx; + struct cvmx_agl_gmx_txx_stat0_s cn56xxp1; +}; + +union cvmx_agl_gmx_txx_stat1 { + uint64_t u64; + struct cvmx_agl_gmx_txx_stat1_s { + uint64_t scol:32; + uint64_t mcol:32; + } s; + struct cvmx_agl_gmx_txx_stat1_s cn52xx; + struct cvmx_agl_gmx_txx_stat1_s cn52xxp1; + struct cvmx_agl_gmx_txx_stat1_s cn56xx; + struct cvmx_agl_gmx_txx_stat1_s cn56xxp1; +}; + +union cvmx_agl_gmx_txx_stat2 { + uint64_t u64; + struct cvmx_agl_gmx_txx_stat2_s { + uint64_t reserved_48_63:16; + uint64_t octs:48; + } s; + struct cvmx_agl_gmx_txx_stat2_s cn52xx; + struct cvmx_agl_gmx_txx_stat2_s cn52xxp1; + struct cvmx_agl_gmx_txx_stat2_s cn56xx; + struct cvmx_agl_gmx_txx_stat2_s cn56xxp1; +}; + +union cvmx_agl_gmx_txx_stat3 { + uint64_t u64; + struct cvmx_agl_gmx_txx_stat3_s { + uint64_t reserved_32_63:32; + uint64_t pkts:32; + } s; + struct cvmx_agl_gmx_txx_stat3_s cn52xx; + struct cvmx_agl_gmx_txx_stat3_s cn52xxp1; + struct cvmx_agl_gmx_txx_stat3_s cn56xx; + struct cvmx_agl_gmx_txx_stat3_s cn56xxp1; +}; + +union cvmx_agl_gmx_txx_stat4 { + uint64_t u64; + struct cvmx_agl_gmx_txx_stat4_s { + uint64_t hist1:32; + uint64_t hist0:32; + } s; + struct cvmx_agl_gmx_txx_stat4_s cn52xx; + struct cvmx_agl_gmx_txx_stat4_s cn52xxp1; + struct cvmx_agl_gmx_txx_stat4_s cn56xx; + struct cvmx_agl_gmx_txx_stat4_s cn56xxp1; +}; + +union cvmx_agl_gmx_txx_stat5 { + uint64_t u64; + struct cvmx_agl_gmx_txx_stat5_s { + uint64_t hist3:32; + uint64_t hist2:32; + } s; + struct cvmx_agl_gmx_txx_stat5_s cn52xx; + struct cvmx_agl_gmx_txx_stat5_s cn52xxp1; + struct cvmx_agl_gmx_txx_stat5_s cn56xx; + struct cvmx_agl_gmx_txx_stat5_s cn56xxp1; +}; + +union cvmx_agl_gmx_txx_stat6 { + uint64_t u64; + struct cvmx_agl_gmx_txx_stat6_s { + uint64_t hist5:32; + uint64_t hist4:32; + } s; + struct cvmx_agl_gmx_txx_stat6_s cn52xx; + struct cvmx_agl_gmx_txx_stat6_s cn52xxp1; + struct cvmx_agl_gmx_txx_stat6_s cn56xx; + struct cvmx_agl_gmx_txx_stat6_s cn56xxp1; +}; + +union cvmx_agl_gmx_txx_stat7 { + uint64_t u64; + struct cvmx_agl_gmx_txx_stat7_s { + uint64_t hist7:32; + uint64_t hist6:32; + } s; + struct cvmx_agl_gmx_txx_stat7_s cn52xx; + struct cvmx_agl_gmx_txx_stat7_s cn52xxp1; + struct cvmx_agl_gmx_txx_stat7_s cn56xx; + struct cvmx_agl_gmx_txx_stat7_s cn56xxp1; +}; + +union cvmx_agl_gmx_txx_stat8 { + uint64_t u64; + struct cvmx_agl_gmx_txx_stat8_s { + uint64_t mcst:32; + uint64_t bcst:32; + } s; + struct cvmx_agl_gmx_txx_stat8_s cn52xx; + struct cvmx_agl_gmx_txx_stat8_s cn52xxp1; + struct cvmx_agl_gmx_txx_stat8_s cn56xx; + struct cvmx_agl_gmx_txx_stat8_s cn56xxp1; +}; + +union cvmx_agl_gmx_txx_stat9 { + uint64_t u64; + struct cvmx_agl_gmx_txx_stat9_s { + uint64_t undflw:32; + uint64_t ctl:32; + } s; + struct cvmx_agl_gmx_txx_stat9_s cn52xx; + struct cvmx_agl_gmx_txx_stat9_s cn52xxp1; + struct cvmx_agl_gmx_txx_stat9_s cn56xx; + struct cvmx_agl_gmx_txx_stat9_s cn56xxp1; +}; + +union cvmx_agl_gmx_txx_stats_ctl { + uint64_t u64; + struct cvmx_agl_gmx_txx_stats_ctl_s { + uint64_t reserved_1_63:63; + uint64_t rd_clr:1; + } s; + struct cvmx_agl_gmx_txx_stats_ctl_s cn52xx; + struct cvmx_agl_gmx_txx_stats_ctl_s cn52xxp1; + struct cvmx_agl_gmx_txx_stats_ctl_s cn56xx; + struct cvmx_agl_gmx_txx_stats_ctl_s cn56xxp1; +}; + +union cvmx_agl_gmx_txx_thresh { + uint64_t u64; + struct cvmx_agl_gmx_txx_thresh_s { + uint64_t reserved_6_63:58; + uint64_t cnt:6; + } s; + struct cvmx_agl_gmx_txx_thresh_s cn52xx; + struct cvmx_agl_gmx_txx_thresh_s cn52xxp1; + struct cvmx_agl_gmx_txx_thresh_s cn56xx; + struct cvmx_agl_gmx_txx_thresh_s cn56xxp1; +}; + +union cvmx_agl_gmx_tx_bp { + uint64_t u64; + struct cvmx_agl_gmx_tx_bp_s { + uint64_t reserved_2_63:62; + uint64_t bp:2; + } s; + struct cvmx_agl_gmx_tx_bp_s cn52xx; + struct cvmx_agl_gmx_tx_bp_s cn52xxp1; + struct cvmx_agl_gmx_tx_bp_cn56xx { + uint64_t reserved_1_63:63; + uint64_t bp:1; + } cn56xx; + struct cvmx_agl_gmx_tx_bp_cn56xx cn56xxp1; +}; + +union cvmx_agl_gmx_tx_col_attempt { + uint64_t u64; + struct cvmx_agl_gmx_tx_col_attempt_s { + uint64_t reserved_5_63:59; + uint64_t limit:5; + } s; + struct cvmx_agl_gmx_tx_col_attempt_s cn52xx; + struct cvmx_agl_gmx_tx_col_attempt_s cn52xxp1; + struct cvmx_agl_gmx_tx_col_attempt_s cn56xx; + struct cvmx_agl_gmx_tx_col_attempt_s cn56xxp1; +}; + +union cvmx_agl_gmx_tx_ifg { + uint64_t u64; + struct cvmx_agl_gmx_tx_ifg_s { + uint64_t reserved_8_63:56; + uint64_t ifg2:4; + uint64_t ifg1:4; + } s; + struct cvmx_agl_gmx_tx_ifg_s cn52xx; + struct cvmx_agl_gmx_tx_ifg_s cn52xxp1; + struct cvmx_agl_gmx_tx_ifg_s cn56xx; + struct cvmx_agl_gmx_tx_ifg_s cn56xxp1; +}; + +union cvmx_agl_gmx_tx_int_en { + uint64_t u64; + struct cvmx_agl_gmx_tx_int_en_s { + uint64_t reserved_18_63:46; + uint64_t late_col:2; + uint64_t reserved_14_15:2; + uint64_t xsdef:2; + uint64_t reserved_10_11:2; + uint64_t xscol:2; + uint64_t reserved_4_7:4; + uint64_t undflw:2; + uint64_t reserved_1_1:1; + uint64_t pko_nxa:1; + } s; + struct cvmx_agl_gmx_tx_int_en_s cn52xx; + struct cvmx_agl_gmx_tx_int_en_s cn52xxp1; + struct cvmx_agl_gmx_tx_int_en_cn56xx { + uint64_t reserved_17_63:47; + uint64_t late_col:1; + uint64_t reserved_13_15:3; + uint64_t xsdef:1; + uint64_t reserved_9_11:3; + uint64_t xscol:1; + uint64_t reserved_3_7:5; + uint64_t undflw:1; + uint64_t reserved_1_1:1; + uint64_t pko_nxa:1; + } cn56xx; + struct cvmx_agl_gmx_tx_int_en_cn56xx cn56xxp1; +}; + +union cvmx_agl_gmx_tx_int_reg { + uint64_t u64; + struct cvmx_agl_gmx_tx_int_reg_s { + uint64_t reserved_18_63:46; + uint64_t late_col:2; + uint64_t reserved_14_15:2; + uint64_t xsdef:2; + uint64_t reserved_10_11:2; + uint64_t xscol:2; + uint64_t reserved_4_7:4; + uint64_t undflw:2; + uint64_t reserved_1_1:1; + uint64_t pko_nxa:1; + } s; + struct cvmx_agl_gmx_tx_int_reg_s cn52xx; + struct cvmx_agl_gmx_tx_int_reg_s cn52xxp1; + struct cvmx_agl_gmx_tx_int_reg_cn56xx { + uint64_t reserved_17_63:47; + uint64_t late_col:1; + uint64_t reserved_13_15:3; + uint64_t xsdef:1; + uint64_t reserved_9_11:3; + uint64_t xscol:1; + uint64_t reserved_3_7:5; + uint64_t undflw:1; + uint64_t reserved_1_1:1; + uint64_t pko_nxa:1; + } cn56xx; + struct cvmx_agl_gmx_tx_int_reg_cn56xx cn56xxp1; +}; + +union cvmx_agl_gmx_tx_jam { + uint64_t u64; + struct cvmx_agl_gmx_tx_jam_s { + uint64_t reserved_8_63:56; + uint64_t jam:8; + } s; + struct cvmx_agl_gmx_tx_jam_s cn52xx; + struct cvmx_agl_gmx_tx_jam_s cn52xxp1; + struct cvmx_agl_gmx_tx_jam_s cn56xx; + struct cvmx_agl_gmx_tx_jam_s cn56xxp1; +}; + +union cvmx_agl_gmx_tx_lfsr { + uint64_t u64; + struct cvmx_agl_gmx_tx_lfsr_s { + uint64_t reserved_16_63:48; + uint64_t lfsr:16; + } s; + struct cvmx_agl_gmx_tx_lfsr_s cn52xx; + struct cvmx_agl_gmx_tx_lfsr_s cn52xxp1; + struct cvmx_agl_gmx_tx_lfsr_s cn56xx; + struct cvmx_agl_gmx_tx_lfsr_s cn56xxp1; +}; + +union cvmx_agl_gmx_tx_ovr_bp { + uint64_t u64; + struct cvmx_agl_gmx_tx_ovr_bp_s { + uint64_t reserved_10_63:54; + uint64_t en:2; + uint64_t reserved_6_7:2; + uint64_t bp:2; + uint64_t reserved_2_3:2; + uint64_t ign_full:2; + } s; + struct cvmx_agl_gmx_tx_ovr_bp_s cn52xx; + struct cvmx_agl_gmx_tx_ovr_bp_s cn52xxp1; + struct cvmx_agl_gmx_tx_ovr_bp_cn56xx { + uint64_t reserved_9_63:55; + uint64_t en:1; + uint64_t reserved_5_7:3; + uint64_t bp:1; + uint64_t reserved_1_3:3; + uint64_t ign_full:1; + } cn56xx; + struct cvmx_agl_gmx_tx_ovr_bp_cn56xx cn56xxp1; +}; + +union cvmx_agl_gmx_tx_pause_pkt_dmac { + uint64_t u64; + struct cvmx_agl_gmx_tx_pause_pkt_dmac_s { + uint64_t reserved_48_63:16; + uint64_t dmac:48; + } s; + struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn52xx; + struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn52xxp1; + struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn56xx; + struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn56xxp1; +}; + +union cvmx_agl_gmx_tx_pause_pkt_type { + uint64_t u64; + struct cvmx_agl_gmx_tx_pause_pkt_type_s { + uint64_t reserved_16_63:48; + uint64_t type:16; + } s; + struct cvmx_agl_gmx_tx_pause_pkt_type_s cn52xx; + struct cvmx_agl_gmx_tx_pause_pkt_type_s cn52xxp1; + struct cvmx_agl_gmx_tx_pause_pkt_type_s cn56xx; + struct cvmx_agl_gmx_tx_pause_pkt_type_s cn56xxp1; +}; + +#endif diff --git a/arch/mips/include/asm/octeon/cvmx-mixx-defs.h b/arch/mips/include/asm/octeon/cvmx-mixx-defs.h new file mode 100644 index 0000000..dab6dca --- /dev/null +++ b/arch/mips/include/asm/octeon/cvmx-mixx-defs.h @@ -0,0 +1,248 @@ +/***********************license start*************** + * Author: Cavium Networks + * + * Contact: support@caviumnetworks.com + * This file is part of the OCTEON SDK + * + * Copyright (c) 2003-2008 Cavium Networks + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, Version 2, as + * published by the Free Software Foundation. + * + * This file is distributed in the hope that it will be useful, but + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or + * NONINFRINGEMENT. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * or visit http://www.gnu.org/licenses/. + * + * This file may also be available under a different license from Cavium. + * Contact Cavium Networks for more information + ***********************license end**************************************/ + +#ifndef __CVMX_MIXX_DEFS_H__ +#define __CVMX_MIXX_DEFS_H__ + +#define CVMX_MIXX_BIST(offset) \ + CVMX_ADD_IO_SEG(0x0001070000100078ull + (((offset) & 1) * 2048)) +#define CVMX_MIXX_CTL(offset) \ + CVMX_ADD_IO_SEG(0x0001070000100020ull + (((offset) & 1) * 2048)) +#define CVMX_MIXX_INTENA(offset) \ + CVMX_ADD_IO_SEG(0x0001070000100050ull + (((offset) & 1) * 2048)) +#define CVMX_MIXX_IRCNT(offset) \ + CVMX_ADD_IO_SEG(0x0001070000100030ull + (((offset) & 1) * 2048)) +#define CVMX_MIXX_IRHWM(offset) \ + CVMX_ADD_IO_SEG(0x0001070000100028ull + (((offset) & 1) * 2048)) +#define CVMX_MIXX_IRING1(offset) \ + CVMX_ADD_IO_SEG(0x0001070000100010ull + (((offset) & 1) * 2048)) +#define CVMX_MIXX_IRING2(offset) \ + CVMX_ADD_IO_SEG(0x0001070000100018ull + (((offset) & 1) * 2048)) +#define CVMX_MIXX_ISR(offset) \ + CVMX_ADD_IO_SEG(0x0001070000100048ull + (((offset) & 1) * 2048)) +#define CVMX_MIXX_ORCNT(offset) \ + CVMX_ADD_IO_SEG(0x0001070000100040ull + (((offset) & 1) * 2048)) +#define CVMX_MIXX_ORHWM(offset) \ + CVMX_ADD_IO_SEG(0x0001070000100038ull + (((offset) & 1) * 2048)) +#define CVMX_MIXX_ORING1(offset) \ + CVMX_ADD_IO_SEG(0x0001070000100000ull + (((offset) & 1) * 2048)) +#define CVMX_MIXX_ORING2(offset) \ + CVMX_ADD_IO_SEG(0x0001070000100008ull + (((offset) & 1) * 2048)) +#define CVMX_MIXX_REMCNT(offset) \ + CVMX_ADD_IO_SEG(0x0001070000100058ull + (((offset) & 1) * 2048)) + +union cvmx_mixx_bist { + uint64_t u64; + struct cvmx_mixx_bist_s { + uint64_t reserved_4_63:60; + uint64_t mrqdat:1; + uint64_t ipfdat:1; + uint64_t irfdat:1; + uint64_t orfdat:1; + } s; + struct cvmx_mixx_bist_s cn52xx; + struct cvmx_mixx_bist_s cn52xxp1; + struct cvmx_mixx_bist_s cn56xx; + struct cvmx_mixx_bist_s cn56xxp1; +}; + +union cvmx_mixx_ctl { + uint64_t u64; + struct cvmx_mixx_ctl_s { + uint64_t reserved_8_63:56; + uint64_t crc_strip:1; + uint64_t busy:1; + uint64_t en:1; + uint64_t reset:1; + uint64_t lendian:1; + uint64_t nbtarb:1; + uint64_t mrq_hwm:2; + } s; + struct cvmx_mixx_ctl_s cn52xx; + struct cvmx_mixx_ctl_s cn52xxp1; + struct cvmx_mixx_ctl_s cn56xx; + struct cvmx_mixx_ctl_s cn56xxp1; +}; + +union cvmx_mixx_intena { + uint64_t u64; + struct cvmx_mixx_intena_s { + uint64_t reserved_7_63:57; + uint64_t orunena:1; + uint64_t irunena:1; + uint64_t data_drpena:1; + uint64_t ithena:1; + uint64_t othena:1; + uint64_t ivfena:1; + uint64_t ovfena:1; + } s; + struct cvmx_mixx_intena_s cn52xx; + struct cvmx_mixx_intena_s cn52xxp1; + struct cvmx_mixx_intena_s cn56xx; + struct cvmx_mixx_intena_s cn56xxp1; +}; + +union cvmx_mixx_ircnt { + uint64_t u64; + struct cvmx_mixx_ircnt_s { + uint64_t reserved_20_63:44; + uint64_t ircnt:20; + } s; + struct cvmx_mixx_ircnt_s cn52xx; + struct cvmx_mixx_ircnt_s cn52xxp1; + struct cvmx_mixx_ircnt_s cn56xx; + struct cvmx_mixx_ircnt_s cn56xxp1; +}; + +union cvmx_mixx_irhwm { + uint64_t u64; + struct cvmx_mixx_irhwm_s { + uint64_t reserved_40_63:24; + uint64_t ibplwm:20; + uint64_t irhwm:20; + } s; + struct cvmx_mixx_irhwm_s cn52xx; + struct cvmx_mixx_irhwm_s cn52xxp1; + struct cvmx_mixx_irhwm_s cn56xx; + struct cvmx_mixx_irhwm_s cn56xxp1; +}; + +union cvmx_mixx_iring1 { + uint64_t u64; + struct cvmx_mixx_iring1_s { + uint64_t reserved_60_63:4; + uint64_t isize:20; + uint64_t reserved_36_39:4; + uint64_t ibase:33; + uint64_t reserved_0_2:3; + } s; + struct cvmx_mixx_iring1_s cn52xx; + struct cvmx_mixx_iring1_s cn52xxp1; + struct cvmx_mixx_iring1_s cn56xx; + struct cvmx_mixx_iring1_s cn56xxp1; +}; + +union cvmx_mixx_iring2 { + uint64_t u64; + struct cvmx_mixx_iring2_s { + uint64_t reserved_52_63:12; + uint64_t itlptr:20; + uint64_t reserved_20_31:12; + uint64_t idbell:20; + } s; + struct cvmx_mixx_iring2_s cn52xx; + struct cvmx_mixx_iring2_s cn52xxp1; + struct cvmx_mixx_iring2_s cn56xx; + struct cvmx_mixx_iring2_s cn56xxp1; +}; + +union cvmx_mixx_isr { + uint64_t u64; + struct cvmx_mixx_isr_s { + uint64_t reserved_7_63:57; + uint64_t orun:1; + uint64_t irun:1; + uint64_t data_drp:1; + uint64_t irthresh:1; + uint64_t orthresh:1; + uint64_t idblovf:1; + uint64_t odblovf:1; + } s; + struct cvmx_mixx_isr_s cn52xx; + struct cvmx_mixx_isr_s cn52xxp1; + struct cvmx_mixx_isr_s cn56xx; + struct cvmx_mixx_isr_s cn56xxp1; +}; + +union cvmx_mixx_orcnt { + uint64_t u64; + struct cvmx_mixx_orcnt_s { + uint64_t reserved_20_63:44; + uint64_t orcnt:20; + } s; + struct cvmx_mixx_orcnt_s cn52xx; + struct cvmx_mixx_orcnt_s cn52xxp1; + struct cvmx_mixx_orcnt_s cn56xx; + struct cvmx_mixx_orcnt_s cn56xxp1; +}; + +union cvmx_mixx_orhwm { + uint64_t u64; + struct cvmx_mixx_orhwm_s { + uint64_t reserved_20_63:44; + uint64_t orhwm:20; + } s; + struct cvmx_mixx_orhwm_s cn52xx; + struct cvmx_mixx_orhwm_s cn52xxp1; + struct cvmx_mixx_orhwm_s cn56xx; + struct cvmx_mixx_orhwm_s cn56xxp1; +}; + +union cvmx_mixx_oring1 { + uint64_t u64; + struct cvmx_mixx_oring1_s { + uint64_t reserved_60_63:4; + uint64_t osize:20; + uint64_t reserved_36_39:4; + uint64_t obase:33; + uint64_t reserved_0_2:3; + } s; + struct cvmx_mixx_oring1_s cn52xx; + struct cvmx_mixx_oring1_s cn52xxp1; + struct cvmx_mixx_oring1_s cn56xx; + struct cvmx_mixx_oring1_s cn56xxp1; +}; + +union cvmx_mixx_oring2 { + uint64_t u64; + struct cvmx_mixx_oring2_s { + uint64_t reserved_52_63:12; + uint64_t otlptr:20; + uint64_t reserved_20_31:12; + uint64_t odbell:20; + } s; + struct cvmx_mixx_oring2_s cn52xx; + struct cvmx_mixx_oring2_s cn52xxp1; + struct cvmx_mixx_oring2_s cn56xx; + struct cvmx_mixx_oring2_s cn56xxp1; +}; + +union cvmx_mixx_remcnt { + uint64_t u64; + struct cvmx_mixx_remcnt_s { + uint64_t reserved_52_63:12; + uint64_t iremcnt:20; + uint64_t reserved_20_31:12; + uint64_t oremcnt:20; + } s; + struct cvmx_mixx_remcnt_s cn52xx; + struct cvmx_mixx_remcnt_s cn52xxp1; + struct cvmx_mixx_remcnt_s cn56xx; + struct cvmx_mixx_remcnt_s cn56xxp1; +}; + +#endif -- cgit v0.10.2 From d6aa60a10b2f5068e331ca2936b1e6c248ae37c1 Mon Sep 17 00:00:00 2001 From: David Daney Date: Wed, 14 Oct 2009 12:04:41 -0700 Subject: NET: Add Ethernet driver for Octeon MGMT devices. The Octeon MGMT Ethernet ports are present in some members of the Octeon SOC family (cn52XX and cn56XX have them). The mdio bus connected to the MGMT PHYs is shared with the main octeon-ethernet driver, we force it to be loaded first by calling octeon_mdiobus_force_mod_depencency. The platform devices for the MGMT Ethernet ports are added in arch/mips/cavium-octeon/octeon-platform.c, and the register definitions for the ports live in arch/mips/include/asm/octeon/ along with their ilk. Although it currently is the only driver in drivers/net/octeon, the directory was created looking forward to the day that octeon-ethernet will move there from its current home in drivers/staging. Signed-off-by: David Daney Acked-by: David S. Miller Signed-off-by: Ralf Baechle diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index a5be9ac..e58a653 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -1953,6 +1953,8 @@ config BCM63XX_ENET source "drivers/net/fs_enet/Kconfig" +source "drivers/net/octeon/Kconfig" + endif # NET_ETHERNET # diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 246323d..ad1346d 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -285,3 +285,5 @@ obj-$(CONFIG_VIRTIO_NET) += virtio_net.o obj-$(CONFIG_SFC) += sfc/ obj-$(CONFIG_WIMAX) += wimax/ + +obj-$(CONFIG_OCTEON_MGMT_ETHERNET) += octeon/ diff --git a/drivers/net/octeon/Kconfig b/drivers/net/octeon/Kconfig new file mode 100644 index 0000000..1e56bbf --- /dev/null +++ b/drivers/net/octeon/Kconfig @@ -0,0 +1,10 @@ +config OCTEON_MGMT_ETHERNET + tristate "Octeon Management port ethernet driver (CN5XXX, CN6XXX)" + depends on CPU_CAVIUM_OCTEON + select PHYLIB + select MDIO_OCTEON + default y + help + This option enables the ethernet driver for the management + port on Cavium Networks' Octeon CN57XX, CN56XX, CN55XX, + CN54XX, CN52XX, and CN6XXX chips. diff --git a/drivers/net/octeon/Makefile b/drivers/net/octeon/Makefile new file mode 100644 index 0000000..906edeca --- /dev/null +++ b/drivers/net/octeon/Makefile @@ -0,0 +1,2 @@ + +obj-$(CONFIG_OCTEON_MGMT_ETHERNET) += octeon_mgmt.o diff --git a/drivers/net/octeon/octeon_mgmt.c b/drivers/net/octeon/octeon_mgmt.c new file mode 100644 index 0000000..050538b --- /dev/null +++ b/drivers/net/octeon/octeon_mgmt.c @@ -0,0 +1,1176 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2009 Cavium Networks + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define DRV_NAME "octeon_mgmt" +#define DRV_VERSION "2.0" +#define DRV_DESCRIPTION \ + "Cavium Networks Octeon MII (management) port Network Driver" + +#define OCTEON_MGMT_NAPI_WEIGHT 16 + +/* + * Ring sizes that are powers of two allow for more efficient modulo + * opertions. + */ +#define OCTEON_MGMT_RX_RING_SIZE 512 +#define OCTEON_MGMT_TX_RING_SIZE 128 + +/* Allow 8 bytes for vlan and FCS. */ +#define OCTEON_MGMT_RX_HEADROOM (ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN) + +union mgmt_port_ring_entry { + u64 d64; + struct { + u64 reserved_62_63:2; + /* Length of the buffer/packet in bytes */ + u64 len:14; + /* For TX, signals that the packet should be timestamped */ + u64 tstamp:1; + /* The RX error code */ + u64 code:7; +#define RING_ENTRY_CODE_DONE 0xf +#define RING_ENTRY_CODE_MORE 0x10 + /* Physical address of the buffer */ + u64 addr:40; + } s; +}; + +struct octeon_mgmt { + struct net_device *netdev; + int port; + int irq; + u64 *tx_ring; + dma_addr_t tx_ring_handle; + unsigned int tx_next; + unsigned int tx_next_clean; + unsigned int tx_current_fill; + /* The tx_list lock also protects the ring related variables */ + struct sk_buff_head tx_list; + + /* RX variables only touched in napi_poll. No locking necessary. */ + u64 *rx_ring; + dma_addr_t rx_ring_handle; + unsigned int rx_next; + unsigned int rx_next_fill; + unsigned int rx_current_fill; + struct sk_buff_head rx_list; + + spinlock_t lock; + unsigned int last_duplex; + unsigned int last_link; + struct device *dev; + struct napi_struct napi; + struct tasklet_struct tx_clean_tasklet; + struct phy_device *phydev; +}; + +static void octeon_mgmt_set_rx_irq(struct octeon_mgmt *p, int enable) +{ + int port = p->port; + union cvmx_mixx_intena mix_intena; + unsigned long flags; + + spin_lock_irqsave(&p->lock, flags); + mix_intena.u64 = cvmx_read_csr(CVMX_MIXX_INTENA(port)); + mix_intena.s.ithena = enable ? 1 : 0; + cvmx_write_csr(CVMX_MIXX_INTENA(port), mix_intena.u64); + spin_unlock_irqrestore(&p->lock, flags); +} + +static void octeon_mgmt_set_tx_irq(struct octeon_mgmt *p, int enable) +{ + int port = p->port; + union cvmx_mixx_intena mix_intena; + unsigned long flags; + + spin_lock_irqsave(&p->lock, flags); + mix_intena.u64 = cvmx_read_csr(CVMX_MIXX_INTENA(port)); + mix_intena.s.othena = enable ? 1 : 0; + cvmx_write_csr(CVMX_MIXX_INTENA(port), mix_intena.u64); + spin_unlock_irqrestore(&p->lock, flags); +} + +static inline void octeon_mgmt_enable_rx_irq(struct octeon_mgmt *p) +{ + octeon_mgmt_set_rx_irq(p, 1); +} + +static inline void octeon_mgmt_disable_rx_irq(struct octeon_mgmt *p) +{ + octeon_mgmt_set_rx_irq(p, 0); +} + +static inline void octeon_mgmt_enable_tx_irq(struct octeon_mgmt *p) +{ + octeon_mgmt_set_tx_irq(p, 1); +} + +static inline void octeon_mgmt_disable_tx_irq(struct octeon_mgmt *p) +{ + octeon_mgmt_set_tx_irq(p, 0); +} + +static unsigned int ring_max_fill(unsigned int ring_size) +{ + return ring_size - 8; +} + +static unsigned int ring_size_to_bytes(unsigned int ring_size) +{ + return ring_size * sizeof(union mgmt_port_ring_entry); +} + +static void octeon_mgmt_rx_fill_ring(struct net_device *netdev) +{ + struct octeon_mgmt *p = netdev_priv(netdev); + int port = p->port; + + while (p->rx_current_fill < ring_max_fill(OCTEON_MGMT_RX_RING_SIZE)) { + unsigned int size; + union mgmt_port_ring_entry re; + struct sk_buff *skb; + + /* CN56XX pass 1 needs 8 bytes of padding. */ + size = netdev->mtu + OCTEON_MGMT_RX_HEADROOM + 8 + NET_IP_ALIGN; + + skb = netdev_alloc_skb(netdev, size); + if (!skb) + break; + skb_reserve(skb, NET_IP_ALIGN); + __skb_queue_tail(&p->rx_list, skb); + + re.d64 = 0; + re.s.len = size; + re.s.addr = dma_map_single(p->dev, skb->data, + size, + DMA_FROM_DEVICE); + + /* Put it in the ring. */ + p->rx_ring[p->rx_next_fill] = re.d64; + dma_sync_single_for_device(p->dev, p->rx_ring_handle, + ring_size_to_bytes(OCTEON_MGMT_RX_RING_SIZE), + DMA_BIDIRECTIONAL); + p->rx_next_fill = + (p->rx_next_fill + 1) % OCTEON_MGMT_RX_RING_SIZE; + p->rx_current_fill++; + /* Ring the bell. */ + cvmx_write_csr(CVMX_MIXX_IRING2(port), 1); + } +} + +static void octeon_mgmt_clean_tx_buffers(struct octeon_mgmt *p) +{ + int port = p->port; + union cvmx_mixx_orcnt mix_orcnt; + union mgmt_port_ring_entry re; + struct sk_buff *skb; + int cleaned = 0; + unsigned long flags; + + mix_orcnt.u64 = cvmx_read_csr(CVMX_MIXX_ORCNT(port)); + while (mix_orcnt.s.orcnt) { + dma_sync_single_for_cpu(p->dev, p->tx_ring_handle, + ring_size_to_bytes(OCTEON_MGMT_TX_RING_SIZE), + DMA_BIDIRECTIONAL); + + spin_lock_irqsave(&p->tx_list.lock, flags); + + re.d64 = p->tx_ring[p->tx_next_clean]; + p->tx_next_clean = + (p->tx_next_clean + 1) % OCTEON_MGMT_TX_RING_SIZE; + skb = __skb_dequeue(&p->tx_list); + + mix_orcnt.u64 = 0; + mix_orcnt.s.orcnt = 1; + + /* Acknowledge to hardware that we have the buffer. */ + cvmx_write_csr(CVMX_MIXX_ORCNT(port), mix_orcnt.u64); + p->tx_current_fill--; + + spin_unlock_irqrestore(&p->tx_list.lock, flags); + + dma_unmap_single(p->dev, re.s.addr, re.s.len, + DMA_TO_DEVICE); + dev_kfree_skb_any(skb); + cleaned++; + + mix_orcnt.u64 = cvmx_read_csr(CVMX_MIXX_ORCNT(port)); + } + + if (cleaned && netif_queue_stopped(p->netdev)) + netif_wake_queue(p->netdev); +} + +static void octeon_mgmt_clean_tx_tasklet(unsigned long arg) +{ + struct octeon_mgmt *p = (struct octeon_mgmt *)arg; + octeon_mgmt_clean_tx_buffers(p); + octeon_mgmt_enable_tx_irq(p); +} + +static void octeon_mgmt_update_rx_stats(struct net_device *netdev) +{ + struct octeon_mgmt *p = netdev_priv(netdev); + int port = p->port; + unsigned long flags; + u64 drop, bad; + + /* These reads also clear the count registers. */ + drop = cvmx_read_csr(CVMX_AGL_GMX_RXX_STATS_PKTS_DRP(port)); + bad = cvmx_read_csr(CVMX_AGL_GMX_RXX_STATS_PKTS_BAD(port)); + + if (drop || bad) { + /* Do an atomic update. */ + spin_lock_irqsave(&p->lock, flags); + netdev->stats.rx_errors += bad; + netdev->stats.rx_dropped += drop; + spin_unlock_irqrestore(&p->lock, flags); + } +} + +static void octeon_mgmt_update_tx_stats(struct net_device *netdev) +{ + struct octeon_mgmt *p = netdev_priv(netdev); + int port = p->port; + unsigned long flags; + + union cvmx_agl_gmx_txx_stat0 s0; + union cvmx_agl_gmx_txx_stat1 s1; + + /* These reads also clear the count registers. */ + s0.u64 = cvmx_read_csr(CVMX_AGL_GMX_TXX_STAT0(port)); + s1.u64 = cvmx_read_csr(CVMX_AGL_GMX_TXX_STAT1(port)); + + if (s0.s.xsdef || s0.s.xscol || s1.s.scol || s1.s.mcol) { + /* Do an atomic update. */ + spin_lock_irqsave(&p->lock, flags); + netdev->stats.tx_errors += s0.s.xsdef + s0.s.xscol; + netdev->stats.collisions += s1.s.scol + s1.s.mcol; + spin_unlock_irqrestore(&p->lock, flags); + } +} + +/* + * Dequeue a receive skb and its corresponding ring entry. The ring + * entry is returned, *pskb is updated to point to the skb. + */ +static u64 octeon_mgmt_dequeue_rx_buffer(struct octeon_mgmt *p, + struct sk_buff **pskb) +{ + union mgmt_port_ring_entry re; + + dma_sync_single_for_cpu(p->dev, p->rx_ring_handle, + ring_size_to_bytes(OCTEON_MGMT_RX_RING_SIZE), + DMA_BIDIRECTIONAL); + + re.d64 = p->rx_ring[p->rx_next]; + p->rx_next = (p->rx_next + 1) % OCTEON_MGMT_RX_RING_SIZE; + p->rx_current_fill--; + *pskb = __skb_dequeue(&p->rx_list); + + dma_unmap_single(p->dev, re.s.addr, + ETH_FRAME_LEN + OCTEON_MGMT_RX_HEADROOM, + DMA_FROM_DEVICE); + + return re.d64; +} + + +static int octeon_mgmt_receive_one(struct octeon_mgmt *p) +{ + int port = p->port; + struct net_device *netdev = p->netdev; + union cvmx_mixx_ircnt mix_ircnt; + union mgmt_port_ring_entry re; + struct sk_buff *skb; + struct sk_buff *skb2; + struct sk_buff *skb_new; + union mgmt_port_ring_entry re2; + int rc = 1; + + + re.d64 = octeon_mgmt_dequeue_rx_buffer(p, &skb); + if (likely(re.s.code == RING_ENTRY_CODE_DONE)) { + /* A good packet, send it up. */ + skb_put(skb, re.s.len); +good: + skb->protocol = eth_type_trans(skb, netdev); + netdev->stats.rx_packets++; + netdev->stats.rx_bytes += skb->len; + netdev->last_rx = jiffies; + netif_receive_skb(skb); + rc = 0; + } else if (re.s.code == RING_ENTRY_CODE_MORE) { + /* + * Packet split across skbs. This can happen if we + * increase the MTU. Buffers that are already in the + * rx ring can then end up being too small. As the rx + * ring is refilled, buffers sized for the new MTU + * will be used and we should go back to the normal + * non-split case. + */ + skb_put(skb, re.s.len); + do { + re2.d64 = octeon_mgmt_dequeue_rx_buffer(p, &skb2); + if (re2.s.code != RING_ENTRY_CODE_MORE + && re2.s.code != RING_ENTRY_CODE_DONE) + goto split_error; + skb_put(skb2, re2.s.len); + skb_new = skb_copy_expand(skb, 0, skb2->len, + GFP_ATOMIC); + if (!skb_new) + goto split_error; + if (skb_copy_bits(skb2, 0, skb_tail_pointer(skb_new), + skb2->len)) + goto split_error; + skb_put(skb_new, skb2->len); + dev_kfree_skb_any(skb); + dev_kfree_skb_any(skb2); + skb = skb_new; + } while (re2.s.code == RING_ENTRY_CODE_MORE); + goto good; + } else { + /* Some other error, discard it. */ + dev_kfree_skb_any(skb); + /* + * Error statistics are accumulated in + * octeon_mgmt_update_rx_stats. + */ + } + goto done; +split_error: + /* Discard the whole mess. */ + dev_kfree_skb_any(skb); + dev_kfree_skb_any(skb2); + while (re2.s.code == RING_ENTRY_CODE_MORE) { + re2.d64 = octeon_mgmt_dequeue_rx_buffer(p, &skb2); + dev_kfree_skb_any(skb2); + } + netdev->stats.rx_errors++; + +done: + /* Tell the hardware we processed a packet. */ + mix_ircnt.u64 = 0; + mix_ircnt.s.ircnt = 1; + cvmx_write_csr(CVMX_MIXX_IRCNT(port), mix_ircnt.u64); + return rc; + +} + +static int octeon_mgmt_receive_packets(struct octeon_mgmt *p, int budget) +{ + int port = p->port; + unsigned int work_done = 0; + union cvmx_mixx_ircnt mix_ircnt; + int rc; + + + mix_ircnt.u64 = cvmx_read_csr(CVMX_MIXX_IRCNT(port)); + while (work_done < budget && mix_ircnt.s.ircnt) { + + rc = octeon_mgmt_receive_one(p); + if (!rc) + work_done++; + + /* Check for more packets. */ + mix_ircnt.u64 = cvmx_read_csr(CVMX_MIXX_IRCNT(port)); + } + + octeon_mgmt_rx_fill_ring(p->netdev); + + return work_done; +} + +static int octeon_mgmt_napi_poll(struct napi_struct *napi, int budget) +{ + struct octeon_mgmt *p = container_of(napi, struct octeon_mgmt, napi); + struct net_device *netdev = p->netdev; + unsigned int work_done = 0; + + work_done = octeon_mgmt_receive_packets(p, budget); + + if (work_done < budget) { + /* We stopped because no more packets were available. */ + napi_complete(napi); + octeon_mgmt_enable_rx_irq(p); + } + octeon_mgmt_update_rx_stats(netdev); + + return work_done; +} + +/* Reset the hardware to clean state. */ +static void octeon_mgmt_reset_hw(struct octeon_mgmt *p) +{ + union cvmx_mixx_ctl mix_ctl; + union cvmx_mixx_bist mix_bist; + union cvmx_agl_gmx_bist agl_gmx_bist; + + mix_ctl.u64 = 0; + cvmx_write_csr(CVMX_MIXX_CTL(p->port), mix_ctl.u64); + do { + mix_ctl.u64 = cvmx_read_csr(CVMX_MIXX_CTL(p->port)); + } while (mix_ctl.s.busy); + mix_ctl.s.reset = 1; + cvmx_write_csr(CVMX_MIXX_CTL(p->port), mix_ctl.u64); + cvmx_read_csr(CVMX_MIXX_CTL(p->port)); + cvmx_wait(64); + + mix_bist.u64 = cvmx_read_csr(CVMX_MIXX_BIST(p->port)); + if (mix_bist.u64) + dev_warn(p->dev, "MIX failed BIST (0x%016llx)\n", + (unsigned long long)mix_bist.u64); + + agl_gmx_bist.u64 = cvmx_read_csr(CVMX_AGL_GMX_BIST); + if (agl_gmx_bist.u64) + dev_warn(p->dev, "AGL failed BIST (0x%016llx)\n", + (unsigned long long)agl_gmx_bist.u64); +} + +struct octeon_mgmt_cam_state { + u64 cam[6]; + u64 cam_mask; + int cam_index; +}; + +static void octeon_mgmt_cam_state_add(struct octeon_mgmt_cam_state *cs, + unsigned char *addr) +{ + int i; + + for (i = 0; i < 6; i++) + cs->cam[i] |= (u64)addr[i] << (8 * (cs->cam_index)); + cs->cam_mask |= (1ULL << cs->cam_index); + cs->cam_index++; +} + +static void octeon_mgmt_set_rx_filtering(struct net_device *netdev) +{ + struct octeon_mgmt *p = netdev_priv(netdev); + int port = p->port; + int i; + union cvmx_agl_gmx_rxx_adr_ctl adr_ctl; + union cvmx_agl_gmx_prtx_cfg agl_gmx_prtx; + unsigned long flags; + unsigned int prev_packet_enable; + unsigned int cam_mode = 1; /* 1 - Accept on CAM match */ + unsigned int multicast_mode = 1; /* 1 - Reject all multicast. */ + struct octeon_mgmt_cam_state cam_state; + struct dev_addr_list *list; + struct list_head *pos; + int available_cam_entries; + + memset(&cam_state, 0, sizeof(cam_state)); + + if ((netdev->flags & IFF_PROMISC) || netdev->dev_addrs.count > 7) { + cam_mode = 0; + available_cam_entries = 8; + } else { + /* + * One CAM entry for the primary address, leaves seven + * for the secondary addresses. + */ + available_cam_entries = 7 - netdev->dev_addrs.count; + } + + if (netdev->flags & IFF_MULTICAST) { + if (cam_mode == 0 || (netdev->flags & IFF_ALLMULTI) + || netdev->mc_count > available_cam_entries) + multicast_mode = 2; /* 1 - Accept all multicast. */ + else + multicast_mode = 0; /* 0 - Use CAM. */ + } + + if (cam_mode == 1) { + /* Add primary address. */ + octeon_mgmt_cam_state_add(&cam_state, netdev->dev_addr); + list_for_each(pos, &netdev->dev_addrs.list) { + struct netdev_hw_addr *hw_addr; + hw_addr = list_entry(pos, struct netdev_hw_addr, list); + octeon_mgmt_cam_state_add(&cam_state, hw_addr->addr); + list = list->next; + } + } + if (multicast_mode == 0) { + i = netdev->mc_count; + list = netdev->mc_list; + while (i--) { + octeon_mgmt_cam_state_add(&cam_state, list->da_addr); + list = list->next; + } + } + + + spin_lock_irqsave(&p->lock, flags); + + /* Disable packet I/O. */ + agl_gmx_prtx.u64 = cvmx_read_csr(CVMX_AGL_GMX_PRTX_CFG(port)); + prev_packet_enable = agl_gmx_prtx.s.en; + agl_gmx_prtx.s.en = 0; + cvmx_write_csr(CVMX_AGL_GMX_PRTX_CFG(port), agl_gmx_prtx.u64); + + + adr_ctl.u64 = 0; + adr_ctl.s.cam_mode = cam_mode; + adr_ctl.s.mcst = multicast_mode; + adr_ctl.s.bcst = 1; /* Allow broadcast */ + + cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CTL(port), adr_ctl.u64); + + cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM0(port), cam_state.cam[0]); + cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM1(port), cam_state.cam[1]); + cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM2(port), cam_state.cam[2]); + cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM3(port), cam_state.cam[3]); + cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM4(port), cam_state.cam[4]); + cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM5(port), cam_state.cam[5]); + cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM_EN(port), cam_state.cam_mask); + + /* Restore packet I/O. */ + agl_gmx_prtx.s.en = prev_packet_enable; + cvmx_write_csr(CVMX_AGL_GMX_PRTX_CFG(port), agl_gmx_prtx.u64); + + spin_unlock_irqrestore(&p->lock, flags); +} + +static int octeon_mgmt_set_mac_address(struct net_device *netdev, void *addr) +{ + struct sockaddr *sa = addr; + + if (!is_valid_ether_addr(sa->sa_data)) + return -EADDRNOTAVAIL; + + memcpy(netdev->dev_addr, sa->sa_data, ETH_ALEN); + + octeon_mgmt_set_rx_filtering(netdev); + + return 0; +} + +static int octeon_mgmt_change_mtu(struct net_device *netdev, int new_mtu) +{ + struct octeon_mgmt *p = netdev_priv(netdev); + int port = p->port; + int size_without_fcs = new_mtu + OCTEON_MGMT_RX_HEADROOM; + + /* + * Limit the MTU to make sure the ethernet packets are between + * 64 bytes and 16383 bytes. + */ + if (size_without_fcs < 64 || size_without_fcs > 16383) { + dev_warn(p->dev, "MTU must be between %d and %d.\n", + 64 - OCTEON_MGMT_RX_HEADROOM, + 16383 - OCTEON_MGMT_RX_HEADROOM); + return -EINVAL; + } + + netdev->mtu = new_mtu; + + cvmx_write_csr(CVMX_AGL_GMX_RXX_FRM_MAX(port), size_without_fcs); + cvmx_write_csr(CVMX_AGL_GMX_RXX_JABBER(port), + (size_without_fcs + 7) & 0xfff8); + + return 0; +} + +static irqreturn_t octeon_mgmt_interrupt(int cpl, void *dev_id) +{ + struct net_device *netdev = dev_id; + struct octeon_mgmt *p = netdev_priv(netdev); + int port = p->port; + union cvmx_mixx_isr mixx_isr; + + mixx_isr.u64 = cvmx_read_csr(CVMX_MIXX_ISR(port)); + + /* Clear any pending interrupts */ + cvmx_write_csr(CVMX_MIXX_ISR(port), + cvmx_read_csr(CVMX_MIXX_ISR(port))); + cvmx_read_csr(CVMX_MIXX_ISR(port)); + + if (mixx_isr.s.irthresh) { + octeon_mgmt_disable_rx_irq(p); + napi_schedule(&p->napi); + } + if (mixx_isr.s.orthresh) { + octeon_mgmt_disable_tx_irq(p); + tasklet_schedule(&p->tx_clean_tasklet); + } + + return IRQ_HANDLED; +} + +static int octeon_mgmt_ioctl(struct net_device *netdev, + struct ifreq *rq, int cmd) +{ + struct octeon_mgmt *p = netdev_priv(netdev); + + if (!netif_running(netdev)) + return -EINVAL; + + if (!p->phydev) + return -EINVAL; + + return phy_mii_ioctl(p->phydev, if_mii(rq), cmd); +} + +static void octeon_mgmt_adjust_link(struct net_device *netdev) +{ + struct octeon_mgmt *p = netdev_priv(netdev); + int port = p->port; + union cvmx_agl_gmx_prtx_cfg prtx_cfg; + unsigned long flags; + int link_changed = 0; + + spin_lock_irqsave(&p->lock, flags); + if (p->phydev->link) { + if (!p->last_link) + link_changed = 1; + if (p->last_duplex != p->phydev->duplex) { + p->last_duplex = p->phydev->duplex; + prtx_cfg.u64 = + cvmx_read_csr(CVMX_AGL_GMX_PRTX_CFG(port)); + prtx_cfg.s.duplex = p->phydev->duplex; + cvmx_write_csr(CVMX_AGL_GMX_PRTX_CFG(port), + prtx_cfg.u64); + } + } else { + if (p->last_link) + link_changed = -1; + } + p->last_link = p->phydev->link; + spin_unlock_irqrestore(&p->lock, flags); + + if (link_changed != 0) { + if (link_changed > 0) { + netif_carrier_on(netdev); + pr_info("%s: Link is up - %d/%s\n", netdev->name, + p->phydev->speed, + DUPLEX_FULL == p->phydev->duplex ? + "Full" : "Half"); + } else { + netif_carrier_off(netdev); + pr_info("%s: Link is down\n", netdev->name); + } + } +} + +static int octeon_mgmt_init_phy(struct net_device *netdev) +{ + struct octeon_mgmt *p = netdev_priv(netdev); + char phy_id[20]; + + if (octeon_is_simulation()) { + /* No PHYs in the simulator. */ + netif_carrier_on(netdev); + return 0; + } + + snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT, "0", p->port); + + p->phydev = phy_connect(netdev, phy_id, octeon_mgmt_adjust_link, 0, + PHY_INTERFACE_MODE_MII); + + if (IS_ERR(p->phydev)) { + p->phydev = NULL; + return -1; + } + + phy_start_aneg(p->phydev); + + return 0; +} + +static int octeon_mgmt_open(struct net_device *netdev) +{ + struct octeon_mgmt *p = netdev_priv(netdev); + int port = p->port; + union cvmx_mixx_ctl mix_ctl; + union cvmx_agl_gmx_inf_mode agl_gmx_inf_mode; + union cvmx_mixx_oring1 oring1; + union cvmx_mixx_iring1 iring1; + union cvmx_agl_gmx_prtx_cfg prtx_cfg; + union cvmx_agl_gmx_rxx_frm_ctl rxx_frm_ctl; + union cvmx_mixx_irhwm mix_irhwm; + union cvmx_mixx_orhwm mix_orhwm; + union cvmx_mixx_intena mix_intena; + struct sockaddr sa; + + /* Allocate ring buffers. */ + p->tx_ring = kzalloc(ring_size_to_bytes(OCTEON_MGMT_TX_RING_SIZE), + GFP_KERNEL); + if (!p->tx_ring) + return -ENOMEM; + p->tx_ring_handle = + dma_map_single(p->dev, p->tx_ring, + ring_size_to_bytes(OCTEON_MGMT_TX_RING_SIZE), + DMA_BIDIRECTIONAL); + p->tx_next = 0; + p->tx_next_clean = 0; + p->tx_current_fill = 0; + + + p->rx_ring = kzalloc(ring_size_to_bytes(OCTEON_MGMT_RX_RING_SIZE), + GFP_KERNEL); + if (!p->rx_ring) + goto err_nomem; + p->rx_ring_handle = + dma_map_single(p->dev, p->rx_ring, + ring_size_to_bytes(OCTEON_MGMT_RX_RING_SIZE), + DMA_BIDIRECTIONAL); + + p->rx_next = 0; + p->rx_next_fill = 0; + p->rx_current_fill = 0; + + octeon_mgmt_reset_hw(p); + + mix_ctl.u64 = cvmx_read_csr(CVMX_MIXX_CTL(port)); + + /* Bring it out of reset if needed. */ + if (mix_ctl.s.reset) { + mix_ctl.s.reset = 0; + cvmx_write_csr(CVMX_MIXX_CTL(port), mix_ctl.u64); + do { + mix_ctl.u64 = cvmx_read_csr(CVMX_MIXX_CTL(port)); + } while (mix_ctl.s.reset); + } + + agl_gmx_inf_mode.u64 = 0; + agl_gmx_inf_mode.s.en = 1; + cvmx_write_csr(CVMX_AGL_GMX_INF_MODE, agl_gmx_inf_mode.u64); + + oring1.u64 = 0; + oring1.s.obase = p->tx_ring_handle >> 3; + oring1.s.osize = OCTEON_MGMT_TX_RING_SIZE; + cvmx_write_csr(CVMX_MIXX_ORING1(port), oring1.u64); + + iring1.u64 = 0; + iring1.s.ibase = p->rx_ring_handle >> 3; + iring1.s.isize = OCTEON_MGMT_RX_RING_SIZE; + cvmx_write_csr(CVMX_MIXX_IRING1(port), iring1.u64); + + /* Disable packet I/O. */ + prtx_cfg.u64 = cvmx_read_csr(CVMX_AGL_GMX_PRTX_CFG(port)); + prtx_cfg.s.en = 0; + cvmx_write_csr(CVMX_AGL_GMX_PRTX_CFG(port), prtx_cfg.u64); + + memcpy(sa.sa_data, netdev->dev_addr, ETH_ALEN); + octeon_mgmt_set_mac_address(netdev, &sa); + + octeon_mgmt_change_mtu(netdev, netdev->mtu); + + /* + * Enable the port HW. Packets are not allowed until + * cvmx_mgmt_port_enable() is called. + */ + mix_ctl.u64 = 0; + mix_ctl.s.crc_strip = 1; /* Strip the ending CRC */ + mix_ctl.s.en = 1; /* Enable the port */ + mix_ctl.s.nbtarb = 0; /* Arbitration mode */ + /* MII CB-request FIFO programmable high watermark */ + mix_ctl.s.mrq_hwm = 1; + cvmx_write_csr(CVMX_MIXX_CTL(port), mix_ctl.u64); + + if (OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X) + || OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X)) { + /* + * Force compensation values, as they are not + * determined properly by HW + */ + union cvmx_agl_gmx_drv_ctl drv_ctl; + + drv_ctl.u64 = cvmx_read_csr(CVMX_AGL_GMX_DRV_CTL); + if (port) { + drv_ctl.s.byp_en1 = 1; + drv_ctl.s.nctl1 = 6; + drv_ctl.s.pctl1 = 6; + } else { + drv_ctl.s.byp_en = 1; + drv_ctl.s.nctl = 6; + drv_ctl.s.pctl = 6; + } + cvmx_write_csr(CVMX_AGL_GMX_DRV_CTL, drv_ctl.u64); + } + + octeon_mgmt_rx_fill_ring(netdev); + + /* Clear statistics. */ + /* Clear on read. */ + cvmx_write_csr(CVMX_AGL_GMX_RXX_STATS_CTL(port), 1); + cvmx_write_csr(CVMX_AGL_GMX_RXX_STATS_PKTS_DRP(port), 0); + cvmx_write_csr(CVMX_AGL_GMX_RXX_STATS_PKTS_BAD(port), 0); + + cvmx_write_csr(CVMX_AGL_GMX_TXX_STATS_CTL(port), 1); + cvmx_write_csr(CVMX_AGL_GMX_TXX_STAT0(port), 0); + cvmx_write_csr(CVMX_AGL_GMX_TXX_STAT1(port), 0); + + /* Clear any pending interrupts */ + cvmx_write_csr(CVMX_MIXX_ISR(port), cvmx_read_csr(CVMX_MIXX_ISR(port))); + + if (request_irq(p->irq, octeon_mgmt_interrupt, 0, netdev->name, + netdev)) { + dev_err(p->dev, "request_irq(%d) failed.\n", p->irq); + goto err_noirq; + } + + /* Interrupt every single RX packet */ + mix_irhwm.u64 = 0; + mix_irhwm.s.irhwm = 0; + cvmx_write_csr(CVMX_MIXX_IRHWM(port), mix_irhwm.u64); + + /* Interrupt when we have 5 or more packets to clean. */ + mix_orhwm.u64 = 0; + mix_orhwm.s.orhwm = 5; + cvmx_write_csr(CVMX_MIXX_ORHWM(port), mix_orhwm.u64); + + /* Enable receive and transmit interrupts */ + mix_intena.u64 = 0; + mix_intena.s.ithena = 1; + mix_intena.s.othena = 1; + cvmx_write_csr(CVMX_MIXX_INTENA(port), mix_intena.u64); + + + /* Enable packet I/O. */ + + rxx_frm_ctl.u64 = 0; + rxx_frm_ctl.s.pre_align = 1; + /* + * When set, disables the length check for non-min sized pkts + * with padding in the client data. + */ + rxx_frm_ctl.s.pad_len = 1; + /* When set, disables the length check for VLAN pkts */ + rxx_frm_ctl.s.vlan_len = 1; + /* When set, PREAMBLE checking is less strict */ + rxx_frm_ctl.s.pre_free = 1; + /* Control Pause Frames can match station SMAC */ + rxx_frm_ctl.s.ctl_smac = 0; + /* Control Pause Frames can match globally assign Multicast address */ + rxx_frm_ctl.s.ctl_mcst = 1; + /* Forward pause information to TX block */ + rxx_frm_ctl.s.ctl_bck = 1; + /* Drop Control Pause Frames */ + rxx_frm_ctl.s.ctl_drp = 1; + /* Strip off the preamble */ + rxx_frm_ctl.s.pre_strp = 1; + /* + * This port is configured to send PREAMBLE+SFD to begin every + * frame. GMX checks that the PREAMBLE is sent correctly. + */ + rxx_frm_ctl.s.pre_chk = 1; + cvmx_write_csr(CVMX_AGL_GMX_RXX_FRM_CTL(port), rxx_frm_ctl.u64); + + /* Enable the AGL block */ + agl_gmx_inf_mode.u64 = 0; + agl_gmx_inf_mode.s.en = 1; + cvmx_write_csr(CVMX_AGL_GMX_INF_MODE, agl_gmx_inf_mode.u64); + + /* Configure the port duplex and enables */ + prtx_cfg.u64 = cvmx_read_csr(CVMX_AGL_GMX_PRTX_CFG(port)); + prtx_cfg.s.tx_en = 1; + prtx_cfg.s.rx_en = 1; + prtx_cfg.s.en = 1; + p->last_duplex = 1; + prtx_cfg.s.duplex = p->last_duplex; + cvmx_write_csr(CVMX_AGL_GMX_PRTX_CFG(port), prtx_cfg.u64); + + p->last_link = 0; + netif_carrier_off(netdev); + + if (octeon_mgmt_init_phy(netdev)) { + dev_err(p->dev, "Cannot initialize PHY.\n"); + goto err_noirq; + } + + netif_wake_queue(netdev); + napi_enable(&p->napi); + + return 0; +err_noirq: + octeon_mgmt_reset_hw(p); + dma_unmap_single(p->dev, p->rx_ring_handle, + ring_size_to_bytes(OCTEON_MGMT_RX_RING_SIZE), + DMA_BIDIRECTIONAL); + kfree(p->rx_ring); +err_nomem: + dma_unmap_single(p->dev, p->tx_ring_handle, + ring_size_to_bytes(OCTEON_MGMT_TX_RING_SIZE), + DMA_BIDIRECTIONAL); + kfree(p->tx_ring); + return -ENOMEM; +} + +static int octeon_mgmt_stop(struct net_device *netdev) +{ + struct octeon_mgmt *p = netdev_priv(netdev); + + napi_disable(&p->napi); + netif_stop_queue(netdev); + + if (p->phydev) + phy_disconnect(p->phydev); + + netif_carrier_off(netdev); + + octeon_mgmt_reset_hw(p); + + + free_irq(p->irq, netdev); + + /* dma_unmap is a nop on Octeon, so just free everything. */ + skb_queue_purge(&p->tx_list); + skb_queue_purge(&p->rx_list); + + dma_unmap_single(p->dev, p->rx_ring_handle, + ring_size_to_bytes(OCTEON_MGMT_RX_RING_SIZE), + DMA_BIDIRECTIONAL); + kfree(p->rx_ring); + + dma_unmap_single(p->dev, p->tx_ring_handle, + ring_size_to_bytes(OCTEON_MGMT_TX_RING_SIZE), + DMA_BIDIRECTIONAL); + kfree(p->tx_ring); + + + return 0; +} + +static int octeon_mgmt_xmit(struct sk_buff *skb, struct net_device *netdev) +{ + struct octeon_mgmt *p = netdev_priv(netdev); + int port = p->port; + union mgmt_port_ring_entry re; + unsigned long flags; + + re.d64 = 0; + re.s.len = skb->len; + re.s.addr = dma_map_single(p->dev, skb->data, + skb->len, + DMA_TO_DEVICE); + + spin_lock_irqsave(&p->tx_list.lock, flags); + + if (unlikely(p->tx_current_fill >= + ring_max_fill(OCTEON_MGMT_TX_RING_SIZE))) { + spin_unlock_irqrestore(&p->tx_list.lock, flags); + + dma_unmap_single(p->dev, re.s.addr, re.s.len, + DMA_TO_DEVICE); + + netif_stop_queue(netdev); + return NETDEV_TX_BUSY; + } + + __skb_queue_tail(&p->tx_list, skb); + + /* Put it in the ring. */ + p->tx_ring[p->tx_next] = re.d64; + p->tx_next = (p->tx_next + 1) % OCTEON_MGMT_TX_RING_SIZE; + p->tx_current_fill++; + + spin_unlock_irqrestore(&p->tx_list.lock, flags); + + dma_sync_single_for_device(p->dev, p->tx_ring_handle, + ring_size_to_bytes(OCTEON_MGMT_TX_RING_SIZE), + DMA_BIDIRECTIONAL); + + netdev->stats.tx_packets++; + netdev->stats.tx_bytes += skb->len; + + /* Ring the bell. */ + cvmx_write_csr(CVMX_MIXX_ORING2(port), 1); + + netdev->trans_start = jiffies; + octeon_mgmt_clean_tx_buffers(p); + octeon_mgmt_update_tx_stats(netdev); + return NETDEV_TX_OK; +} + +#ifdef CONFIG_NET_POLL_CONTROLLER +static void octeon_mgmt_poll_controller(struct net_device *netdev) +{ + struct octeon_mgmt *p = netdev_priv(netdev); + + octeon_mgmt_receive_packets(p, 16); + octeon_mgmt_update_rx_stats(netdev); + return; +} +#endif + +static void octeon_mgmt_get_drvinfo(struct net_device *netdev, + struct ethtool_drvinfo *info) +{ + strncpy(info->driver, DRV_NAME, sizeof(info->driver)); + strncpy(info->version, DRV_VERSION, sizeof(info->version)); + strncpy(info->fw_version, "N/A", sizeof(info->fw_version)); + strncpy(info->bus_info, "N/A", sizeof(info->bus_info)); + info->n_stats = 0; + info->testinfo_len = 0; + info->regdump_len = 0; + info->eedump_len = 0; +} + +static int octeon_mgmt_get_settings(struct net_device *netdev, + struct ethtool_cmd *cmd) +{ + struct octeon_mgmt *p = netdev_priv(netdev); + + if (p->phydev) + return phy_ethtool_gset(p->phydev, cmd); + + return -EINVAL; +} + +static int octeon_mgmt_set_settings(struct net_device *netdev, + struct ethtool_cmd *cmd) +{ + struct octeon_mgmt *p = netdev_priv(netdev); + + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + + if (p->phydev) + return phy_ethtool_sset(p->phydev, cmd); + + return -EINVAL; +} + +static const struct ethtool_ops octeon_mgmt_ethtool_ops = { + .get_drvinfo = octeon_mgmt_get_drvinfo, + .get_link = ethtool_op_get_link, + .get_settings = octeon_mgmt_get_settings, + .set_settings = octeon_mgmt_set_settings +}; + +static const struct net_device_ops octeon_mgmt_ops = { + .ndo_open = octeon_mgmt_open, + .ndo_stop = octeon_mgmt_stop, + .ndo_start_xmit = octeon_mgmt_xmit, + .ndo_set_rx_mode = octeon_mgmt_set_rx_filtering, + .ndo_set_multicast_list = octeon_mgmt_set_rx_filtering, + .ndo_set_mac_address = octeon_mgmt_set_mac_address, + .ndo_do_ioctl = octeon_mgmt_ioctl, + .ndo_change_mtu = octeon_mgmt_change_mtu, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = octeon_mgmt_poll_controller, +#endif +}; + +static int __init octeon_mgmt_probe(struct platform_device *pdev) +{ + struct resource *res_irq; + struct net_device *netdev; + struct octeon_mgmt *p; + int i; + + netdev = alloc_etherdev(sizeof(struct octeon_mgmt)); + if (netdev == NULL) + return -ENOMEM; + + dev_set_drvdata(&pdev->dev, netdev); + p = netdev_priv(netdev); + netif_napi_add(netdev, &p->napi, octeon_mgmt_napi_poll, + OCTEON_MGMT_NAPI_WEIGHT); + + p->netdev = netdev; + p->dev = &pdev->dev; + + p->port = pdev->id; + snprintf(netdev->name, IFNAMSIZ, "mgmt%d", p->port); + + res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!res_irq) + goto err; + + p->irq = res_irq->start; + spin_lock_init(&p->lock); + + skb_queue_head_init(&p->tx_list); + skb_queue_head_init(&p->rx_list); + tasklet_init(&p->tx_clean_tasklet, + octeon_mgmt_clean_tx_tasklet, (unsigned long)p); + + netdev->netdev_ops = &octeon_mgmt_ops; + netdev->ethtool_ops = &octeon_mgmt_ethtool_ops; + + + /* The mgmt ports get the first N MACs. */ + for (i = 0; i < 6; i++) + netdev->dev_addr[i] = octeon_bootinfo->mac_addr_base[i]; + netdev->dev_addr[5] += p->port; + + if (p->port >= octeon_bootinfo->mac_addr_count) + dev_err(&pdev->dev, + "Error %s: Using MAC outside of the assigned range: " + "%02x:%02x:%02x:%02x:%02x:%02x\n", netdev->name, + netdev->dev_addr[0], netdev->dev_addr[1], + netdev->dev_addr[2], netdev->dev_addr[3], + netdev->dev_addr[4], netdev->dev_addr[5]); + + if (register_netdev(netdev)) + goto err; + + dev_info(&pdev->dev, "Version " DRV_VERSION "\n"); + return 0; +err: + free_netdev(netdev); + return -ENOENT; +} + +static int __exit octeon_mgmt_remove(struct platform_device *pdev) +{ + struct net_device *netdev = dev_get_drvdata(&pdev->dev); + + unregister_netdev(netdev); + free_netdev(netdev); + return 0; +} + +static struct platform_driver octeon_mgmt_driver = { + .driver = { + .name = "octeon_mgmt", + .owner = THIS_MODULE, + }, + .probe = octeon_mgmt_probe, + .remove = __exit_p(octeon_mgmt_remove), +}; + +extern void octeon_mdiobus_force_mod_depencency(void); + +static int __init octeon_mgmt_mod_init(void) +{ + /* Force our mdiobus driver module to be loaded first. */ + octeon_mdiobus_force_mod_depencency(); + return platform_driver_register(&octeon_mgmt_driver); +} + +static void __exit octeon_mgmt_mod_exit(void) +{ + platform_driver_unregister(&octeon_mgmt_driver); +} + +module_init(octeon_mgmt_mod_init); +module_exit(octeon_mgmt_mod_exit); + +MODULE_DESCRIPTION(DRV_DESCRIPTION); +MODULE_AUTHOR("David Daney"); +MODULE_LICENSE("GPL"); +MODULE_VERSION(DRV_VERSION); -- cgit v0.10.2 From f6ed1b3b3579db5c8c3aaf6fd3010c706973a35d Mon Sep 17 00:00:00 2001 From: David Daney Date: Wed, 14 Oct 2009 12:04:42 -0700 Subject: Staging: octeon-ethernet: Convert to use PHY Abstraction Layer. The octeon-ethernet driver shares an mdio bus with the octeon-mgmt driver. Here we convert the octeon-ethernet driver to use the PHY Abstraction Layer. Signed-off-by: David Daney Signed-off-by: Ralf Baechle diff --git a/drivers/staging/octeon/Kconfig b/drivers/staging/octeon/Kconfig index 536e238..638ad6b 100644 --- a/drivers/staging/octeon/Kconfig +++ b/drivers/staging/octeon/Kconfig @@ -1,7 +1,8 @@ config OCTEON_ETHERNET tristate "Cavium Networks Octeon Ethernet support" depends on CPU_CAVIUM_OCTEON - select MII + select PHYLIB + select MDIO_OCTEON help This driver supports the builtin ethernet ports on Cavium Networks' products in the Octeon family. This driver supports the diff --git a/drivers/staging/octeon/ethernet-mdio.c b/drivers/staging/octeon/ethernet-mdio.c index 31a58e5..05a5cc0 100644 --- a/drivers/staging/octeon/ethernet-mdio.c +++ b/drivers/staging/octeon/ethernet-mdio.c @@ -26,7 +26,8 @@ **********************************************************************/ #include #include -#include +#include + #include #include @@ -34,86 +35,12 @@ #include "ethernet-defines.h" #include "octeon-ethernet.h" #include "ethernet-mdio.h" +#include "ethernet-util.h" #include "cvmx-helper-board.h" #include "cvmx-smix-defs.h" -DECLARE_MUTEX(mdio_sem); - -/** - * Perform an MII read. Called by the generic MII routines - * - * @dev: Device to perform read for - * @phy_id: The MII phy id - * @location: Register location to read - * Returns Result from the read or zero on failure - */ -static int cvm_oct_mdio_read(struct net_device *dev, int phy_id, int location) -{ - union cvmx_smix_cmd smi_cmd; - union cvmx_smix_rd_dat smi_rd; - - smi_cmd.u64 = 0; - smi_cmd.s.phy_op = 1; - smi_cmd.s.phy_adr = phy_id; - smi_cmd.s.reg_adr = location; - cvmx_write_csr(CVMX_SMIX_CMD(0), smi_cmd.u64); - - do { - if (!in_interrupt()) - yield(); - smi_rd.u64 = cvmx_read_csr(CVMX_SMIX_RD_DAT(0)); - } while (smi_rd.s.pending); - - if (smi_rd.s.val) - return smi_rd.s.dat; - else - return 0; -} - -static int cvm_oct_mdio_dummy_read(struct net_device *dev, int phy_id, - int location) -{ - return 0xffff; -} - -/** - * Perform an MII write. Called by the generic MII routines - * - * @dev: Device to perform write for - * @phy_id: The MII phy id - * @location: Register location to write - * @val: Value to write - */ -static void cvm_oct_mdio_write(struct net_device *dev, int phy_id, int location, - int val) -{ - union cvmx_smix_cmd smi_cmd; - union cvmx_smix_wr_dat smi_wr; - - smi_wr.u64 = 0; - smi_wr.s.dat = val; - cvmx_write_csr(CVMX_SMIX_WR_DAT(0), smi_wr.u64); - - smi_cmd.u64 = 0; - smi_cmd.s.phy_op = 0; - smi_cmd.s.phy_adr = phy_id; - smi_cmd.s.reg_adr = location; - cvmx_write_csr(CVMX_SMIX_CMD(0), smi_cmd.u64); - - do { - if (!in_interrupt()) - yield(); - smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(0)); - } while (smi_wr.s.pending); -} - -static void cvm_oct_mdio_dummy_write(struct net_device *dev, int phy_id, - int location, int val) -{ -} - static void cvm_oct_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { @@ -125,49 +52,37 @@ static void cvm_oct_get_drvinfo(struct net_device *dev, static int cvm_oct_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct octeon_ethernet *priv = netdev_priv(dev); - int ret; - down(&mdio_sem); - ret = mii_ethtool_gset(&priv->mii_info, cmd); - up(&mdio_sem); + if (priv->phydev) + return phy_ethtool_gset(priv->phydev, cmd); - return ret; + return -EINVAL; } static int cvm_oct_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct octeon_ethernet *priv = netdev_priv(dev); - int ret; - down(&mdio_sem); - ret = mii_ethtool_sset(&priv->mii_info, cmd); - up(&mdio_sem); + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + + if (priv->phydev) + return phy_ethtool_sset(priv->phydev, cmd); - return ret; + return -EINVAL; } static int cvm_oct_nway_reset(struct net_device *dev) { struct octeon_ethernet *priv = netdev_priv(dev); - int ret; - down(&mdio_sem); - ret = mii_nway_restart(&priv->mii_info); - up(&mdio_sem); + if (!capable(CAP_NET_ADMIN)) + return -EPERM; - return ret; -} + if (priv->phydev) + return phy_start_aneg(priv->phydev); -static u32 cvm_oct_get_link(struct net_device *dev) -{ - struct octeon_ethernet *priv = netdev_priv(dev); - u32 ret; - - down(&mdio_sem); - ret = mii_link_ok(&priv->mii_info); - up(&mdio_sem); - - return ret; + return -EINVAL; } const struct ethtool_ops cvm_oct_ethtool_ops = { @@ -175,7 +90,7 @@ const struct ethtool_ops cvm_oct_ethtool_ops = { .get_settings = cvm_oct_get_settings, .set_settings = cvm_oct_set_settings, .nway_reset = cvm_oct_nway_reset, - .get_link = cvm_oct_get_link, + .get_link = ethtool_op_get_link, .get_sg = ethtool_op_get_sg, .get_tx_csum = ethtool_op_get_tx_csum, }; @@ -191,41 +106,78 @@ const struct ethtool_ops cvm_oct_ethtool_ops = { int cvm_oct_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct octeon_ethernet *priv = netdev_priv(dev); - struct mii_ioctl_data *data = if_mii(rq); - unsigned int duplex_chg; - int ret; - down(&mdio_sem); - ret = generic_mii_ioctl(&priv->mii_info, data, cmd, &duplex_chg); - up(&mdio_sem); + if (!netif_running(dev)) + return -EINVAL; + + if (!priv->phydev) + return -EINVAL; + + return phy_mii_ioctl(priv->phydev, if_mii(rq), cmd); +} - return ret; +static void cvm_oct_adjust_link(struct net_device *dev) +{ + struct octeon_ethernet *priv = netdev_priv(dev); + cvmx_helper_link_info_t link_info; + + if (priv->last_link != priv->phydev->link) { + priv->last_link = priv->phydev->link; + link_info.u64 = 0; + link_info.s.link_up = priv->last_link ? 1 : 0; + link_info.s.full_duplex = priv->phydev->duplex ? 1 : 0; + link_info.s.speed = priv->phydev->speed; + cvmx_helper_link_set( priv->port, link_info); + if (priv->last_link) { + netif_carrier_on(dev); + if (priv->queue != -1) + DEBUGPRINT("%s: %u Mbps %s duplex, " + "port %2d, queue %2d\n", + dev->name, priv->phydev->speed, + priv->phydev->duplex ? + "Full" : "Half", + priv->port, priv->queue); + else + DEBUGPRINT("%s: %u Mbps %s duplex, " + "port %2d, POW\n", + dev->name, priv->phydev->speed, + priv->phydev->duplex ? + "Full" : "Half", + priv->port); + } else { + netif_carrier_off(dev); + DEBUGPRINT("%s: Link down\n", dev->name); + } + } } + /** - * Setup the MDIO device structures + * Setup the PHY * * @dev: Device to setup * * Returns Zero on success, negative on failure */ -int cvm_oct_mdio_setup_device(struct net_device *dev) +int cvm_oct_phy_setup_device(struct net_device *dev) { struct octeon_ethernet *priv = netdev_priv(dev); - int phy_id = cvmx_helper_board_get_mii_address(priv->port); - if (phy_id != -1) { - priv->mii_info.dev = dev; - priv->mii_info.phy_id = phy_id; - priv->mii_info.phy_id_mask = 0xff; - priv->mii_info.supports_gmii = 1; - priv->mii_info.reg_num_mask = 0x1f; - priv->mii_info.mdio_read = cvm_oct_mdio_read; - priv->mii_info.mdio_write = cvm_oct_mdio_write; - } else { - /* Supply dummy MDIO routines so the kernel won't crash - if the user tries to read them */ - priv->mii_info.mdio_read = cvm_oct_mdio_dummy_read; - priv->mii_info.mdio_write = cvm_oct_mdio_dummy_write; + + int phy_addr = cvmx_helper_board_get_mii_address(priv->port); + if (phy_addr != -1) { + char phy_id[20]; + + snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT, "0", phy_addr); + + priv->phydev = phy_connect(dev, phy_id, cvm_oct_adjust_link, 0, + PHY_INTERFACE_MODE_GMII); + + if (IS_ERR(priv->phydev)) { + priv->phydev = NULL; + return -1; + } + priv->last_link = 0; + phy_start_aneg(priv->phydev); } return 0; } diff --git a/drivers/staging/octeon/ethernet-mdio.h b/drivers/staging/octeon/ethernet-mdio.h index b3328ae..55d0614a 100644 --- a/drivers/staging/octeon/ethernet-mdio.h +++ b/drivers/staging/octeon/ethernet-mdio.h @@ -43,4 +43,4 @@ extern const struct ethtool_ops cvm_oct_ethtool_ops; int cvm_oct_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); -int cvm_oct_mdio_setup_device(struct net_device *dev); +int cvm_oct_phy_setup_device(struct net_device *dev); diff --git a/drivers/staging/octeon/ethernet-proc.c b/drivers/staging/octeon/ethernet-proc.c index 8fa88fc..16308d4 100644 --- a/drivers/staging/octeon/ethernet-proc.c +++ b/drivers/staging/octeon/ethernet-proc.c @@ -25,7 +25,6 @@ * Contact Cavium Networks for more information **********************************************************************/ #include -#include #include #include #include @@ -38,112 +37,6 @@ #include "cvmx-helper.h" #include "cvmx-pip.h" -static unsigned long long cvm_oct_stats_read_switch(struct net_device *dev, - int phy_id, int offset) -{ - struct octeon_ethernet *priv = netdev_priv(dev); - - priv->mii_info.mdio_write(dev, phy_id, 0x1d, 0xcc00 | offset); - return ((uint64_t) priv->mii_info. - mdio_read(dev, phy_id, - 0x1e) << 16) | (uint64_t) priv->mii_info. - mdio_read(dev, phy_id, 0x1f); -} - -static int cvm_oct_stats_switch_show(struct seq_file *m, void *v) -{ - static const int ports[] = { 0, 1, 2, 3, 9, -1 }; - struct net_device *dev = cvm_oct_device[0]; - int index = 0; - - while (ports[index] != -1) { - - /* Latch port */ - struct octeon_ethernet *priv = netdev_priv(dev); - - priv->mii_info.mdio_write(dev, 0x1b, 0x1d, - 0xdc00 | ports[index]); - seq_printf(m, "\nSwitch Port %d\n", ports[index]); - seq_printf(m, "InGoodOctets: %12llu\t" - "OutOctets: %12llu\t" - "64 Octets: %12llu\n", - cvm_oct_stats_read_switch(dev, 0x1b, - 0x00) | - (cvm_oct_stats_read_switch(dev, 0x1b, 0x01) << 32), - cvm_oct_stats_read_switch(dev, 0x1b, - 0x0E) | - (cvm_oct_stats_read_switch(dev, 0x1b, 0x0F) << 32), - cvm_oct_stats_read_switch(dev, 0x1b, 0x08)); - - seq_printf(m, "InBadOctets: %12llu\t" - "OutUnicast: %12llu\t" - "65-127 Octets: %12llu\n", - cvm_oct_stats_read_switch(dev, 0x1b, 0x02), - cvm_oct_stats_read_switch(dev, 0x1b, 0x10), - cvm_oct_stats_read_switch(dev, 0x1b, 0x09)); - - seq_printf(m, "InUnicast: %12llu\t" - "OutBroadcasts: %12llu\t" - "128-255 Octets: %12llu\n", - cvm_oct_stats_read_switch(dev, 0x1b, 0x04), - cvm_oct_stats_read_switch(dev, 0x1b, 0x13), - cvm_oct_stats_read_switch(dev, 0x1b, 0x0A)); - - seq_printf(m, "InBroadcasts: %12llu\t" - "OutMulticasts: %12llu\t" - "256-511 Octets: %12llu\n", - cvm_oct_stats_read_switch(dev, 0x1b, 0x06), - cvm_oct_stats_read_switch(dev, 0x1b, 0x12), - cvm_oct_stats_read_switch(dev, 0x1b, 0x0B)); - - seq_printf(m, "InMulticasts: %12llu\t" - "OutPause: %12llu\t" - "512-1023 Octets:%12llu\n", - cvm_oct_stats_read_switch(dev, 0x1b, 0x07), - cvm_oct_stats_read_switch(dev, 0x1b, 0x15), - cvm_oct_stats_read_switch(dev, 0x1b, 0x0C)); - - seq_printf(m, "InPause: %12llu\t" - "Excessive: %12llu\t" - "1024-Max Octets:%12llu\n", - cvm_oct_stats_read_switch(dev, 0x1b, 0x16), - cvm_oct_stats_read_switch(dev, 0x1b, 0x11), - cvm_oct_stats_read_switch(dev, 0x1b, 0x0D)); - - seq_printf(m, "InUndersize: %12llu\t" - "Collisions: %12llu\n", - cvm_oct_stats_read_switch(dev, 0x1b, 0x18), - cvm_oct_stats_read_switch(dev, 0x1b, 0x1E)); - - seq_printf(m, "InFragments: %12llu\t" - "Deferred: %12llu\n", - cvm_oct_stats_read_switch(dev, 0x1b, 0x19), - cvm_oct_stats_read_switch(dev, 0x1b, 0x05)); - - seq_printf(m, "InOversize: %12llu\t" - "Single: %12llu\n", - cvm_oct_stats_read_switch(dev, 0x1b, 0x1A), - cvm_oct_stats_read_switch(dev, 0x1b, 0x14)); - - seq_printf(m, "InJabber: %12llu\t" - "Multiple: %12llu\n", - cvm_oct_stats_read_switch(dev, 0x1b, 0x1B), - cvm_oct_stats_read_switch(dev, 0x1b, 0x17)); - - seq_printf(m, "In RxErr: %12llu\t" - "OutFCSErr: %12llu\n", - cvm_oct_stats_read_switch(dev, 0x1b, 0x1C), - cvm_oct_stats_read_switch(dev, 0x1b, 0x03)); - - seq_printf(m, "InFCSErr: %12llu\t" - "Late: %12llu\n", - cvm_oct_stats_read_switch(dev, 0x1b, 0x1D), - cvm_oct_stats_read_switch(dev, 0x1b, 0x1F)); - index++; - } - return 0; -} - /** * User is reading /proc/octeon_ethernet_stats * @@ -215,11 +108,6 @@ static int cvm_oct_stats_show(struct seq_file *m, void *v) } } - if (cvm_oct_device[0]) { - priv = netdev_priv(cvm_oct_device[0]); - if (priv->imode == CVMX_HELPER_INTERFACE_MODE_GMII) - cvm_oct_stats_switch_show(m, v); - } return 0; } diff --git a/drivers/staging/octeon/ethernet-rgmii.c b/drivers/staging/octeon/ethernet-rgmii.c index fbaa465..3820f1e 100644 --- a/drivers/staging/octeon/ethernet-rgmii.c +++ b/drivers/staging/octeon/ethernet-rgmii.c @@ -147,32 +147,36 @@ static void cvm_oct_rgmii_poll(struct net_device *dev) cvmx_write_csr(CVMX_GMXX_RXX_INT_REG(index, interface), gmxx_rxx_int_reg.u64); } - - link_info = cvmx_helper_link_autoconf(priv->port); - priv->link_info = link_info.u64; + if (priv->phydev == NULL) { + link_info = cvmx_helper_link_autoconf(priv->port); + priv->link_info = link_info.u64; + } spin_unlock_irqrestore(&global_register_lock, flags); - /* Tell Linux */ - if (link_info.s.link_up) { - - if (!netif_carrier_ok(dev)) - netif_carrier_on(dev); - if (priv->queue != -1) - DEBUGPRINT - ("%s: %u Mbps %s duplex, port %2d, queue %2d\n", - dev->name, link_info.s.speed, - (link_info.s.full_duplex) ? "Full" : "Half", - priv->port, priv->queue); - else - DEBUGPRINT("%s: %u Mbps %s duplex, port %2d, POW\n", - dev->name, link_info.s.speed, - (link_info.s.full_duplex) ? "Full" : "Half", - priv->port); - } else { - - if (netif_carrier_ok(dev)) - netif_carrier_off(dev); - DEBUGPRINT("%s: Link down\n", dev->name); + if (priv->phydev == NULL) { + /* Tell core. */ + if (link_info.s.link_up) { + if (!netif_carrier_ok(dev)) + netif_carrier_on(dev); + if (priv->queue != -1) + DEBUGPRINT("%s: %u Mbps %s duplex, " + "port %2d, queue %2d\n", + dev->name, link_info.s.speed, + (link_info.s.full_duplex) ? + "Full" : "Half", + priv->port, priv->queue); + else + DEBUGPRINT("%s: %u Mbps %s duplex, " + "port %2d, POW\n", + dev->name, link_info.s.speed, + (link_info.s.full_duplex) ? + "Full" : "Half", + priv->port); + } else { + if (netif_carrier_ok(dev)) + netif_carrier_off(dev); + DEBUGPRINT("%s: Link down\n", dev->name); + } } } diff --git a/drivers/staging/octeon/ethernet-sgmii.c b/drivers/staging/octeon/ethernet-sgmii.c index 2b54996..6061d01 100644 --- a/drivers/staging/octeon/ethernet-sgmii.c +++ b/drivers/staging/octeon/ethernet-sgmii.c @@ -113,7 +113,7 @@ int cvm_oct_sgmii_init(struct net_device *dev) struct octeon_ethernet *priv = netdev_priv(dev); cvm_oct_common_init(dev); dev->netdev_ops->ndo_stop(dev); - if (!octeon_is_simulation()) + if (!octeon_is_simulation() && priv->phydev == NULL) priv->poll = cvm_oct_sgmii_poll; /* FIXME: Need autoneg logic */ diff --git a/drivers/staging/octeon/ethernet-xaui.c b/drivers/staging/octeon/ethernet-xaui.c index 0c2e7cc..ee3dc41 100644 --- a/drivers/staging/octeon/ethernet-xaui.c +++ b/drivers/staging/octeon/ethernet-xaui.c @@ -112,7 +112,7 @@ int cvm_oct_xaui_init(struct net_device *dev) struct octeon_ethernet *priv = netdev_priv(dev); cvm_oct_common_init(dev); dev->netdev_ops->ndo_stop(dev); - if (!octeon_is_simulation()) + if (!octeon_is_simulation() && priv->phydev == NULL) priv->poll = cvm_oct_xaui_poll; return 0; diff --git a/drivers/staging/octeon/ethernet.c b/drivers/staging/octeon/ethernet.c index 492c502..4cfd4b1 100644 --- a/drivers/staging/octeon/ethernet.c +++ b/drivers/staging/octeon/ethernet.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include @@ -132,8 +132,6 @@ static struct timer_list cvm_oct_poll_timer; */ struct net_device *cvm_oct_device[TOTAL_NUMBER_OF_PORTS]; -extern struct semaphore mdio_sem; - /** * Periodic timer tick for slow management operations * @@ -160,13 +158,8 @@ static void cvm_do_timer(unsigned long arg) goto out; priv = netdev_priv(cvm_oct_device[port]); - if (priv->poll) { - /* skip polling if we don't get the lock */ - if (!down_trylock(&mdio_sem)) { - priv->poll(cvm_oct_device[port]); - up(&mdio_sem); - } - } + if (priv->poll) + priv->poll(cvm_oct_device[port]); queues_per_port = cvmx_pko_get_num_queues(port); /* Drain any pending packets in the free list */ @@ -524,7 +517,7 @@ int cvm_oct_common_init(struct net_device *dev) dev->features |= NETIF_F_LLTX; SET_ETHTOOL_OPS(dev, &cvm_oct_ethtool_ops); - cvm_oct_mdio_setup_device(dev); + cvm_oct_phy_setup_device(dev); dev->netdev_ops->ndo_set_mac_address(dev, &sa); dev->netdev_ops->ndo_change_mtu(dev, dev->mtu); @@ -540,7 +533,10 @@ int cvm_oct_common_init(struct net_device *dev) void cvm_oct_common_uninit(struct net_device *dev) { - /* Currently nothing to do */ + struct octeon_ethernet *priv = netdev_priv(dev); + + if (priv->phydev) + phy_disconnect(priv->phydev); } static const struct net_device_ops cvm_oct_npi_netdev_ops = { @@ -627,6 +623,8 @@ static const struct net_device_ops cvm_oct_pow_netdev_ops = { #endif }; +extern void octeon_mdiobus_force_mod_depencency(void); + /** * Module/ driver initialization. Creates the linux network * devices. @@ -640,6 +638,7 @@ static int __init cvm_oct_init_module(void) int fau = FAU_NUM_PACKET_BUFFERS_TO_FREE; int qos; + octeon_mdiobus_force_mod_depencency(); pr_notice("cavium-ethernet %s\n", OCTEON_ETHERNET_VERSION); if (OCTEON_IS_MODEL(OCTEON_CN52XX)) diff --git a/drivers/staging/octeon/octeon-ethernet.h b/drivers/staging/octeon/octeon-ethernet.h index 3aef987..402a15b 100644 --- a/drivers/staging/octeon/octeon-ethernet.h +++ b/drivers/staging/octeon/octeon-ethernet.h @@ -50,9 +50,9 @@ struct octeon_ethernet { /* List of outstanding tx buffers per queue */ struct sk_buff_head tx_free_list[16]; /* Device statistics */ - struct net_device_stats stats -; /* Generic MII info structure */ - struct mii_if_info mii_info; + struct net_device_stats stats; + struct phy_device *phydev; + unsigned int last_link; /* Last negotiated link state */ uint64_t link_info; /* Called periodically to check link status */ -- cgit v0.10.2 From 92078e0618f525e22945040b5daea21d4b6d4a16 Mon Sep 17 00:00:00 2001 From: David Daney Date: Wed, 14 Oct 2009 12:16:55 -0700 Subject: MIPS: Add drotr and dins instructions to uasm. Signed-off-by: David Daney Signed-off-by: Ralf Baechle diff --git a/arch/mips/mm/uasm.c b/arch/mips/mm/uasm.c index f467199..0a165c5 100644 --- a/arch/mips/mm/uasm.c +++ b/arch/mips/mm/uasm.c @@ -60,11 +60,11 @@ enum opcode { insn_beql, insn_bgez, insn_bgezl, insn_bltz, insn_bltzl, insn_bne, insn_cache, insn_daddu, insn_daddiu, insn_dmfc0, insn_dmtc0, insn_dsll, insn_dsll32, insn_dsra, insn_dsrl, - insn_dsrl32, insn_dsubu, insn_eret, insn_j, insn_jal, insn_jr, - insn_ld, insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0, + insn_dsrl32, insn_drotr, insn_dsubu, insn_eret, insn_j, insn_jal, + insn_jr, insn_ld, insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0, insn_mtc0, insn_ori, insn_pref, insn_rfe, insn_sc, insn_scd, insn_sd, insn_sll, insn_sra, insn_srl, insn_subu, insn_sw, - insn_tlbp, insn_tlbwi, insn_tlbwr, insn_xor, insn_xori + insn_tlbp, insn_tlbwi, insn_tlbwr, insn_xor, insn_xori, insn_dins }; struct insn { @@ -104,6 +104,7 @@ static struct insn insn_table[] __cpuinitdata = { { insn_dsra, M(spec_op, 0, 0, 0, 0, dsra_op), RT | RD | RE }, { insn_dsrl, M(spec_op, 0, 0, 0, 0, dsrl_op), RT | RD | RE }, { insn_dsrl32, M(spec_op, 0, 0, 0, 0, dsrl32_op), RT | RD | RE }, + { insn_drotr, M(spec_op, 1, 0, 0, 0, dsrl_op), RT | RD | RE }, { insn_dsubu, M(spec_op, 0, 0, 0, 0, dsubu_op), RS | RT | RD }, { insn_eret, M(cop0_op, cop_op, 0, 0, 0, eret_op), 0 }, { insn_j, M(j_op, 0, 0, 0, 0, 0), JIMM }, @@ -132,6 +133,7 @@ static struct insn insn_table[] __cpuinitdata = { { insn_tlbwr, M(cop0_op, cop_op, 0, 0, 0, tlbwr_op), 0 }, { insn_xor, M(spec_op, 0, 0, 0, 0, xor_op), RS | RT | RD }, { insn_xori, M(xori_op, 0, 0, 0, 0, 0), RS | RT | UIMM }, + { insn_dins, M(spec3_op, 0, 0, 0, 0, dins_op), RS | RT | RD | RE }, { insn_invalid, 0, 0 } }; @@ -304,6 +306,12 @@ Ip_u2u1s3(op) \ build_insn(buf, insn##op, b, a, c); \ } +#define I_u2u1msbu3(op) \ +Ip_u2u1msbu3(op) \ +{ \ + build_insn(buf, insn##op, b, a, c+d-1, c); \ +} + #define I_u1u2(op) \ Ip_u1u2(op) \ { \ @@ -349,6 +357,7 @@ I_u2u1u3(_dsll32) I_u2u1u3(_dsra) I_u2u1u3(_dsrl) I_u2u1u3(_dsrl32) +I_u2u1u3(_drotr) I_u3u1u2(_dsubu) I_0(_eret) I_u1(_j) @@ -377,6 +386,7 @@ I_0(_tlbwi) I_0(_tlbwr) I_u3u1u2(_xor) I_u2u1u3(_xori) +I_u2u1msbu3(_dins); /* Handle labels. */ void __cpuinit uasm_build_label(struct uasm_label **lab, u32 *addr, int lid) diff --git a/arch/mips/mm/uasm.h b/arch/mips/mm/uasm.h index c6d1e3d..3d153ed 100644 --- a/arch/mips/mm/uasm.h +++ b/arch/mips/mm/uasm.h @@ -34,6 +34,11 @@ uasm_i##op(u32 **buf, unsigned int a, signed int b, unsigned int c) void __cpuinit \ uasm_i##op(u32 **buf, unsigned int a, unsigned int b, signed int c) +#define Ip_u2u1msbu3(op) \ +void __cpuinit \ +uasm_i##op(u32 **buf, unsigned int a, unsigned int b, unsigned int c, \ + unsigned int d) + #define Ip_u1u2(op) \ void __cpuinit uasm_i##op(u32 **buf, unsigned int a, unsigned int b) @@ -65,6 +70,7 @@ Ip_u2u1u3(_dsll32); Ip_u2u1u3(_dsra); Ip_u2u1u3(_dsrl); Ip_u2u1u3(_dsrl32); +Ip_u2u1u3(_drotr); Ip_u3u1u2(_dsubu); Ip_0(_eret); Ip_u1(_j); @@ -93,6 +99,7 @@ Ip_0(_tlbwi); Ip_0(_tlbwr); Ip_u3u1u2(_xor); Ip_u2u1u3(_xori); +Ip_u2u1msbu3(_dins); /* Handle labels. */ struct uasm_label { -- cgit v0.10.2 From 82622284dd2f8791f9759f3cef601520a8bc63b2 Mon Sep 17 00:00:00 2001 From: David Daney Date: Wed, 14 Oct 2009 12:16:56 -0700 Subject: MIPS: Put PGD in C0_CONTEXT for 64-bit R2 processors. Processors that support the mips64r2 ISA can in four instructions convert a shifted PGD pointer stored in the upper bits of c0_context into a usable pointer. By doing this we save a memory load and associated potential cache miss in the TLB exception handlers. Since the upper bits of c0_context were holding the CPU number, we move this to the upper bits of c0_xcontext which doesn't have enough bits to hold the PGD pointer, but has plenty for the CPU number. Signed-off-by: David Daney Signed-off-by: Ralf Baechle diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index f6f3b99..20b223b 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -1427,6 +1427,9 @@ config CPU_SUPPORTS_64BIT_KERNEL bool config CPU_SUPPORTS_HUGEPAGES bool +config MIPS_PGD_C0_CONTEXT + bool + default y if 64BIT && CPU_MIPSR2 # # Set to y for ptrace access to watch registers. diff --git a/arch/mips/include/asm/mmu_context.h b/arch/mips/include/asm/mmu_context.h index 6083db5..145bb81 100644 --- a/arch/mips/include/asm/mmu_context.h +++ b/arch/mips/include/asm/mmu_context.h @@ -24,6 +24,33 @@ #endif /* SMTC */ #include +#ifdef CONFIG_MIPS_PGD_C0_CONTEXT + +#define TLBMISS_HANDLER_SETUP_PGD(pgd) \ + tlbmiss_handler_setup_pgd((unsigned long)(pgd)) + +static inline void tlbmiss_handler_setup_pgd(unsigned long pgd) +{ + /* Check for swapper_pg_dir and convert to physical address. */ + if ((pgd & CKSEG3) == CKSEG0) + pgd = CPHYSADDR(pgd); + write_c0_context(pgd << 11); +} + +#define TLBMISS_HANDLER_SETUP() \ + do { \ + TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir); \ + write_c0_xcontext((unsigned long) smp_processor_id() << 51); \ + } while (0) + + +static inline unsigned long get_current_pgd(void) +{ + return PHYS_TO_XKSEG_CACHED((read_c0_context() >> 11) & ~0xfffUL); +} + +#else /* CONFIG_MIPS_PGD_C0_CONTEXT: using pgd_current*/ + /* * For the fast tlb miss handlers, we keep a per cpu array of pointers * to the current pgd for each processor. Also, the proc. id is stuffed @@ -46,7 +73,7 @@ extern unsigned long pgd_current[]; back_to_back_c0_hazard(); \ TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir) #endif - +#endif /* CONFIG_MIPS_PGD_C0_CONTEXT*/ #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) #define ASID_INC 0x40 diff --git a/arch/mips/include/asm/stackframe.h b/arch/mips/include/asm/stackframe.h index dd7e220..3b6da33 100644 --- a/arch/mips/include/asm/stackframe.h +++ b/arch/mips/include/asm/stackframe.h @@ -87,15 +87,19 @@ #ifdef CONFIG_SMP #ifdef CONFIG_MIPS_MT_SMTC #define PTEBASE_SHIFT 19 /* TCBIND */ +#define CPU_ID_REG CP0_TCBIND +#define CPU_ID_MFC0 mfc0 +#elif defined(CONFIG_MIPS_PGD_C0_CONTEXT) +#define PTEBASE_SHIFT 48 /* XCONTEXT */ +#define CPU_ID_REG CP0_XCONTEXT +#define CPU_ID_MFC0 MFC0 #else #define PTEBASE_SHIFT 23 /* CONTEXT */ +#define CPU_ID_REG CP0_CONTEXT +#define CPU_ID_MFC0 MFC0 #endif .macro get_saved_sp /* SMP variation */ -#ifdef CONFIG_MIPS_MT_SMTC - mfc0 k0, CP0_TCBIND -#else - MFC0 k0, CP0_CONTEXT -#endif + CPU_ID_MFC0 k0, CPU_ID_REG #if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32) lui k1, %hi(kernelsp) #else @@ -111,11 +115,7 @@ .endm .macro set_saved_sp stackp temp temp2 -#ifdef CONFIG_MIPS_MT_SMTC - mfc0 \temp, CP0_TCBIND -#else - MFC0 \temp, CP0_CONTEXT -#endif + CPU_ID_MFC0 \temp, CPU_ID_REG LONG_SRL \temp, PTEBASE_SHIFT LONG_S \stackp, kernelsp(\temp) .endm diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index 8d1f4f3..9e8d003 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c @@ -462,7 +462,9 @@ void __init_refok free_initmem(void) __pa_symbol(&__init_end)); } +#ifndef CONFIG_MIPS_PGD_C0_CONTEXT unsigned long pgd_current[NR_CPUS]; +#endif /* * On 64-bit we've got three-level pagetables with a slightly * different layout ... diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index bb1719a..3d0baa4 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c @@ -160,6 +160,12 @@ static u32 tlb_handler[128] __cpuinitdata; static struct uasm_label labels[128] __cpuinitdata; static struct uasm_reloc relocs[128] __cpuinitdata; +#ifndef CONFIG_MIPS_PGD_C0_CONTEXT +/* + * CONFIG_MIPS_PGD_C0_CONTEXT implies 64 bit and lack of pgd_current, + * we cannot do r3000 under these circumstances. + */ + /* * The R3000 TLB handler is simple. */ @@ -199,6 +205,7 @@ static void __cpuinit build_r3000_tlb_refill_handler(void) dump_handler((u32 *)ebase, 32); } +#endif /* CONFIG_MIPS_PGD_C0_CONTEXT */ /* * The R4000 TLB handler is much more complicated. We have two @@ -497,8 +504,9 @@ static void __cpuinit build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r, unsigned int tmp, unsigned int ptr) { +#ifndef CONFIG_MIPS_PGD_C0_CONTEXT long pgdc = (long)pgd_current; - +#endif /* * The vmalloc handling is not in the hotpath. */ @@ -506,7 +514,15 @@ build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r, uasm_il_bltz(p, r, tmp, label_vmalloc); /* No uasm_i_nop needed here, since the next insn doesn't touch TMP. */ -#ifdef CONFIG_SMP +#ifdef CONFIG_MIPS_PGD_C0_CONTEXT + /* + * &pgd << 11 stored in CONTEXT [23..63]. + */ + UASM_i_MFC0(p, ptr, C0_CONTEXT); + uasm_i_dins(p, ptr, 0, 0, 23); /* Clear lower 23 bits of context. */ + uasm_i_ori(p, ptr, ptr, 0x540); /* 1 0 1 0 1 << 6 xkphys cached */ + uasm_i_drotr(p, ptr, ptr, 11); +#elif defined(CONFIG_SMP) # ifdef CONFIG_MIPS_MT_SMTC /* * SMTC uses TCBind value as "CPU" index @@ -520,7 +536,7 @@ build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r, */ uasm_i_dmfc0(p, ptr, C0_CONTEXT); uasm_i_dsrl(p, ptr, ptr, 23); -#endif +# endif UASM_i_LA_mostly(p, tmp, pgdc); uasm_i_daddu(p, ptr, ptr, tmp); uasm_i_dmfc0(p, tmp, C0_BADVADDR); @@ -1033,6 +1049,7 @@ build_pte_modifiable(u32 **p, struct uasm_reloc **r, iPTE_LW(p, pte, ptr); } +#ifndef CONFIG_MIPS_PGD_C0_CONTEXT /* * R3000 style TLB load/store/modify handlers. */ @@ -1184,6 +1201,7 @@ static void __cpuinit build_r3000_tlb_modify_handler(void) dump_handler(handle_tlbm, ARRAY_SIZE(handle_tlbm)); } +#endif /* CONFIG_MIPS_PGD_C0_CONTEXT */ /* * R4000 style TLB load/store/modify handlers. @@ -1400,6 +1418,7 @@ void __cpuinit build_tlb_refill_handler(void) case CPU_TX3912: case CPU_TX3922: case CPU_TX3927: +#ifndef CONFIG_MIPS_PGD_C0_CONTEXT build_r3000_tlb_refill_handler(); if (!run_once) { build_r3000_tlb_load_handler(); @@ -1407,6 +1426,9 @@ void __cpuinit build_tlb_refill_handler(void) build_r3000_tlb_modify_handler(); run_once++; } +#else + panic("No R3000 TLB refill handler"); +#endif break; case CPU_R6000: -- cgit v0.10.2 From c1b14a7545e26fc08ea524b58ac590304484ce4f Mon Sep 17 00:00:00 2001 From: Dmitri Vorobiev Date: Wed, 14 Oct 2009 22:02:17 +0300 Subject: MIPS: MIPSsim: Remove unused code The function prom_init_cmdline() doesn't do anything, and nobody calls the prom_getcmdline() function. Since these two are the only functions in the file arch/mips/mipssim/sim_cmdline.c, the whole file can be removed now along with the call to the no-op prom_init_cmdline() routine. Signed-off-by: Dmitri Vorobiev Patchwork: http://patchwork.linux-mips.org/patch/465/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/mipssim/Makefile b/arch/mips/mipssim/Makefile index 57f43c1..41b9657 100644 --- a/arch/mips/mipssim/Makefile +++ b/arch/mips/mipssim/Makefile @@ -17,8 +17,7 @@ # 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. # -obj-y := sim_platform.o sim_setup.o sim_mem.o sim_time.o sim_int.o \ - sim_cmdline.o +obj-y := sim_platform.o sim_setup.o sim_mem.o sim_time.o sim_int.o obj-$(CONFIG_EARLY_PRINTK) += sim_console.o obj-$(CONFIG_MIPS_MT_SMTC) += sim_smtc.o diff --git a/arch/mips/mipssim/sim_cmdline.c b/arch/mips/mipssim/sim_cmdline.c deleted file mode 100644 index 74240e1..0000000 --- a/arch/mips/mipssim/sim_cmdline.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved. - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - */ -#include -#include -#include - -extern char arcs_cmdline[]; - -char * __init prom_getcmdline(void) -{ - return arcs_cmdline; -} - -void __init prom_init_cmdline(void) -{ - /* XXX: Get boot line from environment? */ -} diff --git a/arch/mips/mipssim/sim_setup.c b/arch/mips/mipssim/sim_setup.c index 2877675..0824f6a 100644 --- a/arch/mips/mipssim/sim_setup.c +++ b/arch/mips/mipssim/sim_setup.c @@ -61,7 +61,6 @@ void __init prom_init(void) set_io_port_base(0xbfd00000); pr_info("\nLINUX started...\n"); - prom_init_cmdline(); prom_meminit(); #ifdef CONFIG_MIPS_MT_SMP -- cgit v0.10.2 From 659da2ba3ebf53dc49f7f9a357a1aef046bf3139 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Fri, 16 Oct 2009 14:17:15 +0800 Subject: MIPS: Loongson: Register reserved memory pages Register reserved pages for Loongson family machines. Signed-off-by: Wu Zhangjin Cc: Linux-MIPS Cc: yanh@lemote.com, Cc: huhb@lemote.com Cc: Zhang Le Cc: zhangfx@lemote.com, Signed-off-by: Ralf Baechle diff --git a/arch/mips/loongson/common/mem.c b/arch/mips/loongson/common/mem.c index e94ef15..3f7f153 100644 --- a/arch/mips/loongson/common/mem.c +++ b/arch/mips/loongson/common/mem.c @@ -12,14 +12,22 @@ #include #include +#include void __init prom_init_memory(void) { add_memory_region(0x0, (memsize << 20), BOOT_MEM_RAM); + + add_memory_region(memsize << 20, LOONGSON_PCI_MEM_START - (memsize << + 20), BOOT_MEM_RESERVED); #ifdef CONFIG_64BIT if (highmemsize > 0) add_memory_region(LOONGSON_HIGHMEM_START, highmemsize << 20, BOOT_MEM_RAM); + + add_memory_region(LOONGSON_PCI_MEM_END + 1, LOONGSON_HIGHMEM_START - + LOONGSON_PCI_MEM_END - 1, BOOT_MEM_RESERVED); + #endif /* CONFIG_64BIT */ } -- cgit v0.10.2 From f6d4ff02c60e18797279270d09791768e43cd269 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Fri, 16 Oct 2009 14:17:14 +0800 Subject: MIPS: Fuloong2e: Cleanup Kconfig Changes indention from whitespace to tabs in arch/mips/loongson/Kconfig. Signed-off-by: Wu Zhangjin Cc: Linux-MIPS Cc: yanh@lemote.com Cc: huhb@lemote.com Cc: Zhang Le Cc: zhangfx@lemote.com Signed-off-by: Ralf Baechle diff --git a/arch/mips/loongson/Kconfig b/arch/mips/loongson/Kconfig index d450925..818a028 100644 --- a/arch/mips/loongson/Kconfig +++ b/arch/mips/loongson/Kconfig @@ -1,31 +1,31 @@ choice - prompt "Machine Type" - depends on MACH_LOONGSON + prompt "Machine Type" + depends on MACH_LOONGSON config LEMOTE_FULOONG2E - bool "Lemote Fuloong(2e) mini-PC" - select ARCH_SPARSEMEM_ENABLE - select CEVT_R4K - select CSRC_R4K - select SYS_HAS_CPU_LOONGSON2E - select DMA_NONCOHERENT - select BOOT_ELF32 - select BOARD_SCACHE - select HW_HAS_PCI - select I8259 - select ISA - select IRQ_CPU - select SYS_SUPPORTS_32BIT_KERNEL - select SYS_SUPPORTS_64BIT_KERNEL - select SYS_SUPPORTS_LITTLE_ENDIAN - select SYS_SUPPORTS_HIGHMEM - select SYS_HAS_EARLY_PRINTK - select GENERIC_HARDIRQS_NO__DO_IRQ - select GENERIC_ISA_DMA_SUPPORT_BROKEN - select CPU_HAS_WB - help - Lemote Fuloong(2e) mini-PC board based on the Chinese Loongson-2E CPU and - an FPGA northbridge + bool "Lemote Fuloong(2e) mini-PC" + select ARCH_SPARSEMEM_ENABLE + select CEVT_R4K + select CSRC_R4K + select SYS_HAS_CPU_LOONGSON2E + select DMA_NONCOHERENT + select BOOT_ELF32 + select BOARD_SCACHE + select HW_HAS_PCI + select I8259 + select ISA + select IRQ_CPU + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_64BIT_KERNEL + select SYS_SUPPORTS_LITTLE_ENDIAN + select SYS_SUPPORTS_HIGHMEM + select SYS_HAS_EARLY_PRINTK + select GENERIC_HARDIRQS_NO__DO_IRQ + select GENERIC_ISA_DMA_SUPPORT_BROKEN + select CPU_HAS_WB + help + Lemote Fuloong(2e) mini-PC board based on the Chinese Loongson-2E CPU and + an FPGA northbridge - Lemote Fuloong(2e) mini PC have a VIA686B south bridge. + Lemote Fuloong(2e) mini PC have a VIA686B south bridge. endchoice -- cgit v0.10.2 From db54ff246eae5acb6b7dffec2c05e682f91e0f4e Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Fri, 16 Oct 2009 14:17:16 +0800 Subject: MIPS: Loongson early_printk: Fix variable type of uart_base The uart_base variable here is not a physical address, so, we replace it by unsigned char *. Signed-off-by: Wu Zhangjin Cc: Linux-MIPS Cc: yanh@lemote.com Cc: huhb@lemote.com Cc: Zhang Le Cc: zhangfx@lemote.com Signed-off-by: Ralf Baechle diff --git a/arch/mips/loongson/common/early_printk.c b/arch/mips/loongson/common/early_printk.c index bc73edc..8ec4fb2 100644 --- a/arch/mips/loongson/common/early_printk.c +++ b/arch/mips/loongson/common/early_printk.c @@ -1,7 +1,7 @@ /* early printk support * * Copyright (c) 2009 Philippe Vachon - * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology + * Copyright (c) 2009 Lemote Inc. * Author: Wu Zhangjin, wuzj@lemote.com * * This program is free software; you can redistribute it and/or modify it @@ -16,20 +16,20 @@ #define PORT(base, offset) (u8 *)(base + offset) -static inline unsigned int serial_in(phys_addr_t base, int offset) +static inline unsigned int serial_in(unsigned char *base, int offset) { return readb(PORT(base, offset)); } -static inline void serial_out(phys_addr_t base, int offset, int value) +static inline void serial_out(unsigned char *base, int offset, int value) { writeb(value, PORT(base, offset)); } void prom_putchar(char c) { - phys_addr_t uart_base = - (phys_addr_t) ioremap_nocache(LOONGSON_UART_BASE, 8); + unsigned char *uart_base = + (unsigned char *) ioremap_nocache(LOONGSON_UART_BASE, 8); while ((serial_in(uart_base, UART_LSR) & UART_LSR_THRE) == 0) ; -- cgit v0.10.2 From e8be5283881cb96bafb751e1f9ea34c4e6fc2845 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Fri, 16 Oct 2009 14:17:18 +0800 Subject: MIPS: Loongson: Add serial port support This patch add serial port support for all of the existing loongson family machines. most of the board specific part are put in serial.c, and the base address of the serial ports are defined as macros in machine.h for sharing it between serial.c and early_printk.c Signed-off-by: Wu Zhangjin Cc: Linux-MIPS Cc: yanh@lemote.com Cc: huhb@lemote.com Cc: Zhang Le Cc: zhangfx@lemote.com Signed-off-by: Ralf Baechle diff --git a/arch/mips/loongson/common/Makefile b/arch/mips/loongson/common/Makefile index 656b3cc..d21d116 100644 --- a/arch/mips/loongson/common/Makefile +++ b/arch/mips/loongson/common/Makefile @@ -9,3 +9,4 @@ obj-y += setup.o init.o cmdline.o env.o time.o reset.o irq.o \ # Early printk support # obj-$(CONFIG_EARLY_PRINTK) += early_printk.o +obj-$(CONFIG_SERIAL_8250) += serial.o diff --git a/arch/mips/loongson/common/serial.c b/arch/mips/loongson/common/serial.c new file mode 100644 index 0000000..6d341e4 --- /dev/null +++ b/arch/mips/loongson/common/serial.c @@ -0,0 +1,71 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.org) + * + * Copyright (C) 2009 Lemote, Inc. + * Author: Yan hua (yanhua@lemote.com) + * Author: Wu Zhangjin (wuzj@lemote.com) + */ + +#include +#include +#include + +#include + +#include +#include + +#define PORT(int) \ +{ \ + .irq = int, \ + .uartclk = 1843200, \ + .iobase = (LOONGSON_UART_BASE - LOONGSON_PCIIO_BASE),\ + .iotype = UPIO_PORT, \ + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, \ + .regshift = 0, \ +} + +#define PORT_M(int) \ +{ \ + .irq = MIPS_CPU_IRQ_BASE + (int), \ + .uartclk = 3686400, \ + .iotype = UPIO_MEM, \ + .membase = (void __iomem *)NULL, \ + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, \ + .regshift = 0, \ +} + +static struct plat_serial8250_port uart8250_data[][2] = { + [MACH_LOONGSON_UNKNOWN] {}, + [MACH_LEMOTE_FL2E] {PORT(4), {} }, + [MACH_LEMOTE_FL2F] {PORT(3), {} }, + [MACH_LEMOTE_ML2F7] {PORT_M(3), {} }, + [MACH_LEMOTE_YL2F89] {PORT_M(3), {} }, + [MACH_DEXXON_GDIUM2F10] {PORT_M(3), {} }, + [MACH_LOONGSON_END] {}, +}; + +static struct platform_device uart8250_device = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM, + .dev = { + .platform_data = uart8250_data[LOONGSON_MACHTYPE], + }, +}; + +static int __init serial_init(void) +{ + if (uart8250_data[LOONGSON_MACHTYPE][0].iotype == UPIO_MEM) + uart8250_data[LOONGSON_MACHTYPE][0].membase = + ioremap_nocache(LOONGSON_UART_BASE, 8); + + platform_device_register(&uart8250_device); + + return 0; +} + +device_initcall(serial_init); -- cgit v0.10.2 From e2fee5723bbda4a05c86f16a9d0f889a2c4ecede Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Fri, 16 Oct 2009 14:17:19 +0800 Subject: MIPS: Bonito64: Make Loongson independent from Bonito64 code. The built-in Loongson 2E/2F northbridge in is bonito64-compatible but not identical with it. To avoid influencing the original bonito64 support and make the loongson support more maintainable, it's better to separate the Bonito64 code from the Loongson code. This also prepares the kernel for the coming Loongson 2f machines family support. Signed-off-by: Wu Zhangjin Cc: Linux-MIPS Cc: yanh@lemote.com Cc: huhb@lemote.com Cc: Zhang Le Cc: zhangfx@lemote.com, Signed-off-by: Ralf Baechle diff --git a/arch/mips/include/asm/mach-loongson/loongson.h b/arch/mips/include/asm/mach-loongson/loongson.h index da70bcf..e6869aa 100644 --- a/arch/mips/include/asm/mach-loongson/loongson.h +++ b/arch/mips/include/asm/mach-loongson/loongson.h @@ -15,9 +15,6 @@ #include #include -/* there is an internal bonito64-compatiable northbridge in loongson2e/2f */ -#include - /* loongson internal northbridge initialization */ extern void bonito_irq_init(void); @@ -41,24 +38,181 @@ extern void __init set_irq_trigger_mode(void); extern void __init mach_init_irq(void); extern void mach_irq_dispatch(unsigned int pending); +#define LOONGSON_REG(x) \ + (*(volatile u32 *)((char *)CKSEG1ADDR(LOONGSON_REG_BASE) + (x))) + +#define LOONGSON_IRQ_BASE 32 +#define LOONGSON2_PERFCNT_IRQ (MIPS_CPU_IRQ_BASE + 6) /* cpu perf counter */ + +#define LOONGSON_FLASH_BASE 0x1c000000 +#define LOONGSON_FLASH_SIZE 0x02000000 /* 32M */ +#define LOONGSON_FLASH_TOP (LOONGSON_FLASH_BASE+LOONGSON_FLASH_SIZE-1) + +#define LOONGSON_LIO0_BASE 0x1e000000 +#define LOONGSON_LIO0_SIZE 0x01C00000 /* 28M */ +#define LOONGSON_LIO0_TOP (LOONGSON_LIO0_BASE+LOONGSON_LIO0_SIZE-1) + +#define LOONGSON_BOOT_BASE 0x1fc00000 +#define LOONGSON_BOOT_SIZE 0x00100000 /* 1M */ +#define LOONGSON_BOOT_TOP (LOONGSON_BOOT_BASE+LOONGSON_BOOT_SIZE-1) +#define LOONGSON_REG_BASE 0x1fe00000 +#define LOONGSON_REG_SIZE 0x00100000 /* 256Bytes + 256Bytes + ??? */ +#define LOONGSON_REG_TOP (LOONGSON_REG_BASE+LOONGSON_REG_SIZE-1) + +#define LOONGSON_LIO1_BASE 0x1ff00000 +#define LOONGSON_LIO1_SIZE 0x00100000 /* 1M */ +#define LOONGSON_LIO1_TOP (LOONGSON_LIO1_BASE+LOONGSON_LIO1_SIZE-1) + +#define LOONGSON_PCILO0_BASE 0x10000000 +#define LOONGSON_PCILO1_BASE 0x14000000 +#define LOONGSON_PCILO2_BASE 0x18000000 +#define LOONGSON_PCILO_BASE LOONGSON_PCILO0_BASE +#define LOONGSON_PCILO_SIZE 0x0c000000 /* 64M * 3 */ +#define LOONGSON_PCILO_TOP (LOONGSON_PCILO0_BASE+LOONGSON_PCILO_SIZE-1) + +#define LOONGSON_PCICFG_BASE 0x1fe80000 +#define LOONGSON_PCICFG_SIZE 0x00000800 /* 2K */ +#define LOONGSON_PCICFG_TOP (LOONGSON_PCICFG_BASE+LOONGSON_PCICFG_SIZE-1) +#define LOONGSON_PCIIO_BASE 0x1fd00000 +#define LOONGSON_PCIIO_SIZE 0x00100000 /* 1M */ +#define LOONGSON_PCIIO_TOP (LOONGSON_PCIIO_BASE+LOONGSON_PCIIO_SIZE-1) + +/* Loongson Register Bases */ + +#define LOONGSON_PCICONFIGBASE 0x00 +#define LOONGSON_REGBASE 0x100 + /* PCI Configuration Registers */ -#define LOONGSON_PCI_ISR4C BONITO_PCI_REG(0x4c) + +#define LOONGSON_PCI_REG(x) LOONGSON_REG(LOONGSON_PCICONFIGBASE + (x)) +#define LOONGSON_PCIDID LOONGSON_PCI_REG(0x00) +#define LOONGSON_PCICMD LOONGSON_PCI_REG(0x04) +#define LOONGSON_PCICLASS LOONGSON_PCI_REG(0x08) +#define LOONGSON_PCILTIMER LOONGSON_PCI_REG(0x0c) +#define LOONGSON_PCIBASE0 LOONGSON_PCI_REG(0x10) +#define LOONGSON_PCIBASE1 LOONGSON_PCI_REG(0x14) +#define LOONGSON_PCIBASE2 LOONGSON_PCI_REG(0x18) +#define LOONGSON_PCIBASE3 LOONGSON_PCI_REG(0x1c) +#define LOONGSON_PCIBASE4 LOONGSON_PCI_REG(0x20) +#define LOONGSON_PCIEXPRBASE LOONGSON_PCI_REG(0x30) +#define LOONGSON_PCIINT LOONGSON_PCI_REG(0x3c) + +#define LOONGSON_PCI_ISR4C LOONGSON_PCI_REG(0x4c) + +#define LOONGSON_PCICMD_PERR_CLR 0x80000000 +#define LOONGSON_PCICMD_SERR_CLR 0x40000000 +#define LOONGSON_PCICMD_MABORT_CLR 0x20000000 +#define LOONGSON_PCICMD_MTABORT_CLR 0x10000000 +#define LOONGSON_PCICMD_TABORT_CLR 0x08000000 +#define LOONGSON_PCICMD_MPERR_CLR 0x01000000 +#define LOONGSON_PCICMD_PERRRESPEN 0x00000040 +#define LOONGSON_PCICMD_ASTEPEN 0x00000080 +#define LOONGSON_PCICMD_SERREN 0x00000100 +#define LOONGSON_PCILTIMER_BUSLATENCY 0x0000ff00 +#define LOONGSON_PCILTIMER_BUSLATENCY_SHIFT 8 + +/* Loongson h/w Configuration */ + +#define LOONGSON_GENCFG_OFFSET 0x4 +#define LOONGSON_GENCFG LOONGSON_REG(LOONGSON_REGBASE + LOONGSON_GENCFG_OFFSET) + +#define LOONGSON_GENCFG_DEBUGMODE 0x00000001 +#define LOONGSON_GENCFG_SNOOPEN 0x00000002 +#define LOONGSON_GENCFG_CPUSELFRESET 0x00000004 + +#define LOONGSON_GENCFG_FORCE_IRQA 0x00000008 +#define LOONGSON_GENCFG_IRQA_ISOUT 0x00000010 +#define LOONGSON_GENCFG_IRQA_FROM_INT1 0x00000020 +#define LOONGSON_GENCFG_BYTESWAP 0x00000040 + +#define LOONGSON_GENCFG_UNCACHED 0x00000080 +#define LOONGSON_GENCFG_PREFETCHEN 0x00000100 +#define LOONGSON_GENCFG_WBEHINDEN 0x00000200 +#define LOONGSON_GENCFG_CACHEALG 0x00000c00 +#define LOONGSON_GENCFG_CACHEALG_SHIFT 10 +#define LOONGSON_GENCFG_PCIQUEUE 0x00001000 +#define LOONGSON_GENCFG_CACHESTOP 0x00002000 +#define LOONGSON_GENCFG_MSTRBYTESWAP 0x00004000 +#define LOONGSON_GENCFG_BUSERREN 0x00008000 +#define LOONGSON_GENCFG_NORETRYTIMEOUT 0x00010000 +#define LOONGSON_GENCFG_SHORTCOPYTIMEOUT 0x00020000 + +/* PCI address map control */ + +#define LOONGSON_PCIMAP LOONGSON_REG(LOONGSON_REGBASE + 0x10) +#define LOONGSON_PCIMEMBASECFG LOONGSON_REG(LOONGSON_REGBASE + 0x14) +#define LOONGSON_PCIMAP_CFG LOONGSON_REG(LOONGSON_REGBASE + 0x18) + +/* GPIO Regs - r/w */ + +#define LOONGSON_GPIODATA LOONGSON_REG(LOONGSON_REGBASE + 0x1c) +#define LOONGSON_GPIOIE LOONGSON_REG(LOONGSON_REGBASE + 0x20) + +/* ICU Configuration Regs - r/w */ + +#define LOONGSON_INTEDGE LOONGSON_REG(LOONGSON_REGBASE + 0x24) +#define LOONGSON_INTSTEER LOONGSON_REG(LOONGSON_REGBASE + 0x28) +#define LOONGSON_INTPOL LOONGSON_REG(LOONGSON_REGBASE + 0x2c) + +/* ICU Enable Regs - IntEn & IntISR are r/o. */ + +#define LOONGSON_INTENSET LOONGSON_REG(LOONGSON_REGBASE + 0x30) +#define LOONGSON_INTENCLR LOONGSON_REG(LOONGSON_REGBASE + 0x34) +#define LOONGSON_INTEN LOONGSON_REG(LOONGSON_REGBASE + 0x38) +#define LOONGSON_INTISR LOONGSON_REG(LOONGSON_REGBASE + 0x3c) + +/* ICU */ +#define LOONGSON_ICU_MBOXES 0x0000000f +#define LOONGSON_ICU_MBOXES_SHIFT 0 +#define LOONGSON_ICU_DMARDY 0x00000010 +#define LOONGSON_ICU_DMAEMPTY 0x00000020 +#define LOONGSON_ICU_COPYRDY 0x00000040 +#define LOONGSON_ICU_COPYEMPTY 0x00000080 +#define LOONGSON_ICU_COPYERR 0x00000100 +#define LOONGSON_ICU_PCIIRQ 0x00000200 +#define LOONGSON_ICU_MASTERERR 0x00000400 +#define LOONGSON_ICU_SYSTEMERR 0x00000800 +#define LOONGSON_ICU_DRAMPERR 0x00001000 +#define LOONGSON_ICU_RETRYERR 0x00002000 +#define LOONGSON_ICU_GPIOS 0x01ff0000 +#define LOONGSON_ICU_GPIOS_SHIFT 16 +#define LOONGSON_ICU_GPINS 0x7e000000 +#define LOONGSON_ICU_GPINS_SHIFT 25 +#define LOONGSON_ICU_MBOX(N) (1<<(LOONGSON_ICU_MBOXES_SHIFT+(N))) +#define LOONGSON_ICU_GPIO(N) (1<<(LOONGSON_ICU_GPIOS_SHIFT+(N))) +#define LOONGSON_ICU_GPIN(N) (1<<(LOONGSON_ICU_GPINS_SHIFT+(N))) + +/* PCI prefetch window base & mask */ + +#define LOONGSON_MEM_WIN_BASE_L LOONGSON_REG(LOONGSON_REGBASE + 0x40) +#define LOONGSON_MEM_WIN_BASE_H LOONGSON_REG(LOONGSON_REGBASE + 0x44) +#define LOONGSON_MEM_WIN_MASK_L LOONGSON_REG(LOONGSON_REGBASE + 0x48) +#define LOONGSON_MEM_WIN_MASK_H LOONGSON_REG(LOONGSON_REGBASE + 0x4c) /* PCI_Hit*_Sel_* */ -#define LOONGSON_PCI_HIT0_SEL_L BONITO(BONITO_REGBASE + 0x50) -#define LOONGSON_PCI_HIT0_SEL_H BONITO(BONITO_REGBASE + 0x54) -#define LOONGSON_PCI_HIT1_SEL_L BONITO(BONITO_REGBASE + 0x58) -#define LOONGSON_PCI_HIT1_SEL_H BONITO(BONITO_REGBASE + 0x5c) -#define LOONGSON_PCI_HIT2_SEL_L BONITO(BONITO_REGBASE + 0x60) -#define LOONGSON_PCI_HIT2_SEL_H BONITO(BONITO_REGBASE + 0x64) +#define LOONGSON_PCI_HIT0_SEL_L LOONGSON_REG(LOONGSON_REGBASE + 0x50) +#define LOONGSON_PCI_HIT0_SEL_H LOONGSON_REG(LOONGSON_REGBASE + 0x54) +#define LOONGSON_PCI_HIT1_SEL_L LOONGSON_REG(LOONGSON_REGBASE + 0x58) +#define LOONGSON_PCI_HIT1_SEL_H LOONGSON_REG(LOONGSON_REGBASE + 0x5c) +#define LOONGSON_PCI_HIT2_SEL_L LOONGSON_REG(LOONGSON_REGBASE + 0x60) +#define LOONGSON_PCI_HIT2_SEL_H LOONGSON_REG(LOONGSON_REGBASE + 0x64) /* PXArb Config & Status */ -#define LOONGSON_PXARB_CFG BONITO(BONITO_REGBASE + 0x68) -#define LOONGSON_PXARB_STATUS BONITO(BONITO_REGBASE + 0x6c) +#define LOONGSON_PXARB_CFG LOONGSON_REG(LOONGSON_REGBASE + 0x68) +#define LOONGSON_PXARB_STATUS LOONGSON_REG(LOONGSON_REGBASE + 0x6c) + +/* pcimap */ -/* loongson2-specific perf counter IRQ */ -#define LOONGSON2_PERFCNT_IRQ (MIPS_CPU_IRQ_BASE + 6) +#define LOONGSON_PCIMAP_PCIMAP_LO0 0x0000003f +#define LOONGSON_PCIMAP_PCIMAP_LO0_SHIFT 0 +#define LOONGSON_PCIMAP_PCIMAP_LO1 0x00000fc0 +#define LOONGSON_PCIMAP_PCIMAP_LO1_SHIFT 6 +#define LOONGSON_PCIMAP_PCIMAP_LO2 0x0003f000 +#define LOONGSON_PCIMAP_PCIMAP_LO2_SHIFT 12 +#define LOONGSON_PCIMAP_PCIMAP_2 0x00040000 +#define LOONGSON_PCIMAP_WIN(WIN, ADDR) \ + ((((ADDR)>>26) & LOONGSON_PCIMAP_PCIMAP_LO0) << ((WIN)*6)) #endif /* __ASM_MACH_LOONGSON_LOONGSON_H */ diff --git a/arch/mips/include/asm/mach-loongson/machine.h b/arch/mips/include/asm/mach-loongson/machine.h index 206ea20..ea5954c 100644 --- a/arch/mips/include/asm/mach-loongson/machine.h +++ b/arch/mips/include/asm/mach-loongson/machine.h @@ -13,7 +13,7 @@ #ifdef CONFIG_LEMOTE_FULOONG2E -#define LOONGSON_UART_BASE (BONITO_PCIIO_BASE + 0x3f8) +#define LOONGSON_UART_BASE (LOONGSON_PCIIO_BASE + 0x3f8) #define LOONGSON_MACHTYPE MACH_LEMOTE_FL2E diff --git a/arch/mips/include/asm/mach-loongson/pci.h b/arch/mips/include/asm/mach-loongson/pci.h index f1663ca..576487c 100644 --- a/arch/mips/include/asm/mach-loongson/pci.h +++ b/arch/mips/include/asm/mach-loongson/pci.h @@ -22,13 +22,13 @@ #ifndef __ASM_MACH_LOONGSON_PCI_H_ #define __ASM_MACH_LOONGSON_PCI_H_ -extern struct pci_ops bonito64_pci_ops; +extern struct pci_ops loongson_pci_ops; #ifdef CONFIG_LEMOTE_FULOONG2E /* this pci memory space is mapped by pcimap in pci.c */ -#define LOONGSON_PCI_MEM_START BONITO_PCILO1_BASE -#define LOONGSON_PCI_MEM_END (BONITO_PCILO1_BASE + 0x04000000 * 2) +#define LOONGSON_PCI_MEM_START LOONGSON_PCILO1_BASE +#define LOONGSON_PCI_MEM_END (LOONGSON_PCILO1_BASE + 0x04000000 * 2) /* this is an offset from mips_io_port_base */ #define LOONGSON_PCI_IO_START 0x00004000UL diff --git a/arch/mips/include/asm/mips-boards/bonito64.h b/arch/mips/include/asm/mips-boards/bonito64.h index a576ce0..d14e2ad 100644 --- a/arch/mips/include/asm/mips-boards/bonito64.h +++ b/arch/mips/include/asm/mips-boards/bonito64.h @@ -26,11 +26,6 @@ /* offsets from base register */ #define BONITO(x) (x) -#elif defined(CONFIG_LEMOTE_FULOONG2E) - -#define BONITO(x) (*(volatile u32 *)((char *)CKSEG1ADDR(BONITO_REG_BASE) + (x))) -#define BONITO_IRQ_BASE 32 - #else /* diff --git a/arch/mips/loongson/common/bonito-irq.c b/arch/mips/loongson/common/bonito-irq.c index 3e31e7a..a1cbd11 100644 --- a/arch/mips/loongson/common/bonito-irq.c +++ b/arch/mips/loongson/common/bonito-irq.c @@ -17,13 +17,13 @@ static inline void bonito_irq_enable(unsigned int irq) { - BONITO_INTENSET = (1 << (irq - BONITO_IRQ_BASE)); + LOONGSON_INTENSET = (1 << (irq - LOONGSON_IRQ_BASE)); mmiowb(); } static inline void bonito_irq_disable(unsigned int irq) { - BONITO_INTENCLR = (1 << (irq - BONITO_IRQ_BASE)); + LOONGSON_INTENCLR = (1 << (irq - LOONGSON_IRQ_BASE)); mmiowb(); } @@ -44,8 +44,8 @@ void bonito_irq_init(void) { u32 i; - for (i = BONITO_IRQ_BASE; i < BONITO_IRQ_BASE + 32; i++) + for (i = LOONGSON_IRQ_BASE; i < LOONGSON_IRQ_BASE + 32; i++) set_irq_chip_and_handler(i, &bonito_irq_type, handle_level_irq); - setup_irq(BONITO_IRQ_BASE + 10, &dma_timeout_irqaction); + setup_irq(LOONGSON_IRQ_BASE + 10, &dma_timeout_irqaction); } diff --git a/arch/mips/loongson/common/init.c b/arch/mips/loongson/common/init.c index 3abe927..b7e4913 100644 --- a/arch/mips/loongson/common/init.c +++ b/arch/mips/loongson/common/init.c @@ -18,7 +18,7 @@ void __init prom_init(void) { /* init base address of io space */ set_io_port_base((unsigned long) - ioremap(BONITO_PCIIO_BASE, BONITO_PCIIO_SIZE)); + ioremap(LOONGSON_PCIIO_BASE, LOONGSON_PCIIO_SIZE)); prom_init_cmdline(); prom_init_env(); diff --git a/arch/mips/loongson/common/irq.c b/arch/mips/loongson/common/irq.c index b32b4a3..20e7328 100644 --- a/arch/mips/loongson/common/irq.c +++ b/arch/mips/loongson/common/irq.c @@ -20,21 +20,21 @@ void bonito_irqdispatch(void) int i; /* workaround the IO dma problem: let cpu looping to allow DMA finish */ - int_status = BONITO_INTISR; + int_status = LOONGSON_INTISR; if (int_status & (1 << 10)) { while (int_status & (1 << 10)) { udelay(1); - int_status = BONITO_INTISR; + int_status = LOONGSON_INTISR; } } /* Get pending sources, masked by current enables */ - int_status = BONITO_INTISR & BONITO_INTEN; + int_status = LOONGSON_INTISR & LOONGSON_INTEN; if (int_status != 0) { i = __ffs(int_status); int_status &= ~(1 << i); - do_IRQ(BONITO_IRQ_BASE + i); + do_IRQ(LOONGSON_IRQ_BASE + i); } } @@ -60,13 +60,13 @@ void __init arch_init_irq(void) set_irq_trigger_mode(); /* no steer */ - BONITO_INTSTEER = 0; + LOONGSON_INTSTEER = 0; /* * Mask out all interrupt by writing "1" to all bit position in * the interrupt reset reg. */ - BONITO_INTENCLR = ~0; + LOONGSON_INTENCLR = ~0; /* machine specific irq init */ mach_init_irq(); diff --git a/arch/mips/loongson/common/pci.c b/arch/mips/loongson/common/pci.c index a3a4abf..a7eb8b9 100644 --- a/arch/mips/loongson/common/pci.c +++ b/arch/mips/loongson/common/pci.c @@ -27,7 +27,7 @@ static struct resource loongson_pci_io_resource = { }; static struct pci_controller loongson_pci_controller = { - .pci_ops = &bonito64_pci_ops, + .pci_ops = &loongson_pci_ops, .io_resource = &loongson_pci_io_resource, .mem_resource = &loongson_pci_mem_resource, .mem_offset = 0x00000000UL, @@ -44,15 +44,15 @@ static void __init setup_pcimap(void) * pcimap: PCI_MAP2 PCI_Mem_Lo2 PCI_Mem_Lo1 PCI_Mem_Lo0 * [<2G] [384M,448M] [320M,384M] [0M,64M] */ - BONITO_PCIMAP = BONITO_PCIMAP_PCIMAP_2 | - BONITO_PCIMAP_WIN(2, BONITO_PCILO2_BASE) | - BONITO_PCIMAP_WIN(1, BONITO_PCILO1_BASE) | - BONITO_PCIMAP_WIN(0, 0); + LOONGSON_PCIMAP = LOONGSON_PCIMAP_PCIMAP_2 | + LOONGSON_PCIMAP_WIN(2, LOONGSON_PCILO2_BASE) | + LOONGSON_PCIMAP_WIN(1, LOONGSON_PCILO1_BASE) | + LOONGSON_PCIMAP_WIN(0, 0); /* * PCI-DMA to local mapping: [2G,2G+256M] -> [0M,256M] */ - BONITO_PCIBASE0 = 0x80000000ul; /* base: 2G -> mmap: 0M */ + LOONGSON_PCIBASE0 = 0x80000000ul; /* base: 2G -> mmap: 0M */ /* size: 256M, burst transmission, pre-fetch enable, 64bit */ LOONGSON_PCI_HIT0_SEL_L = 0xc000000cul; LOONGSON_PCI_HIT0_SEL_H = 0xfffffffful; diff --git a/arch/mips/loongson/common/reset.c b/arch/mips/loongson/common/reset.c index 97e9182..d57f171 100644 --- a/arch/mips/loongson/common/reset.c +++ b/arch/mips/loongson/common/reset.c @@ -22,7 +22,7 @@ static void loongson_restart(char *command) mach_prepare_reboot(); /* reboot via jumping to boot base address */ - ((void (*)(void))ioremap_nocache(BONITO_BOOT_BASE, 4)) (); + ((void (*)(void))ioremap_nocache(LOONGSON_BOOT_BASE, 4)) (); } static void loongson_halt(void) diff --git a/arch/mips/loongson/fuloong-2e/irq.c b/arch/mips/loongson/fuloong-2e/irq.c index 7888cf6..320e937 100644 --- a/arch/mips/loongson/fuloong-2e/irq.c +++ b/arch/mips/loongson/fuloong-2e/irq.c @@ -47,8 +47,8 @@ static struct irqaction cascade_irqaction = { void __init set_irq_trigger_mode(void) { /* most bonito irq should be level triggered */ - BONITO_INTEDGE = BONITO_ICU_SYSTEMERR | BONITO_ICU_MASTERERR | - BONITO_ICU_RETRYERR | BONITO_ICU_MBOXES; + LOONGSON_INTEDGE = LOONGSON_ICU_SYSTEMERR | LOONGSON_ICU_MASTERERR | + LOONGSON_ICU_RETRYERR | LOONGSON_ICU_MBOXES; } void __init mach_init_irq(void) diff --git a/arch/mips/loongson/fuloong-2e/reset.c b/arch/mips/loongson/fuloong-2e/reset.c index 677fe18..fc16c67 100644 --- a/arch/mips/loongson/fuloong-2e/reset.c +++ b/arch/mips/loongson/fuloong-2e/reset.c @@ -14,8 +14,8 @@ void mach_prepare_reboot(void) { - BONITO_BONGENCFG &= ~(1 << 2); - BONITO_BONGENCFG |= (1 << 2); + LOONGSON_GENCFG &= ~(1 << 2); + LOONGSON_GENCFG |= (1 << 2); } void mach_prepare_shutdown(void) diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index 91bfe73..0610c86 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile @@ -28,7 +28,7 @@ obj-$(CONFIG_MIPS_COBALT) += fixup-cobalt.o obj-$(CONFIG_SOC_AU1500) += fixup-au1000.o ops-au1000.o obj-$(CONFIG_SOC_AU1550) += fixup-au1000.o ops-au1000.o obj-$(CONFIG_SOC_PNX8550) += fixup-pnx8550.o ops-pnx8550.o -obj-$(CONFIG_LEMOTE_FULOONG2E) += fixup-fuloong2e.o ops-bonito64.o +obj-$(CONFIG_LEMOTE_FULOONG2E) += fixup-fuloong2e.o ops-fuloong2e.o obj-$(CONFIG_MIPS_MALTA) += fixup-malta.o obj-$(CONFIG_PMC_MSP7120_GW) += fixup-pmcmsp.o ops-pmcmsp.o obj-$(CONFIG_PMC_MSP7120_EVAL) += fixup-pmcmsp.o ops-pmcmsp.o diff --git a/arch/mips/pci/fixup-fuloong2e.c b/arch/mips/pci/fixup-fuloong2e.c index 0c4c7a8..4f6d8da 100644 --- a/arch/mips/pci/fixup-fuloong2e.c +++ b/arch/mips/pci/fixup-fuloong2e.c @@ -13,7 +13,8 @@ */ #include #include -#include + +#include /* South bridge slot number is set by the pci probe process */ static u8 sb_slot = 5; @@ -35,7 +36,7 @@ int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) break; } } else { - irq = BONITO_IRQ_BASE + 25 + pin; + irq = LOONGSON_IRQ_BASE + 25 + pin; } return irq; diff --git a/arch/mips/pci/ops-bonito64.c b/arch/mips/pci/ops-bonito64.c index 54e55e7..1b3e03f 100644 --- a/arch/mips/pci/ops-bonito64.c +++ b/arch/mips/pci/ops-bonito64.c @@ -29,13 +29,8 @@ #define PCI_ACCESS_READ 0 #define PCI_ACCESS_WRITE 1 -#ifdef CONFIG_LEMOTE_FULOONG2E -#define CFG_SPACE_REG(offset) (void *)CKSEG1ADDR(BONITO_PCICFG_BASE | (offset)) -#define ID_SEL_BEGIN 11 -#else #define CFG_SPACE_REG(offset) (void *)CKSEG1ADDR(_pcictrl_bonito_pcicfg + (offset)) #define ID_SEL_BEGIN 10 -#endif #define MAX_DEV_NUM (31 - ID_SEL_BEGIN) @@ -77,10 +72,8 @@ static int bonito64_pcibios_config_access(unsigned char access_type, addrp = CFG_SPACE_REG(addr & 0xffff); if (access_type == PCI_ACCESS_WRITE) { writel(cpu_to_le32(*data), addrp); -#ifndef CONFIG_LEMOTE_FULOONG2E /* Wait till done */ while (BONITO_PCIMSTAT & 0xF); -#endif } else { *data = le32_to_cpu(readl(addrp)); } diff --git a/arch/mips/pci/ops-fuloong2e.c b/arch/mips/pci/ops-fuloong2e.c new file mode 100644 index 0000000..171f65c --- /dev/null +++ b/arch/mips/pci/ops-fuloong2e.c @@ -0,0 +1,154 @@ +/* + * fuloong2e specific PCI support. + * + * Copyright (C) 1999, 2000, 2004 MIPS Technologies, Inc. + * All rights reserved. + * Authors: Carsten Langgaard + * Maciej W. Rozycki + * + * Copyright (C) 2009 Lemote Inc. + * Author: Wu Zhangjin + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include + +#include + +#define PCI_ACCESS_READ 0 +#define PCI_ACCESS_WRITE 1 + +#define CFG_SPACE_REG(offset) \ + (void *)CKSEG1ADDR(LOONGSON_PCICFG_BASE | (offset)) +#define ID_SEL_BEGIN 11 +#define MAX_DEV_NUM (31 - ID_SEL_BEGIN) + + +static int loongson_pcibios_config_access(unsigned char access_type, + struct pci_bus *bus, + unsigned int devfn, int where, + u32 *data) +{ + u32 busnum = bus->number; + u32 addr, type; + u32 dummy; + void *addrp; + int device = PCI_SLOT(devfn); + int function = PCI_FUNC(devfn); + int reg = where & ~3; + + if (busnum == 0) { + /* Type 0 configuration for onboard PCI bus */ + if (device > MAX_DEV_NUM) + return -1; + + addr = (1 << (device + ID_SEL_BEGIN)) | (function << 8) | reg; + type = 0; + } else { + /* Type 1 configuration for offboard PCI bus */ + addr = (busnum << 16) | (device << 11) | (function << 8) | reg; + type = 0x10000; + } + + /* Clear aborts */ + LOONGSON_PCICMD |= LOONGSON_PCICMD_MABORT_CLR | \ + LOONGSON_PCICMD_MTABORT_CLR; + + LOONGSON_PCIMAP_CFG = (addr >> 16) | type; + + /* Flush Bonito register block */ + dummy = LOONGSON_PCIMAP_CFG; + mmiowb(); + + addrp = CFG_SPACE_REG(addr & 0xffff); + if (access_type == PCI_ACCESS_WRITE) + writel(cpu_to_le32(*data), addrp); + else + *data = le32_to_cpu(readl(addrp)); + + /* Detect Master/Target abort */ + if (LOONGSON_PCICMD & (LOONGSON_PCICMD_MABORT_CLR | + LOONGSON_PCICMD_MTABORT_CLR)) { + /* Error occurred */ + + /* Clear bits */ + LOONGSON_PCICMD |= (LOONGSON_PCICMD_MABORT_CLR | + LOONGSON_PCICMD_MTABORT_CLR); + + return -1; + } + + return 0; + +} + + +/* + * We can't address 8 and 16 bit words directly. Instead we have to + * read/write a 32bit word and mask/modify the data we actually want. + */ +static int loongson_pcibios_read(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 *val) +{ + u32 data = 0; + + if ((size == 2) && (where & 1)) + return PCIBIOS_BAD_REGISTER_NUMBER; + else if ((size == 4) && (where & 3)) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (loongson_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where, + &data)) + return -1; + + if (size == 1) + *val = (data >> ((where & 3) << 3)) & 0xff; + else if (size == 2) + *val = (data >> ((where & 3) << 3)) & 0xffff; + else + *val = data; + + return PCIBIOS_SUCCESSFUL; +} + +static int loongson_pcibios_write(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 val) +{ + u32 data = 0; + + if ((size == 2) && (where & 1)) + return PCIBIOS_BAD_REGISTER_NUMBER; + else if ((size == 4) && (where & 3)) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (size == 4) + data = val; + else { + if (loongson_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, + where, &data)) + return -1; + + if (size == 1) + data = (data & ~(0xff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + else if (size == 2) + data = (data & ~(0xffff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + } + + if (loongson_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn, where, + &data)) + return -1; + + return PCIBIOS_SUCCESSFUL; +} + +struct pci_ops loongson_pci_ops = { + .read = loongson_pcibios_read, + .write = loongson_pcibios_write +}; -- cgit v0.10.2 From 0e8cccc40665a2943f2bf93b9036579e85a716f4 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Fri, 16 Oct 2009 14:17:20 +0800 Subject: MIPS: Fuloong 2E: Update defconfig file Enable hibernation support by default. Also enable sparsemem to avoid the hibernation failures with flatmem and save memory wasted by flatmem. Signed-off-by: Wu Zhangjin Cc: Linux-MIPS Cc: yanh@lemote.com Cc: huhb@lemote.com Cc: Zhang Le Cc: zhangfx@lemote.com Signed-off-by: Ralf Baechle diff --git a/arch/mips/configs/fuloong2e_defconfig b/arch/mips/configs/fuloong2e_defconfig index 0197f0d..b3626de 100644 --- a/arch/mips/configs/fuloong2e_defconfig +++ b/arch/mips/configs/fuloong2e_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31-rc1 -# Thu Jul 2 22:37:00 2009 +# Linux kernel version: 2.6.32-rc4 +# Fri Oct 16 13:18:01 2009 # CONFIG_MIPS=y @@ -12,6 +12,7 @@ CONFIG_MIPS=y # CONFIG_AR7 is not set # CONFIG_BASLER_EXCITE is not set # CONFIG_BCM47XX is not set +# CONFIG_BCM63XX is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set @@ -105,6 +106,8 @@ CONFIG_CPU_LOONGSON2E=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set # CONFIG_CPU_CAVIUM_OCTEON is not set +CONFIG_SYS_SUPPORTS_ZBOOT=y +CONFIG_SYS_SUPPORTS_ZBOOT_UART16550=y CONFIG_CPU_LOONGSON2=y CONFIG_SYS_HAS_CPU_LOONGSON2E=y CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y @@ -135,12 +138,16 @@ CONFIG_SYS_SUPPORTS_HIGHMEM=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y +# CONFIG_FLATMEM_MANUAL is not set # CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_SPARSEMEM_MANUAL=y +CONFIG_SPARSEMEM=y +CONFIG_HAVE_MEMORY_PRESENT=y CONFIG_SPARSEMEM_STATIC=y + +# +# Memory hotplug is currently incompatible with Software Suspend +# CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_PHYS_ADDR_T_64BIT=y @@ -148,6 +155,7 @@ CONFIG_ZONE_DMA_FLAG=0 CONFIG_VIRT_TO_BUS=y CONFIG_HAVE_MLOCK=y CONFIG_HAVE_MLOCKED_PAGE_BIT=y +# CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 CONFIG_TICK_ONESHOT=y CONFIG_NO_HZ=y @@ -180,6 +188,12 @@ CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 CONFIG_LOCALVERSION="-fuloong2e" # CONFIG_LOCALVERSION_AUTO is not set +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_BZIP2=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_BZIP2 is not set +# CONFIG_KERNEL_LZMA is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y @@ -193,11 +207,12 @@ CONFIG_BSD_PROCESS_ACCT=y # # RCU Subsystem # -CONFIG_CLASSIC_RCU=y -# CONFIG_TREE_RCU is not set -# CONFIG_PREEMPT_RCU is not set +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=64 +# CONFIG_RCU_FANOUT_EXACT is not set # CONFIG_TREE_RCU_TRACE is not set -# CONFIG_PREEMPT_RCU_TRACE is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 @@ -235,18 +250,16 @@ CONFIG_SHMEM=y CONFIG_AIO=y # -# Performance Counters +# Kernel Performance Events And Counters # CONFIG_VM_EVENT_COUNTERS=y CONFIG_PCI_QUIRKS=y -# CONFIG_STRIP_ASM_SYMS is not set # CONFIG_COMPAT_BRK is not set CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set CONFIG_PROFILING=y CONFIG_TRACEPOINTS=y -CONFIG_MARKERS=y CONFIG_OPROFILE=m CONFIG_HAVE_OPROFILE=y CONFIG_HAVE_SYSCALL_WRAPPERS=y @@ -255,8 +268,8 @@ CONFIG_HAVE_SYSCALL_WRAPPERS=y # GCOV-based kernel profiling # # CONFIG_GCOV_KERNEL is not set -# CONFIG_SLOW_WORK is not set -# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set +CONFIG_SLOW_WORK=y +CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y CONFIG_BASE_SMALL=0 @@ -283,7 +296,7 @@ CONFIG_IOSCHED_CFQ=y CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="cfq" -# CONFIG_FREEZER is not set +CONFIG_FREEZER=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) @@ -321,9 +334,14 @@ CONFIG_ARCH_HIBERNATION_POSSIBLE=y CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_PM=y # CONFIG_PM_DEBUG is not set +CONFIG_PM_SLEEP=y # CONFIG_SUSPEND is not set -# CONFIG_HIBERNATION is not set +CONFIG_HIBERNATION_NVS=y +CONFIG_HIBERNATION=y +CONFIG_PM_STD_PARTITION="/dev/hda3" +# CONFIG_PM_RUNTIME is not set CONFIG_NET=y +CONFIG_COMPAT_NETLINK_MESSAGES=y # # Networking options @@ -442,6 +460,7 @@ CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m # CONFIG_IP_DCCP is not set # CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set @@ -473,6 +492,7 @@ CONFIG_NET_CLS_ROUTE=y # CONFIG_AF_RXRPC is not set CONFIG_WIRELESS=y # CONFIG_CFG80211 is not set +CONFIG_CFG80211_DEFAULT_PS_VALUE=0 CONFIG_WIRELESS_OLD_REGULATORY=y CONFIG_WIRELESS_EXT=y CONFIG_WIRELESS_EXT_SYSFS=y @@ -481,7 +501,6 @@ CONFIG_WIRELESS_EXT_SYSFS=y # # CFG80211 needs to be enabled for MAC80211 # -CONFIG_MAC80211_DEFAULT_PS_VALUE=0 # CONFIG_WIMAX is not set # CONFIG_RFKILL is not set CONFIG_NET_9P=m @@ -495,6 +514,7 @@ CONFIG_NET_9P=m # Generic Driver Options # CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_DEVTMPFS is not set CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y CONFIG_FW_LOADER=m @@ -504,9 +524,9 @@ CONFIG_EXTRA_FIRMWARE="" # CONFIG_CONNECTOR is not set CONFIG_MTD=m # CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_TESTS is not set # CONFIG_MTD_CONCAT is not set # CONFIG_MTD_PARTITIONS is not set -# CONFIG_MTD_TESTS is not set # # User Modules And Translation Layers @@ -820,6 +840,7 @@ CONFIG_8139TOO=y # CONFIG_SUNDANCE is not set # CONFIG_TLAN is not set # CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set # CONFIG_VIA_RHINE is not set # CONFIG_SC92031 is not set # CONFIG_ATL2 is not set @@ -867,10 +888,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_SFC is not set # CONFIG_BE2NET is not set # CONFIG_TR is not set - -# -# Wireless LAN -# +CONFIG_WLAN=y # CONFIG_WLAN_PRE80211 is not set # CONFIG_WLAN_80211 is not set @@ -886,6 +904,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_USB_PEGASUS is not set # CONFIG_USB_RTL8150 is not set # CONFIG_USB_USBNET is not set +# CONFIG_USB_CDC_PHONET is not set # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -933,12 +952,16 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # Input Device Drivers # CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ADP5588 is not set CONFIG_KEYBOARD_ATKBD=y -# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_QT2160 is not set # CONFIG_KEYBOARD_LKKBD is not set -# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_MAX7359 is not set # CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_OPENCORES is not set # CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set CONFIG_INPUT_MOUSE=y CONFIG_MOUSE_PS2=y CONFIG_MOUSE_PS2_ALPS=y @@ -946,6 +969,7 @@ CONFIG_MOUSE_PS2_LOGIPS2PP=y CONFIG_MOUSE_PS2_SYNAPTICS=y CONFIG_MOUSE_PS2_TRACKPOINT=y # CONFIG_MOUSE_PS2_ELANTECH is not set +# CONFIG_MOUSE_PS2_SENTELIC is not set # CONFIG_MOUSE_PS2_TOUCHKIT is not set CONFIG_MOUSE_SERIAL=y # CONFIG_MOUSE_APPLETOUCH is not set @@ -1015,6 +1039,7 @@ CONFIG_RTC=y CONFIG_DEVPORT=y CONFIG_I2C=m CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y CONFIG_I2C_CHARDEV=m CONFIG_I2C_HELPER_AUTO=y @@ -1070,9 +1095,6 @@ CONFIG_I2C_VIAPRO=m # Miscellaneous I2C Chip support # # CONFIG_DS1682 is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_PCF8575 is not set -# CONFIG_SENSORS_PCA9539 is not set # CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set @@ -1088,7 +1110,6 @@ CONFIG_I2C_VIAPRO=m # CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set # CONFIG_THERMAL is not set -# CONFIG_THERMAL_HWMON is not set # CONFIG_WATCHDOG is not set CONFIG_SSB_POSSIBLE=y @@ -1105,6 +1126,7 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set # CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set # CONFIG_MFD_PCF50633 is not set # CONFIG_AB3100_CORE is not set @@ -1114,6 +1136,7 @@ CONFIG_SSB_POSSIBLE=y # # Graphics support # +CONFIG_VGA_ARB=y # CONFIG_DRM is not set # CONFIG_VGASTATE is not set CONFIG_VIDEO_OUTPUT_CONTROL=m @@ -1198,6 +1221,7 @@ CONFIG_FONT_8x16=y # CONFIG_LOGO is not set CONFIG_SOUND=y CONFIG_SOUND_OSS_CORE=y +CONFIG_SOUND_OSS_CORE_PRECLAIM=y CONFIG_SND=m CONFIG_SND_TIMER=m CONFIG_SND_PCM=m @@ -1304,7 +1328,6 @@ CONFIG_SND_USB=y CONFIG_AC97_BUS=m CONFIG_HID_SUPPORT=y CONFIG_HID=y -# CONFIG_HID_DEBUG is not set CONFIG_HIDRAW=y # @@ -1356,6 +1379,7 @@ CONFIG_USB_EHCI_TT_NEWSCHED=y # CONFIG_USB_OXU210HP_HCD is not set # CONFIG_USB_ISP116X_HCD is not set CONFIG_USB_ISP1760_HCD=m +# CONFIG_USB_ISP1362_HCD is not set CONFIG_USB_OHCI_HCD=y # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set # CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set @@ -1453,6 +1477,7 @@ CONFIG_UIO_CIF=m # CONFIG_UIO_SMX is not set # CONFIG_UIO_AEC is not set # CONFIG_UIO_SERCOS3 is not set +# CONFIG_UIO_PCI_GENERIC is not set # # TI VLYNQ @@ -1469,10 +1494,10 @@ CONFIG_EXT3_FS=y # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set # CONFIG_EXT3_FS_XATTR is not set CONFIG_EXT4_FS=m -CONFIG_EXT4DEV_COMPAT=y CONFIG_EXT4_FS_XATTR=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y +# CONFIG_EXT4_DEBUG is not set CONFIG_FS_XIP=y CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set @@ -1489,6 +1514,7 @@ CONFIG_FS_POSIX_ACL=y # CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set # CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set CONFIG_FILE_LOCKING=y CONFIG_FSNOTIFY=y CONFIG_DNOTIFY=y @@ -1557,7 +1583,6 @@ CONFIG_OMFS_FS=m # CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set -# CONFIG_NILFS2_FS is not set CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=m CONFIG_NFS_V3=y @@ -1666,6 +1691,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y # CONFIG_ENABLE_MUST_CHECK is not set CONFIG_FRAME_WARN=2048 # CONFIG_MAGIC_SYSRQ is not set +# CONFIG_STRIP_ASM_SYMS is not set # CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set @@ -1678,6 +1704,7 @@ CONFIG_NOP_TRACER=y CONFIG_RING_BUFFER=y CONFIG_EVENT_TRACING=y CONFIG_CONTEXT_SWITCH_TRACER=y +CONFIG_RING_BUFFER_ALLOW_SWAP=y CONFIG_TRACING=y CONFIG_TRACING_SUPPORT=y # CONFIG_FTRACE is not set @@ -1742,11 +1769,13 @@ CONFIG_CRYPTO_XTS=m # CONFIG_CRYPTO_HMAC=y # CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set # # Digest # # CONFIG_CRYPTO_CRC32C is not set +CONFIG_CRYPTO_GHASH=m # CONFIG_CRYPTO_MD4 is not set CONFIG_CRYPTO_MD5=m # CONFIG_CRYPTO_MICHAEL_MIC is not set -- cgit v0.10.2 From 32028f1f7bce32e72183129dc55fc23656e7081c Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 17 Dec 2009 01:57:07 +0000 Subject: MIPS: Remove addinitrd and CONFIG_PROBE_INITRD_HEADER Addinitrd has been superseded by initramfs ages ago. Signed-off-by: Ralf Baechle diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 20b223b..a16b6df 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -2041,15 +2041,6 @@ config STACKTRACE_SUPPORT source "init/Kconfig" -config PROBE_INITRD_HEADER - bool "Probe initrd header created by addinitrd" - depends on BLK_DEV_INITRD - help - Probe initrd header at the last page of kernel image. - Say Y here if you are using arch/mips/boot/addinitrd.c to - add initrd or initramfs image to the kernel image. - Otherwise, say N. - source "kernel/Kconfig.freezer" menu "Bus options (PCI, PCMCIA, EISA, ISA, TC)" diff --git a/arch/mips/boot/Makefile b/arch/mips/boot/Makefile index 2a209d7..094bc84 100644 --- a/arch/mips/boot/Makefile +++ b/arch/mips/boot/Makefile @@ -25,7 +25,7 @@ strip-flags = $(addprefix --remove-section=,$(drop-sections)) VMLINUX = vmlinux -all: vmlinux.ecoff vmlinux.srec addinitrd +all: vmlinux.ecoff vmlinux.srec vmlinux.ecoff: $(obj)/elf2ecoff $(VMLINUX) $(obj)/elf2ecoff $(VMLINUX) vmlinux.ecoff $(E2EFLAGS) @@ -39,11 +39,7 @@ vmlinux.bin: $(VMLINUX) vmlinux.srec: $(VMLINUX) $(OBJCOPY) -S -O srec $(strip-flags) $(VMLINUX) $(obj)/vmlinux.srec -$(obj)/addinitrd: $(obj)/addinitrd.c - $(HOSTCC) -o $@ $^ - -clean-files += addinitrd \ - elf2ecoff \ +clean-files += elf2ecoff \ vmlinux.bin \ vmlinux.ecoff \ vmlinux.srec diff --git a/arch/mips/boot/addinitrd.c b/arch/mips/boot/addinitrd.c deleted file mode 100644 index b5b3feb..0000000 --- a/arch/mips/boot/addinitrd.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - * addinitrd - program to add a initrd image to an ecoff kernel - * - * (C) 1999 Thomas Bogendoerfer - * minor modifications, cleanup: Guido Guenther - * further cleanup: Maciej W. Rozycki - */ - -#include -#include -#include -#include -#include -#include - -#include "ecoff.h" - -#define MIPS_PAGE_SIZE 4096 -#define MIPS_PAGE_MASK (MIPS_PAGE_SIZE-1) - -#define swab16(x) \ - ((unsigned short)( \ - (((unsigned short)(x) & (unsigned short)0x00ffU) << 8) | \ - (((unsigned short)(x) & (unsigned short)0xff00U) >> 8) )) - -#define swab32(x) \ - ((unsigned int)( \ - (((unsigned int)(x) & (unsigned int)0x000000ffUL) << 24) | \ - (((unsigned int)(x) & (unsigned int)0x0000ff00UL) << 8) | \ - (((unsigned int)(x) & (unsigned int)0x00ff0000UL) >> 8) | \ - (((unsigned int)(x) & (unsigned int)0xff000000UL) >> 24) )) - -#define SWAB(a) (swab ? swab32(a) : (a)) - -void die(char *s) -{ - perror(s); - exit(1); -} - -int main(int argc, char *argv[]) -{ - int fd_vmlinux, fd_initrd, fd_outfile; - FILHDR efile; - AOUTHDR eaout; - SCNHDR esecs[3]; - struct stat st; - char buf[1024]; - unsigned long loadaddr; - unsigned long initrd_header[2]; - int i, cnt; - int swab = 0; - - if (argc != 4) { - printf("Usage: %s \n", argv[0]); - exit(1); - } - - if ((fd_vmlinux = open (argv[1], O_RDONLY)) < 0) - die("open vmlinux"); - if (read (fd_vmlinux, &efile, sizeof efile) != sizeof efile) - die("read file header"); - if (read (fd_vmlinux, &eaout, sizeof eaout) != sizeof eaout) - die("read aout header"); - if (read (fd_vmlinux, esecs, sizeof esecs) != sizeof esecs) - die("read section headers"); - /* - * check whether the file is good for us - */ - /* TBD */ - - /* - * check, if we have to swab words - */ - if (ntohs(0xaa55) == 0xaa55) { - if (efile.f_magic == swab16(MIPSELMAGIC)) - swab = 1; - } else { - if (efile.f_magic == swab16(MIPSEBMAGIC)) - swab = 1; - } - - /* make sure we have an empty data segment for the initrd */ - if (eaout.dsize || esecs[1].s_size) { - fprintf(stderr, "Data segment not empty. Giving up!\n"); - exit(1); - } - if ((fd_initrd = open (argv[2], O_RDONLY)) < 0) - die("open initrd"); - if (fstat (fd_initrd, &st) < 0) - die("fstat initrd"); - loadaddr = ((SWAB(esecs[2].s_vaddr) + SWAB(esecs[2].s_size) - + MIPS_PAGE_SIZE-1) & ~MIPS_PAGE_MASK) - 8; - if (loadaddr < (SWAB(esecs[2].s_vaddr) + SWAB(esecs[2].s_size))) - loadaddr += MIPS_PAGE_SIZE; - initrd_header[0] = SWAB(0x494E5244); - initrd_header[1] = SWAB(st.st_size); - eaout.dsize = esecs[1].s_size = initrd_header[1] = SWAB(st.st_size+8); - eaout.data_start = esecs[1].s_vaddr = esecs[1].s_paddr = SWAB(loadaddr); - - if ((fd_outfile = open (argv[3], O_RDWR|O_CREAT|O_TRUNC, 0666)) < 0) - die("open outfile"); - if (write (fd_outfile, &efile, sizeof efile) != sizeof efile) - die("write file header"); - if (write (fd_outfile, &eaout, sizeof eaout) != sizeof eaout) - die("write aout header"); - if (write (fd_outfile, esecs, sizeof esecs) != sizeof esecs) - die("write section headers"); - /* skip padding */ - if(lseek(fd_vmlinux, SWAB(esecs[0].s_scnptr), SEEK_SET) == (off_t)-1) - die("lseek vmlinux"); - if(lseek(fd_outfile, SWAB(esecs[0].s_scnptr), SEEK_SET) == (off_t)-1) - die("lseek outfile"); - /* copy text segment */ - cnt = SWAB(eaout.tsize); - while (cnt) { - if ((i = read (fd_vmlinux, buf, sizeof buf)) <= 0) - die("read vmlinux"); - if (write (fd_outfile, buf, i) != i) - die("write vmlinux"); - cnt -= i; - } - if (write (fd_outfile, initrd_header, sizeof initrd_header) != sizeof initrd_header) - die("write initrd header"); - while ((i = read (fd_initrd, buf, sizeof buf)) > 0) - if (write (fd_outfile, buf, i) != i) - die("write initrd"); - close(fd_vmlinux); - close(fd_initrd); - return 0; -} diff --git a/arch/mips/configs/ar7_defconfig b/arch/mips/configs/ar7_defconfig index 3564830..2cb304a 100644 --- a/arch/mips/configs/ar7_defconfig +++ b/arch/mips/configs/ar7_defconfig @@ -265,7 +265,6 @@ CONFIG_DEFAULT_DEADLINE=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="deadline" -CONFIG_PROBE_INITRD_HEADER=y # CONFIG_FREEZER is not set # diff --git a/arch/mips/configs/cavium-octeon_defconfig b/arch/mips/configs/cavium-octeon_defconfig index 7afaa28..1819a4c 100644 --- a/arch/mips/configs/cavium-octeon_defconfig +++ b/arch/mips/configs/cavium-octeon_defconfig @@ -269,7 +269,6 @@ CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="cfq" CONFIG_CLASSIC_RCU=y -# CONFIG_PROBE_INITRD_HEADER is not set # CONFIG_FREEZER is not set # diff --git a/arch/mips/configs/rbtx49xx_defconfig b/arch/mips/configs/rbtx49xx_defconfig index 6c6a19a..4f3b970 100644 --- a/arch/mips/configs/rbtx49xx_defconfig +++ b/arch/mips/configs/rbtx49xx_defconfig @@ -284,7 +284,6 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" -# CONFIG_PROBE_INITRD_HEADER is not set # CONFIG_FREEZER is not set # diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index fd138c9..bd55f71 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -166,26 +166,8 @@ static unsigned long __init init_initrd(void) * already set up initrd_start and initrd_end. In these cases * perfom sanity checks and use them if all looks good. */ - if (!initrd_start || initrd_end <= initrd_start) { -#ifdef CONFIG_PROBE_INITRD_HEADER - u32 *initrd_header; - - /* - * See if initrd has been added to the kernel image by - * arch/mips/boot/addinitrd.c. In that case a header is - * prepended to initrd and is made up by 8 bytes. The first - * word is a magic number and the second one is the size of - * initrd. Initrd start must be page aligned in any cases. - */ - initrd_header = __va(PAGE_ALIGN(__pa_symbol(&_end) + 8)) - 8; - if (initrd_header[0] != 0x494E5244) - goto disable; - initrd_start = (unsigned long)(initrd_header + 2); - initrd_end = initrd_start + initrd_header[1]; -#else + if (!initrd_start || initrd_end <= initrd_start) goto disable; -#endif - } if (initrd_start & ~PAGE_MASK) { pr_err("initrd start must be page aligned\n"); -- cgit v0.10.2 From b6ee75ed4fa201873d3a2b32dfce2dbd701a2de4 Mon Sep 17 00:00:00 2001 From: David Daney Date: Thu, 5 Nov 2009 11:34:26 -0800 Subject: MIPS: Collect FPU emulator statistics per-CPU. On SMP systems, the collection of statistics can cause cache line bouncing in the lines associated with the counters. Also there are races incrementing the counters on multiple CPUs. To fix both problems, we collect the statistics in per-CPU variables, and add them up in the debugfs read operation. As a test I ran the LTP float_bessel test on a 12 CPU Octeon system. Without CONFIG_DEBUG_FS : 2602 seconds. With CONFIG_DEBUG_FS: 2640 seconds. With non-cpu-local atomic statistics: 14569 seconds. Signed-off-by: David Daney Cc: linux-mips@linux-mips.org Signed-off-by: Ralf Baechle diff --git a/arch/mips/include/asm/fpu_emulator.h b/arch/mips/include/asm/fpu_emulator.h index e518957..aecada6 100644 --- a/arch/mips/include/asm/fpu_emulator.h +++ b/arch/mips/include/asm/fpu_emulator.h @@ -25,17 +25,27 @@ #include #include +#include + +#ifdef CONFIG_DEBUG_FS struct mips_fpu_emulator_stats { - unsigned int emulated; - unsigned int loads; - unsigned int stores; - unsigned int cp1ops; - unsigned int cp1xops; - unsigned int errors; + local_t emulated; + local_t loads; + local_t stores; + local_t cp1ops; + local_t cp1xops; + local_t errors; }; -extern struct mips_fpu_emulator_stats fpuemustats; +DECLARE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats); + +#define MIPS_FPU_EMU_INC_STATS(M) \ + cpu_local_wrap(__local_inc(&__get_cpu_var(fpuemustats).M)) + +#else +#define MIPS_FPU_EMU_INC_STATS(M) do { } while (0) +#endif /* CONFIG_DEBUG_FS */ extern int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc); diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c index 454b539..8f2f8e9 100644 --- a/arch/mips/math-emu/cp1emu.c +++ b/arch/mips/math-emu/cp1emu.c @@ -35,6 +35,7 @@ * better performance by compiling with -msoft-float! */ #include +#include #include #include @@ -68,7 +69,9 @@ static int fpux_emu(struct pt_regs *, /* Further private data for which no space exists in mips_fpu_struct */ -struct mips_fpu_emulator_stats fpuemustats; +#ifdef CONFIG_DEBUG_FS +DEFINE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats); +#endif /* Control registers */ @@ -209,7 +212,7 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx) unsigned int cond; if (get_user(ir, (mips_instruction __user *) xcp->cp0_epc)) { - fpuemustats.errors++; + MIPS_FPU_EMU_INC_STATS(errors); return SIGBUS; } @@ -240,7 +243,7 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx) return SIGILL; } if (get_user(ir, (mips_instruction __user *) emulpc)) { - fpuemustats.errors++; + MIPS_FPU_EMU_INC_STATS(errors); return SIGBUS; } /* __compute_return_epc() will have updated cp0_epc */ @@ -253,16 +256,16 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx) } emul: - fpuemustats.emulated++; + MIPS_FPU_EMU_INC_STATS(emulated); switch (MIPSInst_OPCODE(ir)) { case ldc1_op:{ u64 __user *va = (u64 __user *) (xcp->regs[MIPSInst_RS(ir)] + MIPSInst_SIMM(ir)); u64 val; - fpuemustats.loads++; + MIPS_FPU_EMU_INC_STATS(loads); if (get_user(val, va)) { - fpuemustats.errors++; + MIPS_FPU_EMU_INC_STATS(errors); return SIGBUS; } DITOREG(val, MIPSInst_RT(ir)); @@ -274,10 +277,10 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx) MIPSInst_SIMM(ir)); u64 val; - fpuemustats.stores++; + MIPS_FPU_EMU_INC_STATS(stores); DIFROMREG(val, MIPSInst_RT(ir)); if (put_user(val, va)) { - fpuemustats.errors++; + MIPS_FPU_EMU_INC_STATS(errors); return SIGBUS; } break; @@ -288,9 +291,9 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx) MIPSInst_SIMM(ir)); u32 val; - fpuemustats.loads++; + MIPS_FPU_EMU_INC_STATS(loads); if (get_user(val, va)) { - fpuemustats.errors++; + MIPS_FPU_EMU_INC_STATS(errors); return SIGBUS; } SITOREG(val, MIPSInst_RT(ir)); @@ -302,10 +305,10 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx) MIPSInst_SIMM(ir)); u32 val; - fpuemustats.stores++; + MIPS_FPU_EMU_INC_STATS(stores); SIFROMREG(val, MIPSInst_RT(ir)); if (put_user(val, va)) { - fpuemustats.errors++; + MIPS_FPU_EMU_INC_STATS(errors); return SIGBUS; } break; @@ -429,7 +432,7 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx) if (get_user(ir, (mips_instruction __user *) xcp->cp0_epc)) { - fpuemustats.errors++; + MIPS_FPU_EMU_INC_STATS(errors); return SIGBUS; } @@ -595,7 +598,7 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, { unsigned rcsr = 0; /* resulting csr */ - fpuemustats.cp1xops++; + MIPS_FPU_EMU_INC_STATS(cp1xops); switch (MIPSInst_FMA_FFMT(ir)) { case s_fmt:{ /* 0 */ @@ -610,9 +613,9 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] + xcp->regs[MIPSInst_FT(ir)]); - fpuemustats.loads++; + MIPS_FPU_EMU_INC_STATS(loads); if (get_user(val, va)) { - fpuemustats.errors++; + MIPS_FPU_EMU_INC_STATS(errors); return SIGBUS; } SITOREG(val, MIPSInst_FD(ir)); @@ -622,11 +625,11 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] + xcp->regs[MIPSInst_FT(ir)]); - fpuemustats.stores++; + MIPS_FPU_EMU_INC_STATS(stores); SIFROMREG(val, MIPSInst_FS(ir)); if (put_user(val, va)) { - fpuemustats.errors++; + MIPS_FPU_EMU_INC_STATS(errors); return SIGBUS; } break; @@ -687,9 +690,9 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] + xcp->regs[MIPSInst_FT(ir)]); - fpuemustats.loads++; + MIPS_FPU_EMU_INC_STATS(loads); if (get_user(val, va)) { - fpuemustats.errors++; + MIPS_FPU_EMU_INC_STATS(errors); return SIGBUS; } DITOREG(val, MIPSInst_FD(ir)); @@ -699,10 +702,10 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] + xcp->regs[MIPSInst_FT(ir)]); - fpuemustats.stores++; + MIPS_FPU_EMU_INC_STATS(stores); DIFROMREG(val, MIPSInst_FS(ir)); if (put_user(val, va)) { - fpuemustats.errors++; + MIPS_FPU_EMU_INC_STATS(errors); return SIGBUS; } break; @@ -769,7 +772,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, #endif } rv; /* resulting value */ - fpuemustats.cp1ops++; + MIPS_FPU_EMU_INC_STATS(cp1ops); switch (rfmt = (MIPSInst_FFMT(ir) & 0xf)) { case s_fmt:{ /* 0 */ union { @@ -1240,7 +1243,7 @@ int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx, prevepc = xcp->cp0_epc; if (get_user(insn, (mips_instruction __user *) xcp->cp0_epc)) { - fpuemustats.errors++; + MIPS_FPU_EMU_INC_STATS(errors); return SIGBUS; } if (insn == 0) @@ -1276,33 +1279,50 @@ int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx, } #ifdef CONFIG_DEBUG_FS + +static int fpuemu_stat_get(void *data, u64 *val) +{ + int cpu; + unsigned long sum = 0; + for_each_online_cpu(cpu) { + struct mips_fpu_emulator_stats *ps; + local_t *pv; + ps = &per_cpu(fpuemustats, cpu); + pv = (void *)ps + (unsigned long)data; + sum += local_read(pv); + } + *val = sum; + return 0; +} +DEFINE_SIMPLE_ATTRIBUTE(fops_fpuemu_stat, fpuemu_stat_get, NULL, "%llu\n"); + extern struct dentry *mips_debugfs_dir; static int __init debugfs_fpuemu(void) { struct dentry *d, *dir; - int i; - static struct { - const char *name; - unsigned int *v; - } vars[] __initdata = { - { "emulated", &fpuemustats.emulated }, - { "loads", &fpuemustats.loads }, - { "stores", &fpuemustats.stores }, - { "cp1ops", &fpuemustats.cp1ops }, - { "cp1xops", &fpuemustats.cp1xops }, - { "errors", &fpuemustats.errors }, - }; if (!mips_debugfs_dir) return -ENODEV; dir = debugfs_create_dir("fpuemustats", mips_debugfs_dir); if (!dir) return -ENOMEM; - for (i = 0; i < ARRAY_SIZE(vars); i++) { - d = debugfs_create_u32(vars[i].name, S_IRUGO, dir, vars[i].v); - if (!d) - return -ENOMEM; - } + +#define FPU_STAT_CREATE(M) \ + do { \ + d = debugfs_create_file(#M , S_IRUGO, dir, \ + (void *)offsetof(struct mips_fpu_emulator_stats, M), \ + &fops_fpuemu_stat); \ + if (!d) \ + return -ENOMEM; \ + } while (0) + + FPU_STAT_CREATE(emulated); + FPU_STAT_CREATE(loads); + FPU_STAT_CREATE(stores); + FPU_STAT_CREATE(cp1ops); + FPU_STAT_CREATE(cp1xops); + FPU_STAT_CREATE(errors); + return 0; } __initcall(debugfs_fpuemu); diff --git a/arch/mips/math-emu/dsemul.c b/arch/mips/math-emu/dsemul.c index df7b9d9..36d975a 100644 --- a/arch/mips/math-emu/dsemul.c +++ b/arch/mips/math-emu/dsemul.c @@ -98,7 +98,7 @@ int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc) err |= __put_user(cpc, &fr->epc); if (unlikely(err)) { - fpuemustats.errors++; + MIPS_FPU_EMU_INC_STATS(errors); return SIGBUS; } @@ -136,7 +136,7 @@ int do_dsemulret(struct pt_regs *xcp) err |= __get_user(cookie, &fr->cookie); if (unlikely(err || (insn != BREAK_MATH) || (cookie != BD_COOKIE))) { - fpuemustats.errors++; + MIPS_FPU_EMU_INC_STATS(errors); return 0; } -- cgit v0.10.2 From 04cfb90a92a2f9f7b56b2f85c528be7d1561e0e5 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Fri, 6 Nov 2009 18:35:33 +0800 Subject: MIPS: Loongson: Cleanup machtype support To choose code for different machines by the value of machtype it needs to be initialized as early as possible. So move initialization of mips_machtype to prom_init(). Signed-off-by: Wu Zhangjin Cc: linux-mips@linux-mips.org Signed-off-by: Ralf Baechle diff --git a/arch/mips/include/asm/mach-loongson/loongson.h b/arch/mips/include/asm/mach-loongson/loongson.h index e6869aa..efb2344 100644 --- a/arch/mips/include/asm/mach-loongson/loongson.h +++ b/arch/mips/include/asm/mach-loongson/loongson.h @@ -29,6 +29,7 @@ extern unsigned long memsize, highmemsize; /* loongson-specific command line, env and memory initialization */ extern void __init prom_init_memory(void); extern void __init prom_init_cmdline(void); +extern void __init prom_init_machtype(void); extern void __init prom_init_env(void); /* irq operation functions */ diff --git a/arch/mips/loongson/common/cmdline.c b/arch/mips/loongson/common/cmdline.c index 75f1b24..7ad47f2 100644 --- a/arch/mips/loongson/common/cmdline.c +++ b/arch/mips/loongson/common/cmdline.c @@ -9,7 +9,7 @@ * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology * Author: Fuxin Zhang, zhangfx@lemote.com * - * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology + * Copyright (C) 2009 Lemote Inc. * Author: Wu Zhangjin, wuzj@lemote.com * * This program is free software; you can redistribute it and/or modify it @@ -49,4 +49,6 @@ void __init prom_init_cmdline(void) strcat(arcs_cmdline, " console=ttyS0,115200"); if ((strstr(arcs_cmdline, "root=")) == NULL) strcat(arcs_cmdline, " root=/dev/hda1"); + + prom_init_machtype(); } diff --git a/arch/mips/loongson/common/machtype.c b/arch/mips/loongson/common/machtype.c index 7b34824..7545fe6 100644 --- a/arch/mips/loongson/common/machtype.c +++ b/arch/mips/loongson/common/machtype.c @@ -15,6 +15,9 @@ #include #include +/* please ensure the length of the machtype string is less than 50 */ +#define MACHTYPE_LEN 50 + static const char *system_types[] = { [MACH_LOONGSON_UNKNOWN] "unknown loongson machine", [MACH_LEMOTE_FL2E] "lemote-fuloong-2e-box", @@ -27,24 +30,28 @@ static const char *system_types[] = { const char *get_system_type(void) { - if (mips_machtype == MACH_UNKNOWN) - mips_machtype = LOONGSON_MACHTYPE; - return system_types[mips_machtype]; } -static __init int machtype_setup(char *str) +void __init prom_init_machtype(void) { + char *p, str[MACHTYPE_LEN]; int machtype = MACH_LEMOTE_FL2E; - if (!str) - return -EINVAL; + mips_machtype = LOONGSON_MACHTYPE; + + p = strstr(arcs_cmdline, "machtype="); + if (!p) + return; + p += strlen("machtype="); + strncpy(str, p, MACHTYPE_LEN); + p = strstr(str, " "); + if (p) + *p = '\0'; for (; system_types[machtype]; machtype++) if (strstr(system_types[machtype], str)) { mips_machtype = machtype; break; } - return 0; } -__setup("machtype=", machtype_setup); -- cgit v0.10.2 From a3ed495190ebe918f4584291ed8c76f1c97a84fd Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Fri, 6 Nov 2009 18:35:34 +0800 Subject: MIPS: Loongson: Cleanup the serial port support To share the same kernel image amon different machines we have added the machtype command line support. In the old serial port implementation the UART base address is hardcoded as a macro in machine.h which breaks with machtype, so change that to discover the address dynamically. Also move the initialization of the UART base address to uart_base.c to avoid remapping twice for early_printk.c and serial.c. Signed-off-by: Wu Zhangjin Cc: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/581/ Patchwork: http://patchwork.linux-mips.org/patch/682/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/include/asm/mach-loongson/loongson.h b/arch/mips/include/asm/mach-loongson/loongson.h index efb2344..722db9e 100644 --- a/arch/mips/include/asm/mach-loongson/loongson.h +++ b/arch/mips/include/asm/mach-loongson/loongson.h @@ -31,6 +31,9 @@ extern void __init prom_init_memory(void); extern void __init prom_init_cmdline(void); extern void __init prom_init_machtype(void); extern void __init prom_init_env(void); +extern unsigned long _loongson_uart_base; +extern unsigned long uart8250_base[]; +extern void prom_init_uart_base(void); /* irq operation functions */ extern void bonito_irqdispatch(void); diff --git a/arch/mips/include/asm/mach-loongson/machine.h b/arch/mips/include/asm/mach-loongson/machine.h index ea5954c..d2f5861 100644 --- a/arch/mips/include/asm/mach-loongson/machine.h +++ b/arch/mips/include/asm/mach-loongson/machine.h @@ -13,8 +13,6 @@ #ifdef CONFIG_LEMOTE_FULOONG2E -#define LOONGSON_UART_BASE (LOONGSON_PCIIO_BASE + 0x3f8) - #define LOONGSON_MACHTYPE MACH_LEMOTE_FL2E #endif diff --git a/arch/mips/loongson/common/Makefile b/arch/mips/loongson/common/Makefile index d21d116..be6adf7 100644 --- a/arch/mips/loongson/common/Makefile +++ b/arch/mips/loongson/common/Makefile @@ -3,7 +3,7 @@ # obj-y += setup.o init.o cmdline.o env.o time.o reset.o irq.o \ - pci.o bonito-irq.o mem.o machtype.o + pci.o bonito-irq.o mem.o machtype.o uart_base.o # # Early printk support diff --git a/arch/mips/loongson/common/early_printk.c b/arch/mips/loongson/common/early_printk.c index 8ec4fb2..23e7a8f 100644 --- a/arch/mips/loongson/common/early_printk.c +++ b/arch/mips/loongson/common/early_printk.c @@ -12,7 +12,6 @@ #include #include -#include #define PORT(base, offset) (u8 *)(base + offset) @@ -28,10 +27,14 @@ static inline void serial_out(unsigned char *base, int offset, int value) void prom_putchar(char c) { - unsigned char *uart_base = - (unsigned char *) ioremap_nocache(LOONGSON_UART_BASE, 8); + int timeout; + unsigned char *uart_base; - while ((serial_in(uart_base, UART_LSR) & UART_LSR_THRE) == 0) + uart_base = (unsigned char *)_loongson_uart_base; + timeout = 1024; + + while (((serial_in(uart_base, UART_LSR) & UART_LSR_THRE) == 0) && + (timeout-- > 0)) ; serial_out(uart_base, UART_TX, c); diff --git a/arch/mips/loongson/common/init.c b/arch/mips/loongson/common/init.c index b7e4913..3b1dbc1 100644 --- a/arch/mips/loongson/common/init.c +++ b/arch/mips/loongson/common/init.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology + * Copyright (C) 2009 Lemote Inc. * Author: Wu Zhangjin, wuzj@lemote.com * * This program is free software; you can redistribute it and/or modify it @@ -10,19 +10,22 @@ #include -#include - #include void __init prom_init(void) { - /* init base address of io space */ + /* init base address of io space */ set_io_port_base((unsigned long) ioremap(LOONGSON_PCIIO_BASE, LOONGSON_PCIIO_SIZE)); prom_init_cmdline(); prom_init_env(); prom_init_memory(); + + /*init the uart base address */ +#if defined(CONFIG_EARLY_PRINTK) || defined(CONFIG_SERIAL_8250) + prom_init_uart_base(); +#endif } void __init prom_free_prom_memory(void) diff --git a/arch/mips/loongson/common/serial.c b/arch/mips/loongson/common/serial.c index 6d341e4..dc6488c 100644 --- a/arch/mips/loongson/common/serial.c +++ b/arch/mips/loongson/common/serial.c @@ -23,7 +23,6 @@ { \ .irq = int, \ .uartclk = 1843200, \ - .iobase = (LOONGSON_UART_BASE - LOONGSON_PCIIO_BASE),\ .iotype = UPIO_PORT, \ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, \ .regshift = 0, \ @@ -52,20 +51,20 @@ static struct plat_serial8250_port uart8250_data[][2] = { static struct platform_device uart8250_device = { .name = "serial8250", .id = PLAT8250_DEV_PLATFORM, - .dev = { - .platform_data = uart8250_data[LOONGSON_MACHTYPE], - }, }; static int __init serial_init(void) { - if (uart8250_data[LOONGSON_MACHTYPE][0].iotype == UPIO_MEM) - uart8250_data[LOONGSON_MACHTYPE][0].membase = - ioremap_nocache(LOONGSON_UART_BASE, 8); + if (uart8250_data[mips_machtype][0].iotype == UPIO_MEM) + uart8250_data[mips_machtype][0].membase = + (void __iomem *)_loongson_uart_base; + else if (uart8250_data[mips_machtype][0].iotype == UPIO_PORT) + uart8250_data[mips_machtype][0].iobase = + uart8250_base[mips_machtype] - LOONGSON_PCIIO_BASE; - platform_device_register(&uart8250_device); + uart8250_device.dev.platform_data = uart8250_data[mips_machtype]; - return 0; + return platform_device_register(&uart8250_device); } device_initcall(serial_init); diff --git a/arch/mips/loongson/common/uart_base.c b/arch/mips/loongson/common/uart_base.c new file mode 100644 index 0000000..233c708 --- /dev/null +++ b/arch/mips/loongson/common/uart_base.c @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2009 Lemote Inc. + * Author: Wu Zhangjin, wuzj@lemote.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. + */ + +#include +#include + +#include + +unsigned long __maybe_unused _loongson_uart_base; +EXPORT_SYMBOL(_loongson_uart_base); + +unsigned long __maybe_unused uart8250_base[] = { + [MACH_LOONGSON_UNKNOWN] 0, + [MACH_LEMOTE_FL2E] (LOONGSON_PCIIO_BASE + 0x3f8), + [MACH_LEMOTE_FL2F] (LOONGSON_PCIIO_BASE + 0x2f8), + [MACH_LEMOTE_ML2F7] (LOONGSON_LIO1_BASE + 0x3f8), + [MACH_LEMOTE_YL2F89] (LOONGSON_LIO1_BASE + 0x3f8), + [MACH_DEXXON_GDIUM2F10] (LOONGSON_LIO1_BASE + 0x3f8), + [MACH_LOONGSON_END] 0, +}; +EXPORT_SYMBOL(uart8250_base); + +void __maybe_unused prom_init_uart_base(void) +{ + _loongson_uart_base = + (unsigned long)ioremap_nocache(uart8250_base[mips_machtype], 8); +} -- cgit v0.10.2 From 937893cf5be53203eabc6f4db29f86b1fdeea203 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Fri, 6 Nov 2009 18:45:06 +0800 Subject: MIPS: oprofile: Only do performance counter handling for counter interrupts In Loongson2f IP6 is shared by bonito and perfcounters so we need to avoid do_IRQ for perfcounter when the interrupt is from bonito. Signed-off-by: Wu Zhangjin Cc: linux-mips@linux-mips.org Signed-off-by: Ralf Baechle diff --git a/arch/mips/oprofile/op_model_loongson2.c b/arch/mips/oprofile/op_model_loongson2.c index 575cd14..475ff46 100644 --- a/arch/mips/oprofile/op_model_loongson2.c +++ b/arch/mips/oprofile/op_model_loongson2.c @@ -1,7 +1,7 @@ /* * Loongson2 performance counter driver for oprofile * - * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology + * Copyright (C) 2009 Lemote Inc. * Author: Yanhua * Author: Wu Zhangjin * @@ -125,6 +125,9 @@ static irqreturn_t loongson2_perfcount_handler(int irq, void *dev_id) */ /* Check whether the irq belongs to me */ + enabled = read_c0_perfcnt() & LOONGSON2_PERFCNT_INT_EN; + if (!enabled) + return IRQ_NONE; enabled = reg.cnt1_enabled | reg.cnt2_enabled; if (!enabled) return IRQ_NONE; -- cgit v0.10.2 From 6f7a251a259e5bf58a9ff334bdcfa3e42b6cb7a3 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Fri, 6 Nov 2009 18:45:05 +0800 Subject: MIPS: Loongson: Add basic Loongson 2F support Loongson 2F has built-in DDR2 and PCI-X controller. The PCI-X controller has a programming interface similiar to the the FPGA northbridge used on Loongson 2E. The main differences between Loongson 2E and Loongson 2F include: 1. Loongson 2F has an extra address window configuration module, which is used to map CPU address space to DDR or PCI address space, or map the PCI-DMA address space to DDR or LIO address space. 2. Loongson 2F supports 8 levels of software configurable CPu frequency which can be configured in the LOONGSON_CHIPCFG0 register. The coming cpufreq and standby support are based on this feature. Loongson.h abstracts the modules and corresponding methods are abstracted. Add other Loongson-2F-specific source code including gcc 4.4 support, PCI memory space, PCI IO space, DMA address. Signed-off-by: Wu Zhangjin Cc: linux-mips@linux-mips.org Signed-off-by: Ralf Baechle diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index a16b6df..9618451 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -1073,6 +1073,21 @@ config CPU_LOONGSON2E The Loongson 2E processor implements the MIPS III instruction set with many extensions. + It has an internal FPGA northbridge, which is compatiable to + bonito64. + +config CPU_LOONGSON2F + bool "Loongson 2F" + depends on SYS_HAS_CPU_LOONGSON2F + select CPU_LOONGSON2 + help + The Loongson 2F processor implements the MIPS III instruction set + with many extensions. + + Loongson2F have built-in DDR2 and PCIX controller. The PCIX controller + have a similar programming interface with FPGA northbridge used in + Loongson2E. + config CPU_MIPS32_R1 bool "MIPS32 Release 1" depends on SYS_HAS_CPU_MIPS32_R1 @@ -1317,6 +1332,9 @@ config CPU_LOONGSON2 config SYS_HAS_CPU_LOONGSON2E bool +config SYS_HAS_CPU_LOONGSON2F + bool + config SYS_HAS_CPU_MIPS32_R1 bool diff --git a/arch/mips/Makefile b/arch/mips/Makefile index ba04782..47ecded 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -125,6 +125,8 @@ cflags-$(CONFIG_CPU_TX49XX) += -march=r4600 -Wa,--trap cflags-$(CONFIG_CPU_LOONGSON2) += -Wa,--trap cflags-$(CONFIG_CPU_LOONGSON2E) += \ $(call cc-option,-march=loongson2e,-march=r4600) +cflags-$(CONFIG_CPU_LOONGSON2F) += \ + $(call cc-option,-march=loongson2f,-march=r4600) cflags-$(CONFIG_CPU_MIPS32_R1) += $(call cc-option,-march=mips32,-mips32 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \ -Wa,-mips32 -Wa,--trap diff --git a/arch/mips/include/asm/mach-loongson/dma-coherence.h b/arch/mips/include/asm/mach-loongson/dma-coherence.h index 71a6851..981c75f 100644 --- a/arch/mips/include/asm/mach-loongson/dma-coherence.h +++ b/arch/mips/include/asm/mach-loongson/dma-coherence.h @@ -28,7 +28,11 @@ static inline dma_addr_t plat_map_dma_mem_page(struct device *dev, static inline unsigned long plat_dma_addr_to_phys(struct device *dev, dma_addr_t dma_addr) { +#if defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT) + return (dma_addr > 0x8fffffff) ? dma_addr : (dma_addr & 0x0fffffff); +#else return dma_addr & 0x7fffffff; +#endif } static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr, diff --git a/arch/mips/include/asm/mach-loongson/loongson.h b/arch/mips/include/asm/mach-loongson/loongson.h index 722db9e..62171f2 100644 --- a/arch/mips/include/asm/mach-loongson/loongson.h +++ b/arch/mips/include/asm/mach-loongson/loongson.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology + * Copyright (C) 2009 Lemote, Inc. * Author: Wu Zhangjin * * This program is free software; you can redistribute it and/or modify it @@ -219,4 +219,86 @@ extern void mach_irq_dispatch(unsigned int pending); #define LOONGSON_PCIMAP_WIN(WIN, ADDR) \ ((((ADDR)>>26) & LOONGSON_PCIMAP_PCIMAP_LO0) << ((WIN)*6)) +/* Chip Config */ +#ifdef CONFIG_CPU_LOONGSON2F +#define LOONGSON_CHIPCFG0 LOONGSON_REG(LOONGSON_REGBASE + 0x80) +#endif + +/* + * address windows configuration module + * + * loongson2e do not have this module + */ +#if defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT) + +/* address window config module base address */ +#define LOONGSON_ADDRWINCFG_BASE 0x3ff00000ul +#define LOONGSON_ADDRWINCFG_SIZE 0x180 + +extern unsigned long _loongson_addrwincfg_base; +#define LOONGSON_ADDRWINCFG(offset) \ + (*(volatile u64 *)(_loongson_addrwincfg_base + (offset))) + +#define CPU_WIN0_BASE LOONGSON_ADDRWINCFG(0x00) +#define CPU_WIN1_BASE LOONGSON_ADDRWINCFG(0x08) +#define CPU_WIN2_BASE LOONGSON_ADDRWINCFG(0x10) +#define CPU_WIN3_BASE LOONGSON_ADDRWINCFG(0x18) + +#define CPU_WIN0_MASK LOONGSON_ADDRWINCFG(0x20) +#define CPU_WIN1_MASK LOONGSON_ADDRWINCFG(0x28) +#define CPU_WIN2_MASK LOONGSON_ADDRWINCFG(0x30) +#define CPU_WIN3_MASK LOONGSON_ADDRWINCFG(0x38) + +#define CPU_WIN0_MMAP LOONGSON_ADDRWINCFG(0x40) +#define CPU_WIN1_MMAP LOONGSON_ADDRWINCFG(0x48) +#define CPU_WIN2_MMAP LOONGSON_ADDRWINCFG(0x50) +#define CPU_WIN3_MMAP LOONGSON_ADDRWINCFG(0x58) + +#define PCIDMA_WIN0_BASE LOONGSON_ADDRWINCFG(0x60) +#define PCIDMA_WIN1_BASE LOONGSON_ADDRWINCFG(0x68) +#define PCIDMA_WIN2_BASE LOONGSON_ADDRWINCFG(0x70) +#define PCIDMA_WIN3_BASE LOONGSON_ADDRWINCFG(0x78) + +#define PCIDMA_WIN0_MASK LOONGSON_ADDRWINCFG(0x80) +#define PCIDMA_WIN1_MASK LOONGSON_ADDRWINCFG(0x88) +#define PCIDMA_WIN2_MASK LOONGSON_ADDRWINCFG(0x90) +#define PCIDMA_WIN3_MASK LOONGSON_ADDRWINCFG(0x98) + +#define PCIDMA_WIN0_MMAP LOONGSON_ADDRWINCFG(0xa0) +#define PCIDMA_WIN1_MMAP LOONGSON_ADDRWINCFG(0xa8) +#define PCIDMA_WIN2_MMAP LOONGSON_ADDRWINCFG(0xb0) +#define PCIDMA_WIN3_MMAP LOONGSON_ADDRWINCFG(0xb8) + +#define ADDRWIN_WIN0 0 +#define ADDRWIN_WIN1 1 +#define ADDRWIN_WIN2 2 +#define ADDRWIN_WIN3 3 + +#define ADDRWIN_MAP_DST_DDR 0 +#define ADDRWIN_MAP_DST_PCI 1 +#define ADDRWIN_MAP_DST_LIO 1 + +/* + * s: CPU, PCIDMA + * d: DDR, PCI, LIO + * win: 0, 1, 2, 3 + * src: map source + * dst: map destination + * size: ~mask + 1 + */ +#define LOONGSON_ADDRWIN_CFG(s, d, w, src, dst, size) do {\ + s##_WIN##w##_BASE = (src); \ + s##_WIN##w##_MMAP = (src) | ADDRWIN_MAP_DST_##d; \ + s##_WIN##w##_MASK = ~(size-1); \ +} while (0) + +#define LOONGSON_ADDRWIN_CPUTOPCI(win, src, dst, size) \ + LOONGSON_ADDRWIN_CFG(CPU, PCI, win, src, dst, size) +#define LOONGSON_ADDRWIN_CPUTODDR(win, src, dst, size) \ + LOONGSON_ADDRWIN_CFG(CPU, DDR, win, src, dst, size) +#define LOONGSON_ADDRWIN_PCITODDR(win, src, dst, size) \ + LOONGSON_ADDRWIN_CFG(PCIDMA, DDR, win, src, dst, size) + +#endif /* ! CONFIG_CPU_LOONGSON2F && CONFIG_64BIT */ + #endif /* __ASM_MACH_LOONGSON_LOONGSON_H */ diff --git a/arch/mips/include/asm/mach-loongson/mem.h b/arch/mips/include/asm/mach-loongson/mem.h index bd7b3cb..e9960f3 100644 --- a/arch/mips/include/asm/mach-loongson/mem.h +++ b/arch/mips/include/asm/mach-loongson/mem.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology + * Copyright (C) 2009 Lemote, Inc. * Author: Wu Zhangjin * * This program is free software; you can redistribute it and/or modify it @@ -12,19 +12,30 @@ #define __ASM_MACH_LOONGSON_MEM_H /* - * On Lemote Loongson 2e + * high memory space * - * the high memory space starts from 512M. - * the peripheral registers reside between 0x1000:0000 and 0x2000:0000. + * in loongson2e, starts from 512M + * in loongson2f, starts from 2G 256M */ +#ifdef CONFIG_CPU_LOONGSON2E +#define LOONGSON_HIGHMEM_START 0x20000000 +#else +#define LOONGSON_HIGHMEM_START 0x90000000 +#endif -#ifdef CONFIG_LEMOTE_FULOONG2E - -#define LOONGSON_HIGHMEM_START 0x20000000 +/* + * the peripheral registers(MMIO): + * + * On the Lemote Loongson 2e system, reside between 0x1000:0000 and 0x2000:0000. + * On the Lemote Loongson 2f system, reside between 0x1000:0000 and 0x8000:0000. + */ #define LOONGSON_MMIO_MEM_START 0x10000000 -#define LOONGSON_MMIO_MEM_END 0x20000000 +#ifdef CONFIG_CPU_LOONGSON2E +#define LOONGSON_MMIO_MEM_END 0x20000000 +#else +#define LOONGSON_MMIO_MEM_END 0x80000000 #endif #endif /* __ASM_MACH_LOONGSON_MEM_H */ diff --git a/arch/mips/include/asm/mach-loongson/pci.h b/arch/mips/include/asm/mach-loongson/pci.h index 576487c..31ba908 100644 --- a/arch/mips/include/asm/mach-loongson/pci.h +++ b/arch/mips/include/asm/mach-loongson/pci.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2008 Zhang Le + * Copyright (c) 2009 Wu Zhangjin * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General @@ -24,7 +25,30 @@ extern struct pci_ops loongson_pci_ops; -#ifdef CONFIG_LEMOTE_FULOONG2E +/* this is an offset from mips_io_port_base */ +#define LOONGSON_PCI_IO_START 0x00004000UL + +#if defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT) + +/* + * we use address window2 to map cpu address space to pci space + * window2: cpu [1G, 2G] -> pci [1G, 2G] + * why not use window 0 & 1? because they are used by cpu when booting. + * window0: cpu [0, 256M] -> ddr [0, 256M] + * window1: cpu [256M, 512M] -> pci [256M, 512M] + */ + +/* the smallest LOONGSON_CPU_MEM_SRC can be 512M */ +#define LOONGSON_CPU_MEM_SRC 0x40000000ul /* 1G */ +#define LOONGSON_PCI_MEM_DST LOONGSON_CPU_MEM_SRC + +#define LOONGSON_PCI_MEM_START LOONGSON_PCI_MEM_DST +#define LOONGSON_PCI_MEM_END (0x80000000ul-1) /* 2G */ + +#define MMAP_CPUTOPCI_SIZE (LOONGSON_PCI_MEM_END - \ + LOONGSON_PCI_MEM_START + 1) + +#else /* loongson2f/32bit & loongson2e */ /* this pci memory space is mapped by pcimap in pci.c */ #define LOONGSON_PCI_MEM_START LOONGSON_PCILO1_BASE @@ -32,6 +56,6 @@ extern struct pci_ops loongson_pci_ops; /* this is an offset from mips_io_port_base */ #define LOONGSON_PCI_IO_START 0x00004000UL -#endif +#endif /* !(defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT))*/ #endif /* !__ASM_MACH_LOONGSON_PCI_H_ */ diff --git a/arch/mips/loongson/common/bonito-irq.c b/arch/mips/loongson/common/bonito-irq.c index a1cbd11..2dc2a4c 100644 --- a/arch/mips/loongson/common/bonito-irq.c +++ b/arch/mips/loongson/common/bonito-irq.c @@ -12,6 +12,7 @@ * option) any later version. */ #include +#include #include @@ -35,7 +36,7 @@ static struct irq_chip bonito_irq_type = { .unmask = bonito_irq_enable, }; -static struct irqaction dma_timeout_irqaction = { +static struct irqaction __maybe_unused dma_timeout_irqaction = { .handler = no_action, .name = "dma_timeout", }; @@ -47,5 +48,7 @@ void bonito_irq_init(void) for (i = LOONGSON_IRQ_BASE; i < LOONGSON_IRQ_BASE + 32; i++) set_irq_chip_and_handler(i, &bonito_irq_type, handle_level_irq); +#ifdef CONFIG_CPU_LOONGSON2E setup_irq(LOONGSON_IRQ_BASE + 10, &dma_timeout_irqaction); +#endif } diff --git a/arch/mips/loongson/common/init.c b/arch/mips/loongson/common/init.c index 3b1dbc1..743d357 100644 --- a/arch/mips/loongson/common/init.c +++ b/arch/mips/loongson/common/init.c @@ -12,12 +12,20 @@ #include +/* Loongson CPU address windows config space base address */ +unsigned long __maybe_unused _loongson_addrwincfg_base; + void __init prom_init(void) { /* init base address of io space */ set_io_port_base((unsigned long) ioremap(LOONGSON_PCIIO_BASE, LOONGSON_PCIIO_SIZE)); +#if defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT) + _loongson_addrwincfg_base = (unsigned long) + ioremap(LOONGSON_ADDRWINCFG_BASE, LOONGSON_ADDRWINCFG_SIZE); +#endif + prom_init_cmdline(); prom_init_env(); prom_init_memory(); diff --git a/arch/mips/loongson/common/mem.c b/arch/mips/loongson/common/mem.c index 3f7f153..e93551d 100644 --- a/arch/mips/loongson/common/mem.c +++ b/arch/mips/loongson/common/mem.c @@ -21,14 +21,31 @@ void __init prom_init_memory(void) add_memory_region(memsize << 20, LOONGSON_PCI_MEM_START - (memsize << 20), BOOT_MEM_RESERVED); #ifdef CONFIG_64BIT - if (highmemsize > 0) - add_memory_region(LOONGSON_HIGHMEM_START, - highmemsize << 20, BOOT_MEM_RAM); - - add_memory_region(LOONGSON_PCI_MEM_END + 1, LOONGSON_HIGHMEM_START - - LOONGSON_PCI_MEM_END - 1, BOOT_MEM_RESERVED); - -#endif /* CONFIG_64BIT */ +#ifdef CONFIG_CPU_LOONGSON2F + { + int bit; + + bit = fls(memsize + highmemsize); + if (bit != ffs(memsize + highmemsize)) + bit += 20; + else + bit = bit + 20 - 1; + + /* set cpu window3 to map CPU to DDR: 2G -> 2G */ + LOONGSON_ADDRWIN_CPUTODDR(ADDRWIN_WIN3, 0x80000000ul, + 0x80000000ul, (1 << bit)); + mmiowb(); + } +#endif /* CONFIG_CPU_LOONGSON2F */ + + if (highmemsize > 0) + add_memory_region(LOONGSON_HIGHMEM_START, + highmemsize << 20, BOOT_MEM_RAM); + + add_memory_region(LOONGSON_PCI_MEM_END + 1, LOONGSON_HIGHMEM_START - + LOONGSON_PCI_MEM_END - 1, BOOT_MEM_RESERVED); + +#endif /* CONFIG_64BIT */ } /* override of arch/mips/mm/cache.c: __uncached_access */ diff --git a/arch/mips/loongson/common/pci.c b/arch/mips/loongson/common/pci.c index a7eb8b9..eac43b8 100644 --- a/arch/mips/loongson/common/pci.c +++ b/arch/mips/loongson/common/pci.c @@ -67,6 +67,14 @@ static void __init setup_pcimap(void) /* can not change gnt to break pci transfer when device's gnt not deassert for some broken device */ LOONGSON_PXARB_CFG = 0x00fe0105ul; + +#if defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT) + /* + * set cpu addr window2 to map CPU address space to PCI address space + */ + LOONGSON_ADDRWIN_CPUTOPCI(ADDRWIN_WIN2, LOONGSON_CPU_MEM_SRC, + LOONGSON_PCI_MEM_DST, MMAP_CPUTOPCI_SIZE); +#endif } static int __init pcibios_init(void) -- cgit v0.10.2 From 7d32c6dd816bb0c595aef62294b714a9b8a0f864 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Tue, 10 Nov 2009 00:06:10 +0800 Subject: MIPS: Lemote 2F: Add a LEMOTE_MACH2F kernel option Add a new kernel option for Lemote Loongson 2F family machines. Lemote loongson2f family machines utilize the 2f revision of loongson processor and the AMD CS5536 south bridge. Family members include Fuloong 2F mini PC, Yeeloong 2F notebook, LingLoong all-in-one PC and others. Signed-off-by: Wu Zhangjin Cc: zhangfx@lemote.com Cc: yanh@lemote.com Cc: huhb@lemote.com Cc: Nicholas Mc Guire Cc: Arnaud Patard Cc: loongson-dev@googlegroups.com Cc: linux-mips@linux-mips.org Signed-off-by: Ralf Baechle diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 47ecded..184d5be 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -327,6 +327,7 @@ core-$(CONFIG_MACH_LOONGSON) +=arch/mips/loongson/ cflags-$(CONFIG_MACH_LOONGSON) += -I$(srctree)/arch/mips/include/asm/mach-loongson \ -mno-branch-likely load-$(CONFIG_LEMOTE_FULOONG2E) +=0xffffffff80100000 +load-$(CONFIG_LEMOTE_MACH2F) +=0xffffffff80200000 # # MIPS Malta board diff --git a/arch/mips/include/asm/mach-loongson/machine.h b/arch/mips/include/asm/mach-loongson/machine.h index d2f5861..acf8359 100644 --- a/arch/mips/include/asm/mach-loongson/machine.h +++ b/arch/mips/include/asm/mach-loongson/machine.h @@ -17,4 +17,11 @@ #endif +/* use fuloong2f as the default machine of LEMOTE_MACH2F */ +#ifdef CONFIG_LEMOTE_MACH2F + +#define LOONGSON_MACHTYPE MACH_LEMOTE_FL2F + +#endif + #endif /* __ASM_MACH_LOONGSON_MACHINE_H */ diff --git a/arch/mips/loongson/Kconfig b/arch/mips/loongson/Kconfig index 818a028..3100237 100644 --- a/arch/mips/loongson/Kconfig +++ b/arch/mips/loongson/Kconfig @@ -28,4 +28,33 @@ config LEMOTE_FULOONG2E an FPGA northbridge Lemote Fuloong(2e) mini PC have a VIA686B south bridge. + +config LEMOTE_MACH2F + bool "Lemote Loongson 2F family machines" + select ARCH_SPARSEMEM_ENABLE + select BOARD_SCACHE + select BOOT_ELF32 + select CEVT_R4K + select CPU_HAS_WB + select CS5536 + select CSRC_R4K + select DMA_NONCOHERENT + select GENERIC_HARDIRQS_NO__DO_IRQ + select GENERIC_ISA_DMA_SUPPORT_BROKEN + select HW_HAS_PCI + select I8259 + select IRQ_CPU + select ISA + select SYS_HAS_CPU_LOONGSON2F + select SYS_HAS_EARLY_PRINTK + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_64BIT_KERNEL + select SYS_SUPPORTS_HIGHMEM + select SYS_SUPPORTS_LITTLE_ENDIAN + help + Lemote Loongson 2F family machines utilize the 2F revision of + Loongson processor and the AMD CS5536 south bridge. + + These family machines include fuloong2f mini PC, yeeloong2f notebook, + LingLoong allinone PC and so forth. endchoice -- cgit v0.10.2 From 21a41faa4d59716dac0169a48565109b9e5bf0ea Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Tue, 10 Nov 2009 00:06:11 +0800 Subject: MIPS: Lemote 2f: Enable legacy RTC driver Currently rtclib is not available on Loongson family machines but the legacy RTC driver works well on them. Deselect RTC_LIB to allow the legacy RTC driver to be selected. The rtclib patch series http://www.linux-mips.org/cgi-bin/mesg.cgi?a=linux-mips&i=a91e34bf2595157830d599cb66becd52247b1819.1257383766.git.wuzhangjin%40gmail.com or, in patchworks: http://patchwork.linux-mips.org/patch/570/ http://patchwork.linux-mips.org/patch/571/ http://patchwork.linux-mips.org/patch/572/ is eventually going to switch Lemote platforms to rtclib. Signed-off-by: Wu Zhangjin Cc: zhangfx@lemote.com Cc: yanh@lemote.com Cc: huhb@lemote.com Cc: Nicholas Mc Guire Cc: Arnaud Patard Cc: loongson-dev@googlegroups.com Cc: linux-mips@linux-mips.org Signed-off-by: Ralf Baechle diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 9618451..c2b4cd5 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -7,7 +7,7 @@ config MIPS select HAVE_ARCH_KGDB # Horrible source of confusion. Die, die, die ... select EMBEDDED - select RTC_LIB if !LEMOTE_FULOONG2E + select RTC_LIB if !MACH_LOONGSON mainmenu "Linux/MIPS Kernel Configuration" -- cgit v0.10.2 From 22c21003a91b543d82e87ef2e5195b888b5b9575 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Tue, 10 Nov 2009 00:06:12 +0800 Subject: MIPS: Lemote 2F: Add basic CS5536 VSM support Lemote Loongson 2F family machines use CS5536 as their south bridge and need these lowlevel interfaces to access the devices on CS5536. Virtualize the legacy devices on CS5536 as PCI devices. This way users can access the CS5536 PCI config space directly as a normal multi-function PCI 2.2 device. Signed-off-by: Wu Zhangjin Cc: zhangfx@lemote.com Cc: yanh@lemote.com Cc: huhb@lemote.com Cc: Nicholas Mc Guire Cc: Arnaud Patard Cc: loongson-dev@googlegroups.com Cc: linux-mips@linux-mips.org Signed-off-by: Ralf Baechle diff --git a/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h b/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h new file mode 100644 index 0000000..021f77c --- /dev/null +++ b/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h @@ -0,0 +1,305 @@ +/* + * The header file of cs5536 sourth bridge. + * + * Copyright (C) 2007 Lemote, Inc. + * Author : jlliu + */ + +#ifndef _CS5536_H +#define _CS5536_H + +#include + +extern void _rdmsr(u32 msr, u32 *hi, u32 *lo); +extern void _wrmsr(u32 msr, u32 hi, u32 lo); + +/* + * MSR module base + */ +#define CS5536_SB_MSR_BASE (0x00000000) +#define CS5536_GLIU_MSR_BASE (0x10000000) +#define CS5536_ILLEGAL_MSR_BASE (0x20000000) +#define CS5536_USB_MSR_BASE (0x40000000) +#define CS5536_IDE_MSR_BASE (0x60000000) +#define CS5536_DIVIL_MSR_BASE (0x80000000) +#define CS5536_ACC_MSR_BASE (0xa0000000) +#define CS5536_UNUSED_MSR_BASE (0xc0000000) +#define CS5536_GLCP_MSR_BASE (0xe0000000) + +#define SB_MSR_REG(offset) (CS5536_SB_MSR_BASE | (offset)) +#define GLIU_MSR_REG(offset) (CS5536_GLIU_MSR_BASE | (offset)) +#define ILLEGAL_MSR_REG(offset) (CS5536_ILLEGAL_MSR_BASE | (offset)) +#define USB_MSR_REG(offset) (CS5536_USB_MSR_BASE | (offset)) +#define IDE_MSR_REG(offset) (CS5536_IDE_MSR_BASE | (offset)) +#define DIVIL_MSR_REG(offset) (CS5536_DIVIL_MSR_BASE | (offset)) +#define ACC_MSR_REG(offset) (CS5536_ACC_MSR_BASE | (offset)) +#define UNUSED_MSR_REG(offset) (CS5536_UNUSED_MSR_BASE | (offset)) +#define GLCP_MSR_REG(offset) (CS5536_GLCP_MSR_BASE | (offset)) + +/* + * BAR SPACE OF VIRTUAL PCI : + * range for pci probe use, length is the actual size. + */ +/* IO space for all DIVIL modules */ +#define CS5536_IRQ_RANGE 0xffffffe0 /* USERD FOR PCI PROBE */ +#define CS5536_IRQ_LENGTH 0x20 /* THE REGS ACTUAL LENGTH */ +#define CS5536_SMB_RANGE 0xfffffff8 +#define CS5536_SMB_LENGTH 0x08 +#define CS5536_GPIO_RANGE 0xffffff00 +#define CS5536_GPIO_LENGTH 0x100 +#define CS5536_MFGPT_RANGE 0xffffffc0 +#define CS5536_MFGPT_LENGTH 0x40 +#define CS5536_ACPI_RANGE 0xffffffe0 +#define CS5536_ACPI_LENGTH 0x20 +#define CS5536_PMS_RANGE 0xffffff80 +#define CS5536_PMS_LENGTH 0x80 +/* IO space for IDE */ +#define CS5536_IDE_RANGE 0xfffffff0 +#define CS5536_IDE_LENGTH 0x10 +/* IO space for ACC */ +#define CS5536_ACC_RANGE 0xffffff80 +#define CS5536_ACC_LENGTH 0x80 +/* MEM space for ALL USB modules */ +#define CS5536_OHCI_RANGE 0xfffff000 +#define CS5536_OHCI_LENGTH 0x1000 +#define CS5536_EHCI_RANGE 0xfffff000 +#define CS5536_EHCI_LENGTH 0x1000 + +/* + * PCI MSR ACCESS + */ +#define PCI_MSR_CTRL 0xF0 +#define PCI_MSR_ADDR 0xF4 +#define PCI_MSR_DATA_LO 0xF8 +#define PCI_MSR_DATA_HI 0xFC + +/**************** MSR *****************************/ + +/* + * GLIU STANDARD MSR + */ +#define GLIU_CAP 0x00 +#define GLIU_CONFIG 0x01 +#define GLIU_SMI 0x02 +#define GLIU_ERROR 0x03 +#define GLIU_PM 0x04 +#define GLIU_DIAG 0x05 + +/* + * GLIU SPEC. MSR + */ +#define GLIU_P2D_BM0 0x20 +#define GLIU_P2D_BM1 0x21 +#define GLIU_P2D_BM2 0x22 +#define GLIU_P2D_BMK0 0x23 +#define GLIU_P2D_BMK1 0x24 +#define GLIU_P2D_BM3 0x25 +#define GLIU_P2D_BM4 0x26 +#define GLIU_COH 0x80 +#define GLIU_PAE 0x81 +#define GLIU_ARB 0x82 +#define GLIU_ASMI 0x83 +#define GLIU_AERR 0x84 +#define GLIU_DEBUG 0x85 +#define GLIU_PHY_CAP 0x86 +#define GLIU_NOUT_RESP 0x87 +#define GLIU_NOUT_WDATA 0x88 +#define GLIU_WHOAMI 0x8B +#define GLIU_SLV_DIS 0x8C +#define GLIU_IOD_BM0 0xE0 +#define GLIU_IOD_BM1 0xE1 +#define GLIU_IOD_BM2 0xE2 +#define GLIU_IOD_BM3 0xE3 +#define GLIU_IOD_BM4 0xE4 +#define GLIU_IOD_BM5 0xE5 +#define GLIU_IOD_BM6 0xE6 +#define GLIU_IOD_BM7 0xE7 +#define GLIU_IOD_BM8 0xE8 +#define GLIU_IOD_BM9 0xE9 +#define GLIU_IOD_SC0 0xEA +#define GLIU_IOD_SC1 0xEB +#define GLIU_IOD_SC2 0xEC +#define GLIU_IOD_SC3 0xED +#define GLIU_IOD_SC4 0xEE +#define GLIU_IOD_SC5 0xEF +#define GLIU_IOD_SC6 0xF0 +#define GLIU_IOD_SC7 0xF1 + +/* + * SB STANDARD + */ +#define SB_CAP 0x00 +#define SB_CONFIG 0x01 +#define SB_SMI 0x02 +#define SB_ERROR 0x03 +#define SB_MAR_ERR_EN 0x00000001 +#define SB_TAR_ERR_EN 0x00000002 +#define SB_RSVD_BIT1 0x00000004 +#define SB_EXCEP_ERR_EN 0x00000008 +#define SB_SYSE_ERR_EN 0x00000010 +#define SB_PARE_ERR_EN 0x00000020 +#define SB_TAS_ERR_EN 0x00000040 +#define SB_MAR_ERR_FLAG 0x00010000 +#define SB_TAR_ERR_FLAG 0x00020000 +#define SB_RSVD_BIT2 0x00040000 +#define SB_EXCEP_ERR_FLAG 0x00080000 +#define SB_SYSE_ERR_FLAG 0x00100000 +#define SB_PARE_ERR_FLAG 0x00200000 +#define SB_TAS_ERR_FLAG 0x00400000 +#define SB_PM 0x04 +#define SB_DIAG 0x05 + +/* + * SB SPEC. + */ +#define SB_CTRL 0x10 +#define SB_R0 0x20 +#define SB_R1 0x21 +#define SB_R2 0x22 +#define SB_R3 0x23 +#define SB_R4 0x24 +#define SB_R5 0x25 +#define SB_R6 0x26 +#define SB_R7 0x27 +#define SB_R8 0x28 +#define SB_R9 0x29 +#define SB_R10 0x2A +#define SB_R11 0x2B +#define SB_R12 0x2C +#define SB_R13 0x2D +#define SB_R14 0x2E +#define SB_R15 0x2F + +/* + * GLCP STANDARD + */ +#define GLCP_CAP 0x00 +#define GLCP_CONFIG 0x01 +#define GLCP_SMI 0x02 +#define GLCP_ERROR 0x03 +#define GLCP_PM 0x04 +#define GLCP_DIAG 0x05 + +/* + * GLCP SPEC. + */ +#define GLCP_CLK_DIS_DELAY 0x08 +#define GLCP_PM_CLK_DISABLE 0x09 +#define GLCP_GLB_PM 0x0B +#define GLCP_DBG_OUT 0x0C +#define GLCP_RSVD1 0x0D +#define GLCP_SOFT_COM 0x0E +#define SOFT_BAR_SMB_FLAG 0x00000001 +#define SOFT_BAR_GPIO_FLAG 0x00000002 +#define SOFT_BAR_MFGPT_FLAG 0x00000004 +#define SOFT_BAR_IRQ_FLAG 0x00000008 +#define SOFT_BAR_PMS_FLAG 0x00000010 +#define SOFT_BAR_ACPI_FLAG 0x00000020 +#define SOFT_BAR_IDE_FLAG 0x00000400 +#define SOFT_BAR_ACC_FLAG 0x00000800 +#define SOFT_BAR_OHCI_FLAG 0x00001000 +#define SOFT_BAR_EHCI_FLAG 0x00002000 +#define GLCP_RSVD2 0x0F +#define GLCP_CLK_OFF 0x10 +#define GLCP_CLK_ACTIVE 0x11 +#define GLCP_CLK_DISABLE 0x12 +#define GLCP_CLK4ACK 0x13 +#define GLCP_SYS_RST 0x14 +#define GLCP_RSVD3 0x15 +#define GLCP_DBG_CLK_CTRL 0x16 +#define GLCP_CHIP_REV_ID 0x17 + +/* PIC */ +#define PIC_YSEL_LOW 0x20 +#define PIC_YSEL_LOW_USB_SHIFT 8 +#define PIC_YSEL_LOW_ACC_SHIFT 16 +#define PIC_YSEL_LOW_FLASH_SHIFT 24 +#define PIC_YSEL_HIGH 0x21 +#define PIC_ZSEL_LOW 0x22 +#define PIC_ZSEL_HIGH 0x23 +#define PIC_IRQM_PRIM 0x24 +#define PIC_IRQM_LPC 0x25 +#define PIC_XIRR_STS_LOW 0x26 +#define PIC_XIRR_STS_HIGH 0x27 +#define PCI_SHDW 0x34 + +/* + * DIVIL STANDARD + */ +#define DIVIL_CAP 0x00 +#define DIVIL_CONFIG 0x01 +#define DIVIL_SMI 0x02 +#define DIVIL_ERROR 0x03 +#define DIVIL_PM 0x04 +#define DIVIL_DIAG 0x05 + +/* + * DIVIL SPEC. + */ +#define DIVIL_LBAR_IRQ 0x08 +#define DIVIL_LBAR_KEL 0x09 +#define DIVIL_LBAR_SMB 0x0B +#define DIVIL_LBAR_GPIO 0x0C +#define DIVIL_LBAR_MFGPT 0x0D +#define DIVIL_LBAR_ACPI 0x0E +#define DIVIL_LBAR_PMS 0x0F +#define DIVIL_LEG_IO 0x14 +#define DIVIL_BALL_OPTS 0x15 +#define DIVIL_SOFT_IRQ 0x16 +#define DIVIL_SOFT_RESET 0x17 + +/* MFGPT */ +#define MFGPT_IRQ 0x28 + +/* + * IDE STANDARD + */ +#define IDE_CAP 0x00 +#define IDE_CONFIG 0x01 +#define IDE_SMI 0x02 +#define IDE_ERROR 0x03 +#define IDE_PM 0x04 +#define IDE_DIAG 0x05 + +/* + * IDE SPEC. + */ +#define IDE_IO_BAR 0x08 +#define IDE_CFG 0x10 +#define IDE_DTC 0x12 +#define IDE_CAST 0x13 +#define IDE_ETC 0x14 +#define IDE_INTERNAL_PM 0x15 + +/* + * ACC STANDARD + */ +#define ACC_CAP 0x00 +#define ACC_CONFIG 0x01 +#define ACC_SMI 0x02 +#define ACC_ERROR 0x03 +#define ACC_PM 0x04 +#define ACC_DIAG 0x05 + +/* + * USB STANDARD + */ +#define USB_CAP 0x00 +#define USB_CONFIG 0x01 +#define USB_SMI 0x02 +#define USB_ERROR 0x03 +#define USB_PM 0x04 +#define USB_DIAG 0x05 + +/* + * USB SPEC. + */ +#define USB_OHCI 0x08 +#define USB_EHCI 0x09 + +/****************** NATIVE ***************************/ +/* GPIO : I/O SPACE; REG : 32BITS */ +#define GPIOL_OUT_VAL 0x00 +#define GPIOL_OUT_EN 0x04 + +#endif /* _CS5536_H */ diff --git a/arch/mips/include/asm/mach-loongson/cs5536/cs5536_pci.h b/arch/mips/include/asm/mach-loongson/cs5536/cs5536_pci.h new file mode 100644 index 0000000..0dca9c8 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson/cs5536/cs5536_pci.h @@ -0,0 +1,153 @@ +/* + * the definition file of cs5536 Virtual Support Module(VSM). + * pci configuration space can be accessed through the VSM, so + * there is no need of the MSR read/write now, except the spec. + * MSR registers which are not implemented yet. + * + * Copyright (C) 2007 Lemote Inc. + * Author : jlliu, liujl@lemote.com + */ + +#ifndef _CS5536_PCI_H +#define _CS5536_PCI_H + +#include +#include + +extern void cs5536_pci_conf_write4(int function, int reg, u32 value); +extern u32 cs5536_pci_conf_read4(int function, int reg); + +#define CS5536_ACC_INTR 9 +#define CS5536_IDE_INTR 14 +#define CS5536_USB_INTR 11 +#define CS5536_MFGPT_INTR 5 +#define CS5536_UART1_INTR 4 +#define CS5536_UART2_INTR 3 + +/************** PCI BUS DEVICE FUNCTION ***************/ + +/* + * PCI bus device function + */ +#define PCI_BUS_CS5536 0 +#define PCI_IDSEL_CS5536 14 + +/********** STANDARD PCI-2.2 EXPANSION ****************/ + +/* + * PCI configuration space + * we have to virtualize the PCI configure space head, so we should + * define the necessary IDs and some others. + */ + +/* CONFIG of PCI VENDOR ID*/ +#define CFG_PCI_VENDOR_ID(mod_dev_id, sys_vendor_id) \ + (((mod_dev_id) << 16) | (sys_vendor_id)) + +/* VENDOR ID */ +#define CS5536_VENDOR_ID 0x1022 + +/* DEVICE ID */ +#define CS5536_ISA_DEVICE_ID 0x2090 +#define CS5536_IDE_DEVICE_ID 0x209a +#define CS5536_ACC_DEVICE_ID 0x2093 +#define CS5536_OHCI_DEVICE_ID 0x2094 +#define CS5536_EHCI_DEVICE_ID 0x2095 + +/* CLASS CODE : CLASS SUB-CLASS INTERFACE */ +#define CS5536_ISA_CLASS_CODE 0x060100 +#define CS5536_IDE_CLASS_CODE 0x010180 +#define CS5536_ACC_CLASS_CODE 0x040100 +#define CS5536_OHCI_CLASS_CODE 0x0C0310 +#define CS5536_EHCI_CLASS_CODE 0x0C0320 + +/* BHLC : BIST HEADER-TYPE LATENCY-TIMER CACHE-LINE-SIZE */ + +#define CFG_PCI_CACHE_LINE_SIZE(header_type, latency_timer) \ + ((PCI_NONE_BIST << 24) | ((header_type) << 16) \ + | ((latency_timer) << 8) | PCI_NORMAL_CACHE_LINE_SIZE); + +#define PCI_NONE_BIST 0x00 /* RO not implemented yet. */ +#define PCI_BRIDGE_HEADER_TYPE 0x80 /* RO */ +#define PCI_NORMAL_HEADER_TYPE 0x00 +#define PCI_NORMAL_LATENCY_TIMER 0x00 +#define PCI_NORMAL_CACHE_LINE_SIZE 0x08 /* RW */ + +/* BAR */ +#define PCI_BAR0_REG 0x10 +#define PCI_BAR1_REG 0x14 +#define PCI_BAR2_REG 0x18 +#define PCI_BAR3_REG 0x1c +#define PCI_BAR4_REG 0x20 +#define PCI_BAR5_REG 0x24 +#define PCI_BAR_COUNT 6 +#define PCI_BAR_RANGE_MASK 0xFFFFFFFF + +/* CARDBUS CIS POINTER */ +#define PCI_CARDBUS_CIS_POINTER 0x00000000 + +/* SUBSYSTEM VENDOR ID */ +#define CS5536_SUB_VENDOR_ID CS5536_VENDOR_ID + +/* SUBSYSTEM ID */ +#define CS5536_ISA_SUB_ID CS5536_ISA_DEVICE_ID +#define CS5536_IDE_SUB_ID CS5536_IDE_DEVICE_ID +#define CS5536_ACC_SUB_ID CS5536_ACC_DEVICE_ID +#define CS5536_OHCI_SUB_ID CS5536_OHCI_DEVICE_ID +#define CS5536_EHCI_SUB_ID CS5536_EHCI_DEVICE_ID + +/* EXPANSION ROM BAR */ +#define PCI_EXPANSION_ROM_BAR 0x00000000 + +/* CAPABILITIES POINTER */ +#define PCI_CAPLIST_POINTER 0x00000000 +#define PCI_CAPLIST_USB_POINTER 0x40 +/* INTERRUPT */ + +#define CFG_PCI_INTERRUPT_LINE(pin, mod_intr) \ + ((PCI_MAX_LATENCY << 24) | (PCI_MIN_GRANT << 16) | \ + ((pin) << 8) | (mod_intr)) + +#define PCI_MAX_LATENCY 0x40 +#define PCI_MIN_GRANT 0x00 +#define PCI_DEFAULT_PIN 0x01 + +/*********** EXPANSION PCI REG ************************/ + +/* + * ISA EXPANSION + */ +#define PCI_UART1_INT_REG 0x50 +#define PCI_UART2_INT_REG 0x54 +#define PCI_ISA_FIXUP_REG 0x58 + +/* + * IDE EXPANSION + */ +#define PCI_IDE_CFG_REG 0x40 +#define CS5536_IDE_FLASH_SIGNATURE 0xDEADBEEF +#define PCI_IDE_DTC_REG 0x48 +#define PCI_IDE_CAST_REG 0x4C +#define PCI_IDE_ETC_REG 0x50 +#define PCI_IDE_PM_REG 0x54 +#define PCI_IDE_INT_REG 0x60 + +/* + * ACC EXPANSION + */ +#define PCI_ACC_INT_REG 0x50 + +/* + * OHCI EXPANSION : INTTERUPT IS IMPLEMENTED BY THE OHCI + */ +#define PCI_OHCI_PM_REG 0x40 +#define PCI_OHCI_INT_REG 0x50 + +/* + * EHCI EXPANSION + */ +#define PCI_EHCI_LEGSMIEN_REG 0x50 +#define PCI_EHCI_LEGSMISTS_REG 0x54 +#define PCI_EHCI_FLADJ_REG 0x60 + +#endif /* _CS5536_PCI_H_ */ diff --git a/arch/mips/include/asm/mach-loongson/cs5536/cs5536_vsm.h b/arch/mips/include/asm/mach-loongson/cs5536/cs5536_vsm.h new file mode 100644 index 0000000..6305bea --- /dev/null +++ b/arch/mips/include/asm/mach-loongson/cs5536/cs5536_vsm.h @@ -0,0 +1,31 @@ +/* + * the read/write interfaces for Virtual Support Module(VSM) + * + * Copyright (C) 2009 Lemote, Inc. + * Author: Wu Zhangjin + */ + +#ifndef _CS5536_VSM_H +#define _CS5536_VSM_H + +#include + +typedef void (*cs5536_pci_vsm_write)(int reg, u32 value); +typedef u32 (*cs5536_pci_vsm_read)(int reg); + +#define DECLARE_CS5536_MODULE(name) \ +extern void pci_##name##_write_reg(int reg, u32 value); \ +extern u32 pci_##name##_read_reg(int reg); + +/* ide module */ +DECLARE_CS5536_MODULE(ide) +/* acc module */ +DECLARE_CS5536_MODULE(acc) +/* ohci module */ +DECLARE_CS5536_MODULE(ohci) +/* isa module */ +DECLARE_CS5536_MODULE(isa) +/* ehci module */ +DECLARE_CS5536_MODULE(ehci) + +#endif /* _CS5536_VSM_H */ diff --git a/arch/mips/loongson/Kconfig b/arch/mips/loongson/Kconfig index 3100237..a214127 100644 --- a/arch/mips/loongson/Kconfig +++ b/arch/mips/loongson/Kconfig @@ -58,3 +58,6 @@ config LEMOTE_MACH2F These family machines include fuloong2f mini PC, yeeloong2f notebook, LingLoong allinone PC and so forth. endchoice + +config CS5536 + bool diff --git a/arch/mips/loongson/common/Makefile b/arch/mips/loongson/common/Makefile index be6adf7..a82527f 100644 --- a/arch/mips/loongson/common/Makefile +++ b/arch/mips/loongson/common/Makefile @@ -10,3 +10,9 @@ obj-y += setup.o init.o cmdline.o env.o time.o reset.o irq.o \ # obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-$(CONFIG_SERIAL_8250) += serial.o + +# +# Enable CS5536 Virtual Support Module(VSM) to virtulize the PCI configure +# space +# +obj-$(CONFIG_CS5536) += cs5536/ diff --git a/arch/mips/loongson/common/cs5536/Makefile b/arch/mips/loongson/common/cs5536/Makefile new file mode 100644 index 0000000..31657ee --- /dev/null +++ b/arch/mips/loongson/common/cs5536/Makefile @@ -0,0 +1,8 @@ +# +# Makefile for CS5536 support. +# + +obj-$(CONFIG_CS5536) += cs5536_pci.o cs5536_ide.o cs5536_acc.o cs5536_ohci.o \ + cs5536_isa.o cs5536_ehci.o + +EXTRA_CFLAGS += -Werror diff --git a/arch/mips/loongson/common/cs5536/cs5536_acc.c b/arch/mips/loongson/common/cs5536/cs5536_acc.c new file mode 100644 index 0000000..b49485f --- /dev/null +++ b/arch/mips/loongson/common/cs5536/cs5536_acc.c @@ -0,0 +1,140 @@ +/* + * the ACC Virtual Support Module of AMD CS5536 + * + * Copyright (C) 2007 Lemote, Inc. + * Author : jlliu, liujl@lemote.com + * + * Copyright (C) 2009 Lemote, Inc. + * Author: Wu Zhangjin, wuzj@lemote.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. + */ + +#include +#include + +void pci_acc_write_reg(int reg, u32 value) +{ + u32 hi = 0, lo = value; + + switch (reg) { + case PCI_COMMAND: + _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo); + if (value & PCI_COMMAND_MASTER) + lo |= (0x03 << 8); + else + lo &= ~(0x03 << 8); + _wrmsr(GLIU_MSR_REG(GLIU_PAE), hi, lo); + break; + case PCI_STATUS: + if (value & PCI_STATUS_PARITY) { + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) { + lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + } + } + break; + case PCI_BAR0_REG: + if (value == PCI_BAR_RANGE_MASK) { + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_ACC_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else if (value & 0x01) { + value &= 0xfffffffc; + hi = 0xA0000000 | ((value & 0x000ff000) >> 12); + lo = 0x000fff80 | ((value & 0x00000fff) << 20); + _wrmsr(GLIU_MSR_REG(GLIU_IOD_BM1), hi, lo); + } + break; + case PCI_ACC_INT_REG: + _rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo); + /* disable all the usb interrupt in PIC */ + lo &= ~(0xf << PIC_YSEL_LOW_ACC_SHIFT); + if (value) /* enable all the acc interrupt in PIC */ + lo |= (CS5536_ACC_INTR << PIC_YSEL_LOW_ACC_SHIFT); + _wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo); + break; + default: + break; + } +} + +u32 pci_acc_read_reg(int reg) +{ + u32 hi, lo; + u32 conf_data = 0; + + switch (reg) { + case PCI_VENDOR_ID: + conf_data = + CFG_PCI_VENDOR_ID(CS5536_ACC_DEVICE_ID, CS5536_VENDOR_ID); + break; + case PCI_COMMAND: + _rdmsr(GLIU_MSR_REG(GLIU_IOD_BM1), &hi, &lo); + if (((lo & 0xfff00000) || (hi & 0x000000ff)) + && ((hi & 0xf0000000) == 0xa0000000)) + conf_data |= PCI_COMMAND_IO; + _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo); + if ((lo & 0x300) == 0x300) + conf_data |= PCI_COMMAND_MASTER; + break; + case PCI_STATUS: + conf_data |= PCI_STATUS_66MHZ; + conf_data |= PCI_STATUS_FAST_BACK; + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) + conf_data |= PCI_STATUS_PARITY; + conf_data |= PCI_STATUS_DEVSEL_MEDIUM; + break; + case PCI_CLASS_REVISION: + _rdmsr(ACC_MSR_REG(ACC_CAP), &hi, &lo); + conf_data = lo & 0x000000ff; + conf_data |= (CS5536_ACC_CLASS_CODE << 8); + break; + case PCI_CACHE_LINE_SIZE: + conf_data = + CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE, + PCI_NORMAL_LATENCY_TIMER); + break; + case PCI_BAR0_REG: + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if (lo & SOFT_BAR_ACC_FLAG) { + conf_data = CS5536_ACC_RANGE | + PCI_BASE_ADDRESS_SPACE_IO; + lo &= ~SOFT_BAR_ACC_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else { + _rdmsr(GLIU_MSR_REG(GLIU_IOD_BM1), &hi, &lo); + conf_data = (hi & 0x000000ff) << 12; + conf_data |= (lo & 0xfff00000) >> 20; + conf_data |= 0x01; + conf_data &= ~0x02; + } + break; + case PCI_CARDBUS_CIS: + conf_data = PCI_CARDBUS_CIS_POINTER; + break; + case PCI_SUBSYSTEM_VENDOR_ID: + conf_data = + CFG_PCI_VENDOR_ID(CS5536_ACC_SUB_ID, CS5536_SUB_VENDOR_ID); + break; + case PCI_ROM_ADDRESS: + conf_data = PCI_EXPANSION_ROM_BAR; + break; + case PCI_CAPABILITY_LIST: + conf_data = PCI_CAPLIST_USB_POINTER; + break; + case PCI_INTERRUPT_LINE: + conf_data = + CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_ACC_INTR); + break; + default: + break; + } + + return conf_data; +} diff --git a/arch/mips/loongson/common/cs5536/cs5536_ehci.c b/arch/mips/loongson/common/cs5536/cs5536_ehci.c new file mode 100644 index 0000000..74f9c59 --- /dev/null +++ b/arch/mips/loongson/common/cs5536/cs5536_ehci.c @@ -0,0 +1,158 @@ +/* + * the EHCI Virtual Support Module of AMD CS5536 + * + * Copyright (C) 2007 Lemote, Inc. + * Author : jlliu, liujl@lemote.com + * + * Copyright (C) 2009 Lemote, Inc. + * Author: Wu Zhangjin, wuzj@lemote.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. + */ + +#include +#include + +void pci_ehci_write_reg(int reg, u32 value) +{ + u32 hi = 0, lo = value; + + switch (reg) { + case PCI_COMMAND: + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + if (value & PCI_COMMAND_MASTER) + hi |= PCI_COMMAND_MASTER; + else + hi &= ~PCI_COMMAND_MASTER; + + if (value & PCI_COMMAND_MEMORY) + hi |= PCI_COMMAND_MEMORY; + else + hi &= ~PCI_COMMAND_MEMORY; + _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo); + break; + case PCI_STATUS: + if (value & PCI_STATUS_PARITY) { + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) { + lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + } + } + break; + case PCI_BAR0_REG: + if (value == PCI_BAR_RANGE_MASK) { + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_EHCI_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else if ((value & 0x01) == 0x00) { + _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo); + + value &= 0xfffffff0; + hi = 0x40000000 | ((value & 0xff000000) >> 24); + lo = 0x000fffff | ((value & 0x00fff000) << 8); + _wrmsr(GLIU_MSR_REG(GLIU_P2D_BM4), hi, lo); + } + break; + case PCI_EHCI_LEGSMIEN_REG: + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + hi &= 0x003f0000; + hi |= (value & 0x3f) << 16; + _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo); + break; + case PCI_EHCI_FLADJ_REG: + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + hi &= ~0x00003f00; + hi |= value & 0x00003f00; + _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo); + break; + default: + break; + } +} + +u32 pci_ehci_read_reg(int reg) +{ + u32 conf_data = 0; + u32 hi, lo; + + switch (reg) { + case PCI_VENDOR_ID: + conf_data = + CFG_PCI_VENDOR_ID(CS5536_EHCI_DEVICE_ID, CS5536_VENDOR_ID); + break; + case PCI_COMMAND: + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + if (hi & PCI_COMMAND_MASTER) + conf_data |= PCI_COMMAND_MASTER; + if (hi & PCI_COMMAND_MEMORY) + conf_data |= PCI_COMMAND_MEMORY; + break; + case PCI_STATUS: + conf_data |= PCI_STATUS_66MHZ; + conf_data |= PCI_STATUS_FAST_BACK; + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) + conf_data |= PCI_STATUS_PARITY; + conf_data |= PCI_STATUS_DEVSEL_MEDIUM; + break; + case PCI_CLASS_REVISION: + _rdmsr(USB_MSR_REG(USB_CAP), &hi, &lo); + conf_data = lo & 0x000000ff; + conf_data |= (CS5536_EHCI_CLASS_CODE << 8); + break; + case PCI_CACHE_LINE_SIZE: + conf_data = + CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE, + PCI_NORMAL_LATENCY_TIMER); + break; + case PCI_BAR0_REG: + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if (lo & SOFT_BAR_EHCI_FLAG) { + conf_data = CS5536_EHCI_RANGE | + PCI_BASE_ADDRESS_SPACE_MEMORY; + lo &= ~SOFT_BAR_EHCI_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else { + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + conf_data = lo & 0xfffff000; + } + break; + case PCI_CARDBUS_CIS: + conf_data = PCI_CARDBUS_CIS_POINTER; + break; + case PCI_SUBSYSTEM_VENDOR_ID: + conf_data = + CFG_PCI_VENDOR_ID(CS5536_EHCI_SUB_ID, CS5536_SUB_VENDOR_ID); + break; + case PCI_ROM_ADDRESS: + conf_data = PCI_EXPANSION_ROM_BAR; + break; + case PCI_CAPABILITY_LIST: + conf_data = PCI_CAPLIST_USB_POINTER; + break; + case PCI_INTERRUPT_LINE: + conf_data = + CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_USB_INTR); + break; + case PCI_EHCI_LEGSMIEN_REG: + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + conf_data = (hi & 0x003f0000) >> 16; + break; + case PCI_EHCI_LEGSMISTS_REG: + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + conf_data = (hi & 0x3f000000) >> 24; + break; + case PCI_EHCI_FLADJ_REG: + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + conf_data = hi & 0x00003f00; + break; + default: + break; + } + + return conf_data; +} diff --git a/arch/mips/loongson/common/cs5536/cs5536_ide.c b/arch/mips/loongson/common/cs5536/cs5536_ide.c new file mode 100644 index 0000000..3f61594 --- /dev/null +++ b/arch/mips/loongson/common/cs5536/cs5536_ide.c @@ -0,0 +1,179 @@ +/* + * the IDE Virtual Support Module of AMD CS5536 + * + * Copyright (C) 2007 Lemote, Inc. + * Author : jlliu, liujl@lemote.com + * + * Copyright (C) 2009 Lemote, Inc. + * Author: Wu Zhangjin, wuzj@lemote.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. + */ + +#include +#include + +void pci_ide_write_reg(int reg, u32 value) +{ + u32 hi = 0, lo = value; + + switch (reg) { + case PCI_COMMAND: + _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo); + if (value & PCI_COMMAND_MASTER) + lo |= (0x03 << 4); + else + lo &= ~(0x03 << 4); + _wrmsr(GLIU_MSR_REG(GLIU_PAE), hi, lo); + break; + case PCI_STATUS: + if (value & PCI_STATUS_PARITY) { + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) { + lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + } + } + break; + case PCI_CACHE_LINE_SIZE: + value &= 0x0000ff00; + _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo); + hi &= 0xffffff00; + hi |= (value >> 8); + _wrmsr(SB_MSR_REG(SB_CTRL), hi, lo); + break; + case PCI_BAR4_REG: + if (value == PCI_BAR_RANGE_MASK) { + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_IDE_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else if (value & 0x01) { + lo = (value & 0xfffffff0) | 0x1; + _wrmsr(IDE_MSR_REG(IDE_IO_BAR), hi, lo); + + value &= 0xfffffffc; + hi = 0x60000000 | ((value & 0x000ff000) >> 12); + lo = 0x000ffff0 | ((value & 0x00000fff) << 20); + _wrmsr(GLIU_MSR_REG(GLIU_IOD_BM2), hi, lo); + } + break; + case PCI_IDE_CFG_REG: + if (value == CS5536_IDE_FLASH_SIGNATURE) { + _rdmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), &hi, &lo); + lo |= 0x01; + _wrmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), hi, lo); + } else + _wrmsr(IDE_MSR_REG(IDE_CFG), hi, lo); + break; + case PCI_IDE_DTC_REG: + _wrmsr(IDE_MSR_REG(IDE_DTC), hi, lo); + break; + case PCI_IDE_CAST_REG: + _wrmsr(IDE_MSR_REG(IDE_CAST), hi, lo); + break; + case PCI_IDE_ETC_REG: + _wrmsr(IDE_MSR_REG(IDE_ETC), hi, lo); + break; + case PCI_IDE_PM_REG: + _wrmsr(IDE_MSR_REG(IDE_INTERNAL_PM), hi, lo); + break; + default: + break; + } +} + +u32 pci_ide_read_reg(int reg) +{ + u32 conf_data = 0; + u32 hi, lo; + + switch (reg) { + case PCI_VENDOR_ID: + conf_data = + CFG_PCI_VENDOR_ID(CS5536_IDE_DEVICE_ID, CS5536_VENDOR_ID); + break; + case PCI_COMMAND: + _rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo); + if (lo & 0xfffffff0) + conf_data |= PCI_COMMAND_IO; + _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo); + if ((lo & 0x30) == 0x30) + conf_data |= PCI_COMMAND_MASTER; + break; + case PCI_STATUS: + conf_data |= PCI_STATUS_66MHZ; + conf_data |= PCI_STATUS_FAST_BACK; + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) + conf_data |= PCI_STATUS_PARITY; + conf_data |= PCI_STATUS_DEVSEL_MEDIUM; + break; + case PCI_CLASS_REVISION: + _rdmsr(IDE_MSR_REG(IDE_CAP), &hi, &lo); + conf_data = lo & 0x000000ff; + conf_data |= (CS5536_IDE_CLASS_CODE << 8); + break; + case PCI_CACHE_LINE_SIZE: + _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo); + hi &= 0x000000f8; + conf_data = CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE, hi); + break; + case PCI_BAR4_REG: + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if (lo & SOFT_BAR_IDE_FLAG) { + conf_data = CS5536_IDE_RANGE | + PCI_BASE_ADDRESS_SPACE_IO; + lo &= ~SOFT_BAR_IDE_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else { + _rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo); + conf_data = lo & 0xfffffff0; + conf_data |= 0x01; + conf_data &= ~0x02; + } + break; + case PCI_CARDBUS_CIS: + conf_data = PCI_CARDBUS_CIS_POINTER; + break; + case PCI_SUBSYSTEM_VENDOR_ID: + conf_data = + CFG_PCI_VENDOR_ID(CS5536_IDE_SUB_ID, CS5536_SUB_VENDOR_ID); + break; + case PCI_ROM_ADDRESS: + conf_data = PCI_EXPANSION_ROM_BAR; + break; + case PCI_CAPABILITY_LIST: + conf_data = PCI_CAPLIST_POINTER; + break; + case PCI_INTERRUPT_LINE: + conf_data = + CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_IDE_INTR); + break; + case PCI_IDE_CFG_REG: + _rdmsr(IDE_MSR_REG(IDE_CFG), &hi, &lo); + conf_data = lo; + break; + case PCI_IDE_DTC_REG: + _rdmsr(IDE_MSR_REG(IDE_DTC), &hi, &lo); + conf_data = lo; + break; + case PCI_IDE_CAST_REG: + _rdmsr(IDE_MSR_REG(IDE_CAST), &hi, &lo); + conf_data = lo; + break; + case PCI_IDE_ETC_REG: + _rdmsr(IDE_MSR_REG(IDE_ETC), &hi, &lo); + conf_data = lo; + case PCI_IDE_PM_REG: + _rdmsr(IDE_MSR_REG(IDE_INTERNAL_PM), &hi, &lo); + conf_data = lo; + break; + default: + break; + } + + return conf_data; +} diff --git a/arch/mips/loongson/common/cs5536/cs5536_isa.c b/arch/mips/loongson/common/cs5536/cs5536_isa.c new file mode 100644 index 0000000..b6f17f5 --- /dev/null +++ b/arch/mips/loongson/common/cs5536/cs5536_isa.c @@ -0,0 +1,316 @@ +/* + * the ISA Virtual Support Module of AMD CS5536 + * + * Copyright (C) 2007 Lemote, Inc. + * Author : jlliu, liujl@lemote.com + * + * Copyright (C) 2009 Lemote, Inc. + * Author: Wu Zhangjin, wuzj@lemote.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. + */ + +#include +#include + +/* common variables for PCI_ISA_READ/WRITE_BAR */ +static const u32 divil_msr_reg[6] = { + DIVIL_MSR_REG(DIVIL_LBAR_SMB), DIVIL_MSR_REG(DIVIL_LBAR_GPIO), + DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), DIVIL_MSR_REG(DIVIL_LBAR_IRQ), + DIVIL_MSR_REG(DIVIL_LBAR_PMS), DIVIL_MSR_REG(DIVIL_LBAR_ACPI), +}; + +static const u32 soft_bar_flag[6] = { + SOFT_BAR_SMB_FLAG, SOFT_BAR_GPIO_FLAG, SOFT_BAR_MFGPT_FLAG, + SOFT_BAR_IRQ_FLAG, SOFT_BAR_PMS_FLAG, SOFT_BAR_ACPI_FLAG, +}; + +static const u32 sb_msr_reg[6] = { + SB_MSR_REG(SB_R0), SB_MSR_REG(SB_R1), SB_MSR_REG(SB_R2), + SB_MSR_REG(SB_R3), SB_MSR_REG(SB_R4), SB_MSR_REG(SB_R5), +}; + +static const u32 bar_space_range[6] = { + CS5536_SMB_RANGE, CS5536_GPIO_RANGE, CS5536_MFGPT_RANGE, + CS5536_IRQ_RANGE, CS5536_PMS_RANGE, CS5536_ACPI_RANGE, +}; + +static const int bar_space_len[6] = { + CS5536_SMB_LENGTH, CS5536_GPIO_LENGTH, CS5536_MFGPT_LENGTH, + CS5536_IRQ_LENGTH, CS5536_PMS_LENGTH, CS5536_ACPI_LENGTH, +}; + +/* + * enable the divil module bar space. + * + * For all the DIVIL module LBAR, you should control the DIVIL LBAR reg + * and the RCONFx(0~5) reg to use the modules. + */ +static void divil_lbar_enable(void) +{ + u32 hi, lo; + int offset; + + /* + * The DIVIL IRQ is not used yet. and make the RCONF0 reserved. + */ + + for (offset = DIVIL_LBAR_SMB; offset <= DIVIL_LBAR_PMS; offset++) { + _rdmsr(DIVIL_MSR_REG(offset), &hi, &lo); + hi |= 0x01; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_SMB), hi, lo); + } +} + +/* + * disable the divil module bar space. + */ +static void divil_lbar_disable(void) +{ + u32 hi, lo; + int offset; + + for (offset = DIVIL_LBAR_SMB; offset <= DIVIL_LBAR_PMS; offset++) { + _rdmsr(DIVIL_MSR_REG(offset), &hi, &lo); + hi &= ~0x01; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_SMB), hi, lo); + } +} + +/* + * BAR write: write value to the n BAR + */ + +void pci_isa_write_bar(int n, u32 value) +{ + u32 hi = 0, lo = value; + + if (value == PCI_BAR_RANGE_MASK) { + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= soft_bar_flag[n]; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else if (value & 0x01) { + /* NATIVE reg */ + hi = 0x0000f001; + lo &= bar_space_range[n]; + _wrmsr(divil_msr_reg[n], hi, lo); + + /* RCONFx is 4bytes in units for I/O space */ + hi = ((value & 0x000ffffc) << 12) | + ((bar_space_len[n] - 4) << 12) | 0x01; + lo = ((value & 0x000ffffc) << 12) | 0x01; + _wrmsr(sb_msr_reg[n], hi, lo); + } +} + +/* + * BAR read: read the n BAR + */ + +u32 pci_isa_read_bar(int n) +{ + u32 conf_data = 0; + u32 hi, lo; + + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if (lo & soft_bar_flag[n]) { + conf_data = bar_space_range[n] | PCI_BASE_ADDRESS_SPACE_IO; + lo &= ~soft_bar_flag[n]; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else { + _rdmsr(divil_msr_reg[n], &hi, &lo); + conf_data = lo & bar_space_range[n]; + conf_data |= 0x01; + conf_data &= ~0x02; + } + return conf_data; +} + +/* + * isa_write: ISA write transfer + * + * We assume that this is not a bus master transfer. + */ +void pci_isa_write_reg(int reg, u32 value) +{ + u32 hi = 0, lo = value; + u32 temp; + + switch (reg) { + case PCI_COMMAND: + if (value & PCI_COMMAND_IO) + divil_lbar_enable(); + else + divil_lbar_disable(); + break; + case PCI_STATUS: + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + temp = lo & 0x0000ffff; + if ((value & PCI_STATUS_SIG_TARGET_ABORT) && + (lo & SB_TAS_ERR_EN)) + temp |= SB_TAS_ERR_FLAG; + + if ((value & PCI_STATUS_REC_TARGET_ABORT) && + (lo & SB_TAR_ERR_EN)) + temp |= SB_TAR_ERR_FLAG; + + if ((value & PCI_STATUS_REC_MASTER_ABORT) + && (lo & SB_MAR_ERR_EN)) + temp |= SB_MAR_ERR_FLAG; + + if ((value & PCI_STATUS_DETECTED_PARITY) + && (lo & SB_PARE_ERR_EN)) + temp |= SB_PARE_ERR_FLAG; + + lo = temp; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + break; + case PCI_CACHE_LINE_SIZE: + value &= 0x0000ff00; + _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo); + hi &= 0xffffff00; + hi |= (value >> 8); + _wrmsr(SB_MSR_REG(SB_CTRL), hi, lo); + break; + case PCI_BAR0_REG: + pci_isa_write_bar(0, value); + break; + case PCI_BAR1_REG: + pci_isa_write_bar(1, value); + break; + case PCI_BAR2_REG: + pci_isa_write_bar(2, value); + break; + case PCI_BAR3_REG: + pci_isa_write_bar(3, value); + break; + case PCI_BAR4_REG: + pci_isa_write_bar(4, value); + break; + case PCI_BAR5_REG: + pci_isa_write_bar(5, value); + break; + case PCI_UART1_INT_REG: + _rdmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), &hi, &lo); + /* disable uart1 interrupt in PIC */ + lo &= ~(0xf << 24); + if (value) /* enable uart1 interrupt in PIC */ + lo |= (CS5536_UART1_INTR << 24); + _wrmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), hi, lo); + break; + case PCI_UART2_INT_REG: + _rdmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), &hi, &lo); + /* disable uart2 interrupt in PIC */ + lo &= ~(0xf << 28); + if (value) /* enable uart2 interrupt in PIC */ + lo |= (CS5536_UART2_INTR << 28); + _wrmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), hi, lo); + break; + case PCI_ISA_FIXUP_REG: + if (value) { + /* enable the TARGET ABORT/MASTER ABORT etc. */ + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + lo |= 0x00000063; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + } + + default: + /* ALL OTHER PCI CONFIG SPACE HEADER IS NOT IMPLEMENTED. */ + break; + } +} + +/* + * isa_read: ISA read transfers + * + * We assume that this is not a bus master transfer. + */ +u32 pci_isa_read_reg(int reg) +{ + u32 conf_data = 0; + u32 hi, lo; + + switch (reg) { + case PCI_VENDOR_ID: + conf_data = + CFG_PCI_VENDOR_ID(CS5536_ISA_DEVICE_ID, CS5536_VENDOR_ID); + break; + case PCI_COMMAND: + /* we just check the first LBAR for the IO enable bit, */ + /* maybe we should changed later. */ + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_SMB), &hi, &lo); + if (hi & 0x01) + conf_data |= PCI_COMMAND_IO; + break; + case PCI_STATUS: + conf_data |= PCI_STATUS_66MHZ; + conf_data |= PCI_STATUS_DEVSEL_MEDIUM; + conf_data |= PCI_STATUS_FAST_BACK; + + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_TAS_ERR_FLAG) + conf_data |= PCI_STATUS_SIG_TARGET_ABORT; + if (lo & SB_TAR_ERR_FLAG) + conf_data |= PCI_STATUS_REC_TARGET_ABORT; + if (lo & SB_MAR_ERR_FLAG) + conf_data |= PCI_STATUS_REC_MASTER_ABORT; + if (lo & SB_PARE_ERR_FLAG) + conf_data |= PCI_STATUS_DETECTED_PARITY; + break; + case PCI_CLASS_REVISION: + _rdmsr(GLCP_MSR_REG(GLCP_CHIP_REV_ID), &hi, &lo); + conf_data = lo & 0x000000ff; + conf_data |= (CS5536_ISA_CLASS_CODE << 8); + break; + case PCI_CACHE_LINE_SIZE: + _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo); + hi &= 0x000000f8; + conf_data = CFG_PCI_CACHE_LINE_SIZE(PCI_BRIDGE_HEADER_TYPE, hi); + break; + /* + * we only use the LBAR of DIVIL, no RCONF used. + * all of them are IO space. + */ + case PCI_BAR0_REG: + return pci_isa_read_bar(0); + break; + case PCI_BAR1_REG: + return pci_isa_read_bar(1); + break; + case PCI_BAR2_REG: + return pci_isa_read_bar(2); + break; + case PCI_BAR3_REG: + break; + case PCI_BAR4_REG: + return pci_isa_read_bar(4); + break; + case PCI_BAR5_REG: + return pci_isa_read_bar(5); + break; + case PCI_CARDBUS_CIS: + conf_data = PCI_CARDBUS_CIS_POINTER; + break; + case PCI_SUBSYSTEM_VENDOR_ID: + conf_data = + CFG_PCI_VENDOR_ID(CS5536_ISA_SUB_ID, CS5536_SUB_VENDOR_ID); + break; + case PCI_ROM_ADDRESS: + conf_data = PCI_EXPANSION_ROM_BAR; + break; + case PCI_CAPABILITY_LIST: + conf_data = PCI_CAPLIST_POINTER; + break; + case PCI_INTERRUPT_LINE: + /* no interrupt used here */ + conf_data = CFG_PCI_INTERRUPT_LINE(0x00, 0x00); + break; + default: + break; + } + + return conf_data; +} diff --git a/arch/mips/loongson/common/cs5536/cs5536_ohci.c b/arch/mips/loongson/common/cs5536/cs5536_ohci.c new file mode 100644 index 0000000..8fdb02b --- /dev/null +++ b/arch/mips/loongson/common/cs5536/cs5536_ohci.c @@ -0,0 +1,147 @@ +/* + * the OHCI Virtual Support Module of AMD CS5536 + * + * Copyright (C) 2007 Lemote, Inc. + * Author : jlliu, liujl@lemote.com + * + * Copyright (C) 2009 Lemote, Inc. + * Author: Wu Zhangjin, wuzj@lemote.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. + */ + +#include +#include + +void pci_ohci_write_reg(int reg, u32 value) +{ + u32 hi = 0, lo = value; + + switch (reg) { + case PCI_COMMAND: + _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo); + if (value & PCI_COMMAND_MASTER) + hi |= PCI_COMMAND_MASTER; + else + hi &= ~PCI_COMMAND_MASTER; + + if (value & PCI_COMMAND_MEMORY) + hi |= PCI_COMMAND_MEMORY; + else + hi &= ~PCI_COMMAND_MEMORY; + _wrmsr(USB_MSR_REG(USB_OHCI), hi, lo); + break; + case PCI_STATUS: + if (value & PCI_STATUS_PARITY) { + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) { + lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + } + } + break; + case PCI_BAR0_REG: + if (value == PCI_BAR_RANGE_MASK) { + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_OHCI_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else if ((value & 0x01) == 0x00) { + _wrmsr(USB_MSR_REG(USB_OHCI), hi, lo); + + value &= 0xfffffff0; + hi = 0x40000000 | ((value & 0xff000000) >> 24); + lo = 0x000fffff | ((value & 0x00fff000) << 8); + _wrmsr(GLIU_MSR_REG(GLIU_P2D_BM3), hi, lo); + } + break; + case PCI_OHCI_INT_REG: + _rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo); + lo &= ~(0xf << PIC_YSEL_LOW_USB_SHIFT); + if (value) /* enable all the usb interrupt in PIC */ + lo |= (CS5536_USB_INTR << PIC_YSEL_LOW_USB_SHIFT); + _wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo); + break; + default: + break; + } +} + +u32 pci_ohci_read_reg(int reg) +{ + u32 conf_data = 0; + u32 hi, lo; + + switch (reg) { + case PCI_VENDOR_ID: + conf_data = + CFG_PCI_VENDOR_ID(CS5536_OHCI_DEVICE_ID, CS5536_VENDOR_ID); + break; + case PCI_COMMAND: + _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo); + if (hi & PCI_COMMAND_MASTER) + conf_data |= PCI_COMMAND_MASTER; + if (hi & PCI_COMMAND_MEMORY) + conf_data |= PCI_COMMAND_MEMORY; + break; + case PCI_STATUS: + conf_data |= PCI_STATUS_66MHZ; + conf_data |= PCI_STATUS_FAST_BACK; + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) + conf_data |= PCI_STATUS_PARITY; + conf_data |= PCI_STATUS_DEVSEL_MEDIUM; + break; + case PCI_CLASS_REVISION: + _rdmsr(USB_MSR_REG(USB_CAP), &hi, &lo); + conf_data = lo & 0x000000ff; + conf_data |= (CS5536_OHCI_CLASS_CODE << 8); + break; + case PCI_CACHE_LINE_SIZE: + conf_data = + CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE, + PCI_NORMAL_LATENCY_TIMER); + break; + case PCI_BAR0_REG: + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if (lo & SOFT_BAR_OHCI_FLAG) { + conf_data = CS5536_OHCI_RANGE | + PCI_BASE_ADDRESS_SPACE_MEMORY; + lo &= ~SOFT_BAR_OHCI_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else { + _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo); + conf_data = lo & 0xffffff00; + conf_data &= ~0x0000000f; /* 32bit mem */ + } + break; + case PCI_CARDBUS_CIS: + conf_data = PCI_CARDBUS_CIS_POINTER; + break; + case PCI_SUBSYSTEM_VENDOR_ID: + conf_data = + CFG_PCI_VENDOR_ID(CS5536_OHCI_SUB_ID, CS5536_SUB_VENDOR_ID); + break; + case PCI_ROM_ADDRESS: + conf_data = PCI_EXPANSION_ROM_BAR; + break; + case PCI_CAPABILITY_LIST: + conf_data = PCI_CAPLIST_USB_POINTER; + break; + case PCI_INTERRUPT_LINE: + conf_data = + CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_USB_INTR); + break; + case PCI_OHCI_INT_REG: + _rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo); + if ((lo & 0x00000f00) == CS5536_USB_INTR) + conf_data = 1; + break; + default: + break; + } + + return conf_data; +} diff --git a/arch/mips/loongson/common/cs5536/cs5536_pci.c b/arch/mips/loongson/common/cs5536/cs5536_pci.c new file mode 100644 index 0000000..e23f3d7 --- /dev/null +++ b/arch/mips/loongson/common/cs5536/cs5536_pci.c @@ -0,0 +1,87 @@ +/* + * read/write operation to the PCI config space of CS5536 + * + * Copyright (C) 2007 Lemote, Inc. + * Author : jlliu, liujl@lemote.com + * + * Copyright (C) 2009 Lemote, Inc. + * Author: Wu Zhangjin, wuzj@lemote.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. + * + * the Virtual Support Module(VSM) for virtulizing the PCI + * configure space are defined in cs5536_modulename.c respectively, + * + * after this virtulizing, user can access the PCI configure space + * directly as a normal multi-function PCI device which follows + * the PCI-2.2 spec. + */ + +#include +#include + +enum { + CS5536_FUNC_START = -1, + CS5536_ISA_FUNC, + reserved_func, + CS5536_IDE_FUNC, + CS5536_ACC_FUNC, + CS5536_OHCI_FUNC, + CS5536_EHCI_FUNC, + CS5536_FUNC_END, +}; + +static const cs5536_pci_vsm_write vsm_conf_write[] = { + [CS5536_ISA_FUNC] pci_isa_write_reg, + [reserved_func] NULL, + [CS5536_IDE_FUNC] pci_ide_write_reg, + [CS5536_ACC_FUNC] pci_acc_write_reg, + [CS5536_OHCI_FUNC] pci_ohci_write_reg, + [CS5536_EHCI_FUNC] pci_ehci_write_reg, +}; + +static const cs5536_pci_vsm_read vsm_conf_read[] = { + [CS5536_ISA_FUNC] pci_isa_read_reg, + [reserved_func] NULL, + [CS5536_IDE_FUNC] pci_ide_read_reg, + [CS5536_ACC_FUNC] pci_acc_read_reg, + [CS5536_OHCI_FUNC] pci_ohci_read_reg, + [CS5536_EHCI_FUNC] pci_ehci_read_reg, +}; + +/* + * write to PCI config space and transfer it to MSR write. + */ +void cs5536_pci_conf_write4(int function, int reg, u32 value) +{ + if ((function <= CS5536_FUNC_START) || (function >= CS5536_FUNC_END)) + return; + if ((reg < 0) || (reg > 0x100) || ((reg & 0x03) != 0)) + return; + + if (vsm_conf_write[function] != NULL) + vsm_conf_write[function](reg, value); +} + +/* + * read PCI config space and transfer it to MSR access. + */ +u32 cs5536_pci_conf_read4(int function, int reg) +{ + u32 data = 0; + + if ((function <= CS5536_FUNC_START) || (function >= CS5536_FUNC_END)) + return 0; + if ((reg < 0) || ((reg & 0x03) != 0)) + return 0; + if (reg > 0x100) + return 0xffffffff; + + if (vsm_conf_read[function] != NULL) + data = vsm_conf_read[function](reg); + + return data; +} -- cgit v0.10.2 From 1032bce3ef81cb31fc85233ca668c17288e7884c Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Tue, 10 Nov 2009 00:06:13 +0800 Subject: MIPS: Lemote 2F: Add PCI support PCI support for the Fuloong 2E and Lemote Loongson 2F family machines is mostly identical with the exception of CS5536 support. Rename ops-fuloong2e.c to ops-loongson2.c then add the CS5536 support to share most of the source code among Loongson machines. Signed-off-by: Wu Zhangjin Cc: zhangfx@lemote.com Cc: yanh@lemote.com Cc: huhb@lemote.com Cc: Nicholas Mc Guire Cc: Arnaud Patard Cc: loongson-dev@googlegroups.com Cc: linux-mips@linux-mips.org Signed-off-by: Ralf Baechle diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index 0610c86..c9a0dc1 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile @@ -28,7 +28,8 @@ obj-$(CONFIG_MIPS_COBALT) += fixup-cobalt.o obj-$(CONFIG_SOC_AU1500) += fixup-au1000.o ops-au1000.o obj-$(CONFIG_SOC_AU1550) += fixup-au1000.o ops-au1000.o obj-$(CONFIG_SOC_PNX8550) += fixup-pnx8550.o ops-pnx8550.o -obj-$(CONFIG_LEMOTE_FULOONG2E) += fixup-fuloong2e.o ops-fuloong2e.o +obj-$(CONFIG_LEMOTE_FULOONG2E) += fixup-fuloong2e.o ops-loongson2.o +obj-$(CONFIG_LEMOTE_MACH2F) += fixup-lemote2f.o ops-loongson2.o obj-$(CONFIG_MIPS_MALTA) += fixup-malta.o obj-$(CONFIG_PMC_MSP7120_GW) += fixup-pmcmsp.o ops-pmcmsp.o obj-$(CONFIG_PMC_MSP7120_EVAL) += fixup-pmcmsp.o ops-pmcmsp.o diff --git a/arch/mips/pci/fixup-lemote2f.c b/arch/mips/pci/fixup-lemote2f.c new file mode 100644 index 0000000..caf2ede --- /dev/null +++ b/arch/mips/pci/fixup-lemote2f.c @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2008 Lemote Technology + * Copyright (C) 2004 ICT CAS + * Author: Li xiaoyu, lixy@ict.ac.cn + * + * Copyright (C) 2007 Lemote, Inc. + * Author: Fuxin Zhang, zhangfx@lemote.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. + */ +#include +#include + +#include +#include +#include + +/* PCI interrupt pins + * + * These should not be changed, or you should consider loongson2f interrupt + * register and your pci card dispatch + */ + +#define PCIA 4 +#define PCIB 5 +#define PCIC 6 +#define PCID 7 + +/* all the pci device has the PCIA pin, check the datasheet. */ +static char irq_tab[][5] __initdata = { + /* INTA INTB INTC INTD */ + {0, 0, 0, 0, 0}, /* 11: Unused */ + {0, 0, 0, 0, 0}, /* 12: Unused */ + {0, 0, 0, 0, 0}, /* 13: Unused */ + {0, 0, 0, 0, 0}, /* 14: Unused */ + {0, 0, 0, 0, 0}, /* 15: Unused */ + {0, 0, 0, 0, 0}, /* 16: Unused */ + {0, PCIA, 0, 0, 0}, /* 17: RTL8110-0 */ + {0, PCIB, 0, 0, 0}, /* 18: RTL8110-1 */ + {0, PCIC, 0, 0, 0}, /* 19: SiI3114 */ + {0, PCID, 0, 0, 0}, /* 20: 3-ports nec usb */ + {0, PCIA, PCIB, PCIC, PCID}, /* 21: PCI-SLOT */ + {0, 0, 0, 0, 0}, /* 22: Unused */ + {0, 0, 0, 0, 0}, /* 23: Unused */ + {0, 0, 0, 0, 0}, /* 24: Unused */ + {0, 0, 0, 0, 0}, /* 25: Unused */ + {0, 0, 0, 0, 0}, /* 26: Unused */ + {0, 0, 0, 0, 0}, /* 27: Unused */ +}; + +int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +{ + int virq; + + if ((PCI_SLOT(dev->devfn) != PCI_IDSEL_CS5536) + && (PCI_SLOT(dev->devfn) < 32)) { + virq = irq_tab[slot][pin]; + printk(KERN_INFO "slot: %d, pin: %d, irq: %d\n", slot, pin, + virq + LOONGSON_IRQ_BASE); + if (virq != 0) + return LOONGSON_IRQ_BASE + virq; + else + return 0; + } else if (PCI_SLOT(dev->devfn) == PCI_IDSEL_CS5536) { /* cs5536 */ + switch (PCI_FUNC(dev->devfn)) { + case 2: + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, + CS5536_IDE_INTR); + return CS5536_IDE_INTR; /* for IDE */ + case 3: + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, + CS5536_ACC_INTR); + return CS5536_ACC_INTR; /* for AUDIO */ + case 4: /* for OHCI */ + case 5: /* for EHCI */ + case 6: /* for UDC */ + case 7: /* for OTG */ + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, + CS5536_USB_INTR); + return CS5536_USB_INTR; + } + return dev->irq; + } else { + printk(KERN_INFO " strange pci slot number.\n"); + return 0; + } +} + +/* Do platform specific device initialization at pci_enable_device() time */ +int pcibios_plat_dev_init(struct pci_dev *dev) +{ + return 0; +} + +/* CS5536 SPEC. fixup */ +static void __init loongson_cs5536_isa_fixup(struct pci_dev *pdev) +{ + /* the uart1 and uart2 interrupt in PIC is enabled as default */ + pci_write_config_dword(pdev, PCI_UART1_INT_REG, 1); + pci_write_config_dword(pdev, PCI_UART2_INT_REG, 1); +} + +static void __init loongson_cs5536_ide_fixup(struct pci_dev *pdev) +{ + /* setting the mutex pin as IDE function */ + pci_write_config_dword(pdev, PCI_IDE_CFG_REG, + CS5536_IDE_FLASH_SIGNATURE); +} + +static void __init loongson_cs5536_acc_fixup(struct pci_dev *pdev) +{ + /* enable the AUDIO interrupt in PIC */ + pci_write_config_dword(pdev, PCI_ACC_INT_REG, 1); + + pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xc0); +} + +static void __init loongson_cs5536_ohci_fixup(struct pci_dev *pdev) +{ + /* enable the OHCI interrupt in PIC */ + /* THE OHCI, EHCI, UDC, OTG are shared with interrupt in PIC */ + pci_write_config_dword(pdev, PCI_OHCI_INT_REG, 1); +} + +static void __init loongson_cs5536_ehci_fixup(struct pci_dev *pdev) +{ + u32 hi, lo; + + /* Serial short detect enable */ + _rdmsr(USB_MSR_REG(USB_CONFIG), &hi, &lo); + _wrmsr(USB_MSR_REG(USB_CONFIG), (1 << 1) | (1 << 2) | (1 << 3), lo); + + /* setting the USB2.0 micro frame length */ + pci_write_config_dword(pdev, PCI_EHCI_FLADJ_REG, 0x2000); +} + +static void __init loongson_nec_fixup(struct pci_dev *pdev) +{ + unsigned int val; + + pci_read_config_dword(pdev, 0xe0, &val); + /* Only 2 port be used */ + pci_write_config_dword(pdev, 0xe0, (val & ~3) | 0x2); +} + +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA, + loongson_cs5536_isa_fixup); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_OHC, + loongson_cs5536_ohci_fixup); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_EHC, + loongson_cs5536_ehci_fixup); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_AUDIO, + loongson_cs5536_acc_fixup); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_IDE, + loongson_cs5536_ide_fixup); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_USB, + loongson_nec_fixup); diff --git a/arch/mips/pci/ops-fuloong2e.c b/arch/mips/pci/ops-fuloong2e.c deleted file mode 100644 index 171f65c..0000000 --- a/arch/mips/pci/ops-fuloong2e.c +++ /dev/null @@ -1,154 +0,0 @@ -/* - * fuloong2e specific PCI support. - * - * Copyright (C) 1999, 2000, 2004 MIPS Technologies, Inc. - * All rights reserved. - * Authors: Carsten Langgaard - * Maciej W. Rozycki - * - * Copyright (C) 2009 Lemote Inc. - * Author: Wu Zhangjin - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - */ -#include -#include -#include -#include - -#include - -#define PCI_ACCESS_READ 0 -#define PCI_ACCESS_WRITE 1 - -#define CFG_SPACE_REG(offset) \ - (void *)CKSEG1ADDR(LOONGSON_PCICFG_BASE | (offset)) -#define ID_SEL_BEGIN 11 -#define MAX_DEV_NUM (31 - ID_SEL_BEGIN) - - -static int loongson_pcibios_config_access(unsigned char access_type, - struct pci_bus *bus, - unsigned int devfn, int where, - u32 *data) -{ - u32 busnum = bus->number; - u32 addr, type; - u32 dummy; - void *addrp; - int device = PCI_SLOT(devfn); - int function = PCI_FUNC(devfn); - int reg = where & ~3; - - if (busnum == 0) { - /* Type 0 configuration for onboard PCI bus */ - if (device > MAX_DEV_NUM) - return -1; - - addr = (1 << (device + ID_SEL_BEGIN)) | (function << 8) | reg; - type = 0; - } else { - /* Type 1 configuration for offboard PCI bus */ - addr = (busnum << 16) | (device << 11) | (function << 8) | reg; - type = 0x10000; - } - - /* Clear aborts */ - LOONGSON_PCICMD |= LOONGSON_PCICMD_MABORT_CLR | \ - LOONGSON_PCICMD_MTABORT_CLR; - - LOONGSON_PCIMAP_CFG = (addr >> 16) | type; - - /* Flush Bonito register block */ - dummy = LOONGSON_PCIMAP_CFG; - mmiowb(); - - addrp = CFG_SPACE_REG(addr & 0xffff); - if (access_type == PCI_ACCESS_WRITE) - writel(cpu_to_le32(*data), addrp); - else - *data = le32_to_cpu(readl(addrp)); - - /* Detect Master/Target abort */ - if (LOONGSON_PCICMD & (LOONGSON_PCICMD_MABORT_CLR | - LOONGSON_PCICMD_MTABORT_CLR)) { - /* Error occurred */ - - /* Clear bits */ - LOONGSON_PCICMD |= (LOONGSON_PCICMD_MABORT_CLR | - LOONGSON_PCICMD_MTABORT_CLR); - - return -1; - } - - return 0; - -} - - -/* - * We can't address 8 and 16 bit words directly. Instead we have to - * read/write a 32bit word and mask/modify the data we actually want. - */ -static int loongson_pcibios_read(struct pci_bus *bus, unsigned int devfn, - int where, int size, u32 *val) -{ - u32 data = 0; - - if ((size == 2) && (where & 1)) - return PCIBIOS_BAD_REGISTER_NUMBER; - else if ((size == 4) && (where & 3)) - return PCIBIOS_BAD_REGISTER_NUMBER; - - if (loongson_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where, - &data)) - return -1; - - if (size == 1) - *val = (data >> ((where & 3) << 3)) & 0xff; - else if (size == 2) - *val = (data >> ((where & 3) << 3)) & 0xffff; - else - *val = data; - - return PCIBIOS_SUCCESSFUL; -} - -static int loongson_pcibios_write(struct pci_bus *bus, unsigned int devfn, - int where, int size, u32 val) -{ - u32 data = 0; - - if ((size == 2) && (where & 1)) - return PCIBIOS_BAD_REGISTER_NUMBER; - else if ((size == 4) && (where & 3)) - return PCIBIOS_BAD_REGISTER_NUMBER; - - if (size == 4) - data = val; - else { - if (loongson_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, - where, &data)) - return -1; - - if (size == 1) - data = (data & ~(0xff << ((where & 3) << 3))) | - (val << ((where & 3) << 3)); - else if (size == 2) - data = (data & ~(0xffff << ((where & 3) << 3))) | - (val << ((where & 3) << 3)); - } - - if (loongson_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn, where, - &data)) - return -1; - - return PCIBIOS_SUCCESSFUL; -} - -struct pci_ops loongson_pci_ops = { - .read = loongson_pcibios_read, - .write = loongson_pcibios_write -}; diff --git a/arch/mips/pci/ops-loongson2.c b/arch/mips/pci/ops-loongson2.c new file mode 100644 index 0000000..aa5d3da --- /dev/null +++ b/arch/mips/pci/ops-loongson2.c @@ -0,0 +1,208 @@ +/* + * fuloong2e specific PCI support. + * + * Copyright (C) 1999, 2000, 2004 MIPS Technologies, Inc. + * All rights reserved. + * Authors: Carsten Langgaard + * Maciej W. Rozycki + * + * Copyright (C) 2009 Lemote Inc. + * Author: Wu Zhangjin + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include + +#include + +#ifdef CONFIG_CS5536 +#include +#include +#endif + +#define PCI_ACCESS_READ 0 +#define PCI_ACCESS_WRITE 1 + +#define CFG_SPACE_REG(offset) \ + (void *)CKSEG1ADDR(LOONGSON_PCICFG_BASE | (offset)) +#define ID_SEL_BEGIN 11 +#define MAX_DEV_NUM (31 - ID_SEL_BEGIN) + + +static int loongson_pcibios_config_access(unsigned char access_type, + struct pci_bus *bus, + unsigned int devfn, int where, + u32 *data) +{ + u32 busnum = bus->number; + u32 addr, type; + u32 dummy; + void *addrp; + int device = PCI_SLOT(devfn); + int function = PCI_FUNC(devfn); + int reg = where & ~3; + + if (busnum == 0) { + /* board-specific part,currently,only fuloong2f,yeeloong2f + * use CS5536, fuloong2e use via686b, gdium has no + * south bridge + */ +#ifdef CONFIG_CS5536 + /* cs5536_pci_conf_read4/write4() will call _rdmsr/_wrmsr() to + * access the regsters PCI_MSR_ADDR, PCI_MSR_DATA_LO, + * PCI_MSR_DATA_HI, which is bigger than PCI_MSR_CTRL, so, it + * will not go this branch, but the others. so, no calling dead + * loop here. + */ + if ((PCI_IDSEL_CS5536 == device) && (reg < PCI_MSR_CTRL)) { + switch (access_type) { + case PCI_ACCESS_READ: + *data = cs5536_pci_conf_read4(function, reg); + break; + case PCI_ACCESS_WRITE: + cs5536_pci_conf_write4(function, reg, *data); + break; + } + return 0; + } +#endif + /* Type 0 configuration for onboard PCI bus */ + if (device > MAX_DEV_NUM) + return -1; + + addr = (1 << (device + ID_SEL_BEGIN)) | (function << 8) | reg; + type = 0; + } else { + /* Type 1 configuration for offboard PCI bus */ + addr = (busnum << 16) | (device << 11) | (function << 8) | reg; + type = 0x10000; + } + + /* Clear aborts */ + LOONGSON_PCICMD |= LOONGSON_PCICMD_MABORT_CLR | \ + LOONGSON_PCICMD_MTABORT_CLR; + + LOONGSON_PCIMAP_CFG = (addr >> 16) | type; + + /* Flush Bonito register block */ + dummy = LOONGSON_PCIMAP_CFG; + mmiowb(); + + addrp = CFG_SPACE_REG(addr & 0xffff); + if (access_type == PCI_ACCESS_WRITE) + writel(cpu_to_le32(*data), addrp); + else + *data = le32_to_cpu(readl(addrp)); + + /* Detect Master/Target abort */ + if (LOONGSON_PCICMD & (LOONGSON_PCICMD_MABORT_CLR | + LOONGSON_PCICMD_MTABORT_CLR)) { + /* Error occurred */ + + /* Clear bits */ + LOONGSON_PCICMD |= (LOONGSON_PCICMD_MABORT_CLR | + LOONGSON_PCICMD_MTABORT_CLR); + + return -1; + } + + return 0; + +} + + +/* + * We can't address 8 and 16 bit words directly. Instead we have to + * read/write a 32bit word and mask/modify the data we actually want. + */ +static int loongson_pcibios_read(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 *val) +{ + u32 data = 0; + + if ((size == 2) && (where & 1)) + return PCIBIOS_BAD_REGISTER_NUMBER; + else if ((size == 4) && (where & 3)) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (loongson_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where, + &data)) + return -1; + + if (size == 1) + *val = (data >> ((where & 3) << 3)) & 0xff; + else if (size == 2) + *val = (data >> ((where & 3) << 3)) & 0xffff; + else + *val = data; + + return PCIBIOS_SUCCESSFUL; +} + +static int loongson_pcibios_write(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 val) +{ + u32 data = 0; + + if ((size == 2) && (where & 1)) + return PCIBIOS_BAD_REGISTER_NUMBER; + else if ((size == 4) && (where & 3)) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (size == 4) + data = val; + else { + if (loongson_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, + where, &data)) + return -1; + + if (size == 1) + data = (data & ~(0xff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + else if (size == 2) + data = (data & ~(0xffff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + } + + if (loongson_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn, where, + &data)) + return -1; + + return PCIBIOS_SUCCESSFUL; +} + +struct pci_ops loongson_pci_ops = { + .read = loongson_pcibios_read, + .write = loongson_pcibios_write +}; + +#ifdef CONFIG_CS5536 +void _rdmsr(u32 msr, u32 *hi, u32 *lo) +{ + struct pci_bus bus = { + .number = PCI_BUS_CS5536 + }; + u32 devfn = PCI_DEVFN(PCI_IDSEL_CS5536, 0); + loongson_pcibios_write(&bus, devfn, PCI_MSR_ADDR, 4, msr); + loongson_pcibios_read(&bus, devfn, PCI_MSR_DATA_LO, 4, lo); + loongson_pcibios_read(&bus, devfn, PCI_MSR_DATA_HI, 4, hi); +} +EXPORT_SYMBOL(_rdmsr); + +void _wrmsr(u32 msr, u32 hi, u32 lo) +{ + struct pci_bus bus = { + .number = PCI_BUS_CS5536 + }; + u32 devfn = PCI_DEVFN(PCI_IDSEL_CS5536, 0); + loongson_pcibios_write(&bus, devfn, PCI_MSR_ADDR, 4, msr); + loongson_pcibios_write(&bus, devfn, PCI_MSR_DATA_LO, 4, lo); + loongson_pcibios_write(&bus, devfn, PCI_MSR_DATA_HI, 4, hi); +} +EXPORT_SYMBOL(_wrmsr); +#endif -- cgit v0.10.2 From 6616db78eecab1236781c546670391e1e5dff256 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Tue, 10 Nov 2009 00:06:14 +0800 Subject: MIPS: Lemote 2F: Add IRQ support The generic i8259_irq() will make kernel hang on booting, so Loongson 2F needs its own polling method. IP6 is shared by the bonito interrupt and perfcounter interrupts. Signed-off-by: Wu Zhangjin Cc: zhangfx@lemote.com Cc: yanh@lemote.com Cc: huhb@lemote.com Cc: Nicholas Mc Guire Cc: Arnaud Patard Cc: loongson-dev@googlegroups.com Cc: linux-mips@linux-mips.org Signed-off-by: Ralf Baechle diff --git a/arch/mips/loongson/Makefile b/arch/mips/loongson/Makefile index 39048c4..2b76cb0 100644 --- a/arch/mips/loongson/Makefile +++ b/arch/mips/loongson/Makefile @@ -9,3 +9,9 @@ obj-$(CONFIG_MACH_LOONGSON) += common/ # obj-$(CONFIG_LEMOTE_FULOONG2E) += fuloong-2e/ + +# +# Lemote loongson2f family machines +# + +obj-$(CONFIG_LEMOTE_MACH2F) += lemote-2f/ diff --git a/arch/mips/loongson/lemote-2f/Makefile b/arch/mips/loongson/lemote-2f/Makefile new file mode 100644 index 0000000..2e18897 --- /dev/null +++ b/arch/mips/loongson/lemote-2f/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for lemote loongson2f family machines +# + +obj-y += irq.o diff --git a/arch/mips/loongson/lemote-2f/irq.c b/arch/mips/loongson/lemote-2f/irq.c new file mode 100644 index 0000000..50e7bb6 --- /dev/null +++ b/arch/mips/loongson/lemote-2f/irq.c @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2007 Lemote Inc. + * Author: Fuxin Zhang, zhangfx@lemote.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. + */ + +#include + +#include +#include +#include + +#include +#include + +#define LOONGSON_TIMER_IRQ (MIPS_CPU_IRQ_BASE + 7) /* cpu timer */ +#define LOONGSON_PERFCNT_IRQ (MIPS_CPU_IRQ_BASE + 6) /* cpu perf counter */ +#define LOONGSON_NORTH_BRIDGE_IRQ (MIPS_CPU_IRQ_BASE + 6) /* bonito */ +#define LOONGSON_UART_IRQ (MIPS_CPU_IRQ_BASE + 3) /* cpu serial port */ +#define LOONGSON_SOUTH_BRIDGE_IRQ (MIPS_CPU_IRQ_BASE + 2) /* i8259 */ + +#define LOONGSON_INT_BIT_INT0 (1 << 11) +#define LOONGSON_INT_BIT_INT1 (1 << 12) + +/* + * The generic i8259_irq() make the kernel hang on booting. Since we cannot + * get the irq via the IRR directly, we access the ISR instead. + */ +static inline int mach_i8259_irq(void) +{ + int irq, isr; + + irq = -1; + + if ((LOONGSON_INTISR & LOONGSON_INTEN) & LOONGSON_INT_BIT_INT0) { + spin_lock(&i8259A_lock); + isr = inb(PIC_MASTER_CMD) & + ~inb(PIC_MASTER_IMR) & ~(1 << PIC_CASCADE_IR); + if (!isr) + isr = (inb(PIC_SLAVE_CMD) & ~inb(PIC_SLAVE_IMR)) << 8; + irq = ffs(isr) - 1; + if (unlikely(irq == 7)) { + /* + * This may be a spurious interrupt. + * + * Read the interrupt status register (ISR). If the most + * significant bit is not set then there is no valid + * interrupt. + */ + outb(0x0B, PIC_MASTER_ISR); /* ISR register */ + if (~inb(PIC_MASTER_ISR) & 0x80) + irq = -1; + } + spin_unlock(&i8259A_lock); + } + + return irq; +} + +static void i8259_irqdispatch(void) +{ + int irq; + + irq = mach_i8259_irq(); + if (irq >= 0) + do_IRQ(irq); + else + spurious_interrupt(); +} + +void mach_irq_dispatch(unsigned int pending) +{ + if (pending & CAUSEF_IP7) + do_IRQ(LOONGSON_TIMER_IRQ); + else if (pending & CAUSEF_IP6) { /* North Bridge, Perf counter */ +#ifdef CONFIG_OPROFILE + do_IRQ(LOONGSON2_PERFCNT_IRQ); +#endif + bonito_irqdispatch(); + } else if (pending & CAUSEF_IP3) /* CPU UART */ + do_IRQ(LOONGSON_UART_IRQ); + else if (pending & CAUSEF_IP2) /* South Bridge */ + i8259_irqdispatch(); + else + spurious_interrupt(); +} + +void __init set_irq_trigger_mode(void) +{ + /* setup cs5536 as high level trigger */ + LOONGSON_INTPOL = LOONGSON_INT_BIT_INT0 | LOONGSON_INT_BIT_INT1; + LOONGSON_INTEDGE &= ~(LOONGSON_INT_BIT_INT0 | LOONGSON_INT_BIT_INT1); +} + +static irqreturn_t ip6_action(int cpl, void *dev_id) +{ + return IRQ_HANDLED; +} + +struct irqaction ip6_irqaction = { + .handler = ip6_action, + .name = "cascade", + .flags = IRQF_SHARED, +}; + +struct irqaction cascade_irqaction = { + .handler = no_action, + .name = "cascade", +}; + +void __init mach_init_irq(void) +{ + /* init all controller + * 0-15 ------> i8259 interrupt + * 16-23 ------> mips cpu interrupt + * 32-63 ------> bonito irq + */ + + /* Sets the first-level interrupt dispatcher. */ + mips_cpu_irq_init(); + init_i8259_irqs(); + bonito_irq_init(); + + /* setup north bridge irq (bonito) */ + setup_irq(LOONGSON_NORTH_BRIDGE_IRQ, &ip6_irqaction); + /* setup source bridge irq (i8259) */ + setup_irq(LOONGSON_SOUTH_BRIDGE_IRQ, &cascade_irqaction); +} -- cgit v0.10.2 From 2ee98e0f46a12423d5ecd7da520a1dd94540c37d Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Tue, 10 Nov 2009 00:06:15 +0800 Subject: MIPS: Lemote 2F: Add reset support Fuloong 2F, Yeeloong 2F and Menglong 2F have different reset / shutdown logic. Signed-off-by: Wu Zhangjin Cc: zhangfx@lemote.com Cc: yanh@lemote.com Cc: huhb@lemote.com Cc: Nicholas Mc Guire Cc: Arnaud Patard Cc: loongson-dev@googlegroups.com Cc: linux-mips@linux-mips.org Signed-off-by: Ralf Baechle diff --git a/arch/mips/include/asm/mach-loongson/loongson.h b/arch/mips/include/asm/mach-loongson/loongson.h index 62171f2..9911390 100644 --- a/arch/mips/include/asm/mach-loongson/loongson.h +++ b/arch/mips/include/asm/mach-loongson/loongson.h @@ -42,6 +42,13 @@ extern void __init set_irq_trigger_mode(void); extern void __init mach_init_irq(void); extern void mach_irq_dispatch(unsigned int pending); +/* We need this in some places... */ +#define delay() ({ \ + int x; \ + for (x = 0; x < 100000; x++) \ + __asm__ __volatile__(""); \ +}) + #define LOONGSON_REG(x) \ (*(volatile u32 *)((char *)CKSEG1ADDR(LOONGSON_REG_BASE) + (x))) diff --git a/arch/mips/loongson/lemote-2f/Makefile b/arch/mips/loongson/lemote-2f/Makefile index 2e18897..da543b1 100644 --- a/arch/mips/loongson/lemote-2f/Makefile +++ b/arch/mips/loongson/lemote-2f/Makefile @@ -2,4 +2,4 @@ # Makefile for lemote loongson2f family machines # -obj-y += irq.o +obj-y += irq.o reset.o diff --git a/arch/mips/loongson/lemote-2f/reset.c b/arch/mips/loongson/lemote-2f/reset.c new file mode 100644 index 0000000..0458a1c --- /dev/null +++ b/arch/mips/loongson/lemote-2f/reset.c @@ -0,0 +1,172 @@ +/* Board-specific reboot/shutdown routines + * + * Copyright (c) 2009 Philippe Vachon + * + * Copyright (C) 2009 Lemote Inc. + * Author: Wu Zhangjin, wuzj@lemote.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. + */ + +#include +#include +#include + +#include + +#include + +#include + +static void reset_cpu(void) +{ + /* + * reset cpu to full speed, this is needed when enabling cpu frequency + * scalling + */ + LOONGSON_CHIPCFG0 |= 0x7; +} + +/* reset support for fuloong2f */ + +static void fl2f_reboot(void) +{ + reset_cpu(); + + /* send a reset signal to south bridge. + * + * NOTE: if enable "Power Management" in kernel, rtl8169 will not reset + * normally with this reset operation and it will not work in PMON, but + * you can type halt command and then reboot, seems the hardware reset + * logic not work normally. + */ + { + u32 hi, lo; + _rdmsr(DIVIL_MSR_REG(DIVIL_SOFT_RESET), &hi, &lo); + lo |= 0x00000001; + _wrmsr(DIVIL_MSR_REG(DIVIL_SOFT_RESET), hi, lo); + } +} + +static void fl2f_shutdown(void) +{ + u32 hi, lo, val; + int gpio_base; + + /* get gpio base */ + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), &hi, &lo); + gpio_base = lo & 0xff00; + + /* make cs5536 gpio13 output enable */ + val = inl(gpio_base + GPIOL_OUT_EN); + val &= ~(1 << (16 + 13)); + val |= (1 << 13); + outl(val, gpio_base + GPIOL_OUT_EN); + mmiowb(); + /* make cs5536 gpio13 output low level voltage. */ + val = inl(gpio_base + GPIOL_OUT_VAL) & ~(1 << (13)); + val |= (1 << (16 + 13)); + outl(val, gpio_base + GPIOL_OUT_VAL); + mmiowb(); +} + +/* reset support for yeeloong2f and mengloong2f notebook */ + +/* + * The following registers are determined by the EC index configuration. + * 1. fill the PORT_HIGH as EC register high part. + * 2. fill the PORT_LOW as EC register low part. + * 3. fill the PORT_DATA as EC register write data or get the data from it. + */ + +#define EC_IO_PORT_HIGH 0x0381 +#define EC_IO_PORT_LOW 0x0382 +#define EC_IO_PORT_DATA 0x0383 +#define REG_RESET_HIGH 0xF4 /* reset the machine auto-clear : rd/wr */ +#define REG_RESET_LOW 0xEC +#define BIT_RESET_ON (1 << 0) + +void ml2f_reboot(void) +{ + reset_cpu(); + + /* sending an reset signal to EC(embedded controller) */ + outb(REG_RESET_HIGH, EC_IO_PORT_HIGH); + outb(REG_RESET_LOW, EC_IO_PORT_LOW); + mmiowb(); + outb(BIT_RESET_ON, EC_IO_PORT_DATA); + mmiowb(); +} + +#define yl2f89_reboot ml2f_reboot + +/* menglong(7inches) laptop has different shutdown logic from 8.9inches */ +#define EC_SHUTDOWN_IO_PORT_HIGH 0xff2d +#define EC_SHUTDOWN_IO_PORT_LOW 0xff2e +#define EC_SHUTDOWN_IO_PORT_DATA 0xff2f +#define REG_SHUTDOWN_HIGH 0xFC +#define REG_SHUTDOWN_LOW 0x29 +#define BIT_SHUTDOWN_ON (1 << 1) + +static void ml2f_shutdown(void) +{ + u8 val; + u64 i; + + outb(REG_SHUTDOWN_HIGH, EC_SHUTDOWN_IO_PORT_HIGH); + outb(REG_SHUTDOWN_LOW, EC_SHUTDOWN_IO_PORT_LOW); + mmiowb(); + val = inb(EC_SHUTDOWN_IO_PORT_DATA); + outb(val & (~BIT_SHUTDOWN_ON), EC_SHUTDOWN_IO_PORT_DATA); + mmiowb(); + /* need enough wait here... how many microseconds needs? */ + for (i = 0; i < 0x10000; i++) + delay(); + outb(val | BIT_SHUTDOWN_ON, EC_SHUTDOWN_IO_PORT_DATA); + mmiowb(); +} + +static void yl2f89_shutdown(void) +{ + /* cpu-gpio0 output low */ + LOONGSON_GPIODATA &= ~0x00000001; + /* cpu-gpio0 as output */ + LOONGSON_GPIOIE &= ~0x00000001; +} + +void mach_prepare_reboot(void) +{ + switch (mips_machtype) { + case MACH_LEMOTE_FL2F: + fl2f_reboot(); + break; + case MACH_LEMOTE_ML2F7: + ml2f_reboot(); + break; + case MACH_LEMOTE_YL2F89: + yl2f89_reboot(); + break; + default: + break; + } +} + +void mach_prepare_shutdown(void) +{ + switch (mips_machtype) { + case MACH_LEMOTE_FL2F: + fl2f_shutdown(); + break; + case MACH_LEMOTE_ML2F7: + ml2f_shutdown(); + break; + case MACH_LEMOTE_YL2F89: + yl2f89_shutdown(); + break; + default: + break; + } +} -- cgit v0.10.2 From 6e34358ed4f89556b5474ff883ac148750189ef0 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Tue, 10 Nov 2009 00:06:16 +0800 Subject: MIPS: Lemote 2F: Add defconfig file Add default config file for Lemote Loongson 2F family machines. The resulting kernel image can be shared between Fuloong 2F, Yeeloong 2F and other Lemote Loongson 2F family machines. If you are using an old PMON, and not using a 2f box, please add a new command line argument in the boot.cfg. For example, add this argument for 8.9inches notebook: machtype=lemote-yeeloong-2f-8.9inches or machtype=8.9 More information from arch/mips/loongson/common/machtype.c. Signed-off-by: Wu Zhangjin Cc: zhangfx@lemote.com Cc: yanh@lemote.com Cc: huhb@lemote.com Cc: Nicholas Mc Guire Cc: Arnaud Patard Cc: loongson-dev@googlegroups.com Cc: linux-mips@linux-mips.org Signed-off-by: Ralf Baechle diff --git a/arch/mips/configs/lemote2f_defconfig b/arch/mips/configs/lemote2f_defconfig new file mode 100644 index 0000000..89e88a0 --- /dev/null +++ b/arch/mips/configs/lemote2f_defconfig @@ -0,0 +1,1836 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.32-rc6 +# Mon Nov 9 23:42:42 2009 +# +CONFIG_MIPS=y + +# +# Machine selection +# +# CONFIG_MACH_ALCHEMY is not set +# CONFIG_AR7 is not set +# CONFIG_BASLER_EXCITE is not set +# CONFIG_BCM47XX is not set +# CONFIG_BCM63XX is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_MACH_DECSTATION is not set +# CONFIG_MACH_JAZZ is not set +# CONFIG_LASAT is not set +CONFIG_MACH_LOONGSON=y +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SIM is not set +# CONFIG_NEC_MARKEINS is not set +# CONFIG_MACH_VR41XX is not set +# CONFIG_NXP_STB220 is not set +# CONFIG_NXP_STB225 is not set +# CONFIG_PNX8550_JBS is not set +# CONFIG_PNX8550_STB810 is not set +# CONFIG_PMC_MSP is not set +# CONFIG_PMC_YOSEMITE is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SGI_IP28 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SIBYTE_CRHINE is not set +# CONFIG_SIBYTE_CARMEL is not set +# CONFIG_SIBYTE_CRHONE is not set +# CONFIG_SIBYTE_RHONE is not set +# CONFIG_SIBYTE_SWARM is not set +# CONFIG_SIBYTE_LITTLESUR is not set +# CONFIG_SIBYTE_SENTOSA is not set +# CONFIG_SIBYTE_BIGSUR is not set +# CONFIG_SNI_RM is not set +# CONFIG_MACH_TX39XX is not set +# CONFIG_MACH_TX49XX is not set +# CONFIG_MIKROTIK_RB532 is not set +# CONFIG_WR_PPMC is not set +# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set +# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set +# CONFIG_ALCHEMY_GPIO_INDIRECT is not set +CONFIG_ARCH_SPARSEMEM_ENABLE=y +# CONFIG_LEMOTE_FULOONG2E is not set +CONFIG_LEMOTE_MACH2F=y +CONFIG_CS5536=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_SUPPORTS_OPROFILE=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_SCHED_OMIT_FRAME_POINTER=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_CEVT_R4K_LIB=y +CONFIG_CEVT_R4K=y +CONFIG_CSRC_R4K_LIB=y +CONFIG_CSRC_R4K=y +CONFIG_DMA_NONCOHERENT=y +CONFIG_DMA_NEED_PCI_MAP_STATE=y +CONFIG_EARLY_PRINTK=y +CONFIG_SYS_HAS_EARLY_PRINTK=y +CONFIG_I8259=y +# CONFIG_NO_IOPORT is not set +CONFIG_GENERIC_ISA_DMA=y +CONFIG_GENERIC_ISA_DMA_SUPPORT_BROKEN=y +# CONFIG_CPU_BIG_ENDIAN is not set +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y +CONFIG_IRQ_CPU=y +CONFIG_BOOT_ELF32=y +CONFIG_MIPS_L1_CACHE_SHIFT=5 + +# +# CPU selection +# +# CONFIG_CPU_LOONGSON2E is not set +CONFIG_CPU_LOONGSON2F=y +# CONFIG_CPU_MIPS32_R1 is not set +# CONFIG_CPU_MIPS32_R2 is not set +# CONFIG_CPU_MIPS64_R1 is not set +# CONFIG_CPU_MIPS64_R2 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R5500 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set +# CONFIG_CPU_SB1 is not set +# CONFIG_CPU_CAVIUM_OCTEON is not set +CONFIG_SYS_SUPPORTS_ZBOOT=y +CONFIG_SYS_SUPPORTS_ZBOOT_UART16550=y +CONFIG_CPU_LOONGSON2=y +CONFIG_SYS_HAS_CPU_LOONGSON2F=y +CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y +CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y + +# +# Kernel type +# +# CONFIG_32BIT is not set +CONFIG_64BIT=y +# CONFIG_PAGE_SIZE_4KB is not set +# CONFIG_PAGE_SIZE_8KB is not set +CONFIG_PAGE_SIZE_16KB=y +# CONFIG_PAGE_SIZE_32KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_BOARD_SCACHE=y +CONFIG_MIPS_MT_DISABLED=y +# CONFIG_MIPS_MT_SMP is not set +# CONFIG_MIPS_MT_SMTC is not set +CONFIG_CPU_HAS_WB=y +CONFIG_CPU_HAS_SYNC=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_CPU_SUPPORTS_HIGHMEM=y +CONFIG_SYS_SUPPORTS_HIGHMEM=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_SELECT_MEMORY_MODEL=y +# CONFIG_FLATMEM_MANUAL is not set +# CONFIG_DISCONTIGMEM_MANUAL is not set +CONFIG_SPARSEMEM_MANUAL=y +CONFIG_SPARSEMEM=y +CONFIG_HAVE_MEMORY_PRESENT=y +CONFIG_SPARSEMEM_STATIC=y + +# +# Memory hotplug is currently incompatible with Software Suspend +# +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_PHYS_ADDR_T_64BIT=y +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +CONFIG_HAVE_MLOCK=y +CONFIG_HAVE_MLOCKED_PAGE_BIT=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +# CONFIG_HZ_48 is not set +# CONFIG_HZ_100 is not set +# CONFIG_HZ_128 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_256 is not set +# CONFIG_HZ_1000 is not set +# CONFIG_HZ_1024 is not set +CONFIG_SYS_SUPPORTS_ARBIT_HZ=y +CONFIG_HZ=250 +# CONFIG_PREEMPT_NONE is not set +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREEMPT=y +# CONFIG_KEXEC is not set +# CONFIG_SECCOMP is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_BZIP2=y +CONFIG_HAVE_KERNEL_LZMA=y +# CONFIG_KERNEL_GZIP is not set +# CONFIG_KERNEL_BZIP2 is not set +CONFIG_KERNEL_LZMA=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +# CONFIG_TASKSTATS is not set +CONFIG_AUDIT=y + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=64 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_TREE_RCU_TRACE is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=15 +# CONFIG_GROUP_SCHED is not set +# CONFIG_CGROUPS is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_EMBEDDED=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_PCSPKR_PLATFORM=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y + +# +# Kernel Performance Events And Counters +# +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_PCI_QUIRKS=y +CONFIG_SLUB_DEBUG=y +CONFIG_COMPAT_BRK=y +# CONFIG_SLAB is not set +CONFIG_SLUB=y +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +CONFIG_HAVE_OPROFILE=y +CONFIG_HAVE_SYSCALL_WRAPPERS=y + +# +# GCOV-based kernel profiling +# +# CONFIG_SLOW_WORK is not set +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODVERSIONS=y +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_BLOCK=y +CONFIG_BLK_DEV_BSG=y +CONFIG_BLK_DEV_INTEGRITY=y +CONFIG_BLOCK_COMPAT=y + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +CONFIG_FREEZER=y + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +CONFIG_HW_HAS_PCI=y +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +# CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_PCI_LEGACY=y +# CONFIG_PCI_STUB is not set +# CONFIG_PCI_IOV is not set +CONFIG_ISA=y +CONFIG_MMU=y +# CONFIG_PCCARD is not set +# CONFIG_HOTPLUG_PCI is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +# CONFIG_HAVE_AOUT is not set +# CONFIG_BINFMT_MISC is not set +CONFIG_MIPS32_COMPAT=y +CONFIG_COMPAT=y +CONFIG_SYSVIPC_COMPAT=y +CONFIG_MIPS32_O32=y +CONFIG_MIPS32_N32=y +CONFIG_BINFMT_ELF32=y + +# +# Power management options +# +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_PM=y +# CONFIG_PM_DEBUG is not set +CONFIG_PM_SLEEP=y +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +CONFIG_HIBERNATION_NVS=y +CONFIG_HIBERNATION=y +CONFIG_PM_STD_PARTITION="/dev/hda3" +# CONFIG_PM_RUNTIME is not set +CONFIG_NET=y +CONFIG_COMPAT_NETLINK_MESSAGES=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_ASK_IP_FIB_HASH=y +# CONFIG_IP_FIB_TRIE is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +CONFIG_IP_MROUTE=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m +CONFIG_INET_LRO=y +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_BIC=y +CONFIG_TCP_CONG_CUBIC=y +CONFIG_TCP_CONG_WESTWOOD=m +CONFIG_TCP_CONG_HTCP=m +# CONFIG_TCP_CONG_HSTCP is not set +# CONFIG_TCP_CONG_HYBLA is not set +# CONFIG_TCP_CONG_VEGAS is not set +# CONFIG_TCP_CONG_SCALABLE is not set +# CONFIG_TCP_CONG_LP is not set +# CONFIG_TCP_CONG_VENO is not set +# CONFIG_TCP_CONG_YEAH is not set +# CONFIG_TCP_CONG_ILLINOIS is not set +CONFIG_DEFAULT_BIC=y +# CONFIG_DEFAULT_CUBIC is not set +# CONFIG_DEFAULT_HTCP is not set +# CONFIG_DEFAULT_VEGAS is not set +# CONFIG_DEFAULT_WESTWOOD is not set +# CONFIG_DEFAULT_RENO is not set +CONFIG_DEFAULT_TCP_CONG="bic" +# CONFIG_TCP_MD5SIG is not set +CONFIG_IPV6=m +CONFIG_IPV6_PRIVACY=y +# CONFIG_IPV6_ROUTER_PREF is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +# CONFIG_INET6_AH is not set +# CONFIG_INET6_ESP is not set +# CONFIG_INET6_IPCOMP is not set +# CONFIG_IPV6_MIP6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +CONFIG_IPV6_SIT=m +CONFIG_IPV6_NDISC_NODETYPE=y +# CONFIG_IPV6_TUNNEL is not set +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPV6_MROUTE is not set +CONFIG_NETWORK_SECMARK=y +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_ADVANCED=y + +# +# Core Netfilter Configuration +# +# CONFIG_NETFILTER_NETLINK_QUEUE is not set +# CONFIG_NETFILTER_NETLINK_LOG is not set +# CONFIG_NF_CONNTRACK is not set +# CONFIG_NETFILTER_XTABLES is not set +# CONFIG_IP_VS is not set + +# +# IP: Netfilter Configuration +# +# CONFIG_NF_DEFRAG_IPV4 is not set +# CONFIG_IP_NF_QUEUE is not set +# CONFIG_IP_NF_IPTABLES is not set +# CONFIG_IP_NF_ARPTABLES is not set + +# +# IPv6: Netfilter Configuration +# +# CONFIG_IP6_NF_QUEUE is not set +# CONFIG_IP6_NF_IPTABLES is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_NET_DSA is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +CONFIG_NET_SCHED=y + +# +# Queueing/Scheduling +# +# CONFIG_NET_SCH_CBQ is not set +# CONFIG_NET_SCH_HTB is not set +# CONFIG_NET_SCH_HFSC is not set +# CONFIG_NET_SCH_PRIO is not set +# CONFIG_NET_SCH_MULTIQ is not set +# CONFIG_NET_SCH_RED is not set +# CONFIG_NET_SCH_SFQ is not set +# CONFIG_NET_SCH_TEQL is not set +# CONFIG_NET_SCH_TBF is not set +# CONFIG_NET_SCH_GRED is not set +# CONFIG_NET_SCH_DSMARK is not set +# CONFIG_NET_SCH_NETEM is not set +# CONFIG_NET_SCH_DRR is not set +# CONFIG_NET_SCH_INGRESS is not set + +# +# Classification +# +CONFIG_NET_CLS=y +# CONFIG_NET_CLS_BASIC is not set +# CONFIG_NET_CLS_TCINDEX is not set +# CONFIG_NET_CLS_ROUTE4 is not set +# CONFIG_NET_CLS_FW is not set +# CONFIG_NET_CLS_U32 is not set +# CONFIG_NET_CLS_RSVP is not set +# CONFIG_NET_CLS_RSVP6 is not set +# CONFIG_NET_CLS_FLOW is not set +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_STACK=32 +# CONFIG_NET_EMATCH_CMP is not set +# CONFIG_NET_EMATCH_NBYTE is not set +# CONFIG_NET_EMATCH_U32 is not set +# CONFIG_NET_EMATCH_META is not set +# CONFIG_NET_EMATCH_TEXT is not set +CONFIG_NET_CLS_ACT=y +# CONFIG_NET_ACT_POLICE is not set +# CONFIG_NET_ACT_GACT is not set +# CONFIG_NET_ACT_MIRRED is not set +# CONFIG_NET_ACT_NAT is not set +# CONFIG_NET_ACT_PEDIT is not set +# CONFIG_NET_ACT_SIMP is not set +# CONFIG_NET_ACT_SKBEDIT is not set +CONFIG_NET_SCH_FIFO=y +# CONFIG_DCB is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set +CONFIG_FIB_RULES=y +CONFIG_WIRELESS=y +# CONFIG_CFG80211 is not set +CONFIG_CFG80211_DEFAULT_PS_VALUE=0 +# CONFIG_WIRELESS_OLD_REGULATORY is not set +CONFIG_WIRELESS_EXT=y +CONFIG_WIRELESS_EXT_SYSFS=y +# CONFIG_LIB80211 is not set + +# +# CFG80211 needs to be enabled for MAC80211 +# +# CONFIG_WIMAX is not set +CONFIG_RFKILL=m +# CONFIG_RFKILL_INPUT is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_DEVTMPFS is not set +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +# CONFIG_MTD is not set +# CONFIG_PARPORT is not set +# CONFIG_PNP is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_CRYPTOLOOP=y +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=8192 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_MISC_DEVICES=y +# CONFIG_PHANTOM is not set +# CONFIG_SGI_IOC4 is not set +# CONFIG_TIFM_CORE is not set +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_HP_ILO is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_CB710_CORE is not set +CONFIG_HAVE_IDE=y +CONFIG_IDE=y + +# +# Please see Documentation/ide/ide.txt for help/info on IDE drives +# +CONFIG_IDE_XFER_MODE=y +CONFIG_IDE_TIMINGS=y +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_IDE_GD=y +CONFIG_IDE_GD_ATA=y +# CONFIG_IDE_GD_ATAPI is not set +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +CONFIG_IDE_TASK_IOCTL=y +CONFIG_IDE_PROC_FS=y + +# +# IDE chipset support/bugfixes +# +# CONFIG_IDE_GENERIC is not set +# CONFIG_BLK_DEV_PLATFORM is not set +CONFIG_BLK_DEV_IDEDMA_SFF=y + +# +# PCI IDE chipsets support +# +CONFIG_BLK_DEV_IDEPCI=y +# CONFIG_IDEPCI_PCIBUS_ORDER is not set +# CONFIG_BLK_DEV_OFFBOARD is not set +CONFIG_BLK_DEV_GENERIC=y +# CONFIG_BLK_DEV_OPTI621 is not set +CONFIG_BLK_DEV_IDEDMA_PCI=y +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +CONFIG_BLK_DEV_AMD74XX=y +# CONFIG_BLK_DEV_CMD64X is not set +# CONFIG_BLK_DEV_TRIFLEX is not set +# CONFIG_BLK_DEV_CS5520 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_HPT366 is not set +# CONFIG_BLK_DEV_JMICRON is not set +# CONFIG_BLK_DEV_SC1200 is not set +# CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_IT8172 is not set +# CONFIG_BLK_DEV_IT8213 is not set +# CONFIG_BLK_DEV_IT821X is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_BLK_DEV_TC86C001 is not set + +# +# Other IDE chipsets support +# + +# +# Note: most of these also require special kernel boot parameters +# +# CONFIG_BLK_DEV_4DRIVES is not set +# CONFIG_BLK_DEV_ALI14XX is not set +# CONFIG_BLK_DEV_DTC2278 is not set +# CONFIG_BLK_DEV_HT6560B is not set +# CONFIG_BLK_DEV_QD65XX is not set +# CONFIG_BLK_DEV_UMC8672 is not set +CONFIG_BLK_DEV_IDEDMA=y + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=m +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=m +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +CONFIG_CHR_DEV_SG=m +# CONFIG_CHR_DEV_SCH is not set +CONFIG_SCSI_MULTI_LUN=y +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +# CONFIG_SCSI_LOWLEVEL is not set +# CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# + +# +# You can enable one or both FireWire driver stacks. +# + +# +# See the help texts for more information. +# +# CONFIG_FIREWIRE is not set +# CONFIG_IEEE1394 is not set +# CONFIG_I2O is not set +CONFIG_NETDEVICES=y +# CONFIG_IFB is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +# CONFIG_ARCNET is not set +# CONFIG_PHYLIB is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_AX88796 is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_SMC91X is not set +# CONFIG_DM9000 is not set +# CONFIG_ETHOC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_DNET is not set +# CONFIG_NET_TULIP is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_AC3200 is not set +# CONFIG_APRICOT is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +# CONFIG_CS89x0 is not set +# CONFIG_TC35815 is not set +# CONFIG_E100 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_8139CP is not set +CONFIG_8139TOO=y +# CONFIG_8139TOO_PIO is not set +CONFIG_8139TOO_TUNE_TWISTER=y +# CONFIG_8139TOO_8129 is not set +# CONFIG_8139_OLD_RX_RESET is not set +# CONFIG_R6040 is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SMSC9420 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_SC92031 is not set +# CONFIG_ATL2 is not set +CONFIG_NETDEV_1000=y +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_E1000E is not set +# CONFIG_IP1000 is not set +# CONFIG_IGB is not set +# CONFIG_IGBVF is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +CONFIG_R8169=y +# CONFIG_SIS190 is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set +# CONFIG_CNIC is not set +# CONFIG_QLA3XXX is not set +# CONFIG_ATL1 is not set +# CONFIG_ATL1E is not set +# CONFIG_ATL1C is not set +# CONFIG_JME is not set +# CONFIG_NETDEV_10000 is not set +# CONFIG_TR is not set +CONFIG_WLAN=y +CONFIG_WLAN_PRE80211=y +# CONFIG_STRIP is not set +# CONFIG_WAVELAN is not set +CONFIG_WLAN_80211=y +# CONFIG_LIBERTAS is not set +# CONFIG_ATMEL is not set +# CONFIG_PRISM54 is not set +# CONFIG_USB_ZD1201 is not set +# CONFIG_HOSTAP is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +# CONFIG_USB_HSO is not set +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NET_FC is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_OPENCORES is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +# CONFIG_MOUSE_PS2_ALPS is not set +# CONFIG_MOUSE_PS2_LOGIPS2PP is not set +CONFIG_MOUSE_PS2_SYNAPTICS=y +# CONFIG_MOUSE_PS2_TRACKPOINT is not set +# CONFIG_MOUSE_PS2_ELANTECH is not set +# CONFIG_MOUSE_PS2_SENTELIC is not set +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_APPLETOUCH is not set +# CONFIG_MOUSE_BCM5974 is not set +# CONFIG_MOUSE_INPORT is not set +# CONFIG_MOUSE_LOGIBM is not set +# CONFIG_MOUSE_PC110PAD is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +# CONFIG_SERIO_SERPORT is not set +# CONFIG_SERIO_PCIPS2 is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_DEVKMEM=y +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_COMPUTONE is not set +# CONFIG_ROCKETPORT is not set +# CONFIG_CYCLADES is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_ISI is not set +# CONFIG_SYNCLINKMP is not set +# CONFIG_SYNCLINK_GT is not set +# CONFIG_N_HDLC is not set +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +# CONFIG_STALDRV is not set +# CONFIG_NOZOMI is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_PCI is not set +CONFIG_SERIAL_8250_NR_UARTS=16 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_FOURPORT=y +# CONFIG_SERIAL_8250_ACCENT is not set +# CONFIG_SERIAL_8250_BOCA is not set +# CONFIG_SERIAL_8250_EXAR_ST16C554 is not set +# CONFIG_SERIAL_8250_HUB6 is not set +# CONFIG_SERIAL_8250_SHARE_IRQ is not set +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_RSA is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=16 +# CONFIG_IPMI_HANDLER is not set +CONFIG_HW_RANDOM=y +# CONFIG_HW_RANDOM_TIMERIOMEM is not set +CONFIG_RTC=y +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_DEVPORT=y +# CONFIG_I2C is not set +# CONFIG_SPI is not set + +# +# PPS support +# +# CONFIG_PPS is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Native drivers +# +# CONFIG_SENSORS_I5K_AMB is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_F71882FG is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_VT8231 is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +CONFIG_THERMAL=y +# CONFIG_THERMAL_HWMON is not set +# CONFIG_WATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_REGULATOR is not set +CONFIG_MEDIA_SUPPORT=m + +# +# Multimedia core support +# +CONFIG_VIDEO_DEV=m +CONFIG_VIDEO_V4L2_COMMON=m +CONFIG_VIDEO_ALLOW_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +# CONFIG_DVB_CORE is not set +CONFIG_VIDEO_MEDIA=m + +# +# Multimedia drivers +# +# CONFIG_MEDIA_ATTACH is not set +CONFIG_VIDEO_V4L2=m +CONFIG_VIDEO_V4L1=m +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +CONFIG_VIDEO_HELPER_CHIPS_AUTO=y +# CONFIG_VIDEO_VIVI is not set +# CONFIG_VIDEO_PMS is not set +# CONFIG_VIDEO_CPIA is not set +# CONFIG_VIDEO_CPIA2 is not set +# CONFIG_VIDEO_STRADIS is not set +CONFIG_V4L_USB_DRIVERS=y +CONFIG_USB_VIDEO_CLASS=m +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y +CONFIG_USB_GSPCA=m +# CONFIG_USB_M5602 is not set +# CONFIG_USB_STV06XX is not set +# CONFIG_USB_GL860 is not set +# CONFIG_USB_GSPCA_CONEX is not set +# CONFIG_USB_GSPCA_ETOMS is not set +# CONFIG_USB_GSPCA_FINEPIX is not set +# CONFIG_USB_GSPCA_JEILINJ is not set +# CONFIG_USB_GSPCA_MARS is not set +# CONFIG_USB_GSPCA_MR97310A is not set +# CONFIG_USB_GSPCA_OV519 is not set +# CONFIG_USB_GSPCA_OV534 is not set +# CONFIG_USB_GSPCA_PAC207 is not set +# CONFIG_USB_GSPCA_PAC7311 is not set +# CONFIG_USB_GSPCA_SN9C20X is not set +# CONFIG_USB_GSPCA_SONIXB is not set +# CONFIG_USB_GSPCA_SONIXJ is not set +# CONFIG_USB_GSPCA_SPCA500 is not set +# CONFIG_USB_GSPCA_SPCA501 is not set +# CONFIG_USB_GSPCA_SPCA505 is not set +# CONFIG_USB_GSPCA_SPCA506 is not set +# CONFIG_USB_GSPCA_SPCA508 is not set +# CONFIG_USB_GSPCA_SPCA561 is not set +# CONFIG_USB_GSPCA_SQ905 is not set +# CONFIG_USB_GSPCA_SQ905C is not set +# CONFIG_USB_GSPCA_STK014 is not set +# CONFIG_USB_GSPCA_SUNPLUS is not set +# CONFIG_USB_GSPCA_T613 is not set +# CONFIG_USB_GSPCA_TV8532 is not set +# CONFIG_USB_GSPCA_VC032X is not set +# CONFIG_USB_GSPCA_ZC3XX is not set +# CONFIG_VIDEO_HDPVR is not set +# CONFIG_USB_VICAM is not set +# CONFIG_USB_IBMCAM is not set +# CONFIG_USB_KONICAWC is not set +# CONFIG_USB_QUICKCAM_MESSENGER is not set +# CONFIG_USB_ET61X251 is not set +# CONFIG_USB_OV511 is not set +# CONFIG_USB_SE401 is not set +# CONFIG_USB_SN9C102 is not set +# CONFIG_USB_STV680 is not set +# CONFIG_USB_ZC0301 is not set +# CONFIG_USB_PWC is not set +CONFIG_USB_PWC_INPUT_EVDEV=y +# CONFIG_USB_ZR364XX is not set +# CONFIG_USB_STKWEBCAM is not set +# CONFIG_USB_S2255 is not set +# CONFIG_RADIO_ADAPTERS is not set +# CONFIG_DAB is not set + +# +# Graphics support +# +CONFIG_VGA_ARB=y +# CONFIG_DRM is not set +# CONFIG_VGASTATE is not set +CONFIG_VIDEO_OUTPUT_CONTROL=y +CONFIG_FB=y +CONFIG_FIRMWARE_EDID=y +# CONFIG_FB_DDC is not set +CONFIG_FB_BOOT_VESA_SUPPORT=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_TILEBLITTING=y + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_CIRRUS is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_NVIDIA is not set +# CONFIG_FB_RIVA is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_S3 is not set +# CONFIG_FB_SAVAGE is not set +CONFIG_FB_SIS=y +CONFIG_FB_SIS_300=y +CONFIG_FB_SIS_315=y +# CONFIG_FB_VIA is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_KYRO is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_VT8623 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_ARK is not set +# CONFIG_FB_PM3 is not set +# CONFIG_FB_CARMINE is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_BROADSHEET is not set +CONFIG_BACKLIGHT_LCD_SUPPORT=y +# CONFIG_LCD_CLASS_DEVICE is not set +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_GENERIC=y + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y +CONFIG_FONTS=y +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +CONFIG_FONT_6x11=y +CONFIG_FONT_7x14=y +CONFIG_FONT_PEARL_8x8=y +CONFIG_FONT_ACORN_8x8=y +CONFIG_FONT_MINI_4x6=y +CONFIG_FONT_SUN8x16=y +CONFIG_FONT_SUN12x22=y +CONFIG_FONT_10x18=y +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_LOGO_LINUX_CLUT224=y +CONFIG_SOUND=m +# CONFIG_SOUND_OSS_CORE is not set +CONFIG_SND=m +CONFIG_SND_TIMER=m +CONFIG_SND_PCM=m +# CONFIG_SND_SEQUENCER is not set +# CONFIG_SND_MIXER_OSS is not set +# CONFIG_SND_PCM_OSS is not set +# CONFIG_SND_HRTIMER is not set +# CONFIG_SND_RTCTIMER is not set +# CONFIG_SND_DYNAMIC_MINORS is not set +# CONFIG_SND_SUPPORT_OLD_API is not set +# CONFIG_SND_VERBOSE_PROCFS is not set +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +CONFIG_SND_VMASTER=y +# CONFIG_SND_RAWMIDI_SEQ is not set +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set +CONFIG_SND_AC97_CODEC=m +# CONFIG_SND_DRIVERS is not set +CONFIG_SND_PCI=y +# CONFIG_SND_AD1889 is not set +# CONFIG_SND_ALS300 is not set +# CONFIG_SND_ALI5451 is not set +# CONFIG_SND_ATIIXP is not set +# CONFIG_SND_ATIIXP_MODEM is not set +# CONFIG_SND_AU8810 is not set +# CONFIG_SND_AU8820 is not set +# CONFIG_SND_AU8830 is not set +# CONFIG_SND_AW2 is not set +# CONFIG_SND_AZT3328 is not set +# CONFIG_SND_BT87X is not set +# CONFIG_SND_CA0106 is not set +# CONFIG_SND_CMIPCI is not set +# CONFIG_SND_OXYGEN is not set +# CONFIG_SND_CS4281 is not set +# CONFIG_SND_CS46XX is not set +CONFIG_SND_CS5535AUDIO=m +# CONFIG_SND_CTXFI is not set +# CONFIG_SND_DARLA20 is not set +# CONFIG_SND_GINA20 is not set +# CONFIG_SND_LAYLA20 is not set +# CONFIG_SND_DARLA24 is not set +# CONFIG_SND_GINA24 is not set +# CONFIG_SND_LAYLA24 is not set +# CONFIG_SND_MONA is not set +# CONFIG_SND_MIA is not set +# CONFIG_SND_ECHO3G is not set +# CONFIG_SND_INDIGO is not set +# CONFIG_SND_INDIGOIO is not set +# CONFIG_SND_INDIGODJ is not set +# CONFIG_SND_INDIGOIOX is not set +# CONFIG_SND_INDIGODJX is not set +# CONFIG_SND_EMU10K1 is not set +# CONFIG_SND_EMU10K1X is not set +# CONFIG_SND_ENS1370 is not set +# CONFIG_SND_ENS1371 is not set +# CONFIG_SND_ES1938 is not set +# CONFIG_SND_ES1968 is not set +# CONFIG_SND_FM801 is not set +# CONFIG_SND_HDA_INTEL is not set +# CONFIG_SND_HDSP is not set +# CONFIG_SND_HDSPM is not set +# CONFIG_SND_HIFIER is not set +# CONFIG_SND_ICE1712 is not set +# CONFIG_SND_ICE1724 is not set +# CONFIG_SND_INTEL8X0 is not set +# CONFIG_SND_INTEL8X0M is not set +# CONFIG_SND_KORG1212 is not set +# CONFIG_SND_LX6464ES is not set +# CONFIG_SND_MAESTRO3 is not set +# CONFIG_SND_MIXART is not set +# CONFIG_SND_NM256 is not set +# CONFIG_SND_PCXHR is not set +# CONFIG_SND_RIPTIDE is not set +# CONFIG_SND_RME32 is not set +# CONFIG_SND_RME96 is not set +# CONFIG_SND_RME9652 is not set +# CONFIG_SND_SONICVIBES is not set +# CONFIG_SND_TRIDENT is not set +# CONFIG_SND_VIA82XX is not set +# CONFIG_SND_VIA82XX_MODEM is not set +# CONFIG_SND_VIRTUOSO is not set +# CONFIG_SND_VX222 is not set +# CONFIG_SND_YMFPCI is not set +# CONFIG_SND_MIPS is not set +# CONFIG_SND_USB is not set +# CONFIG_SND_SOC is not set +# CONFIG_SOUND_PRIME is not set +CONFIG_AC97_BUS=m +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +CONFIG_HIDRAW=y + +# +# USB Input Devices +# +CONFIG_USB_HID=y +# CONFIG_HID_PID is not set +CONFIG_USB_HIDDEV=y + +# +# Special HID drivers +# +# CONFIG_HID_A4TECH is not set +# CONFIG_HID_APPLE is not set +# CONFIG_HID_BELKIN is not set +# CONFIG_HID_CHERRY is not set +# CONFIG_HID_CHICONY is not set +# CONFIG_HID_CYPRESS is not set +# CONFIG_HID_DRAGONRISE is not set +# CONFIG_HID_EZKEY is not set +# CONFIG_HID_KYE is not set +# CONFIG_HID_GYRATION is not set +# CONFIG_HID_TWINHAN is not set +# CONFIG_HID_KENSINGTON is not set +# CONFIG_HID_LOGITECH is not set +# CONFIG_HID_MICROSOFT is not set +# CONFIG_HID_MONTEREY is not set +# CONFIG_HID_NTRIG is not set +# CONFIG_HID_PANTHERLORD is not set +# CONFIG_HID_PETALYNX is not set +# CONFIG_HID_SAMSUNG is not set +# CONFIG_HID_SONY is not set +# CONFIG_HID_SUNPLUS is not set +# CONFIG_HID_GREENASIA is not set +# CONFIG_HID_SMARTJOYPLUS is not set +# CONFIG_HID_TOPSEED is not set +# CONFIG_HID_THRUSTMASTER is not set +# CONFIG_HID_ZEROPLUS is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_DEVICE_CLASS is not set +CONFIG_USB_DYNAMIC_MINORS=y +CONFIG_USB_SUSPEND=y +# CONFIG_USB_OTG is not set +CONFIG_USB_OTG_WHITELIST=y +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +CONFIG_USB_MON=y +# CONFIG_USB_WUSB is not set +# CONFIG_USB_WUSB_CBAF is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_XHCI_HCD is not set +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +# CONFIG_USB_EHCI_TT_NEWSCHED is not set +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_ISP1362_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +CONFIG_USB_UHCI_HCD=m +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_WHCI_HCD is not set +# CONFIG_USB_HWA_HCD is not set + +# +# USB Device Class drivers +# +CONFIG_USB_ACM=m +# CONFIG_USB_PRINTER is not set +CONFIG_USB_WDM=m +# CONFIG_USB_TMC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +CONFIG_USB_STORAGE=m +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_DATAFAB=m +CONFIG_USB_STORAGE_FREECOM=m +CONFIG_USB_STORAGE_ISD200=m +CONFIG_USB_STORAGE_USBAT=m +CONFIG_USB_STORAGE_SDDR09=m +CONFIG_USB_STORAGE_SDDR55=m +CONFIG_USB_STORAGE_JUMPSHOT=m +CONFIG_USB_STORAGE_ALAUDA=m +# CONFIG_USB_STORAGE_ONETOUCH is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB port drivers +# +CONFIG_USB_SERIAL=m +# CONFIG_USB_EZUSB is not set +CONFIG_USB_SERIAL_GENERIC=y +# CONFIG_USB_SERIAL_AIRCABLE is not set +# CONFIG_USB_SERIAL_ARK3116 is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_CH341 is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# CONFIG_USB_SERIAL_CP210X is not set +# CONFIG_USB_SERIAL_CYPRESS_M8 is not set +# CONFIG_USB_SERIAL_EMPEG is not set +# CONFIG_USB_SERIAL_FTDI_SIO is not set +# CONFIG_USB_SERIAL_FUNSOFT is not set +# CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_IPAQ is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_EDGEPORT_TI is not set +# CONFIG_USB_SERIAL_GARMIN is not set +# CONFIG_USB_SERIAL_IPW is not set +# CONFIG_USB_SERIAL_IUU is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KLSI is not set +# CONFIG_USB_SERIAL_KOBIL_SCT is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_MOS7720 is not set +# CONFIG_USB_SERIAL_MOS7840 is not set +# CONFIG_USB_SERIAL_MOTOROLA is not set +# CONFIG_USB_SERIAL_NAVMAN is not set +# CONFIG_USB_SERIAL_PL2303 is not set +# CONFIG_USB_SERIAL_OTI6858 is not set +# CONFIG_USB_SERIAL_QUALCOMM is not set +# CONFIG_USB_SERIAL_SPCP8X5 is not set +# CONFIG_USB_SERIAL_HP4X is not set +# CONFIG_USB_SERIAL_SAFE is not set +# CONFIG_USB_SERIAL_SIEMENS_MPI is not set +# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set +# CONFIG_USB_SERIAL_SYMBOL is not set +# CONFIG_USB_SERIAL_TI is not set +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +# CONFIG_USB_SERIAL_OPTION is not set +# CONFIG_USB_SERIAL_OMNINET is not set +# CONFIG_USB_SERIAL_OPTICON is not set +# CONFIG_USB_SERIAL_DEBUG is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_BERRY_CHARGE is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_VST is not set +# CONFIG_USB_GADGET is not set + +# +# OTG and related infrastructure +# +# CONFIG_NOP_USB_XCEIV is not set +# CONFIG_UWB is not set +# CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set +# CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set +# CONFIG_INFINIBAND is not set +# CONFIG_RTC_CLASS is not set +# CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set + +# +# TI VLYNQ +# +CONFIG_STAGING=y +# CONFIG_STAGING_EXCLUDE_BUILD is not set +# CONFIG_ET131X is not set +# CONFIG_USB_IP_COMMON is not set +# CONFIG_PRISM2_USB is not set +# CONFIG_ECHO is not set +# CONFIG_COMEDI is not set +# CONFIG_ASUS_OLED is not set +# CONFIG_ALTERA_PCIE_CHDMA is not set +# CONFIG_RTL8187SE is not set +# CONFIG_RTL8192SU is not set +# CONFIG_RTL8192E is not set +# CONFIG_INPUT_MIMIO is not set +# CONFIG_TRANZPORT is not set + +# +# Android +# + +# +# Qualcomm MSM Camera And Video +# + +# +# Camera Sensor Selection +# +# CONFIG_INPUT_GPIO is not set +# CONFIG_DST is not set +# CONFIG_POHMELFS is not set +# CONFIG_B3DFG is not set +# CONFIG_PLAN9AUTH is not set +# CONFIG_LINE6_USB is not set +# CONFIG_USB_SERIAL_QUATECH2 is not set +# CONFIG_USB_SERIAL_QUATECH_USB2 is not set +# CONFIG_VT6655 is not set +# CONFIG_VT6656 is not set +# CONFIG_FB_UDL is not set +# CONFIG_VME_BUS is not set + +# +# RAR Register Driver +# +# CONFIG_RAR_REGISTER is not set +# CONFIG_IIO is not set +CONFIG_FB_SM7XX=y +CONFIG_FB_SM7XX_ACCEL=y + +# +# File systems +# +# CONFIG_EXT2_FS is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +# CONFIG_EXT4_FS is not set +CONFIG_JBD=y +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_QUOTA=y +# CONFIG_QUOTA_NETLINK_INTERFACE is not set +CONFIG_PRINT_QUOTA_WARNING=y +# CONFIG_QFMT_V1 is not set +# CONFIG_QFMT_V2 is not set +CONFIG_QUOTACTL=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +# CONFIG_MSDOS_FS is not set +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set +# CONFIG_MISC_FILESYSTEMS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +# CONFIG_NFS_V4 is not set +# CONFIG_NFSD is not set +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +CONFIG_NFS_ACL_SUPPORT=m +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=m +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="utf-8" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set +# CONFIG_DLM is not set + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_PRINTK_TIME=y +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +# CONFIG_MAGIC_SYSRQ is not set +CONFIG_STRIP_ASM_SYMS=y +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +CONFIG_SYSCTL_SYSCALL_CHECK=y +CONFIG_TRACING_SUPPORT=y +# CONFIG_FTRACE is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_CMDLINE="" + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +CONFIG_CRYPTO_WORKQUEUE=y +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +# CONFIG_CRYPTO_ECB is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_GHASH is not set +# CONFIG_CRYPTO_MD4 is not set +# CONFIG_CRYPTO_MD5 is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_DES is not set +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +# CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_HW=y +# CONFIG_CRYPTO_DEV_HIFN_795X is not set +# CONFIG_BINARY_PRINTF is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +CONFIG_CRC_T10DIF=y +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_AUDIT_GENERIC=y +CONFIG_ZLIB_INFLATE=m +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_NLATTR=y -- cgit v0.10.2 From 55045ff5557bc804752e84dca5d1b1f1d4bb4e31 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Wed, 11 Nov 2009 13:39:12 +0800 Subject: MIPS: Loongson 2F: Cleanup the #if clauses This patch adds two new kernel options: CPU_SUPPORTS_CPUFREQ and CPU_SUPPORTS_ADDRWINCFG to describe the new features of Loongons 2F and replaces the several ugly #if clauses by them. These two options will be utilized by the future loongson revisions and related drivers such as the coming Loongson 2F CPUFreq driver. Signed-off-by: Wu Zhangjin Cc: linux-mips@linux-mips.org Cc: Wu Zhangjin Signed-off-by: Ralf Baechle diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index c2b4cd5..51e4e5b 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -1334,6 +1334,8 @@ config SYS_HAS_CPU_LOONGSON2E config SYS_HAS_CPU_LOONGSON2F bool + select CPU_SUPPORTS_CPUFREQ + select CPU_SUPPORTS_ADDRWINCFG if 64BIT config SYS_HAS_CPU_MIPS32_R1 bool @@ -1443,6 +1445,10 @@ config CPU_SUPPORTS_32BIT_KERNEL bool config CPU_SUPPORTS_64BIT_KERNEL bool +config CPU_SUPPORTS_CPUFREQ + bool +config CPU_SUPPORTS_ADDRWINCFG + bool config CPU_SUPPORTS_HUGEPAGES bool config MIPS_PGD_C0_CONTEXT diff --git a/arch/mips/include/asm/mach-loongson/loongson.h b/arch/mips/include/asm/mach-loongson/loongson.h index 9911390..9bccdb5 100644 --- a/arch/mips/include/asm/mach-loongson/loongson.h +++ b/arch/mips/include/asm/mach-loongson/loongson.h @@ -227,7 +227,7 @@ extern void mach_irq_dispatch(unsigned int pending); ((((ADDR)>>26) & LOONGSON_PCIMAP_PCIMAP_LO0) << ((WIN)*6)) /* Chip Config */ -#ifdef CONFIG_CPU_LOONGSON2F +#ifdef CONFIG_CPU_SUPPORTS_CPUFREQ #define LOONGSON_CHIPCFG0 LOONGSON_REG(LOONGSON_REGBASE + 0x80) #endif @@ -236,7 +236,7 @@ extern void mach_irq_dispatch(unsigned int pending); * * loongson2e do not have this module */ -#if defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT) +#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG /* address window config module base address */ #define LOONGSON_ADDRWINCFG_BASE 0x3ff00000ul @@ -306,6 +306,6 @@ extern unsigned long _loongson_addrwincfg_base; #define LOONGSON_ADDRWIN_PCITODDR(win, src, dst, size) \ LOONGSON_ADDRWIN_CFG(PCIDMA, DDR, win, src, dst, size) -#endif /* ! CONFIG_CPU_LOONGSON2F && CONFIG_64BIT */ +#endif /* ! CONFIG_CPU_SUPPORTS_ADDRWINCFG */ #endif /* __ASM_MACH_LOONGSON_LOONGSON_H */ diff --git a/arch/mips/include/asm/mach-loongson/pci.h b/arch/mips/include/asm/mach-loongson/pci.h index 31ba908..a199a4f 100644 --- a/arch/mips/include/asm/mach-loongson/pci.h +++ b/arch/mips/include/asm/mach-loongson/pci.h @@ -28,7 +28,7 @@ extern struct pci_ops loongson_pci_ops; /* this is an offset from mips_io_port_base */ #define LOONGSON_PCI_IO_START 0x00004000UL -#if defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT) +#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG /* * we use address window2 to map cpu address space to pci space @@ -56,6 +56,6 @@ extern struct pci_ops loongson_pci_ops; /* this is an offset from mips_io_port_base */ #define LOONGSON_PCI_IO_START 0x00004000UL -#endif /* !(defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT))*/ +#endif /* !CONFIG_CPU_SUPPORTS_ADDRWINCFG */ #endif /* !__ASM_MACH_LOONGSON_PCI_H_ */ diff --git a/arch/mips/loongson/common/init.c b/arch/mips/loongson/common/init.c index 743d357..2b92a23 100644 --- a/arch/mips/loongson/common/init.c +++ b/arch/mips/loongson/common/init.c @@ -21,7 +21,7 @@ void __init prom_init(void) set_io_port_base((unsigned long) ioremap(LOONGSON_PCIIO_BASE, LOONGSON_PCIIO_SIZE)); -#if defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT) +#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG _loongson_addrwincfg_base = (unsigned long) ioremap(LOONGSON_ADDRWINCFG_BASE, LOONGSON_ADDRWINCFG_SIZE); #endif diff --git a/arch/mips/loongson/common/mem.c b/arch/mips/loongson/common/mem.c index e93551d..981e919 100644 --- a/arch/mips/loongson/common/mem.c +++ b/arch/mips/loongson/common/mem.c @@ -20,8 +20,7 @@ void __init prom_init_memory(void) add_memory_region(memsize << 20, LOONGSON_PCI_MEM_START - (memsize << 20), BOOT_MEM_RESERVED); -#ifdef CONFIG_64BIT -#ifdef CONFIG_CPU_LOONGSON2F +#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG { int bit; @@ -36,8 +35,9 @@ void __init prom_init_memory(void) 0x80000000ul, (1 << bit)); mmiowb(); } -#endif /* CONFIG_CPU_LOONGSON2F */ +#endif /* !CONFIG_CPU_SUPPORTS_ADDRWINCFG */ +#ifdef CONFIG_64BIT if (highmemsize > 0) add_memory_region(LOONGSON_HIGHMEM_START, highmemsize << 20, BOOT_MEM_RAM); @@ -45,7 +45,7 @@ void __init prom_init_memory(void) add_memory_region(LOONGSON_PCI_MEM_END + 1, LOONGSON_HIGHMEM_START - LOONGSON_PCI_MEM_END - 1, BOOT_MEM_RESERVED); -#endif /* CONFIG_64BIT */ +#endif /* !CONFIG_64BIT */ } /* override of arch/mips/mm/cache.c: __uncached_access */ diff --git a/arch/mips/loongson/common/pci.c b/arch/mips/loongson/common/pci.c index eac43b8..31d8c5e 100644 --- a/arch/mips/loongson/common/pci.c +++ b/arch/mips/loongson/common/pci.c @@ -68,7 +68,7 @@ static void __init setup_pcimap(void) deassert for some broken device */ LOONGSON_PXARB_CFG = 0x00fe0105ul; -#if defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT) +#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG /* * set cpu addr window2 to map CPU address space to PCI address space */ -- cgit v0.10.2 From 22f1fdfd62a5f6ab738ffe03dc2ee9f1f25dabc4 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Wed, 11 Nov 2009 13:59:23 +0800 Subject: MIPS: Add support for uncached accelerated mappings. Loongson2f support video acceleration. Signed-off-by: Wu Zhangjin Cc: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/624/ Patchwork: http://patchwork.linux-mips.org/patch/625/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 51e4e5b..e2116b1 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -1336,6 +1336,7 @@ config SYS_HAS_CPU_LOONGSON2F bool select CPU_SUPPORTS_CPUFREQ select CPU_SUPPORTS_ADDRWINCFG if 64BIT + select CPU_SUPPORTS_UNCACHED_ACCELERATED config SYS_HAS_CPU_MIPS32_R1 bool @@ -1451,6 +1452,8 @@ config CPU_SUPPORTS_ADDRWINCFG bool config CPU_SUPPORTS_HUGEPAGES bool +config CPU_SUPPORTS_UNCACHED_ACCELERATED + bool config MIPS_PGD_C0_CONTEXT bool default y if 64BIT && CPU_MIPSR2 diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h index d6eb613..1854336 100644 --- a/arch/mips/include/asm/pgtable.h +++ b/arch/mips/include/asm/pgtable.h @@ -390,6 +390,19 @@ static inline int io_remap_pfn_range(struct vm_area_struct *vma, #include /* + * uncached accelerated TLB map for video memory access + */ +#ifdef CONFIG_CPU_SUPPORTS_UNCACHED_ACCELERATED +#define __HAVE_PHYS_MEM_ACCESS_PROT + +struct file; +pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, + unsigned long size, pgprot_t vma_prot); +int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn, + unsigned long size, pgprot_t *vma_prot); +#endif + +/* * We provide our own get_unmapped area to cope with the virtual aliasing * constraints placed on us by the cache architecture. */ diff --git a/arch/mips/loongson/common/mem.c b/arch/mips/loongson/common/mem.c index 981e919..ceacd09 100644 --- a/arch/mips/loongson/common/mem.c +++ b/arch/mips/loongson/common/mem.c @@ -58,3 +58,61 @@ int __uncached_access(struct file *file, unsigned long addr) ((addr >= LOONGSON_MMIO_MEM_START) && (addr < LOONGSON_MMIO_MEM_END)); } + +#ifdef CONFIG_CPU_SUPPORTS_UNCACHED_ACCELERATED + +#include +#include +#include + +static unsigned long uca_start, uca_end; + +pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, + unsigned long size, pgprot_t vma_prot) +{ + unsigned long offset = pfn << PAGE_SHIFT; + unsigned long end = offset + size; + + if (__uncached_access(file, offset)) { + if (((uca_start && offset) >= uca_start) && + (end <= uca_end)) + return __pgprot((pgprot_val(vma_prot) & + ~_CACHE_MASK) | + _CACHE_UNCACHED_ACCELERATED); + else + return pgprot_noncached(vma_prot); + } + return vma_prot; +} + +static int __init find_vga_mem_init(void) +{ + struct pci_dev *dev = 0; + struct resource *r; + int idx; + + if (uca_start) + return 0; + + for_each_pci_dev(dev) { + if ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA) { + for (idx = 0; idx < PCI_NUM_RESOURCES; idx++) { + r = &dev->resource[idx]; + if (!r->start && r->end) + continue; + if (r->flags & IORESOURCE_IO) + continue; + if (r->flags & IORESOURCE_MEM) { + uca_start = r->start; + uca_end = r->end; + return 0; + } + } + } + } + + return 0; +} + +late_initcall(find_vga_mem_init); +#endif /* !CONFIG_CPU_SUPPORTS_UNCACHED_ACCELERATED */ -- cgit v0.10.2 From f181bf60e3f31cdab48bd8b9d913201ed2f9e522 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Wed, 11 Nov 2009 14:57:05 +0800 Subject: MIPS: Loongson 2F: Add suspend support framework This patch add basic suspend support for loongson2f family machines, loongson2f have a specific feature: when we set it's frequency to ZERO, it will go into a wait mode, and then can be waked up by the external interrupt. so, if we setup suitable interrupts before putting it into wait mode, we will be able wake it up whenever we want via sending the relative interrupts to it. These interrupts are board-specific, Yeeloong2F use the keyboard interrupt and SCI interrupt, but LingLoong and Fuloong2F use the interrupts connected to the processors directly. and BTW: some old LingLoong and FuLoong2F have no such interrupts connected, so, there is no way to wake them up from suspend mode. and therefore, please do not enable the kernel support for them. The board-specific support will be added in the coming patches. Signed-off-by: Wu Zhangjin Cc: linux-mips@linux-mips.org Cc: yanh@lemote.com Cc: huhb@lemote.com Cc: Wu Zhangjin Cc: Len Brown Cc: Rafael J. Wysocki Cc: linux-pm@lists.linux-foundation.org Patchwork: http://patchwork.linux-mips.org/patch/629/ Acked-by: Pavel Machek Signed-off-by: Ralf Baechle diff --git a/arch/mips/loongson/Kconfig b/arch/mips/loongson/Kconfig index a214127..17e72fd 100644 --- a/arch/mips/loongson/Kconfig +++ b/arch/mips/loongson/Kconfig @@ -61,3 +61,8 @@ endchoice config CS5536 bool + +config LOONGSON_SUSPEND + bool + default y + depends on CPU_SUPPORTS_CPUFREQ && SUSPEND diff --git a/arch/mips/loongson/common/Makefile b/arch/mips/loongson/common/Makefile index a82527f..a21724d 100644 --- a/arch/mips/loongson/common/Makefile +++ b/arch/mips/loongson/common/Makefile @@ -16,3 +16,9 @@ obj-$(CONFIG_SERIAL_8250) += serial.o # space # obj-$(CONFIG_CS5536) += cs5536/ + +# +# Suspend Support +# + +obj-$(CONFIG_LOONGSON_SUSPEND) += pm.o diff --git a/arch/mips/loongson/common/pm.c b/arch/mips/loongson/common/pm.c new file mode 100644 index 0000000..b625fec --- /dev/null +++ b/arch/mips/loongson/common/pm.c @@ -0,0 +1,161 @@ +/* + * loongson-specific suspend support + * + * Copyright (C) 2009 Lemote Inc. + * Author: Wu Zhangjin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ +#include +#include +#include + +#include +#include + +#include + +static unsigned int __maybe_unused cached_master_mask; /* i8259A */ +static unsigned int __maybe_unused cached_slave_mask; +static unsigned int __maybe_unused cached_bonito_irq_mask; /* bonito */ + +void arch_suspend_disable_irqs(void) +{ + /* disable all mips events */ + local_irq_disable(); + +#ifdef CONFIG_I8259 + /* disable all events of i8259A */ + cached_slave_mask = inb(PIC_SLAVE_IMR); + cached_master_mask = inb(PIC_MASTER_IMR); + + outb(0xff, PIC_SLAVE_IMR); + inb(PIC_SLAVE_IMR); + outb(0xff, PIC_MASTER_IMR); + inb(PIC_MASTER_IMR); +#endif + /* disable all events of bonito */ + cached_bonito_irq_mask = LOONGSON_INTEN; + LOONGSON_INTENCLR = 0xffff; + (void)LOONGSON_INTENCLR; +} + +void arch_suspend_enable_irqs(void) +{ + /* enable all mips events */ + local_irq_enable(); +#ifdef CONFIG_I8259 + /* only enable the cached events of i8259A */ + outb(cached_slave_mask, PIC_SLAVE_IMR); + outb(cached_master_mask, PIC_MASTER_IMR); +#endif + /* enable all cached events of bonito */ + LOONGSON_INTENSET = cached_bonito_irq_mask; + (void)LOONGSON_INTENSET; +} + +/* + * Setup the board-specific events for waking up loongson from wait mode + */ +void __weak setup_wakeup_events(void) +{ +} + +/* + * Check wakeup events + */ +int __weak wakeup_loongson(void) +{ + return 1; +} + +/* + * If the events are really what we want to wakeup the CPU, wake it up + * otherwise put the CPU asleep again. + */ +static void wait_for_wakeup_events(void) +{ + while (!wakeup_loongson()) + LOONGSON_CHIPCFG0 &= ~0x7; +} + +/* + * Stop all perf counters + * + * $24 is the control register of Loongson perf counter + */ +static inline void stop_perf_counters(void) +{ + __write_64bit_c0_register($24, 0, 0); +} + + +static void loongson_suspend_enter(void) +{ + static unsigned int cached_cpu_freq; + + /* setup wakeup events via enabling the IRQs */ + setup_wakeup_events(); + + stop_perf_counters(); + + cached_cpu_freq = LOONGSON_CHIPCFG0; + + /* Put CPU into wait mode */ + LOONGSON_CHIPCFG0 &= ~0x7; + + /* wait for the given events to wakeup cpu from wait mode */ + wait_for_wakeup_events(); + + LOONGSON_CHIPCFG0 = cached_cpu_freq; + mmiowb(); +} + +void __weak mach_suspend(void) +{ +} + +void __weak mach_resume(void) +{ +} + +static int loongson_pm_enter(suspend_state_t state) +{ + mach_suspend(); + + /* processor specific suspend */ + loongson_suspend_enter(); + + mach_resume(); + + return 0; +} + +static int loongson_pm_valid_state(suspend_state_t state) +{ + switch (state) { + case PM_SUSPEND_ON: + case PM_SUSPEND_STANDBY: + case PM_SUSPEND_MEM: + return 1; + + default: + return 0; + } +} + +static struct platform_suspend_ops loongson_pm_ops = { + .valid = loongson_pm_valid_state, + .enter = loongson_pm_enter, +}; + +static int __init loongson_pm_init(void) +{ + suspend_set_ops(&loongson_pm_ops); + + return 0; +} +arch_initcall(loongson_pm_init); -- cgit v0.10.2 From a9e8641f4c252f93875cf30cb28c0f333539f0bf Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Wed, 11 Nov 2009 14:57:41 +0800 Subject: MIPS: Yeeloong 2F: Add board specific suspend support Lemote Loongson 2F family machines need an external interrupt to wake the system from the suspend mode. For YeeLoong 2F and Mengloong 2F setup the keyboard interrupt as the wakeup interrupt. The new Fuloong 2F and LingLoong 2F have a button to directly send an interrupt to the CPU so there is no need to setup an interrupt. Signed-off-by: Wu Zhangjin Cc: linux-mips@linux-mips.org Cc: yanh@lemote.com Cc: huhb@lemote.com Cc: Wu Zhangjin Cc: Len Brown Cc: Rafael J. Wysocki Cc: linux-pm@lists.linux-foundation.org Patchwork: http://patchwork.linux-mips.org/patch/630/ Acked-by: Pavel Machek Signed-off-by: Ralf Baechle diff --git a/arch/mips/loongson/lemote-2f/Makefile b/arch/mips/loongson/lemote-2f/Makefile index da543b1..5add7b2 100644 --- a/arch/mips/loongson/lemote-2f/Makefile +++ b/arch/mips/loongson/lemote-2f/Makefile @@ -3,3 +3,9 @@ # obj-y += irq.o reset.o + +# +# Suspend Support +# + +obj-$(CONFIG_LOONGSON_SUSPEND) += pm.o diff --git a/arch/mips/loongson/lemote-2f/pm.c b/arch/mips/loongson/lemote-2f/pm.c new file mode 100644 index 0000000..8090d05 --- /dev/null +++ b/arch/mips/loongson/lemote-2f/pm.c @@ -0,0 +1,73 @@ +/* + * Lemote loongson2f family machines' specific suspend support + * + * Copyright (C) 2009 Lemote Inc. + * Author: Wu Zhangjin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#define I8042_KBD_IRQ 1 +#define I8042_CTR_KBDINT 0x01 +#define I8042_CTR_KBDDIS 0x10 + +static unsigned char i8042_ctr; + +static int i8042_enable_kbd_port(void) +{ + if (i8042_command(&i8042_ctr, I8042_CMD_CTL_RCTR)) { + pr_err("i8042.c: Can't read CTR while enabling i8042 kbd port." + "\n"); + return -EIO; + } + + i8042_ctr &= ~I8042_CTR_KBDDIS; + i8042_ctr |= I8042_CTR_KBDINT; + + if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { + i8042_ctr &= ~I8042_CTR_KBDINT; + i8042_ctr |= I8042_CTR_KBDDIS; + pr_err("i8042.c: Failed to enable KBD port.\n"); + + return -EIO; + } + + return 0; +} + +/* + * The i8042 is connnected to i8259A + */ +void setup_wakeup_events(void) +{ + int irq_mask; + + switch (mips_machtype) { + case MACH_LEMOTE_ML2F7: + case MACH_LEMOTE_YL2F89: + /* open the keyboard irq in i8259A */ + outb((0xff & ~(1 << I8042_KBD_IRQ)), PIC_MASTER_IMR); + irq_mask = inb(PIC_MASTER_IMR); + + /* enable keyboard port */ + i8042_enable_kbd_port(); + break; + + default: + break; + } +} -- cgit v0.10.2 From 13e79b462212ac46a046932af06117eaf7a9f77b Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Fri, 13 Nov 2009 16:04:53 +0900 Subject: MIPS: Sibyte: Use hweight8 instead of counting bits Signed-off-by: Akinobu Mita Cc: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/637/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/mm/cerr-sb1.c b/arch/mips/mm/cerr-sb1.c index 1bd1f18..3571090 100644 --- a/arch/mips/mm/cerr-sb1.c +++ b/arch/mips/mm/cerr-sb1.c @@ -567,13 +567,10 @@ static uint32_t extract_dc(unsigned short addr, int data) datalo = ((unsigned long long)datalohi << 32) | datalolo; ecc = dc_ecc(datalo); if (ecc != datahi) { - int bits = 0; + int bits; bad_ecc |= 1 << (3-offset); ecc ^= datahi; - while (ecc) { - if (ecc & 1) bits++; - ecc >>= 1; - } + bits = hweight8(ecc); res |= (bits == 1) ? CP0_CERRD_DATA_SBE : CP0_CERRD_DATA_DBE; } printk(" %02X-%016llX", datahi, datalo); -- cgit v0.10.2 From a3a0f8c8ed2e2470f4dcd6da95020d41fed84747 Mon Sep 17 00:00:00 2001 From: David VomLehn Date: Sun, 30 Aug 2009 17:15:11 -0700 Subject: MIPS: PowerTV: Base files for Cisco PowerTV platform Add the Cisco Powertv cable settop box to the MIPS tree. This platform is based on a MIPS 24Kc processor with various devices integrated on the same ASIC. There are multiple models of this box, with differing configuration but the same kernel runs across the product line. Signed-off-by: David VomLehn Cc: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/132/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index e2116b1..e7f3854 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -338,6 +338,24 @@ config PMC_YOSEMITE Yosemite is an evaluation board for the RM9000x2 processor manufactured by PMC-Sierra. +config POWERTV + bool "Cisco PowerTV" + select BOOT_ELF32 + select CEVT_R4K + select CPU_MIPSR2_IRQ_VI + select CPU_MIPSR2_IRQ_EI + select CSRC_POWERTV + select DMA_NONCOHERENT + select HW_HAS_PCI + select SYS_HAS_EARLY_PRINTK + select SYS_HAS_CPU_MIPS32_R2 + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_BIG_ENDIAN + select SYS_SUPPORTS_HIGHMEM + select USB_OHCI_LITTLE_ENDIAN + help + This enables support for the Cisco PowerTV Platform. + config SGI_IP22 bool "SGI IP22 (Indy/Indigo2)" select ARC @@ -683,6 +701,7 @@ source "arch/mips/bcm63xx/Kconfig" source "arch/mips/jazz/Kconfig" source "arch/mips/lasat/Kconfig" source "arch/mips/pmc-sierra/Kconfig" +source "arch/mips/powertv/Kconfig" source "arch/mips/sgi-ip27/Kconfig" source "arch/mips/sibyte/Kconfig" source "arch/mips/txx9/Kconfig" @@ -782,6 +801,9 @@ config CSRC_BCM1480 config CSRC_IOASIC bool +config CSRC_POWERTV + bool + config CSRC_R4K_LIB bool diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 184d5be..0a7e614 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -445,6 +445,13 @@ core-$(CONFIG_NEC_MARKEINS) += arch/mips/emma/markeins/ load-$(CONFIG_NEC_MARKEINS) += 0xffffffff88100000 # +# Cisco PowerTV Platform +# +core-$(CONFIG_POWERTV) += arch/mips/powertv/ +cflags-$(CONFIG_POWERTV) += -I$(srctree)/arch/mips/include/asm/mach-powertv +load-$(CONFIG_POWERTV) += 0xffffffff90800000 + +# # SGI IP22 (Indy/Indigo2) # # Set the load address to >= 0xffffffff88069000 if you want to leave space for diff --git a/arch/mips/configs/powertv_defconfig b/arch/mips/configs/powertv_defconfig new file mode 100644 index 0000000..3aff69ab --- /dev/null +++ b/arch/mips/configs/powertv_defconfig @@ -0,0 +1,1549 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.31-rc5 +# Fri Aug 28 14:49:33 2009 +# +CONFIG_MIPS=y + +# +# Machine selection +# +# CONFIG_MACH_ALCHEMY is not set +# CONFIG_AR7 is not set +# CONFIG_BASLER_EXCITE is not set +# CONFIG_BCM47XX is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_MACH_DECSTATION is not set +# CONFIG_MACH_JAZZ is not set +# CONFIG_LASAT is not set +# CONFIG_LEMOTE_FULONG is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SIM is not set +# CONFIG_NEC_MARKEINS is not set +# CONFIG_MACH_VR41XX is not set +# CONFIG_NXP_STB220 is not set +# CONFIG_NXP_STB225 is not set +# CONFIG_PNX8550_JBS is not set +# CONFIG_PNX8550_STB810 is not set +# CONFIG_PMC_MSP is not set +# CONFIG_PMC_YOSEMITE is not set +CONFIG_POWERTV=y +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SGI_IP28 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SIBYTE_CRHINE is not set +# CONFIG_SIBYTE_CARMEL is not set +# CONFIG_SIBYTE_CRHONE is not set +# CONFIG_SIBYTE_RHONE is not set +# CONFIG_SIBYTE_SWARM is not set +# CONFIG_SIBYTE_LITTLESUR is not set +# CONFIG_SIBYTE_SENTOSA is not set +# CONFIG_SIBYTE_BIGSUR is not set +# CONFIG_SNI_RM is not set +# CONFIG_MACH_TX39XX is not set +# CONFIG_MACH_TX49XX is not set +# CONFIG_MIKROTIK_RB532 is not set +# CONFIG_WR_PPMC is not set +# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set +# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set +# CONFIG_ALCHEMY_GPIO_INDIRECT is not set +# CONFIG_MIN_RUNTIME_RESOURCES is not set +# CONFIG_BOOTLOADER_DRIVER is not set +CONFIG_BOOTLOADER_FAMILY="R2" +CONFIG_CSRC_POWERTV=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_SUPPORTS_OPROFILE=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_SCHED_OMIT_FRAME_POINTER=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_CEVT_R4K_LIB=y +CONFIG_CEVT_R4K=y +CONFIG_DMA_NONCOHERENT=y +CONFIG_DMA_NEED_PCI_MAP_STATE=y +# CONFIG_EARLY_PRINTK is not set +CONFIG_SYS_HAS_EARLY_PRINTK=y +# CONFIG_NO_IOPORT is not set +CONFIG_CPU_BIG_ENDIAN=y +# CONFIG_CPU_LITTLE_ENDIAN is not set +CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y +CONFIG_BOOT_ELF32=y +CONFIG_MIPS_L1_CACHE_SHIFT=5 + +# +# CPU selection +# +# CONFIG_CPU_LOONGSON2 is not set +# CONFIG_CPU_MIPS32_R1 is not set +CONFIG_CPU_MIPS32_R2=y +# CONFIG_CPU_MIPS64_R1 is not set +# CONFIG_CPU_MIPS64_R2 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R5500 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set +# CONFIG_CPU_SB1 is not set +# CONFIG_CPU_CAVIUM_OCTEON is not set +CONFIG_SYS_HAS_CPU_MIPS32_R2=y +CONFIG_CPU_MIPS32=y +CONFIG_CPU_MIPSR2=y +CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y +CONFIG_HARDWARE_WATCHPOINTS=y + +# +# Kernel type +# +CONFIG_32BIT=y +# CONFIG_64BIT is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_32KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_CPU_HAS_PREFETCH=y +CONFIG_MIPS_MT_DISABLED=y +# CONFIG_MIPS_MT_SMP is not set +# CONFIG_MIPS_MT_SMTC is not set +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_MIPSR2_IRQ_VI=y +CONFIG_CPU_MIPSR2_IRQ_EI=y +CONFIG_CPU_HAS_SYNC=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +# CONFIG_HIGHMEM is not set +CONFIG_CPU_SUPPORTS_HIGHMEM=y +CONFIG_SYS_SUPPORTS_HIGHMEM=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +CONFIG_HAVE_MLOCK=y +CONFIG_HAVE_MLOCKED_PAGE_BIT=y +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +# CONFIG_HZ_48 is not set +# CONFIG_HZ_100 is not set +# CONFIG_HZ_128 is not set +# CONFIG_HZ_250 is not set +# CONFIG_HZ_256 is not set +CONFIG_HZ_1000=y +# CONFIG_HZ_1024 is not set +CONFIG_SYS_SUPPORTS_ARBIT_HZ=y +CONFIG_HZ=1000 +# CONFIG_PREEMPT_NONE is not set +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREEMPT=y +# CONFIG_KEXEC is not set +# CONFIG_SECCOMP is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +# CONFIG_SWAP is not set +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_CLASSIC_RCU=y +# CONFIG_TREE_RCU is not set +# CONFIG_PREEMPT_RCU is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_PREEMPT_RCU_TRACE is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=16 +CONFIG_GROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +# CONFIG_RT_GROUP_SCHED is not set +CONFIG_USER_SCHED=y +# CONFIG_CGROUP_SCHED is not set +# CONFIG_CGROUPS is not set +# CONFIG_SYSFS_DEPRECATED_V2 is not set +CONFIG_RELAY=y +# CONFIG_NAMESPACES is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_RD_GZIP is not set +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_EMBEDDED=y +# CONFIG_SYSCTL_SYSCALL is not set +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +# CONFIG_PCSPKR_PLATFORM is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +# CONFIG_EPOLL is not set +# CONFIG_SIGNALFD is not set +CONFIG_TIMERFD=y +# CONFIG_EVENTFD is not set +CONFIG_SHMEM=y +CONFIG_AIO=y + +# +# Performance Counters +# +# CONFIG_VM_EVENT_COUNTERS is not set +CONFIG_PCI_QUIRKS=y +# CONFIG_SLUB_DEBUG is not set +# CONFIG_STRIP_ASM_SYMS is not set +CONFIG_COMPAT_BRK=y +# CONFIG_SLAB is not set +CONFIG_SLUB=y +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set +CONFIG_HAVE_OPROFILE=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +# CONFIG_SLOW_WORK is not set +# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_BLOCK=y +CONFIG_LBDAF=y +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_NOOP=y +CONFIG_DEFAULT_IOSCHED="noop" +# CONFIG_PROBE_INITRD_HEADER is not set +# CONFIG_FREEZER is not set + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +CONFIG_HW_HAS_PCI=y +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCI_LEGACY is not set +# CONFIG_PCI_DEBUG is not set +# CONFIG_PCI_STUB is not set +# CONFIG_PCI_IOV is not set +CONFIG_MMU=y +# CONFIG_PCCARD is not set +# CONFIG_HOTPLUG_PCI is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +# CONFIG_HAVE_AOUT is not set +# CONFIG_BINFMT_MISC is not set +CONFIG_TRAD_SIGNALS=y + +# +# Power management options +# +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +# CONFIG_PM is not set +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +CONFIG_XFRM_IPCOMP=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_ASK_IP_FIB_HASH=y +# CONFIG_IP_FIB_TRIE is not set +CONFIG_IP_FIB_HASH=y +# CONFIG_IP_MULTIPLE_TABLES is not set +# CONFIG_IP_ROUTE_MULTIPATH is not set +# CONFIG_IP_ROUTE_VERBOSE is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +# CONFIG_INET_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +CONFIG_IPV6=y +CONFIG_IPV6_PRIVACY=y +# CONFIG_IPV6_ROUTER_PREF is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +CONFIG_INET6_AH=y +CONFIG_INET6_ESP=y +CONFIG_INET6_IPCOMP=y +# CONFIG_IPV6_MIP6 is not set +CONFIG_INET6_XFRM_TUNNEL=y +CONFIG_INET6_TUNNEL=y +# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET6_XFRM_MODE_TUNNEL is not set +# CONFIG_INET6_XFRM_MODE_BEET is not set +# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +# CONFIG_IPV6_SIT is not set +CONFIG_IPV6_TUNNEL=y +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPV6_MROUTE is not set +# CONFIG_NETWORK_SECMARK is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_ADVANCED=y +# CONFIG_BRIDGE_NETFILTER is not set + +# +# Core Netfilter Configuration +# +# CONFIG_NETFILTER_NETLINK_QUEUE is not set +# CONFIG_NETFILTER_NETLINK_LOG is not set +# CONFIG_NF_CONNTRACK is not set +CONFIG_NETFILTER_XTABLES=y +# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set +# CONFIG_NETFILTER_XT_TARGET_MARK is not set +# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set +# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set +# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set +# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set +# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set +# CONFIG_NETFILTER_XT_MATCH_DCCP is not set +# CONFIG_NETFILTER_XT_MATCH_DSCP is not set +# CONFIG_NETFILTER_XT_MATCH_ESP is not set +# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set +# CONFIG_NETFILTER_XT_MATCH_HL is not set +# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set +# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set +# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set +# CONFIG_NETFILTER_XT_MATCH_MAC is not set +# CONFIG_NETFILTER_XT_MATCH_MARK is not set +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y +# CONFIG_NETFILTER_XT_MATCH_OWNER is not set +# CONFIG_NETFILTER_XT_MATCH_POLICY is not set +# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set +# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set +# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set +# CONFIG_NETFILTER_XT_MATCH_REALM is not set +# CONFIG_NETFILTER_XT_MATCH_RECENT is not set +# CONFIG_NETFILTER_XT_MATCH_SCTP is not set +# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set +# CONFIG_NETFILTER_XT_MATCH_STRING is not set +# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set +# CONFIG_NETFILTER_XT_MATCH_TIME is not set +# CONFIG_NETFILTER_XT_MATCH_U32 is not set +# CONFIG_IP_VS is not set + +# +# IP: Netfilter Configuration +# +# CONFIG_NF_DEFRAG_IPV4 is not set +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_IPTABLES=y +# CONFIG_IP_NF_MATCH_ADDRTYPE is not set +# CONFIG_IP_NF_MATCH_AH is not set +# CONFIG_IP_NF_MATCH_ECN is not set +# CONFIG_IP_NF_MATCH_TTL is not set +CONFIG_IP_NF_FILTER=y +# CONFIG_IP_NF_TARGET_REJECT is not set +# CONFIG_IP_NF_TARGET_LOG is not set +# CONFIG_IP_NF_TARGET_ULOG is not set +# CONFIG_IP_NF_MANGLE is not set +# CONFIG_IP_NF_TARGET_TTL is not set +# CONFIG_IP_NF_RAW is not set +CONFIG_IP_NF_ARPTABLES=y +CONFIG_IP_NF_ARPFILTER=y +# CONFIG_IP_NF_ARP_MANGLE is not set + +# +# IPv6: Netfilter Configuration +# +# CONFIG_IP6_NF_QUEUE is not set +CONFIG_IP6_NF_IPTABLES=y +# CONFIG_IP6_NF_MATCH_AH is not set +# CONFIG_IP6_NF_MATCH_EUI64 is not set +# CONFIG_IP6_NF_MATCH_FRAG is not set +# CONFIG_IP6_NF_MATCH_OPTS is not set +# CONFIG_IP6_NF_MATCH_HL is not set +# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set +# CONFIG_IP6_NF_MATCH_MH is not set +# CONFIG_IP6_NF_MATCH_RT is not set +# CONFIG_IP6_NF_TARGET_HL is not set +# CONFIG_IP6_NF_TARGET_LOG is not set +CONFIG_IP6_NF_FILTER=y +# CONFIG_IP6_NF_TARGET_REJECT is not set +# CONFIG_IP6_NF_MANGLE is not set +# CONFIG_IP6_NF_RAW is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +CONFIG_STP=y +CONFIG_BRIDGE=y +# CONFIG_NET_DSA is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +CONFIG_LLC=y +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +CONFIG_NET_SCHED=y + +# +# Queueing/Scheduling +# +# CONFIG_NET_SCH_CBQ is not set +# CONFIG_NET_SCH_HTB is not set +# CONFIG_NET_SCH_HFSC is not set +# CONFIG_NET_SCH_PRIO is not set +# CONFIG_NET_SCH_MULTIQ is not set +# CONFIG_NET_SCH_RED is not set +# CONFIG_NET_SCH_SFQ is not set +# CONFIG_NET_SCH_TEQL is not set +CONFIG_NET_SCH_TBF=y +# CONFIG_NET_SCH_GRED is not set +# CONFIG_NET_SCH_DSMARK is not set +# CONFIG_NET_SCH_NETEM is not set +# CONFIG_NET_SCH_DRR is not set + +# +# Classification +# +# CONFIG_NET_CLS_BASIC is not set +# CONFIG_NET_CLS_TCINDEX is not set +# CONFIG_NET_CLS_ROUTE4 is not set +# CONFIG_NET_CLS_FW is not set +# CONFIG_NET_CLS_U32 is not set +# CONFIG_NET_CLS_RSVP is not set +# CONFIG_NET_CLS_RSVP6 is not set +# CONFIG_NET_CLS_FLOW is not set +# CONFIG_NET_EMATCH is not set +# CONFIG_NET_CLS_ACT is not set +CONFIG_NET_SCH_FIFO=y +# CONFIG_DCB is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set +# CONFIG_WIRELESS is not set +# CONFIG_WIMAX is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_TESTS is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_INTEL_VR_NOR is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_CAFE is not set +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_ALAUDA is not set +# CONFIG_MTD_ONENAND is not set + +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=32768 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_BLK_DEV_HD is not set +# CONFIG_MISC_DEVICES is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_SCSI_PROC_FS is not set + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +# CONFIG_SCSI_LOWLEVEL is not set +# CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set +CONFIG_ATA=y +# CONFIG_ATA_NONSTANDARD is not set +CONFIG_SATA_PMP=y +# CONFIG_SATA_AHCI is not set +# CONFIG_SATA_SIL24 is not set +CONFIG_ATA_SFF=y +# CONFIG_SATA_SVW is not set +# CONFIG_ATA_PIIX is not set +# CONFIG_SATA_MV is not set +# CONFIG_SATA_NV is not set +# CONFIG_PDC_ADMA is not set +# CONFIG_SATA_QSTOR is not set +# CONFIG_SATA_PROMISE is not set +# CONFIG_SATA_SX4 is not set +# CONFIG_SATA_SIL is not set +# CONFIG_SATA_SIS is not set +# CONFIG_SATA_ULI is not set +# CONFIG_SATA_VIA is not set +# CONFIG_SATA_VITESSE is not set +# CONFIG_SATA_INIC162X is not set +# CONFIG_PATA_ALI is not set +# CONFIG_PATA_AMD is not set +# CONFIG_PATA_ARTOP is not set +# CONFIG_PATA_ATIIXP is not set +# CONFIG_PATA_CMD640_PCI is not set +# CONFIG_PATA_CMD64X is not set +# CONFIG_PATA_CS5520 is not set +# CONFIG_PATA_CS5530 is not set +# CONFIG_PATA_CYPRESS is not set +# CONFIG_PATA_EFAR is not set +# CONFIG_ATA_GENERIC is not set +# CONFIG_PATA_HPT366 is not set +# CONFIG_PATA_HPT37X is not set +# CONFIG_PATA_HPT3X2N is not set +# CONFIG_PATA_HPT3X3 is not set +# CONFIG_PATA_IT821X is not set +# CONFIG_PATA_IT8213 is not set +# CONFIG_PATA_JMICRON is not set +# CONFIG_PATA_TRIFLEX is not set +# CONFIG_PATA_MARVELL is not set +# CONFIG_PATA_MPIIX is not set +# CONFIG_PATA_OLDPIIX is not set +# CONFIG_PATA_NETCELL is not set +# CONFIG_PATA_NINJA32 is not set +# CONFIG_PATA_NS87410 is not set +# CONFIG_PATA_NS87415 is not set +# CONFIG_PATA_OPTI is not set +# CONFIG_PATA_OPTIDMA is not set +# CONFIG_PATA_PDC_OLD is not set +# CONFIG_PATA_RADISYS is not set +# CONFIG_PATA_RZ1000 is not set +# CONFIG_PATA_SC1200 is not set +# CONFIG_PATA_SERVERWORKS is not set +# CONFIG_PATA_PDC2027X is not set +# CONFIG_PATA_SIL680 is not set +# CONFIG_PATA_SIS is not set +# CONFIG_PATA_VIA is not set +# CONFIG_PATA_WINBOND is not set +# CONFIG_PATA_PLATFORM is not set +# CONFIG_PATA_SCH is not set +# CONFIG_MD is not set +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# + +# +# You can enable one or both FireWire driver stacks. +# + +# +# See the help texts for more information. +# +# CONFIG_FIREWIRE is not set +# CONFIG_IEEE1394 is not set +# CONFIG_I2O is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +# CONFIG_ARCNET is not set +# CONFIG_PHYLIB is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_AX88796 is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_SMC91X is not set +# CONFIG_DM9000 is not set +# CONFIG_ETHOC is not set +# CONFIG_DNET is not set +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_NET_PCI is not set +# CONFIG_B44 is not set +# CONFIG_KS8842 is not set +# CONFIG_ATL2 is not set +CONFIG_NETDEV_1000=y +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_E1000E is not set +# CONFIG_IP1000 is not set +# CONFIG_IGB is not set +# CONFIG_IGBVF is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SIS190 is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set +# CONFIG_CNIC is not set +# CONFIG_QLA3XXX is not set +# CONFIG_ATL1 is not set +# CONFIG_ATL1E is not set +# CONFIG_ATL1C is not set +# CONFIG_JME is not set +CONFIG_NETDEV_10000=y +# CONFIG_CHELSIO_T1 is not set +CONFIG_CHELSIO_T3_DEPENDS=y +# CONFIG_CHELSIO_T3 is not set +# CONFIG_ENIC is not set +# CONFIG_IXGBE is not set +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set +# CONFIG_VXGE is not set +# CONFIG_MYRI10GE is not set +# CONFIG_NETXEN_NIC is not set +# CONFIG_NIU is not set +# CONFIG_MLX4_EN is not set +# CONFIG_MLX4_CORE is not set +# CONFIG_TEHUTI is not set +# CONFIG_BNX2X is not set +# CONFIG_QLGE is not set +# CONFIG_SFC is not set +# CONFIG_BE2NET is not set +# CONFIG_TR is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +CONFIG_USB_RTL8150=y +# CONFIG_USB_USBNET is not set +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NET_FC is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_DEVKMEM is not set +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_NOZOMI is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_JSM is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +# CONFIG_LEGACY_PTYS is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_DEVPORT=y +# CONFIG_I2C is not set +# CONFIG_SPI is not set + +# +# PPS support +# +# CONFIG_PPS is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +# CONFIG_THERMAL_HWMON is not set +# CONFIG_WATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_REGULATOR is not set +# CONFIG_MEDIA_SUPPORT is not set + +# +# Graphics support +# +# CONFIG_DRM is not set +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +# CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_SOUND is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set +# CONFIG_HIDRAW is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=y +# CONFIG_HID_PID is not set +CONFIG_USB_HIDDEV=y + +# +# Special HID drivers +# +# CONFIG_HID_A4TECH is not set +# CONFIG_HID_APPLE is not set +# CONFIG_HID_BELKIN is not set +# CONFIG_HID_CHERRY is not set +# CONFIG_HID_CHICONY is not set +# CONFIG_HID_CYPRESS is not set +# CONFIG_HID_DRAGONRISE is not set +# CONFIG_HID_EZKEY is not set +# CONFIG_HID_KYE is not set +# CONFIG_HID_GYRATION is not set +# CONFIG_HID_KENSINGTON is not set +# CONFIG_HID_LOGITECH is not set +# CONFIG_HID_MICROSOFT is not set +# CONFIG_HID_MONTEREY is not set +# CONFIG_HID_NTRIG is not set +# CONFIG_HID_PANTHERLORD is not set +# CONFIG_HID_PETALYNX is not set +# CONFIG_HID_SAMSUNG is not set +# CONFIG_HID_SONY is not set +# CONFIG_HID_SUNPLUS is not set +# CONFIG_HID_GREENASIA is not set +# CONFIG_HID_SMARTJOYPLUS is not set +# CONFIG_HID_TOPSEED is not set +# CONFIG_HID_THRUSTMASTER is not set +# CONFIG_HID_ZEROPLUS is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_DEVICE_CLASS is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_MON is not set +# CONFIG_USB_WUSB is not set +# CONFIG_USB_WUSB_CBAF is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_XHCI_HCD is not set +CONFIG_USB_EHCI_HCD=y +# CONFIG_USB_EHCI_ROOT_HUB_TT is not set +# CONFIG_USB_EHCI_TT_NEWSCHED is not set +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_UHCI_HCD is not set +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_WHCI_HCD is not set +# CONFIG_USB_HWA_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_WDM is not set +# CONFIG_USB_TMC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_ONETOUCH is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB port drivers +# +CONFIG_USB_SERIAL=y +CONFIG_USB_SERIAL_CONSOLE=y +# CONFIG_USB_EZUSB is not set +# CONFIG_USB_SERIAL_GENERIC is not set +# CONFIG_USB_SERIAL_AIRCABLE is not set +# CONFIG_USB_SERIAL_ARK3116 is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_CH341 is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +CONFIG_USB_SERIAL_CP210X=y +# CONFIG_USB_SERIAL_CYPRESS_M8 is not set +# CONFIG_USB_SERIAL_EMPEG is not set +# CONFIG_USB_SERIAL_FTDI_SIO is not set +# CONFIG_USB_SERIAL_FUNSOFT is not set +# CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_IPAQ is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_EDGEPORT_TI is not set +# CONFIG_USB_SERIAL_GARMIN is not set +# CONFIG_USB_SERIAL_IPW is not set +# CONFIG_USB_SERIAL_IUU is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KLSI is not set +# CONFIG_USB_SERIAL_KOBIL_SCT is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_MOS7720 is not set +# CONFIG_USB_SERIAL_MOS7840 is not set +# CONFIG_USB_SERIAL_MOTOROLA is not set +# CONFIG_USB_SERIAL_NAVMAN is not set +# CONFIG_USB_SERIAL_PL2303 is not set +# CONFIG_USB_SERIAL_OTI6858 is not set +# CONFIG_USB_SERIAL_QUALCOMM is not set +# CONFIG_USB_SERIAL_SPCP8X5 is not set +# CONFIG_USB_SERIAL_HP4X is not set +# CONFIG_USB_SERIAL_SAFE is not set +# CONFIG_USB_SERIAL_SIEMENS_MPI is not set +# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set +# CONFIG_USB_SERIAL_SYMBOL is not set +# CONFIG_USB_SERIAL_TI is not set +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +# CONFIG_USB_SERIAL_OPTION is not set +# CONFIG_USB_SERIAL_OMNINET is not set +# CONFIG_USB_SERIAL_OPTICON is not set +# CONFIG_USB_SERIAL_DEBUG is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_BERRY_CHARGE is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_VST is not set +# CONFIG_USB_GADGET is not set + +# +# OTG and related infrastructure +# +# CONFIG_NOP_USB_XCEIV is not set +# CONFIG_UWB is not set +# CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set +# CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set +# CONFIG_INFINIBAND is not set +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set +# CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set + +# +# TI VLYNQ +# +# CONFIG_STAGING is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set +# CONFIG_EXT3_FS_XATTR is not set +# CONFIG_EXT4_FS is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +# CONFIG_DNOTIFY is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +CONFIG_FUSE_FS=y +# CONFIG_CUSE is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +CONFIG_CRAMFS=y +# CONFIG_SQUASHFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set +# CONFIG_DLM is not set + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_PRINTK_TIME=y +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 +# CONFIG_SCHED_DEBUG is not set +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_DEBUG_PREEMPT is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_PAGE_POISONING is not set +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_PREEMPT_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_ENABLE_DEFAULT_TRACERS is not set +# CONFIG_BOOT_TRACER is not set +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +# CONFIG_KMEMCHECK is not set +CONFIG_CMDLINE="rw dhash_entries=1024 ihash_entries=1024 ip=10.0.1.3:10.0.1.1:10.0.1.1:255.255.255.0:zeus:eth0: root=/dev/nfs nfsroot=/nfsroot/cramfs,wsize=512,rsize=512,tcp nokgdb console=ttyUSB0,115200 memsize=252M" +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_RUNTIME_DEBUG is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +# CONFIG_CRYPTO_FIPS is not set +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +CONFIG_CRYPTO_WORKQUEUE=y +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_AUTHENC=y +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +# CONFIG_CRYPTO_ECB is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +CONFIG_CRYPTO_HMAC=y +# CONFIG_CRYPTO_XCBC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +CONFIG_CRYPTO_SHA1=y +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +CONFIG_CRYPTO_DEFLATE=y +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +# CONFIG_CRYPTO_ANSI_CPRNG is not set +# CONFIG_CRYPTO_HW is not set +# CONFIG_BINARY_PRINTF is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC_T10DIF is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_NLATTR=y diff --git a/arch/mips/include/asm/mach-powertv/asic.h b/arch/mips/include/asm/mach-powertv/asic.h new file mode 100644 index 0000000..bcad43a --- /dev/null +++ b/arch/mips/include/asm/mach-powertv/asic.h @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2009 Cisco Systems, Inc. + * + * 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 _ASM_MACH_POWERTV_ASIC_H +#define _ASM_MACH_POWERTV_ASIC_H + +#include +#include + +#define DVR_CAPABLE (1<<0) +#define PCIE_CAPABLE (1<<1) +#define FFS_CAPABLE (1<<2) +#define DISPLAY_CAPABLE (1<<3) + +/* Platform Family types + * For compitability, the new value must be added in the end */ +enum family_type { + FAMILY_8500, + FAMILY_8500RNG, + FAMILY_4500, + FAMILY_1500, + FAMILY_8600, + FAMILY_4600, + FAMILY_4600VZA, + FAMILY_8600VZB, + FAMILY_1500VZE, + FAMILY_1500VZF, + FAMILIES +}; + +/* Register maps for each ASIC */ +extern const struct register_map calliope_register_map; +extern const struct register_map cronus_register_map; +extern const struct register_map zeus_register_map; + +extern struct resource dvr_cronus_resources[]; +extern struct resource dvr_zeus_resources[]; +extern struct resource non_dvr_calliope_resources[]; +extern struct resource non_dvr_cronus_resources[]; +extern struct resource non_dvr_cronuslite_resources[]; +extern struct resource non_dvr_vz_calliope_resources[]; +extern struct resource non_dvr_vze_calliope_resources[]; +extern struct resource non_dvr_vzf_calliope_resources[]; +extern struct resource non_dvr_zeus_resources[]; + +extern void powertv_platform_init(void); +extern void platform_alloc_bootmem(void); +extern enum asic_type platform_get_asic(void); +extern enum family_type platform_get_family(void); +extern int platform_supports_dvr(void); +extern int platform_supports_ffs(void); +extern int platform_supports_pcie(void); +extern int platform_supports_display(void); +extern void configure_platform(void); +extern void platform_configure_usb_ehci(void); +extern void platform_unconfigure_usb_ehci(void); +extern void platform_configure_usb_ohci(void); +extern void platform_unconfigure_usb_ohci(void); + +/* Platform Resources */ +#define ASIC_RESOURCE_GET_EXISTS 1 +extern struct resource *asic_resource_get(const char *name); +extern void platform_release_memory(void *baddr, int size); + +/* Reboot Cause */ +extern void set_reboot_cause(char code, unsigned int data, unsigned int data2); +extern void set_locked_reboot_cause(char code, unsigned int data, + unsigned int data2); + +enum sys_reboot_type { + sys_unknown_reboot = 0x00, /* Unknown reboot cause */ + sys_davic_change = 0x01, /* Reboot due to change in DAVIC + * mode */ + sys_user_reboot = 0x02, /* Reboot initiated by user */ + sys_system_reboot = 0x03, /* Reboot initiated by OS */ + sys_trap_reboot = 0x04, /* Reboot due to a CPU trap */ + sys_silent_reboot = 0x05, /* Silent reboot */ + sys_boot_ldr_reboot = 0x06, /* Bootloader reboot */ + sys_power_up_reboot = 0x07, /* Power on bootup. Older + * drivers may report as + * userReboot. */ + sys_code_change = 0x08, /* Reboot to take code change. + * Older drivers may report as + * userReboot. */ + sys_hardware_reset = 0x09, /* HW watchdog or front-panel + * reset button reset. Older + * drivers may report as + * userReboot. */ + sys_watchdogInterrupt = 0x0A /* Pre-watchdog interrupt */ +}; + +#endif /* _ASM_MACH_POWERTV_ASIC_H */ diff --git a/arch/mips/include/asm/mach-powertv/asic_regs.h b/arch/mips/include/asm/mach-powertv/asic_regs.h new file mode 100644 index 0000000..9a65c93 --- /dev/null +++ b/arch/mips/include/asm/mach-powertv/asic_regs.h @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2009 Cisco Systems, Inc. + * + * 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 __ASM_MACH_POWERTV_ASIC_H_ +#define __ASM_MACH_POWERTV_ASIC_H_ +#include + +/* ASIC types */ +enum asic_type { + ASIC_UNKNOWN, + ASIC_ZEUS, + ASIC_CALLIOPE, + ASIC_CRONUS, + ASIC_CRONUSLITE, + ASICS +}; + +/* hardcoded values read from Chip Version registers */ +#define CRONUS_10 0x0B4C1C20 +#define CRONUS_11 0x0B4C1C21 +#define CRONUSLITE_10 0x0B4C1C40 + +#define NAND_FLASH_BASE 0x03000000 +#define ZEUS_IO_BASE 0x09000000 +#define CALLIOPE_IO_BASE 0x08000000 +#define CRONUS_IO_BASE 0x09000000 +#define ASIC_IO_SIZE 0x01000000 + +/* Definitions for backward compatibility */ +#define UART1_INTSTAT uart1_intstat +#define UART1_INTEN uart1_inten +#define UART1_CONFIG1 uart1_config1 +#define UART1_CONFIG2 uart1_config2 +#define UART1_DIVISORHI uart1_divisorhi +#define UART1_DIVISORLO uart1_divisorlo +#define UART1_DATA uart1_data +#define UART1_STATUS uart1_status + +/* ASIC register enumeration */ +struct register_map { + u32 eic_slow0_strt_add; + u32 eic_cfg_bits; + u32 eic_ready_status; + + u32 chipver3; + u32 chipver2; + u32 chipver1; + u32 chipver0; + + u32 uart1_intstat; + u32 uart1_inten; + u32 uart1_config1; + u32 uart1_config2; + u32 uart1_divisorhi; + u32 uart1_divisorlo; + u32 uart1_data; + u32 uart1_status; + + u32 int_stat_3; + u32 int_stat_2; + u32 int_stat_1; + u32 int_stat_0; + u32 int_config; + u32 int_int_scan; + u32 ien_int_3; + u32 ien_int_2; + u32 ien_int_1; + u32 ien_int_0; + u32 int_level_3_3; + u32 int_level_3_2; + u32 int_level_3_1; + u32 int_level_3_0; + u32 int_level_2_3; + u32 int_level_2_2; + u32 int_level_2_1; + u32 int_level_2_0; + u32 int_level_1_3; + u32 int_level_1_2; + u32 int_level_1_1; + u32 int_level_1_0; + u32 int_level_0_3; + u32 int_level_0_2; + u32 int_level_0_1; + u32 int_level_0_0; + u32 int_docsis_en; + + u32 mips_pll_setup; + u32 usb_fs; + u32 test_bus; + u32 crt_spare; + u32 usb2_ohci_int_mask; + u32 usb2_strap; + u32 ehci_hcapbase; + u32 ohci_hc_revision; + u32 bcm1_bs_lmi_steer; + u32 usb2_control; + u32 usb2_stbus_obc; + u32 usb2_stbus_mess_size; + u32 usb2_stbus_chunk_size; + + u32 pcie_regs; + u32 tim_ch; + u32 tim_cl; + u32 gpio_dout; + u32 gpio_din; + u32 gpio_dir; + u32 watchdog; + u32 front_panel; + + u32 register_maps; +}; + +extern enum asic_type asic; +extern const struct register_map *register_map; +extern unsigned long asic_phy_base; /* Physical address of ASIC */ +extern unsigned long asic_base; /* Virtual address of ASIC */ + +/* + * Macros to interface to registers through their ioremapped address + * asic_reg_offset Returns the offset of a given register from the start + * of the ASIC address space + * asic_reg_phys_addr Returns the physical address of the given register + * asic_reg_addr Returns the iomapped virtual address of the given + * register. + */ +#define asic_reg_offset(x) (register_map->x) +#define asic_reg_phys_addr(x) (asic_phy_base + asic_reg_offset(x)) +#define asic_reg_addr(x) \ + ((unsigned int *) (asic_base + asic_reg_offset(x))) + +/* + * The asic_reg macro is gone. It should be replaced by either asic_read or + * asic_write, as appropriate. + */ + +#define asic_read(x) readl(asic_reg_addr(x)) +#define asic_write(v, x) writel(v, asic_reg_addr(x)) + +extern void asic_irq_init(void); +#endif diff --git a/arch/mips/include/asm/mach-powertv/dma-coherence.h b/arch/mips/include/asm/mach-powertv/dma-coherence.h new file mode 100644 index 0000000..5b8d5eb --- /dev/null +++ b/arch/mips/include/asm/mach-powertv/dma-coherence.h @@ -0,0 +1,119 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Version from mach-generic modified to support PowerTV port + * Portions Copyright (C) 2009 Cisco Systems, Inc. + * Copyright (C) 2006 Ralf Baechle + * + */ + +#ifndef __ASM_MACH_POWERTV_DMA_COHERENCE_H +#define __ASM_MACH_POWERTV_DMA_COHERENCE_H + +#include +#include +#include +#include + +static inline bool is_kseg2(void *addr) +{ + return (unsigned long)addr >= KSEG2; +} + +static inline unsigned long virt_to_phys_from_pte(void *addr) +{ + pgd_t *pgd; + pud_t *pud; + pmd_t *pmd; + pte_t *ptep, pte; + + unsigned long virt_addr = (unsigned long)addr; + unsigned long phys_addr = 0UL; + + /* get the page global directory. */ + pgd = pgd_offset_k(virt_addr); + + if (!pgd_none(*pgd)) { + /* get the page upper directory */ + pud = pud_offset(pgd, virt_addr); + if (!pud_none(*pud)) { + /* get the page middle directory */ + pmd = pmd_offset(pud, virt_addr); + if (!pmd_none(*pmd)) { + /* get a pointer to the page table entry */ + ptep = pte_offset(pmd, virt_addr); + pte = *ptep; + /* check for a valid page */ + if (pte_present(pte)) { + /* get the physical address the page is + * refering to */ + phys_addr = (unsigned long) + page_to_phys(pte_page(pte)); + /* add the offset within the page */ + phys_addr |= (virt_addr & ~PAGE_MASK); + } + } + } + } + + return phys_addr; +} + +static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, + size_t size) +{ + if (is_kseg2(addr)) + return phys_to_bus(virt_to_phys_from_pte(addr)); + else + return phys_to_bus(virt_to_phys(addr)); +} + +static inline dma_addr_t plat_map_dma_mem_page(struct device *dev, + struct page *page) +{ + return phys_to_bus(page_to_phys(page)); +} + +static inline unsigned long plat_dma_addr_to_phys(struct device *dev, + dma_addr_t dma_addr) +{ + return bus_to_phys(dma_addr); +} + +static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr, + size_t size, enum dma_data_direction direction) +{ +} + +static inline int plat_dma_supported(struct device *dev, u64 mask) +{ + /* + * we fall back to GFP_DMA when the mask isn't all 1s, + * so we can't guarantee allocations that must be + * within a tighter range than GFP_DMA.. + */ + if (mask < DMA_BIT_MASK(24)) + return 0; + + return 1; +} + +static inline void plat_extra_sync_for_device(struct device *dev) +{ + return; +} + +static inline int plat_dma_mapping_error(struct device *dev, + dma_addr_t dma_addr) +{ + return 0; +} + +static inline int plat_device_is_coherent(struct device *dev) +{ + return 0; +} + +#endif /* __ASM_MACH_POWERTV_DMA_COHERENCE_H */ diff --git a/arch/mips/include/asm/mach-powertv/interrupts.h b/arch/mips/include/asm/mach-powertv/interrupts.h new file mode 100644 index 0000000..629a574 --- /dev/null +++ b/arch/mips/include/asm/mach-powertv/interrupts.h @@ -0,0 +1,254 @@ +/* + * Copyright (C) 2009 Cisco Systems, Inc. + * + * 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 _ASM_MACH_POWERTV_INTERRUPTS_H_ +#define _ASM_MACH_POWERTV_INTERRUPTS_H_ + +/* + * Defines for all of the interrupt lines + */ + +/* Definitions for backward compatibility */ +#define kIrq_Uart1 irq_uart1 + +#define ibase 0 + +/*------------- Register: int_stat_3 */ +/* 126 unused (bit 31) */ +#define irq_asc2video (ibase+126) /* ASC 2 Video Interrupt */ +#define irq_asc1video (ibase+125) /* ASC 1 Video Interrupt */ +#define irq_comms_block_wd (ibase+124) /* ASC 1 Video Interrupt */ +#define irq_fdma_mailbox (ibase+123) /* FDMA Mailbox Output */ +#define irq_fdma_gp (ibase+122) /* FDMA GP Output */ +#define irq_mips_pic (ibase+121) /* MIPS Performance Counter + * Interrupt */ +#define irq_mips_timer (ibase+120) /* MIPS Timer Interrupt */ +#define irq_memory_protect (ibase+119) /* Memory Protection Interrupt + * -- Ored by glue logic inside + * SPARC ILC (see + * INT_MEM_PROT_STAT, below, + * for individual interrupts) + */ +/* 118 unused (bit 22) */ +#define irq_sbag (ibase+117) /* SBAG Interrupt -- Ored by + * glue logic inside SPARC ILC + * (see INT_SBAG_STAT, below, + * for individual interrupts) */ +#define irq_qam_b_fec (ibase+116) /* QAM B FEC Interrupt */ +#define irq_qam_a_fec (ibase+115) /* QAM A FEC Interrupt */ +/* 114 unused (bit 18) */ +#define irq_mailbox (ibase+113) /* Mailbox Debug Interrupt -- + * Ored by glue logic inside + * SPARC ILC (see + * INT_MAILBOX_STAT, below, for + * individual interrupts) */ +#define irq_fuse_stat1 (ibase+112) /* Fuse Status 1 */ +#define irq_fuse_stat2 (ibase+111) /* Fuse Status 2 */ +#define irq_fuse_stat3 (ibase+110) /* Blitter Interrupt / Fuse + * Status 3 */ +#define irq_blitter (ibase+110) /* Blitter Interrupt / Fuse + * Status 3 */ +#define irq_avc1_pp0 (ibase+109) /* AVC Decoder #1 PP0 + * Interrupt */ +#define irq_avc1_pp1 (ibase+108) /* AVC Decoder #1 PP1 + * Interrupt */ +#define irq_avc1_mbe (ibase+107) /* AVC Decoder #1 MBE + * Interrupt */ +#define irq_avc2_pp0 (ibase+106) /* AVC Decoder #2 PP0 + * Interrupt */ +#define irq_avc2_pp1 (ibase+105) /* AVC Decoder #2 PP1 + * Interrupt */ +#define irq_avc2_mbe (ibase+104) /* AVC Decoder #2 MBE + * Interrupt */ +#define irq_zbug_spi (ibase+103) /* Zbug SPI Slave Interrupt */ +#define irq_qam_mod2 (ibase+102) /* QAM Modulator 2 DMA + * Interrupt */ +#define irq_ir_rx (ibase+101) /* IR RX 2 Interrupt */ +#define irq_aud_dsp2 (ibase+100) /* Audio DSP #2 Interrupt */ +#define irq_aud_dsp1 (ibase+99) /* Audio DSP #1 Interrupt */ +#define irq_docsis (ibase+98) /* DOCSIS Debug Interrupt */ +#define irq_sd_dvp1 (ibase+97) /* SD DVP #1 Interrupt */ +#define irq_sd_dvp2 (ibase+96) /* SD DVP #2 Interrupt */ +/*------------- Register: int_stat_2 */ +#define irq_hd_dvp (ibase+95) /* HD DVP Interrupt */ +#define kIrq_Prewatchdog (ibase+94) /* watchdog Pre-Interrupt */ +#define irq_timer2 (ibase+93) /* Programmable Timer + * Interrupt 2 */ +#define irq_1394 (ibase+92) /* 1394 Firewire Interrupt */ +#define irq_usbohci (ibase+91) /* USB 2.0 OHCI Interrupt */ +#define irq_usbehci (ibase+90) /* USB 2.0 EHCI Interrupt */ +#define irq_pciexp (ibase+89) /* PCI Express 0 Interrupt */ +#define irq_pciexp0 (ibase+89) /* PCI Express 0 Interrupt */ +#define irq_afe1 (ibase+88) /* AFE 1 Interrupt */ +#define irq_sata (ibase+87) /* SATA 1 Interrupt */ +#define irq_sata1 (ibase+87) /* SATA 1 Interrupt */ +#define irq_dtcp (ibase+86) /* DTCP Interrupt */ +#define irq_pciexp1 (ibase+85) /* PCI Express 1 Interrupt */ +/* 84 unused (bit 20) */ +/* 83 unused (bit 19) */ +/* 82 unused (bit 18) */ +#define irq_sata2 (ibase+81) /* SATA2 Interrupt */ +#define irq_uart2 (ibase+80) /* UART2 Interrupt */ +#define irq_legacy_usb (ibase+79) /* Legacy USB Host ISR (1.1 + * Host module) */ +#define irq_pod (ibase+78) /* POD Interrupt */ +#define irq_slave_usb (ibase+77) /* Slave USB */ +#define irq_denc1 (ibase+76) /* DENC #1 VTG Interrupt */ +#define irq_vbi_vtg (ibase+75) /* VBI VTG Interrupt */ +#define irq_afe2 (ibase+74) /* AFE 2 Interrupt */ +#define irq_denc2 (ibase+73) /* DENC #2 VTG Interrupt */ +#define irq_asc2 (ibase+72) /* ASC #2 Interrupt */ +#define irq_asc1 (ibase+71) /* ASC #1 Interrupt */ +#define irq_mod_dma (ibase+70) /* Modulator DMA Interrupt */ +#define irq_byte_eng1 (ibase+69) /* Byte Engine Interrupt [1] */ +#define irq_byte_eng0 (ibase+68) /* Byte Engine Interrupt [0] */ +/* 67 unused (bit 03) */ +/* 66 unused (bit 02) */ +/* 65 unused (bit 01) */ +/* 64 unused (bit 00) */ +/*------------- Register: int_stat_1 */ +/* 63 unused (bit 31) */ +/* 62 unused (bit 30) */ +/* 61 unused (bit 29) */ +/* 60 unused (bit 28) */ +/* 59 unused (bit 27) */ +/* 58 unused (bit 26) */ +/* 57 unused (bit 25) */ +/* 56 unused (bit 24) */ +#define irq_buf_dma_mem2mem (ibase+55) /* BufDMA Memory to Memory + * Interrupt */ +#define irq_buf_dma_usbtransmit (ibase+54) /* BufDMA USB Transmit + * Interrupt */ +#define irq_buf_dma_qpskpodtransmit (ibase+53) /* BufDMA QPSK/POD Tramsit + * Interrupt */ +#define irq_buf_dma_transmit_error (ibase+52) /* BufDMA Transmit Error + * Interrupt */ +#define irq_buf_dma_usbrecv (ibase+51) /* BufDMA USB Receive + * Interrupt */ +#define irq_buf_dma_qpskpodrecv (ibase+50) /* BufDMA QPSK/POD Receive + * Interrupt */ +#define irq_buf_dma_recv_error (ibase+49) /* BufDMA Receive Error + * Interrupt */ +#define irq_qamdma_transmit_play (ibase+48) /* QAMDMA Transmit/Play + * Interrupt */ +#define irq_qamdma_transmit_error (ibase+47) /* QAMDMA Transmit Error + * Interrupt */ +#define irq_qamdma_recv2high (ibase+46) /* QAMDMA Receive 2 High + * (Chans 63-32) */ +#define irq_qamdma_recv2low (ibase+45) /* QAMDMA Receive 2 Low + * (Chans 31-0) */ +#define irq_qamdma_recv1high (ibase+44) /* QAMDMA Receive 1 High + * (Chans 63-32) */ +#define irq_qamdma_recv1low (ibase+43) /* QAMDMA Receive 1 Low + * (Chans 31-0) */ +#define irq_qamdma_recv_error (ibase+42) /* QAMDMA Receive Error + * Interrupt */ +#define irq_mpegsplice (ibase+41) /* MPEG Splice Interrupt */ +#define irq_deinterlace_rdy (ibase+40) /* Deinterlacer Frame Ready + * Interrupt */ +#define irq_ext_in0 (ibase+39) /* External Interrupt irq_in0 */ +#define irq_gpio3 (ibase+38) /* GP I/O IRQ 3 - From GP I/O + * Module */ +#define irq_gpio2 (ibase+37) /* GP I/O IRQ 2 - From GP I/O + * Module (ABE_intN) */ +#define irq_pcrcmplt1 (ibase+36) /* PCR Capture Complete or + * Discontinuity 1 */ +#define irq_pcrcmplt2 (ibase+35) /* PCR Capture Complete or + * Discontinuity 2 */ +#define irq_parse_peierr (ibase+34) /* PID Parser Error Detect + * (PEI) */ +#define irq_parse_cont_err (ibase+33) /* PID Parser continuity error + * detect */ +#define irq_ds1framer (ibase+32) /* DS1 Framer Interrupt */ +/*------------- Register: int_stat_0 */ +#define irq_gpio1 (ibase+31) /* GP I/O IRQ 1 - From GP I/O + * Module */ +#define irq_gpio0 (ibase+30) /* GP I/O IRQ 0 - From GP I/O + * Module */ +#define irq_qpsk_out_aloha (ibase+29) /* QPSK Output Slotted Aloha + * (chan 3) Transmission + * Completed OK */ +#define irq_qpsk_out_tdma (ibase+28) /* QPSK Output TDMA (chan 2) + * Transmission Completed OK */ +#define irq_qpsk_out_reserve (ibase+27) /* QPSK Output Reservation + * (chan 1) Transmission + * Completed OK */ +#define irq_qpsk_out_aloha_err (ibase+26) /* QPSK Output Slotted Aloha + * (chan 3)Transmission + * completed with Errors. */ +#define irq_qpsk_out_tdma_err (ibase+25) /* QPSK Output TDMA (chan 2) + * Transmission completed with + * Errors. */ +#define irq_qpsk_out_rsrv_err (ibase+24) /* QPSK Output Reservation + * (chan 1) Transmission + * completed with Errors */ +#define irq_aloha_fail (ibase+23) /* Unsuccessful Resend of Aloha + * for N times. Aloha retry + * timeout for channel 3. */ +#define irq_timer1 (ibase+22) /* Programmable Timer + * Interrupt */ +#define irq_keyboard (ibase+21) /* Keyboard Module Interrupt */ +#define irq_i2c (ibase+20) /* I2C Module Interrupt */ +#define irq_spi (ibase+19) /* SPI Module Interrupt */ +#define irq_irblaster (ibase+18) /* IR Blaster Interrupt */ +#define irq_splice_detect (ibase+17) /* PID Key Change Interrupt or + * Splice Detect Interrupt */ +#define irq_se_micro (ibase+16) /* Secure Micro I/F Module + * Interrupt */ +#define irq_uart1 (ibase+15) /* UART Interrupt */ +#define irq_irrecv (ibase+14) /* IR Receiver Interrupt */ +#define irq_host_int1 (ibase+13) /* Host-to-Host Interrupt 1 */ +#define irq_host_int0 (ibase+12) /* Host-to-Host Interrupt 0 */ +#define irq_qpsk_hecerr (ibase+11) /* QPSK HEC Error Interrupt */ +#define irq_qpsk_crcerr (ibase+10) /* QPSK AAL-5 CRC Error + * Interrupt */ +/* 9 unused (bit 09) */ +/* 8 unused (bit 08) */ +#define irq_psicrcerr (ibase+7) /* QAM PSI CRC Error + * Interrupt */ +#define irq_psilength_err (ibase+6) /* QAM PSI Length Error + * Interrupt */ +#define irq_esfforward (ibase+5) /* ESF Interrupt Mark From + * Forward Path Reference - + * every 3ms when forward Mbits + * and forward slot control + * bytes are updated. */ +#define irq_esfreverse (ibase+4) /* ESF Interrupt Mark from + * Reverse Path Reference - + * delayed from forward mark by + * the ranging delay plus a + * fixed amount. When reverse + * Mbits and reverse slot + * control bytes are updated. + * Occurs every 3ms for 3.0M and + * 1.554 M upstream rates and + * every 6 ms for 256K upstream + * rate. */ +#define irq_aloha_timeout (ibase+3) /* Slotted-Aloha timeout on + * Channel 1. */ +#define irq_reservation (ibase+2) /* Partial (or Incremental) + * Reservation Message Completed + * or Slotted aloha verify for + * channel 1. */ +#define irq_aloha3 (ibase+1) /* Slotted-Aloha Message Verify + * Interrupt or Reservation + * increment completed for + * channel 3. */ +#define irq_mpeg_d (ibase+0) /* MPEG Decoder Interrupt */ +#endif /* _ASM_MACH_POWERTV_INTERRUPTS_H_ */ + diff --git a/arch/mips/include/asm/mach-powertv/ioremap.h b/arch/mips/include/asm/mach-powertv/ioremap.h new file mode 100644 index 0000000..e6276d5 --- /dev/null +++ b/arch/mips/include/asm/mach-powertv/ioremap.h @@ -0,0 +1,90 @@ +/* + * 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. + * + * Portions Copyright (C) Cisco Systems, Inc. + */ +#ifndef __ASM_MACH_POWERTV_IOREMAP_H +#define __ASM_MACH_POWERTV_IOREMAP_H + +#include + +#define LOW_MEM_BOUNDARY_PHYS 0x20000000 +#define LOW_MEM_BOUNDARY_MASK (~(LOW_MEM_BOUNDARY_PHYS - 1)) + +/* + * The bus addresses are different than the physical addresses that + * the processor sees by an offset. This offset varies by ASIC + * version. Define a variable to hold the offset and some macros to + * make the conversion simpler. */ +extern unsigned long phys_to_bus_offset; + +#ifdef CONFIG_HIGHMEM +#define MEM_GAP_PHYS 0x60000000 +/* + * TODO: We will use the hard code for conversion between physical and + * bus until the bootloader releases their device tree to us. + */ +#define phys_to_bus(x) (((x) < LOW_MEM_BOUNDARY_PHYS) ? \ + ((x) + phys_to_bus_offset) : (x)) +#define bus_to_phys(x) (((x) < MEM_GAP_PHYS_ADDR) ? \ + ((x) - phys_to_bus_offset) : (x)) +#else +#define phys_to_bus(x) ((x) + phys_to_bus_offset) +#define bus_to_phys(x) ((x) - phys_to_bus_offset) +#endif + +/* + * Determine whether the address we are given is for an ASIC device + * Params: addr Address to check + * Returns: Zero if the address is not for ASIC devices, non-zero + * if it is. + */ +static inline int asic_is_device_addr(phys_t addr) +{ + return !((phys_t)addr & (phys_t) LOW_MEM_BOUNDARY_MASK); +} + +/* + * Determine whether the address we are given is external RAM mappable + * into KSEG1. + * Params: addr Address to check + * Returns: Zero if the address is not for external RAM and + */ +static inline int asic_is_lowmem_ram_addr(phys_t addr) +{ + /* + * The RAM always starts at the following address in the processor's + * physical address space + */ + static const phys_t phys_ram_base = 0x10000000; + phys_t bus_ram_base; + + bus_ram_base = phys_to_bus_offset + phys_ram_base; + + return addr >= bus_ram_base && + addr < (bus_ram_base + (LOW_MEM_BOUNDARY_PHYS - phys_ram_base)); +} + +/* + * Allow physical addresses to be fixed up to help peripherals located + * outside the low 32-bit range -- generic pass-through version. + */ +static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size) +{ + return phys_addr; +} + +static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size, + unsigned long flags) +{ + return NULL; +} + +static inline int plat_iounmap(const volatile void __iomem *addr) +{ + return 0; +} +#endif /* __ASM_MACH_POWERTV_IOREMAP_H */ diff --git a/arch/mips/include/asm/mach-powertv/irq.h b/arch/mips/include/asm/mach-powertv/irq.h new file mode 100644 index 0000000..4bd5d0c --- /dev/null +++ b/arch/mips/include/asm/mach-powertv/irq.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2009 Cisco Systems, Inc. + * + * 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 _ASM_MACH_POWERTV_IRQ_H +#define _ASM_MACH_POWERTV_IRQ_H +#include + +#define MIPS_CPU_IRQ_BASE ibase +#define NR_IRQS 127 +#endif diff --git a/arch/mips/include/asm/mach-powertv/powertv-clock.h b/arch/mips/include/asm/mach-powertv/powertv-clock.h new file mode 100644 index 0000000..6f3e9a0 --- /dev/null +++ b/arch/mips/include/asm/mach-powertv/powertv-clock.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2009 Cisco Systems, Inc. + * + * 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 + */ +/* + * Local definitions for the powertv PCI code + */ + +#ifndef _POWERTV_PCI_POWERTV_PCI_H_ +#define _POWERTV_PCI_POWERTV_PCI_H_ +extern int asic_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin); +extern int asic_pcie_init(void); +extern int asic_pcie_init(void); + +extern int log_level; +#endif diff --git a/arch/mips/include/asm/mach-powertv/war.h b/arch/mips/include/asm/mach-powertv/war.h new file mode 100644 index 0000000..7ac05ec --- /dev/null +++ b/arch/mips/include/asm/mach-powertv/war.h @@ -0,0 +1,28 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * This version for the PowerTV platform copied from the Malta version. + * + * Copyright (C) 2002, 2004, 2007 by Ralf Baechle + * Portions copyright (C) 2009 Cisco Systems, Inc. + */ +#ifndef __ASM_MACH_POWERTV_WAR_H +#define __ASM_MACH_POWERTV_WAR_H + +#define R4600_V1_INDEX_ICACHEOP_WAR 0 +#define R4600_V1_HIT_CACHEOP_WAR 0 +#define R4600_V2_HIT_CACHEOP_WAR 0 +#define R5432_CP0_INTERRUPT_WAR 0 +#define BCM1250_M3_WAR 0 +#define SIBYTE_1956_WAR 0 +#define MIPS4K_ICACHE_REFILL_WAR 1 +#define MIPS_CACHE_SYNC_WAR 1 +#define TX49XX_ICACHE_INDEX_INV_WAR 0 +#define RM9000_CDEX_SMP_WAR 0 +#define ICACHE_REFILLS_WORKAROUND_WAR 1 +#define R10000_LLSC_WAR 0 +#define MIPS34K_MISSED_ITLB_WAR 0 + +#endif /* __ASM_MACH_POWERTV_WAR_H */ diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index eecd2a9..a446aa2 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -19,6 +19,7 @@ obj-$(CONFIG_CEVT_SB1250) += cevt-sb1250.o obj-$(CONFIG_CEVT_TXX9) += cevt-txx9.o obj-$(CONFIG_CSRC_BCM1480) += csrc-bcm1480.o obj-$(CONFIG_CSRC_IOASIC) += csrc-ioasic.o +obj-$(CONFIG_CSRC_POWERTV) += csrc-powertv.o obj-$(CONFIG_CSRC_R4K_LIB) += csrc-r4k.o obj-$(CONFIG_CSRC_SB1250) += csrc-sb1250.o obj-$(CONFIG_SYNC_R4K) += sync-r4k.o diff --git a/arch/mips/kernel/csrc-powertv.c b/arch/mips/kernel/csrc-powertv.c new file mode 100644 index 0000000..a27c16c --- /dev/null +++ b/arch/mips/kernel/csrc-powertv.c @@ -0,0 +1,180 @@ +/* + * Copyright (C) 2008 Scientific-Atlanta, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +/* + * The file comes from kernel/csrc-r4k.c + */ +#include +#include + +#include /* Not included in linux/time.h */ + +#include +#include "powertv-clock.h" + +/* MIPS PLL Register Definitions */ +#define PLL_GET_M(x) (((x) >> 8) & 0x000000FF) +#define PLL_GET_N(x) (((x) >> 16) & 0x000000FF) +#define PLL_GET_P(x) (((x) >> 24) & 0x00000007) + +/* + * returns: Clock frequency in kHz + */ +unsigned int __init mips_get_pll_freq(void) +{ + unsigned int pll_reg, m, n, p; + unsigned int fin = 54000; /* Base frequency in kHz */ + unsigned int fout; + + /* Read PLL register setting */ + pll_reg = asic_read(mips_pll_setup); + m = PLL_GET_M(pll_reg); + n = PLL_GET_N(pll_reg); + p = PLL_GET_P(pll_reg); + pr_info("MIPS PLL Register:0x%x M=%d N=%d P=%d\n", pll_reg, m, n, p); + + /* Calculate clock frequency = (2 * N * 54MHz) / (M * (2**P)) */ + fout = ((2 * n * fin) / (m * (0x01 << p))); + + pr_info("MIPS Clock Freq=%d kHz\n", fout); + + return fout; +} + +static cycle_t c0_hpt_read(struct clocksource *cs) +{ + return read_c0_count(); +} + +static struct clocksource clocksource_mips = { + .name = "powertv-counter", + .read = c0_hpt_read, + .mask = CLOCKSOURCE_MASK(32), + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + +static void __init powertv_c0_hpt_clocksource_init(void) +{ + unsigned int pll_freq = mips_get_pll_freq(); + + pr_info("CPU frequency %d.%02d MHz\n", pll_freq / 1000, + (pll_freq % 1000) * 100 / 1000); + + mips_hpt_frequency = pll_freq / 2 * 1000; + + clocksource_mips.rating = 200 + mips_hpt_frequency / 10000000; + + clocksource_set_clock(&clocksource_mips, mips_hpt_frequency); + + clocksource_register(&clocksource_mips); +} + +/** + * struct tim_c - free running counter + * @hi: High 16 bits of the counter + * @lo: Low 32 bits of the counter + * + * Lays out the structure of the free running counter in memory. This counter + * increments at a rate of 27 MHz/8 on all platforms. + */ +struct tim_c { + unsigned int hi; + unsigned int lo; +}; + +static struct tim_c *tim_c; + +static cycle_t tim_c_read(struct clocksource *cs) +{ + unsigned int hi; + unsigned int next_hi; + unsigned int lo; + + hi = readl(&tim_c->hi); + + for (;;) { + lo = readl(&tim_c->lo); + next_hi = readl(&tim_c->hi); + if (next_hi == hi) + break; + hi = next_hi; + } + +pr_crit("%s: read %llx\n", __func__, ((u64) hi << 32) | lo); + return ((u64) hi << 32) | lo; +} + +#define TIM_C_SIZE 48 /* # bits in the timer */ + +static struct clocksource clocksource_tim_c = { + .name = "powertv-tim_c", + .read = tim_c_read, + .mask = CLOCKSOURCE_MASK(TIM_C_SIZE), + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + +/** + * powertv_tim_c_clocksource_init - set up a clock source for the TIM_C clock + * + * The hard part here is coming up with a constant k and shift s such that + * the 48-bit TIM_C value multiplied by k doesn't overflow and that value, + * when shifted right by s, yields the corresponding number of nanoseconds. + * We know that TIM_C counts at 27 MHz/8, so each cycle corresponds to + * 1 / (27,000,000/8) seconds. Multiply that by a billion and you get the + * number of nanoseconds. Since the TIM_C value has 48 bits and the math is + * done in 64 bits, avoiding an overflow means that k must be less than + * 64 - 48 = 16 bits. + */ +static void __init powertv_tim_c_clocksource_init(void) +{ + int prescale; + unsigned long dividend; + unsigned long k; + int s; + const int max_k_bits = (64 - 48) - 1; + const unsigned long billion = 1000000000; + const unsigned long counts_per_second = 27000000 / 8; + + prescale = BITS_PER_LONG - ilog2(billion) - 1; + dividend = billion << prescale; + k = dividend / counts_per_second; + s = ilog2(k) - max_k_bits; + + if (s < 0) + s = prescale; + + else { + k >>= s; + s += prescale; + } + + clocksource_tim_c.mult = k; + clocksource_tim_c.shift = s; + clocksource_tim_c.rating = 200; + + clocksource_register(&clocksource_tim_c); + tim_c = (struct tim_c *) asic_reg_addr(tim_ch); +} + +/** + powertv_clocksource_init - initialize all clocksources + */ +void __init powertv_clocksource_init(void) +{ + powertv_c0_hpt_clocksource_init(); + powertv_tim_c_clocksource_init(); +} diff --git a/arch/mips/powertv/Kconfig b/arch/mips/powertv/Kconfig new file mode 100644 index 0000000..ff0e7e3 --- /dev/null +++ b/arch/mips/powertv/Kconfig @@ -0,0 +1,21 @@ +source "arch/mips/powertv/asic/Kconfig" + +config BOOTLOADER_DRIVER + bool "PowerTV Bootloader Driver Support" + default n + depends on POWERTV + help + Use this option if you want to load bootloader driver. + +config BOOTLOADER_FAMILY + string "POWERTV Bootloader Family string" + default "85" + depends on POWERTV && !BOOTLOADER_DRIVER + help + This value should be specified when the bootloader driver is disabled + and must be exactly two characters long. Families supported are: + R1 - RNG-100 R2 - RNG-200 + A1 - Class A B1 - Class B + E1 - Class E F1 - Class F + 44 - 45xx 46 - 46xx + 85 - 85xx 86 - 86xx diff --git a/arch/mips/powertv/Makefile b/arch/mips/powertv/Makefile new file mode 100644 index 0000000..2c51671 --- /dev/null +++ b/arch/mips/powertv/Makefile @@ -0,0 +1,28 @@ +# +# Carsten Langgaard, carstenl@mips.com +# Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. +# +# Carsten Langgaard, carstenl@mips.com +# Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. +# Portions copyright (C) 2009 Cisco Systems, Inc. +# +# This program is free software; you can distribute it and/or modify it +# under the terms of the GNU General Public License (Version 2) as +# published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. +# +# Makefile for the Cisco PowerTV-specific kernel interface routines +# under Linux. +# + +obj-y += cmdline.o init.o memory.o reset.o time.o powertv_setup.o asic/ pci/ + +EXTRA_CFLAGS += -Wall -Werror diff --git a/arch/mips/powertv/asic/Kconfig b/arch/mips/powertv/asic/Kconfig new file mode 100644 index 0000000..2016bfe --- /dev/null +++ b/arch/mips/powertv/asic/Kconfig @@ -0,0 +1,28 @@ +config MIN_RUNTIME_RESOURCES + bool "Support for minimum runtime resources" + default n + depends on POWERTV + help + Enables support for minimizing the number of (SA asic) runtime + resources that are preallocated by the kernel. + +config MIN_RUNTIME_DOCSIS + bool "Support for minimum DOCSIS resource" + default y + depends on MIN_RUNTIME_RESOURCES + help + Enables support for the preallocated DOCSIS resource. + +config MIN_RUNTIME_PMEM + bool "Support for minimum PMEM resource" + default y + depends on MIN_RUNTIME_RESOURCES + help + Enables support for the preallocated Memory resource. + +config MIN_RUNTIME_TFTP + bool "Support for minimum TFTP resource" + default y + depends on MIN_RUNTIME_RESOURCES + help + Enables support for the preallocated TFTP resource. diff --git a/arch/mips/powertv/asic/Makefile b/arch/mips/powertv/asic/Makefile new file mode 100644 index 0000000..bebfdcf --- /dev/null +++ b/arch/mips/powertv/asic/Makefile @@ -0,0 +1,23 @@ +# +# Copyright (C) 2009 Scientific-Atlanta, Inc. +# +# 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 +# + +obj-y += asic-calliope.o asic-cronus.o asic-zeus.o asic_devices.o asic_int.o \ + irq_asic.o prealloc-calliope.o prealloc-cronus.o \ + prealloc-cronuslite.o prealloc-zeus.o + +EXTRA_CFLAGS += -Wall -Werror diff --git a/arch/mips/powertv/asic/asic-calliope.c b/arch/mips/powertv/asic/asic-calliope.c new file mode 100644 index 0000000..03d3884 --- /dev/null +++ b/arch/mips/powertv/asic/asic-calliope.c @@ -0,0 +1,98 @@ +/* + * Locations of devices in the Calliope ASIC. + * + * Copyright (C) 2005-2009 Scientific-Atlanta, Inc. + * + * 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 + * + * Author: Ken Eppinett + * David Schleef + * + * Description: Defines the platform resources for the SA settop. + */ + +#include + +const struct register_map calliope_register_map = { + .eic_slow0_strt_add = 0x800000, + .eic_cfg_bits = 0x800038, + .eic_ready_status = 0x80004c, + + .chipver3 = 0xA00800, + .chipver2 = 0xA00804, + .chipver1 = 0xA00808, + .chipver0 = 0xA0080c, + + /* The registers of IRBlaster */ + .uart1_intstat = 0xA01800, + .uart1_inten = 0xA01804, + .uart1_config1 = 0xA01808, + .uart1_config2 = 0xA0180C, + .uart1_divisorhi = 0xA01810, + .uart1_divisorlo = 0xA01814, + .uart1_data = 0xA01818, + .uart1_status = 0xA0181C, + + .int_stat_3 = 0xA02800, + .int_stat_2 = 0xA02804, + .int_stat_1 = 0xA02808, + .int_stat_0 = 0xA0280c, + .int_config = 0xA02810, + .int_int_scan = 0xA02818, + .ien_int_3 = 0xA02830, + .ien_int_2 = 0xA02834, + .ien_int_1 = 0xA02838, + .ien_int_0 = 0xA0283c, + .int_level_3_3 = 0xA02880, + .int_level_3_2 = 0xA02884, + .int_level_3_1 = 0xA02888, + .int_level_3_0 = 0xA0288c, + .int_level_2_3 = 0xA02890, + .int_level_2_2 = 0xA02894, + .int_level_2_1 = 0xA02898, + .int_level_2_0 = 0xA0289c, + .int_level_1_3 = 0xA028a0, + .int_level_1_2 = 0xA028a4, + .int_level_1_1 = 0xA028a8, + .int_level_1_0 = 0xA028ac, + .int_level_0_3 = 0xA028b0, + .int_level_0_2 = 0xA028b4, + .int_level_0_1 = 0xA028b8, + .int_level_0_0 = 0xA028bc, + .int_docsis_en = 0xA028F4, + + .mips_pll_setup = 0x980000, + .usb_fs = 0x980030, /* -default 72800028- */ + .test_bus = 0x9800CC, + .crt_spare = 0x9800d4, + .usb2_ohci_int_mask = 0x9A000c, + .usb2_strap = 0x9A0014, + .ehci_hcapbase = 0x9BFE00, + .ohci_hc_revision = 0x9BFC00, + .bcm1_bs_lmi_steer = 0x9E0004, + .usb2_control = 0x9E0054, + .usb2_stbus_obc = 0x9BFF00, + .usb2_stbus_mess_size = 0x9BFF04, + .usb2_stbus_chunk_size = 0x9BFF08, + + .pcie_regs = 0x000000, /* -doesn't exist- */ + .tim_ch = 0xA02C10, + .tim_cl = 0xA02C14, + .gpio_dout = 0xA02c20, + .gpio_din = 0xA02c24, + .gpio_dir = 0xA02c2C, + .watchdog = 0xA02c30, + .front_panel = 0x000000, /* -not used- */ +}; diff --git a/arch/mips/powertv/asic/asic-cronus.c b/arch/mips/powertv/asic/asic-cronus.c new file mode 100644 index 0000000..5f4589c --- /dev/null +++ b/arch/mips/powertv/asic/asic-cronus.c @@ -0,0 +1,98 @@ +/* + * Locations of devices in the Cronus ASIC + * + * Copyright (C) 2005-2009 Scientific-Atlanta, Inc. + * + * 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 + * + * Author: Ken Eppinett + * David Schleef + * + * Description: Defines the platform resources for the SA settop. + */ + +#include + +const struct register_map cronus_register_map = { + .eic_slow0_strt_add = 0x000000, + .eic_cfg_bits = 0x000038, + .eic_ready_status = 0x00004C, + + .chipver3 = 0x2A0800, + .chipver2 = 0x2A0804, + .chipver1 = 0x2A0808, + .chipver0 = 0x2A080C, + + /* The registers of IRBlaster */ + .uart1_intstat = 0x2A1800, + .uart1_inten = 0x2A1804, + .uart1_config1 = 0x2A1808, + .uart1_config2 = 0x2A180C, + .uart1_divisorhi = 0x2A1810, + .uart1_divisorlo = 0x2A1814, + .uart1_data = 0x2A1818, + .uart1_status = 0x2A181C, + + .int_stat_3 = 0x2A2800, + .int_stat_2 = 0x2A2804, + .int_stat_1 = 0x2A2808, + .int_stat_0 = 0x2A280C, + .int_config = 0x2A2810, + .int_int_scan = 0x2A2818, + .ien_int_3 = 0x2A2830, + .ien_int_2 = 0x2A2834, + .ien_int_1 = 0x2A2838, + .ien_int_0 = 0x2A283C, + .int_level_3_3 = 0x2A2880, + .int_level_3_2 = 0x2A2884, + .int_level_3_1 = 0x2A2888, + .int_level_3_0 = 0x2A288C, + .int_level_2_3 = 0x2A2890, + .int_level_2_2 = 0x2A2894, + .int_level_2_1 = 0x2A2898, + .int_level_2_0 = 0x2A289C, + .int_level_1_3 = 0x2A28A0, + .int_level_1_2 = 0x2A28A4, + .int_level_1_1 = 0x2A28A8, + .int_level_1_0 = 0x2A28AC, + .int_level_0_3 = 0x2A28B0, + .int_level_0_2 = 0x2A28B4, + .int_level_0_1 = 0x2A28B8, + .int_level_0_0 = 0x2A28BC, + .int_docsis_en = 0x2A28F4, + + .mips_pll_setup = 0x1C0000, + .usb_fs = 0x1C0018, + .test_bus = 0x1C00CC, + .crt_spare = 0x1c00d4, + .usb2_ohci_int_mask = 0x20000C, + .usb2_strap = 0x200014, + .ehci_hcapbase = 0x21FE00, + .ohci_hc_revision = 0x1E0000, + .bcm1_bs_lmi_steer = 0x2E0008, + .usb2_control = 0x2E004C, + .usb2_stbus_obc = 0x21FF00, + .usb2_stbus_mess_size = 0x21FF04, + .usb2_stbus_chunk_size = 0x21FF08, + + .pcie_regs = 0x220000, + .tim_ch = 0x2A2C10, + .tim_cl = 0x2A2C14, + .gpio_dout = 0x2A2C20, + .gpio_din = 0x2A2C24, + .gpio_dir = 0x2A2C2C, + .watchdog = 0x2A2C30, + .front_panel = 0x2A3800, +}; diff --git a/arch/mips/powertv/asic/asic-zeus.c b/arch/mips/powertv/asic/asic-zeus.c new file mode 100644 index 0000000..1469daa --- /dev/null +++ b/arch/mips/powertv/asic/asic-zeus.c @@ -0,0 +1,98 @@ +/* + * Locations of devices in the Zeus ASIC + * + * Copyright (C) 2005-2009 Scientific-Atlanta, Inc. + * + * 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 + * + * Author: Ken Eppinett + * David Schleef + * + * Description: Defines the platform resources for the SA settop. + */ + +#include + +const struct register_map zeus_register_map = { + .eic_slow0_strt_add = 0x000000, + .eic_cfg_bits = 0x000038, + .eic_ready_status = 0x00004c, + + .chipver3 = 0x280800, + .chipver2 = 0x280804, + .chipver1 = 0x280808, + .chipver0 = 0x28080c, + + /* The registers of IRBlaster */ + .uart1_intstat = 0x281800, + .uart1_inten = 0x281804, + .uart1_config1 = 0x281808, + .uart1_config2 = 0x28180C, + .uart1_divisorhi = 0x281810, + .uart1_divisorlo = 0x281814, + .uart1_data = 0x281818, + .uart1_status = 0x28181C, + + .int_stat_3 = 0x282800, + .int_stat_2 = 0x282804, + .int_stat_1 = 0x282808, + .int_stat_0 = 0x28280c, + .int_config = 0x282810, + .int_int_scan = 0x282818, + .ien_int_3 = 0x282830, + .ien_int_2 = 0x282834, + .ien_int_1 = 0x282838, + .ien_int_0 = 0x28283c, + .int_level_3_3 = 0x282880, + .int_level_3_2 = 0x282884, + .int_level_3_1 = 0x282888, + .int_level_3_0 = 0x28288c, + .int_level_2_3 = 0x282890, + .int_level_2_2 = 0x282894, + .int_level_2_1 = 0x282898, + .int_level_2_0 = 0x28289c, + .int_level_1_3 = 0x2828a0, + .int_level_1_2 = 0x2828a4, + .int_level_1_1 = 0x2828a8, + .int_level_1_0 = 0x2828ac, + .int_level_0_3 = 0x2828b0, + .int_level_0_2 = 0x2828b4, + .int_level_0_1 = 0x2828b8, + .int_level_0_0 = 0x2828bc, + .int_docsis_en = 0x2828F4, + + .mips_pll_setup = 0x1a0000, + .usb_fs = 0x1a0018, + .test_bus = 0x1a0238, + .crt_spare = 0x1a0090, + .usb2_ohci_int_mask = 0x1e000c, + .usb2_strap = 0x1e0014, + .ehci_hcapbase = 0x1FFE00, + .ohci_hc_revision = 0x1FFC00, + .bcm1_bs_lmi_steer = 0x2C0008, + .usb2_control = 0x2c01a0, + .usb2_stbus_obc = 0x1FFF00, + .usb2_stbus_mess_size = 0x1FFF04, + .usb2_stbus_chunk_size = 0x1FFF08, + + .pcie_regs = 0x200000, + .tim_ch = 0x282C10, + .tim_cl = 0x282C14, + .gpio_dout = 0x282c20, + .gpio_din = 0x282c24, + .gpio_dir = 0x282c2C, + .watchdog = 0x282c30, + .front_panel = 0x283800, +}; diff --git a/arch/mips/powertv/asic/asic_devices.c b/arch/mips/powertv/asic/asic_devices.c new file mode 100644 index 0000000..bae8288 --- /dev/null +++ b/arch/mips/powertv/asic/asic_devices.c @@ -0,0 +1,787 @@ +/* + * ASIC Device List Intialization + * + * Description: Defines the platform resources for the SA settop. + * + * Copyright (C) 2005-2009 Scientific-Atlanta, Inc. + * + * 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 + * + * Author: Ken Eppinett + * David Schleef + * + * Description: Defines the platform resources for the SA settop. + * + * NOTE: The bootloader allocates persistent memory at an address which is + * 16 MiB below the end of the highest address in KSEG0. All fixed + * address memory reservations must avoid this region. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#ifdef CONFIG_BOOTLOADER_DRIVER +#include +#endif +#include + +#define BOOTLDRFAMILY(byte1, byte0) (((byte1) << 8) | (byte0)) + +/* + * Forward Prototypes + */ +static void pmem_setup_resource(void); + +/* + * Global Variables + */ +enum asic_type asic; + +unsigned int platform_features; +unsigned int platform_family; +const struct register_map *register_map; +EXPORT_SYMBOL(register_map); /* Exported for testing */ +unsigned long asic_phy_base; +unsigned long asic_base; +EXPORT_SYMBOL(asic_base); /* Exported for testing */ +struct resource *gp_resources; +static bool usb_configured; + +/* + * Don't recommend to use it directly, it is usually used by kernel internally. + * Portable code should be using interfaces such as ioremp, dma_map_single, etc. + */ +unsigned long phys_to_bus_offset; +EXPORT_SYMBOL(phys_to_bus_offset); + +/* + * + * IO Resource Definition + * + */ + +struct resource asic_resource = { + .name = "ASIC Resource", + .start = 0, + .end = ASIC_IO_SIZE, + .flags = IORESOURCE_MEM, +}; + +/* + * + * USB Host Resource Definition + * + */ + +static struct resource ehci_resources[] = { + { + .parent = &asic_resource, + .start = 0, + .end = 0xff, + .flags = IORESOURCE_MEM, + }, + { + .start = irq_usbehci, + .end = irq_usbehci, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 ehci_dmamask = DMA_BIT_MASK(32); + +static struct platform_device ehci_device = { + .name = "powertv-ehci", + .id = 0, + .num_resources = 2, + .resource = ehci_resources, + .dev = { + .dma_mask = &ehci_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + +static struct resource ohci_resources[] = { + { + .parent = &asic_resource, + .start = 0, + .end = 0xff, + .flags = IORESOURCE_MEM, + }, + { + .start = irq_usbohci, + .end = irq_usbohci, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 ohci_dmamask = DMA_BIT_MASK(32); + +static struct platform_device ohci_device = { + .name = "powertv-ohci", + .id = 0, + .num_resources = 2, + .resource = ohci_resources, + .dev = { + .dma_mask = &ohci_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + +static struct platform_device *platform_devices[] = { + &ehci_device, + &ohci_device, +}; + +/* + * + * Platform Configuration and Device Initialization + * + */ +static void __init fs_update(int pe, int md, int sdiv, int disable_div_by_3) +{ + int en_prg, byp, pwr, nsb, val; + int sout; + + sout = 1; + en_prg = 1; + byp = 0; + nsb = 1; + pwr = 1; + + val = ((sdiv << 29) | (md << 24) | (pe<<8) | (sout<<3) | (byp<<2) | + (nsb<<1) | (disable_div_by_3<<5)); + + asic_write(val, usb_fs); + asic_write(val | (en_prg<<4), usb_fs); + asic_write(val | (en_prg<<4) | pwr, usb_fs); +} + +/* + * Allow override of bootloader-specified model + */ +static char __initdata cmdline[COMMAND_LINE_SIZE]; + +#define FORCEFAMILY_PARAM "forcefamily" + +static __init int check_forcefamily(unsigned char forced_family[2]) +{ + const char *p; + + forced_family[0] = '\0'; + forced_family[1] = '\0'; + + /* Check the command line for a forcefamily directive */ + strncpy(cmdline, arcs_cmdline, COMMAND_LINE_SIZE - 1); + p = strstr(cmdline, FORCEFAMILY_PARAM); + if (p && (p != cmdline) && (*(p - 1) != ' ')) + p = strstr(p, " " FORCEFAMILY_PARAM "="); + + if (p) { + p += strlen(FORCEFAMILY_PARAM "="); + + if (*p == '\0' || *(p + 1) == '\0' || + (*(p + 2) != '\0' && *(p + 2) != ' ')) + pr_err(FORCEFAMILY_PARAM " must be exactly two " + "characters long, ignoring value\n"); + + else { + forced_family[0] = *p; + forced_family[1] = *(p + 1); + } + } + + return 0; +} + +/* + * platform_set_family - determine major platform family type. + * + * Returns family type; -1 if none + * Returns the family type; -1 if none + * + */ +static __init noinline void platform_set_family(void) +{ +#define BOOTLDRFAMILY(byte1, byte0) (((byte1) << 8) | (byte0)) + + unsigned char forced_family[2]; + unsigned short bootldr_family; + + check_forcefamily(forced_family); + + if (forced_family[0] != '\0' && forced_family[1] != '\0') + bootldr_family = BOOTLDRFAMILY(forced_family[0], + forced_family[1]); + else { + +#ifdef CONFIG_BOOTLOADER_DRIVER + bootldr_family = (unsigned short) kbldr_GetSWFamily(); +#else +#if defined(CONFIG_BOOTLOADER_FAMILY) + bootldr_family = (unsigned short) BOOTLDRFAMILY( + CONFIG_BOOTLOADER_FAMILY[0], + CONFIG_BOOTLOADER_FAMILY[1]); +#else +#error "Unknown Bootloader Family" +#endif +#endif + } + + pr_info("Bootloader Family = 0x%04X\n", bootldr_family); + + switch (bootldr_family) { + case BOOTLDRFAMILY('R', '1'): + platform_family = FAMILY_1500; + break; + case BOOTLDRFAMILY('4', '4'): + platform_family = FAMILY_4500; + break; + case BOOTLDRFAMILY('4', '6'): + platform_family = FAMILY_4600; + break; + case BOOTLDRFAMILY('A', '1'): + platform_family = FAMILY_4600VZA; + break; + case BOOTLDRFAMILY('8', '5'): + platform_family = FAMILY_8500; + break; + case BOOTLDRFAMILY('R', '2'): + platform_family = FAMILY_8500RNG; + break; + case BOOTLDRFAMILY('8', '6'): + platform_family = FAMILY_8600; + break; + case BOOTLDRFAMILY('B', '1'): + platform_family = FAMILY_8600VZB; + break; + case BOOTLDRFAMILY('E', '1'): + platform_family = FAMILY_1500VZE; + break; + case BOOTLDRFAMILY('F', '1'): + platform_family = FAMILY_1500VZF; + break; + default: + platform_family = -1; + } +} + +unsigned int platform_get_family(void) +{ + return platform_family; +} +EXPORT_SYMBOL(platform_get_family); + +/* + * \brief usb_eye_configure() for optimizing the USB eye on Calliope. + * + * \param unsigned int value saved to the register. + * + * \return none + * + */ +static void __init usb_eye_configure(unsigned int value) +{ + asic_write(asic_read(crt_spare) | value, crt_spare); +} + +/* + * platform_get_asic - determine the ASIC type. + * + * \param none + * + * \return ASIC type; ASIC_UNKNOWN if none + * + */ +enum asic_type platform_get_asic(void) +{ + return asic; +} +EXPORT_SYMBOL(platform_get_asic); + +/* + * platform_configure_usb - usb configuration based on platform type. + * @bcm1_usb2_ctl: value for the BCM1_USB2_CTL register, which is + * quirky + */ +static void __init platform_configure_usb(void) +{ + u32 bcm1_usb2_ctl; + + if (usb_configured) + return; + + switch (asic) { + case ASIC_ZEUS: + fs_update(0x0000, 0x11, 0x02, 0); + bcm1_usb2_ctl = 0x803; + break; + + case ASIC_CRONUS: + case ASIC_CRONUSLITE: + fs_update(0x0000, 0x11, 0x02, 0); + bcm1_usb2_ctl = 0x803; + break; + + case ASIC_CALLIOPE: + fs_update(0x0000, 0x11, 0x02, 1); + + switch (platform_family) { + case FAMILY_1500VZE: + break; + + case FAMILY_1500VZF: + usb_eye_configure(0x003c0000); + break; + + default: + usb_eye_configure(0x00300000); + break; + } + + bcm1_usb2_ctl = 0x803; + break; + + default: + pr_err("Unknown ASIC type: %d\n", asic); + break; + } + + /* turn on USB power */ + asic_write(0, usb2_strap); + /* Enable all OHCI interrupts */ + asic_write(bcm1_usb2_ctl, usb2_control); + /* USB2_STBUS_OBC store32/load32 */ + asic_write(3, usb2_stbus_obc); + /* USB2_STBUS_MESS_SIZE 2 packets */ + asic_write(1, usb2_stbus_mess_size); + /* USB2_STBUS_CHUNK_SIZE 2 packets */ + asic_write(1, usb2_stbus_chunk_size); + + usb_configured = true; +} + +/* + * Set up the USB EHCI interface + */ +void platform_configure_usb_ehci() +{ + platform_configure_usb(); +} + +/* + * Set up the USB OHCI interface + */ +void platform_configure_usb_ohci() +{ + platform_configure_usb(); +} + +/* + * Shut the USB EHCI interface down--currently a NOP + */ +void platform_unconfigure_usb_ehci() +{ +} + +/* + * Shut the USB OHCI interface down--currently a NOP + */ +void platform_unconfigure_usb_ohci() +{ +} + +/** + * configure_platform - configuration based on platform type. + */ +void __init configure_platform(void) +{ + platform_set_family(); + + switch (platform_family) { + case FAMILY_1500: + case FAMILY_1500VZE: + case FAMILY_1500VZF: + platform_features = FFS_CAPABLE; + asic = ASIC_CALLIOPE; + asic_phy_base = CALLIOPE_IO_BASE; + register_map = &calliope_register_map; + asic_base = (unsigned long)ioremap_nocache(asic_phy_base, + ASIC_IO_SIZE); + + if (platform_family == FAMILY_1500VZE) { + gp_resources = non_dvr_vze_calliope_resources; + pr_info("Platform: 1500/Vz Class E - " + "CALLIOPE, NON_DVR_CAPABLE\n"); + } else if (platform_family == FAMILY_1500VZF) { + gp_resources = non_dvr_vzf_calliope_resources; + pr_info("Platform: 1500/Vz Class F - " + "CALLIOPE, NON_DVR_CAPABLE\n"); + } else { + gp_resources = non_dvr_calliope_resources; + pr_info("Platform: 1500/RNG100 - CALLIOPE, " + "NON_DVR_CAPABLE\n"); + } + break; + + case FAMILY_4500: + platform_features = FFS_CAPABLE | PCIE_CAPABLE | + DISPLAY_CAPABLE; + asic = ASIC_ZEUS; + asic_phy_base = ZEUS_IO_BASE; + register_map = &zeus_register_map; + asic_base = (unsigned long)ioremap_nocache(asic_phy_base, + ASIC_IO_SIZE); + gp_resources = non_dvr_zeus_resources; + + pr_info("Platform: 4500 - ZEUS, NON_DVR_CAPABLE\n"); + break; + + case FAMILY_4600: + { + unsigned int chipversion = 0; + + /* The settop has PCIE but it isn't used, so don't advertise + * it*/ + platform_features = FFS_CAPABLE | DISPLAY_CAPABLE; + asic_phy_base = CRONUS_IO_BASE; /* same as Cronus */ + register_map = &cronus_register_map; /* same as Cronus */ + asic_base = (unsigned long)ioremap_nocache(asic_phy_base, + ASIC_IO_SIZE); + gp_resources = non_dvr_cronuslite_resources; + + /* ASIC version will determine if this is a real CronusLite or + * Castrati(Cronus) */ + chipversion = asic_read(chipver3) << 24; + chipversion |= asic_read(chipver2) << 16; + chipversion |= asic_read(chipver1) << 8; + chipversion |= asic_read(chipver0); + + if ((chipversion == CRONUS_10) || (chipversion == CRONUS_11)) + asic = ASIC_CRONUS; + else + asic = ASIC_CRONUSLITE; + + pr_info("Platform: 4600 - %s, NON_DVR_CAPABLE, " + "chipversion=0x%08X\n", + (asic == ASIC_CRONUS) ? "CRONUS" : "CRONUS LITE", + chipversion); + break; + } + case FAMILY_4600VZA: + platform_features = FFS_CAPABLE | DISPLAY_CAPABLE; + asic = ASIC_CRONUS; + asic_phy_base = CRONUS_IO_BASE; + register_map = &cronus_register_map; + asic_base = (unsigned long)ioremap_nocache(asic_phy_base, + ASIC_IO_SIZE); + gp_resources = non_dvr_cronus_resources; + + pr_info("Platform: Vz Class A - CRONUS, NON_DVR_CAPABLE\n"); + break; + + case FAMILY_8500: + case FAMILY_8500RNG: + platform_features = DVR_CAPABLE | PCIE_CAPABLE | + DISPLAY_CAPABLE; + asic = ASIC_ZEUS; + asic_phy_base = ZEUS_IO_BASE; + register_map = &zeus_register_map; + asic_base = (unsigned long)ioremap_nocache(asic_phy_base, + ASIC_IO_SIZE); + gp_resources = dvr_zeus_resources; + + pr_info("Platform: 8500/RNG200 - ZEUS, DVR_CAPABLE\n"); + break; + + case FAMILY_8600: + case FAMILY_8600VZB: + platform_features = DVR_CAPABLE | PCIE_CAPABLE | + DISPLAY_CAPABLE; + asic = ASIC_CRONUS; + asic_phy_base = CRONUS_IO_BASE; + register_map = &cronus_register_map; + asic_base = (unsigned long)ioremap_nocache(asic_phy_base, + ASIC_IO_SIZE); + gp_resources = dvr_cronus_resources; + + pr_info("Platform: 8600/Vz Class B - CRONUS, " + "DVR_CAPABLE\n"); + break; + + default: + pr_crit("Platform: UNKNOWN PLATFORM\n"); + break; + } + + switch (asic) { + case ASIC_ZEUS: + phys_to_bus_offset = 0x30000000; + break; + case ASIC_CALLIOPE: + phys_to_bus_offset = 0x10000000; + break; + case ASIC_CRONUSLITE: + /* Fall through */ + case ASIC_CRONUS: + /* + * TODO: We suppose 0x10000000 aliases into 0x20000000- + * 0x2XXXXXXX. If 0x10000000 aliases into 0x60000000- + * 0x6XXXXXXX, the offset should be 0x50000000, not 0x10000000. + */ + phys_to_bus_offset = 0x10000000; + break; + default: + phys_to_bus_offset = 0x00000000; + break; + } +} + +/** + * platform_devices_init - sets up USB device resourse. + */ +static int __init platform_devices_init(void) +{ + pr_notice("%s: ----- Initializing USB resources -----\n", __func__); + + asic_resource.start = asic_phy_base; + asic_resource.end += asic_resource.start; + + ehci_resources[0].start = asic_reg_phys_addr(ehci_hcapbase); + ehci_resources[0].end += ehci_resources[0].start; + + ohci_resources[0].start = asic_reg_phys_addr(ohci_hc_revision); + ohci_resources[0].end += ohci_resources[0].start; + + set_io_port_base(0); + + platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); + + return 0; +} + +arch_initcall(platform_devices_init); + +/* + * + * BOOTMEM ALLOCATION + * + */ +/* + * Allocates/reserves the Platform memory resources early in the boot process. + * This ignores any resources that are designated IORESOURCE_IO + */ +void __init platform_alloc_bootmem(void) +{ + int i; + int total = 0; + + /* Get persistent memory data from command line before allocating + * resources. This need to happen before normal command line parsing + * has been done */ + pmem_setup_resource(); + + /* Loop through looking for resources that want a particular address */ + for (i = 0; gp_resources[i].flags != 0; i++) { + int size = gp_resources[i].end - gp_resources[i].start + 1; + if ((gp_resources[i].start != 0) && + ((gp_resources[i].flags & IORESOURCE_MEM) != 0)) { + reserve_bootmem(bus_to_phys(gp_resources[i].start), + size, 0); + total += gp_resources[i].end - + gp_resources[i].start + 1; + pr_info("reserve resource %s at %08x (%u bytes)\n", + gp_resources[i].name, gp_resources[i].start, + gp_resources[i].end - + gp_resources[i].start + 1); + } + } + + /* Loop through assigning addresses for those that are left */ + for (i = 0; gp_resources[i].flags != 0; i++) { + int size = gp_resources[i].end - gp_resources[i].start + 1; + if ((gp_resources[i].start == 0) && + ((gp_resources[i].flags & IORESOURCE_MEM) != 0)) { + void *mem = alloc_bootmem_pages(size); + + if (mem == NULL) + pr_err("Unable to allocate bootmem pages " + "for %s\n", gp_resources[i].name); + + else { + gp_resources[i].start = + phys_to_bus(virt_to_phys(mem)); + gp_resources[i].end = + gp_resources[i].start + size - 1; + total += size; + pr_info("allocate resource %s at %08x " + "(%u bytes)\n", + gp_resources[i].name, + gp_resources[i].start, size); + } + } + } + + pr_info("Total Platform driver memory allocation: 0x%08x\n", total); + + /* indicate resources that are platform I/O related */ + for (i = 0; gp_resources[i].flags != 0; i++) { + if ((gp_resources[i].start != 0) && + ((gp_resources[i].flags & IORESOURCE_IO) != 0)) { + pr_info("reserved platform resource %s at %08x\n", + gp_resources[i].name, gp_resources[i].start); + } + } +} + +/* + * + * PERSISTENT MEMORY (PMEM) CONFIGURATION + * + */ +static unsigned long pmemaddr __initdata; + +static int __init early_param_pmemaddr(char *p) +{ + pmemaddr = (unsigned long)simple_strtoul(p, NULL, 0); + return 0; +} +early_param("pmemaddr", early_param_pmemaddr); + +static long pmemlen __initdata; + +static int __init early_param_pmemlen(char *p) +{ +/* TODO: we can use this code when and if the bootloader ever changes this */ +#if 0 + pmemlen = (unsigned long)simple_strtoul(p, NULL, 0); +#else + pmemlen = 0x20000; +#endif + return 0; +} +early_param("pmemlen", early_param_pmemlen); + +/* + * Set up persistent memory. If we were given values, we patch the array of + * resources. Otherwise, persistent memory may be allocated anywhere at all. + */ +static void __init pmem_setup_resource(void) +{ + struct resource *resource; + resource = asic_resource_get("DiagPersistentMemory"); + + if (resource && pmemaddr && pmemlen) { + /* The address provided by bootloader is in kseg0. Convert to + * a bus address. */ + resource->start = phys_to_bus(pmemaddr - 0x80000000); + resource->end = resource->start + pmemlen - 1; + + pr_info("persistent memory: start=0x%x end=0x%x\n", + resource->start, resource->end); + } +} + +/* + * + * RESOURCE ACCESS FUNCTIONS + * + */ + +/** + * asic_resource_get - retrieves parameters for a platform resource. + * @name: string to match resource + * + * Returns a pointer to a struct resource corresponding to the given name. + * + * CANNOT BE NAMED platform_resource_get, which would be the obvious choice, + * as this function name is already declared + */ +struct resource *asic_resource_get(const char *name) +{ + int i; + + for (i = 0; gp_resources[i].flags != 0; i++) { + if (strcmp(gp_resources[i].name, name) == 0) + return &gp_resources[i]; + } + + return NULL; +} +EXPORT_SYMBOL(asic_resource_get); + +/** + * platform_release_memory - release pre-allocated memory + * @ptr: pointer to memory to release + * @size: size of resource + * + * This must only be called for memory allocated or reserved via the boot + * memory allocator. + */ +void platform_release_memory(void *ptr, int size) +{ + unsigned long addr; + unsigned long end; + + addr = ((unsigned long)ptr + (PAGE_SIZE - 1)) & PAGE_MASK; + end = ((unsigned long)ptr + size) & PAGE_MASK; + + for (; addr < end; addr += PAGE_SIZE) { + ClearPageReserved(virt_to_page(__va(addr))); + init_page_count(virt_to_page(__va(addr))); + free_page((unsigned long)__va(addr)); + } +} +EXPORT_SYMBOL(platform_release_memory); + +/* + * + * FEATURE AVAILABILITY FUNCTIONS + * + */ +int platform_supports_dvr(void) +{ + return (platform_features & DVR_CAPABLE) != 0; +} + +int platform_supports_ffs(void) +{ + return (platform_features & FFS_CAPABLE) != 0; +} + +int platform_supports_pcie(void) +{ + return (platform_features & PCIE_CAPABLE) != 0; +} + +int platform_supports_display(void) +{ + return (platform_features & DISPLAY_CAPABLE) != 0; +} diff --git a/arch/mips/powertv/asic/asic_int.c b/arch/mips/powertv/asic/asic_int.c new file mode 100644 index 0000000..80b2eed --- /dev/null +++ b/arch/mips/powertv/asic/asic_int.c @@ -0,0 +1,125 @@ +/* + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2000, 2001, 2004 MIPS Technologies, Inc. + * Copyright (C) 2001 Ralf Baechle + * Portions copyright (C) 2009 Cisco Systems, Inc. + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Routines for generic manipulation of the interrupts found on the PowerTV + * platform. + * + * The interrupt controller is located in the South Bridge a PIIX4 device + * with two internal 82C95 interrupt controllers. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +static DEFINE_SPINLOCK(asic_irq_lock); + +static inline int get_int(void) +{ + unsigned long flags; + int irq; + + spin_lock_irqsave(&asic_irq_lock, flags); + + irq = (asic_read(int_int_scan) >> 4) - 1; + + if (irq == 0 || irq >= NR_IRQS) + irq = -1; + + spin_unlock_irqrestore(&asic_irq_lock, flags); + + return irq; +} + +static void asic_irqdispatch(void) +{ + int irq; + + irq = get_int(); + if (irq < 0) + return; /* interrupt has already been cleared */ + + do_IRQ(irq); +} + +static inline int clz(unsigned long x) +{ + __asm__( + " .set push \n" + " .set mips32 \n" + " clz %0, %1 \n" + " .set pop \n" + : "=r" (x) + : "r" (x)); + + return x; +} + +/* + * Version of ffs that only looks at bits 12..15. + */ +static inline unsigned int irq_ffs(unsigned int pending) +{ + return fls(pending) - 1 + CAUSEB_IP; +} + +/* + * TODO: check how it works under EIC mode. + */ +asmlinkage void plat_irq_dispatch(void) +{ + unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; + int irq; + + irq = irq_ffs(pending); + + if (irq == CAUSEF_IP3) + asic_irqdispatch(); + else if (irq >= 0) + do_IRQ(irq); + else + spurious_interrupt(); +} + +void __init arch_init_irq(void) +{ + int i; + + asic_irq_init(); + + /* + * Initialize interrupt exception vectors. + */ + if (cpu_has_veic || cpu_has_vint) { + int nvec = cpu_has_veic ? 64 : 8; + for (i = 0; i < nvec; i++) + set_vi_handler(i, asic_irqdispatch); + } +} diff --git a/arch/mips/powertv/asic/irq_asic.c b/arch/mips/powertv/asic/irq_asic.c new file mode 100644 index 0000000..b54d244 --- /dev/null +++ b/arch/mips/powertv/asic/irq_asic.c @@ -0,0 +1,116 @@ +/* + * Portions copyright (C) 2005-2009 Scientific Atlanta + * Portions copyright (C) 2009 Cisco Systems, Inc. + * + * Modified from arch/mips/kernel/irq-rm7000.c: + * Copyright (C) 2003 Ralf Baechle + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include + +#include +#include +#include + +#include + +static inline void unmask_asic_irq(unsigned int irq) +{ + unsigned long enable_bit; + + enable_bit = (1 << (irq & 0x1f)); + + switch (irq >> 5) { + case 0: + asic_write(asic_read(ien_int_0) | enable_bit, ien_int_0); + break; + case 1: + asic_write(asic_read(ien_int_1) | enable_bit, ien_int_1); + break; + case 2: + asic_write(asic_read(ien_int_2) | enable_bit, ien_int_2); + break; + case 3: + asic_write(asic_read(ien_int_3) | enable_bit, ien_int_3); + break; + default: + BUG(); + } +} + +static inline void mask_asic_irq(unsigned int irq) +{ + unsigned long disable_mask; + + disable_mask = ~(1 << (irq & 0x1f)); + + switch (irq >> 5) { + case 0: + asic_write(asic_read(ien_int_0) & disable_mask, ien_int_0); + break; + case 1: + asic_write(asic_read(ien_int_1) & disable_mask, ien_int_1); + break; + case 2: + asic_write(asic_read(ien_int_2) & disable_mask, ien_int_2); + break; + case 3: + asic_write(asic_read(ien_int_3) & disable_mask, ien_int_3); + break; + default: + BUG(); + } +} + +static struct irq_chip asic_irq_chip = { + .name = "ASIC Level", + .ack = mask_asic_irq, + .mask = mask_asic_irq, + .mask_ack = mask_asic_irq, + .unmask = unmask_asic_irq, + .eoi = unmask_asic_irq, +}; + +void __init asic_irq_init(void) +{ + int i; + + /* set priority to 0 */ + write_c0_status(read_c0_status() & ~(0x0000fc00)); + + asic_write(0, ien_int_0); + asic_write(0, ien_int_1); + asic_write(0, ien_int_2); + asic_write(0, ien_int_3); + + asic_write(0x0fffffff, int_level_3_3); + asic_write(0xffffffff, int_level_3_2); + asic_write(0xffffffff, int_level_3_1); + asic_write(0xffffffff, int_level_3_0); + asic_write(0xffffffff, int_level_2_3); + asic_write(0xffffffff, int_level_2_2); + asic_write(0xffffffff, int_level_2_1); + asic_write(0xffffffff, int_level_2_0); + asic_write(0xffffffff, int_level_1_3); + asic_write(0xffffffff, int_level_1_2); + asic_write(0xffffffff, int_level_1_1); + asic_write(0xffffffff, int_level_1_0); + asic_write(0xffffffff, int_level_0_3); + asic_write(0xffffffff, int_level_0_2); + asic_write(0xffffffff, int_level_0_1); + asic_write(0xffffffff, int_level_0_0); + + asic_write(0xf, int_int_scan); + + /* + * Initialize interrupt handlers. + */ + for (i = 0; i < NR_IRQS; i++) + set_irq_chip_and_handler(i, &asic_irq_chip, handle_level_irq); +} diff --git a/arch/mips/powertv/asic/prealloc-calliope.c b/arch/mips/powertv/asic/prealloc-calliope.c new file mode 100644 index 0000000..cd5b76a --- /dev/null +++ b/arch/mips/powertv/asic/prealloc-calliope.c @@ -0,0 +1,620 @@ +/* + * Memory pre-allocations for Calliope boxes. + * + * Copyright (C) 2005-2009 Scientific-Atlanta, Inc. + * + * 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 + * + * Author: Ken Eppinett + * David Schleef + */ + +#include +#include + +/* + * NON_DVR_CAPABLE CALLIOPE RESOURCES + */ +struct resource non_dvr_calliope_resources[] __initdata = +{ + /* + * VIDEO / LX1 + */ + { + .name = "ST231aImage", /* Delta-Mu 1 image and ram */ + .start = 0x24000000, + .end = 0x24200000 - 1, /*2MiB */ + .flags = IORESOURCE_MEM, + }, + { + .name = "ST231aMonitor", /*8KiB block ST231a monitor */ + .start = 0x24200000, + .end = 0x24202000 - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "MediaMemory1", + .start = 0x24202000, + .end = 0x26700000 - 1, /*~36.9MiB (32MiB - (2MiB + 8KiB)) */ + .flags = IORESOURCE_MEM, + }, + /* + * Sysaudio Driver + */ + { + .name = "DSP_Image_Buff", + .start = 0x00000000, + .end = 0x000FFFFF, + .flags = IORESOURCE_MEM, + }, + { + .name = "ADSC_CPU_PCM_Buff", + .start = 0x00000000, + .end = 0x00009FFF, + .flags = IORESOURCE_MEM, + }, + { + .name = "ADSC_AUX_Buff", + .start = 0x00000000, + .end = 0x00003FFF, + .flags = IORESOURCE_MEM, + }, + { + .name = "ADSC_Main_Buff", + .start = 0x00000000, + .end = 0x00003FFF, + .flags = IORESOURCE_MEM, + }, + /* + * STAVEM driver/STAPI + */ + { + .name = "AVMEMPartition0", + .start = 0x00000000, + .end = 0x00600000 - 1, /* 6 MB total */ + .flags = IORESOURCE_MEM, + }, + /* + * DOCSIS Subsystem + */ + { + .name = "Docsis", + .start = 0x22000000, + .end = 0x22700000 - 1, + .flags = IORESOURCE_MEM, + }, + /* + * GHW HAL Driver + */ + { + .name = "GraphicsHeap", + .start = 0x22700000, + .end = 0x23500000 - 1, /* 14 MB total */ + .flags = IORESOURCE_MEM, + }, + /* + * multi com buffer area + */ + { + .name = "MulticomSHM", + .start = 0x23700000, + .end = 0x23720000 - 1, + .flags = IORESOURCE_MEM, + }, + /* + * DMA Ring buffer (don't need recording buffers) + */ + { + .name = "BMM_Buffer", + .start = 0x00000000, + .end = 0x000AA000 - 1, + .flags = IORESOURCE_MEM, + }, + /* + * Display bins buffer for unit0 + */ + { + .name = "DisplayBins0", + .start = 0x00000000, + .end = 0x00000FFF, /* 4 KB total */ + .flags = IORESOURCE_MEM, + }, + /* + * + * AVFS: player HAL memory + * + * + */ + { + .name = "AvfsDmaMem", + .start = 0x00000000, + .end = 0x002c4c00 - 1, /* 945K * 3 for playback */ + .flags = IORESOURCE_MEM, + }, + /* + * PMEM + */ + { + .name = "DiagPersistentMemory", + .start = 0x00000000, + .end = 0x10000 - 1, + .flags = IORESOURCE_MEM, + }, + /* + * Smartcard + */ + { + .name = "SmartCardInfo", + .start = 0x00000000, + .end = 0x2800 - 1, + .flags = IORESOURCE_MEM, + }, + /* + * NAND Flash + */ + { + .name = "NandFlash", + .start = NAND_FLASH_BASE, + .end = NAND_FLASH_BASE + 0x400 - 1, + .flags = IORESOURCE_IO, + }, + /* + * Synopsys GMAC Memory Region + */ + { + .name = "GMAC", + .start = 0x00000000, + .end = 0x00010000 - 1, + .flags = IORESOURCE_MEM, + }, + /* + * Add other resources here + * + */ + { }, +}; + +struct resource non_dvr_vz_calliope_resources[] __initdata = +{ + /* + * VIDEO / LX1 + */ + { + .name = "ST231aImage", /* Delta-Mu 1 image and ram */ + .start = 0x24000000, + .end = 0x24200000 - 1, /*2 Meg */ + .flags = IORESOURCE_MEM, + }, + { + .name = "ST231aMonitor", /* 8k block ST231a monitor */ + .start = 0x24200000, + .end = 0x24202000 - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "MediaMemory1", + .start = 0x22202000, + .end = 0x22C20B85 - 1, /* 10.12 Meg */ + .flags = IORESOURCE_MEM, + }, + /* + * Sysaudio Driver + */ + { + .name = "DSP_Image_Buff", + .start = 0x00000000, + .end = 0x000FFFFF, + .flags = IORESOURCE_MEM, + }, + { + .name = "ADSC_CPU_PCM_Buff", + .start = 0x00000000, + .end = 0x00009FFF, + .flags = IORESOURCE_MEM, + }, + { + .name = "ADSC_AUX_Buff", + .start = 0x00000000, + .end = 0x00003FFF, + .flags = IORESOURCE_MEM, + }, + { + .name = "ADSC_Main_Buff", + .start = 0x00000000, + .end = 0x00003FFF, + .flags = IORESOURCE_MEM, + }, + /* + * STAVEM driver/STAPI + */ + { + .name = "AVMEMPartition0", + .start = 0x20300000, + .end = 0x20620000-1, /*3.125 MB total */ + .flags = IORESOURCE_MEM, + }, + /* + * GHW HAL Driver + */ + { + .name = "GraphicsHeap", + .start = 0x20100000, + .end = 0x20300000 - 1, + .flags = IORESOURCE_MEM, + }, + /* + * multi com buffer area + */ + { + .name = "MulticomSHM", + .start = 0x23900000, + .end = 0x23920000 - 1, + .flags = IORESOURCE_MEM, + }, + /* + * DMA Ring buffer + */ + { + .name = "BMM_Buffer", + .start = 0x00000000, + .end = 0x000AA000 - 1, + .flags = IORESOURCE_MEM, + }, + /* + * Display bins buffer for unit0 + */ + { + .name = "DisplayBins0", + .start = 0x00000000, + .end = 0x00000FFF, + .flags = IORESOURCE_MEM, + }, + /* + * PMEM + */ + { + .name = "DiagPersistentMemory", + .start = 0x00000000, + .end = 0x10000 - 1, + .flags = IORESOURCE_MEM, + }, + /* + * Smartcard + */ + { + .name = "SmartCardInfo", + .start = 0x00000000, + .end = 0x2800 - 1, + .flags = IORESOURCE_MEM, + }, + /* + * NAND Flash + */ + { + .name = "NandFlash", + .start = NAND_FLASH_BASE, + .end = NAND_FLASH_BASE+0x400 - 1, + .flags = IORESOURCE_IO, + }, + /* + * Synopsys GMAC Memory Region + */ + { + .name = "GMAC", + .start = 0x00000000, + .end = 0x00010000 - 1, + .flags = IORESOURCE_MEM, + }, + /* + * Add other resources here + */ + { }, +}; + +struct resource non_dvr_vze_calliope_resources[] __initdata = +{ + /* + * VIDEO / LX1 + */ + { + .name = "ST231aImage", /* Delta-Mu 1 image and ram */ + .start = 0x22000000, + .end = 0x22200000 - 1, /*2 Meg */ + .flags = IORESOURCE_MEM, + }, + { + .name = "ST231aMonitor", /* 8k block ST231a monitor */ + .start = 0x22200000, + .end = 0x22202000 - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "MediaMemory1", + .start = 0x22202000, + .end = 0x22C20B85 - 1, /* 10.12 Meg */ + .flags = IORESOURCE_MEM, + }, + /* + * Sysaudio Driver + */ + { + .name = "DSP_Image_Buff", + .start = 0x00000000, + .end = 0x000FFFFF, + .flags = IORESOURCE_MEM, + }, + { + .name = "ADSC_CPU_PCM_Buff", + .start = 0x00000000, + .end = 0x00009FFF, + .flags = IORESOURCE_MEM, + }, + { + .name = "ADSC_AUX_Buff", + .start = 0x00000000, + .end = 0x00003FFF, + .flags = IORESOURCE_MEM, + }, + { + .name = "ADSC_Main_Buff", + .start = 0x00000000, + .end = 0x00003FFF, + .flags = IORESOURCE_MEM, + }, + /* + * STAVEM driver/STAPI + */ + { + .name = "AVMEMPartition0", + .start = 0x20396000, + .end = 0x206B6000 - 1, /* 3.125 MB total */ + .flags = IORESOURCE_MEM, + }, + /* + * GHW HAL Driver + */ + { + .name = "GraphicsHeap", + .start = 0x20100000, + .end = 0x20396000 - 1, + .flags = IORESOURCE_MEM, + }, + /* + * multi com buffer area + */ + { + .name = "MulticomSHM", + .start = 0x206B6000, + .end = 0x206D6000 - 1, + .flags = IORESOURCE_MEM, + }, + /* + * DMA Ring buffer + */ + { + .name = "BMM_Buffer", + .start = 0x00000000, + .end = 0x000AA000 - 1, + .flags = IORESOURCE_MEM, + }, + /* + * Display bins buffer for unit0 + */ + { + .name = "DisplayBins0", + .start = 0x00000000, + .end = 0x00000FFF, + .flags = IORESOURCE_MEM, + }, + /* + * PMEM + */ + { + .name = "DiagPersistentMemory", + .start = 0x00000000, + .end = 0x10000 - 1, + .flags = IORESOURCE_MEM, + }, + /* + * Smartcard + */ + { + .name = "SmartCardInfo", + .start = 0x00000000, + .end = 0x2800 - 1, + .flags = IORESOURCE_MEM, + }, + /* + * NAND Flash + */ + { + .name = "NandFlash", + .start = NAND_FLASH_BASE, + .end = NAND_FLASH_BASE+0x400 - 1, + .flags = IORESOURCE_MEM, + }, + /* + * Synopsys GMAC Memory Region + */ + { + .name = "GMAC", + .start = 0x00000000, + .end = 0x00010000 - 1, + .flags = IORESOURCE_MEM, + }, + /* + * Add other resources here + */ + { }, +}; + +struct resource non_dvr_vzf_calliope_resources[] __initdata = +{ + /* + * VIDEO / LX1 + */ + { + .name = "ST231aImage", /*Delta-Mu 1 image and ram */ + .start = 0x24000000, + .end = 0x24200000 - 1, /*2MiB */ + .flags = IORESOURCE_MEM, + }, + { + .name = "ST231aMonitor", /*8KiB block ST231a monitor */ + .start = 0x24200000, + .end = 0x24202000 - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "MediaMemory1", + .start = 0x24202000, + /* ~19.4 (21.5MiB - (2MiB + 8KiB)) */ + .end = 0x25580000 - 1, + .flags = IORESOURCE_MEM, + }, + /* + * Sysaudio Driver + */ + { + .name = "DSP_Image_Buff", + .start = 0x00000000, + .end = 0x000FFFFF, + .flags = IORESOURCE_MEM, + }, + { + .name = "ADSC_CPU_PCM_Buff", + .start = 0x00000000, + .end = 0x00009FFF, + .flags = IORESOURCE_MEM, + }, + { + .name = "ADSC_AUX_Buff", + .start = 0x00000000, + .end = 0x00003FFF, + .flags = IORESOURCE_MEM, + }, + { + .name = "ADSC_Main_Buff", + .start = 0x00000000, + .end = 0x00003FFF, + .flags = IORESOURCE_MEM, + }, + /* + * STAVEM driver/STAPI + */ + { + .name = "AVMEMPartition0", + .start = 0x00000000, + .end = 0x00480000 - 1, /* 4.5 MB total */ + .flags = IORESOURCE_MEM, + }, + /* + * GHW HAL Driver + */ + { + .name = "GraphicsHeap", + .start = 0x22700000, + .end = 0x23500000 - 1, /* 14 MB total */ + .flags = IORESOURCE_MEM, + }, + /* + * multi com buffer area + */ + { + .name = "MulticomSHM", + .start = 0x23700000, + .end = 0x23720000 - 1, + .flags = IORESOURCE_MEM, + }, + /* + * DMA Ring buffer (don't need recording buffers) + */ + { + .name = "BMM_Buffer", + .start = 0x00000000, + .end = 0x000AA000 - 1, + .flags = IORESOURCE_MEM, + }, + /* + * Display bins buffer for unit0 + */ + { + .name = "DisplayBins0", + .start = 0x00000000, + .end = 0x00000FFF, /* 4 KB total */ + .flags = IORESOURCE_MEM, + }, + /* + * Display bins buffer for unit1 + */ + { + .name = "DisplayBins1", + .start = 0x00000000, + .end = 0x00000FFF, /* 4 KB total */ + .flags = IORESOURCE_MEM, + }, + /* + * + * AVFS: player HAL memory + * + * + */ + { + .name = "AvfsDmaMem", + .start = 0x00000000, + .end = 0x002c4c00 - 1, /* 945K * 3 for playback */ + .flags = IORESOURCE_MEM, + }, + /* + * PMEM + */ + { + .name = "DiagPersistentMemory", + .start = 0x00000000, + .end = 0x10000 - 1, + .flags = IORESOURCE_MEM, + }, + /* + * Smartcard + */ + { + .name = "SmartCardInfo", + .start = 0x00000000, + .end = 0x2800 - 1, + .flags = IORESOURCE_MEM, + }, + /* + * NAND Flash + */ + { + .name = "NandFlash", + .start = NAND_FLASH_BASE, + .end = NAND_FLASH_BASE + 0x400 - 1, + .flags = IORESOURCE_MEM, + }, + /* + * Synopsys GMAC Memory Region + */ + { + .name = "GMAC", + .start = 0x00000000, + .end = 0x00010000 - 1, + .flags = IORESOURCE_MEM, + }, + /* + * Add other resources here + */ + { }, +}; diff --git a/arch/mips/powertv/asic/prealloc-cronus.c b/arch/mips/powertv/asic/prealloc-cronus.c new file mode 100644 index 0000000..45a5c3e --- /dev/null +++ b/arch/mips/powertv/asic/prealloc-cronus.c @@ -0,0 +1,608 @@ +/* + * Memory pre-allocations for Cronus boxes. + * + * Copyright (C) 2005-2009 Scientific-Atlanta, Inc. + * + * 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 + * + * Author: Ken Eppinett + * David Schleef + */ + +#include +#include + +/* + * DVR_CAPABLE CRONUS RESOURCES + */ +struct resource dvr_cronus_resources[] __initdata = +{ + /* + * + * VIDEO1 / LX1 + * + */ + { + .name = "ST231aImage", /* Delta-Mu 1 image and ram */ + .start = 0x24000000, + .end = 0x241FFFFF, /* 2MiB */ + .flags = IORESOURCE_MEM, + }, + { + .name = "ST231aMonitor", /* 8KiB block ST231a monitor */ + .start = 0x24200000, + .end = 0x24201FFF, + .flags = IORESOURCE_MEM, + }, + { + .name = "MediaMemory1", + .start = 0x24202000, + .end = 0x25FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */ + .flags = IORESOURCE_MEM, + }, + /* + * + * VIDEO2 / LX2 + * + */ + { + .name = "ST231bImage", /* Delta-Mu 2 image and ram */ + .start = 0x60000000, + .end = 0x601FFFFF, /* 2MiB */ + .flags = IORESOURCE_IO, + }, + { + .name = "ST231bMonitor", /* 8KiB block ST231b monitor */ + .start = 0x60200000, + .end = 0x60201FFF, + .flags = IORESOURCE_IO, + }, + { + .name = "MediaMemory2", + .start = 0x60202000, + .end = 0x61FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */ + .flags = IORESOURCE_IO, + }, + /* + * + * Sysaudio Driver + * + * This driver requires: + * + * Arbitrary Based Buffers: + * DSP_Image_Buff - DSP code and data images (1MB) + * ADSC_CPU_PCM_Buff - ADSC CPU PCM buffer (40KB) + * ADSC_AUX_Buff - ADSC AUX buffer (16KB) + * ADSC_Main_Buff - ADSC Main buffer (16KB) + * + */ + { + .name = "DSP_Image_Buff", + .start = 0x00000000, + .end = 0x000FFFFF, + .flags = IORESOURCE_MEM, + }, + { + .name = "ADSC_CPU_PCM_Buff", + .start = 0x00000000, + .end = 0x00009FFF, + .flags = IORESOURCE_MEM, + }, + { + .name = "ADSC_AUX_Buff", + .start = 0x00000000, + .end = 0x00003FFF, + .flags = IORESOURCE_MEM, + }, + { + .name = "ADSC_Main_Buff", + .start = 0x00000000, + .end = 0x00003FFF, + .flags = IORESOURCE_MEM, + }, + /* + * + * STAVEM driver/STAPI + * + * This driver requires: + * + * Arbitrary Based Buffers: + * This memory area is used for allocating buffers for Video decoding + * purposes. Allocation/De-allocation within this buffer is managed + * by the STAVMEM driver of the STAPI. They could be Decimated + * Picture Buffers, Intermediate Buffers, as deemed necessary for + * video decoding purposes, for any video decoders on Zeus. + * + */ + { + .name = "AVMEMPartition0", + .start = 0x63580000, + .end = 0x64180000 - 1, /* 12 MB total */ + .flags = IORESOURCE_IO, + }, + /* + * + * DOCSIS Subsystem + * + * This driver requires: + * + * Arbitrary Based Buffers: + * Docsis - + * + */ + { + .name = "Docsis", + .start = 0x62000000, + .end = 0x62700000 - 1, /* 7 MB total */ + .flags = IORESOURCE_IO, + }, + /* + * + * GHW HAL Driver + * + * This driver requires: + * + * Arbitrary Based Buffers: + * GraphicsHeap - PowerTV Graphics Heap + * + */ + { + .name = "GraphicsHeap", + .start = 0x62700000, + .end = 0x63500000 - 1, /* 14 MB total */ + .flags = IORESOURCE_IO, + }, + /* + * + * multi com buffer area + * + * This driver requires: + * + * Arbitrary Based Buffers: + * Docsis - + * + */ + { + .name = "MulticomSHM", + .start = 0x26000000, + .end = 0x26020000 - 1, + .flags = IORESOURCE_MEM, + }, + /* + * + * DMA Ring buffer + * + * This driver requires: + * + * Arbitrary Based Buffers: + * Docsis - + * + */ + { + .name = "BMM_Buffer", + .start = 0x00000000, + .end = 0x00280000 - 1, + .flags = IORESOURCE_MEM, + }, + /* + * + * Display bins buffer for unit0 + * + * This driver requires: + * + * Arbitrary Based Buffers: + * Display Bins for unit0 + * + */ + { + .name = "DisplayBins0", + .start = 0x00000000, + .end = 0x00000FFF, /* 4 KB total */ + .flags = IORESOURCE_MEM, + }, + /* + * + * Display bins buffer + * + * This driver requires: + * + * Arbitrary Based Buffers: + * Display Bins for unit1 + * + */ + { + .name = "DisplayBins1", + .start = 0x64AD4000, + .end = 0x64AD5000 - 1, /* 4 KB total */ + .flags = IORESOURCE_IO, + }, + /* + * + * ITFS + * + * This driver requires: + * + * Arbitrary Based Buffers: + * Docsis - + * + */ + { + .name = "ITFS", + .start = 0x64180000, + /* 815,104 bytes each for 2 ITFS partitions. */ + .end = 0x6430DFFF, + .flags = IORESOURCE_IO, + }, + /* + * + * AVFS + * + * This driver requires: + * + * Arbitrary Based Buffers: + * Docsis - + * + */ + { + .name = "AvfsDmaMem", + .start = 0x6430E000, + /* (945K * 8) = (128K *3) 5 playbacks / 3 server */ + .end = 0x64AD0000 - 1, + .flags = IORESOURCE_IO, + }, + { + .name = "AvfsFileSys", + .start = 0x64AD0000, + .end = 0x64AD1000 - 1, /* 4K */ + .flags = IORESOURCE_IO, + }, + /* + * + * PMEM + * + * This driver requires: + * + * Arbitrary Based Buffers: + * Persistent memory for diagnostics. + * + */ + { + .name = "DiagPersistentMemory", + .start = 0x00000000, + .end = 0x10000 - 1, + .flags = IORESOURCE_MEM, + }, + /* + * + * Smartcard + * + * This driver requires: + * + * Arbitrary Based Buffers: + * Read and write buffers for Internal/External cards + * + */ + { + .name = "SmartCardInfo", + .start = 0x64AD1000, + .end = 0x64AD3800 - 1, + .flags = IORESOURCE_IO, + }, + /* + * + * KAVNET + * NP Reset Vector - must be of the form xxCxxxxx + * NP Image - must be video bank 1 + * NP IPC - must be video bank 2 + */ + { + .name = "NP_Reset_Vector", + .start = 0x27c00000, + .end = 0x27c01000 - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "NP_Image", + .start = 0x27020000, + .end = 0x27060000 - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "NP_IPC", + .start = 0x63500000, + .end = 0x63580000 - 1, + .flags = IORESOURCE_IO, + }, + /* + * Add other resources here + */ + { }, +}; + +/* + * NON_DVR_CAPABLE CRONUS RESOURCES + */ +struct resource non_dvr_cronus_resources[] __initdata = +{ + /* + * + * VIDEO1 / LX1 + * + */ + { + .name = "ST231aImage", /* Delta-Mu 1 image and ram */ + .start = 0x24000000, + .end = 0x241FFFFF, /* 2MiB */ + .flags = IORESOURCE_MEM, + }, + { + .name = "ST231aMonitor", /* 8KiB block ST231a monitor */ + .start = 0x24200000, + .end = 0x24201FFF, + .flags = IORESOURCE_MEM, + }, + { + .name = "MediaMemory1", + .start = 0x24202000, + .end = 0x25FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */ + .flags = IORESOURCE_MEM, + }, + /* + * + * VIDEO2 / LX2 + * + */ + { + .name = "ST231bImage", /* Delta-Mu 2 image and ram */ + .start = 0x60000000, + .end = 0x601FFFFF, /* 2MiB */ + .flags = IORESOURCE_IO, + }, + { + .name = "ST231bMonitor", /* 8KiB block ST231b monitor */ + .start = 0x60200000, + .end = 0x60201FFF, + .flags = IORESOURCE_IO, + }, + { + .name = "MediaMemory2", + .start = 0x60202000, + .end = 0x61FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */ + .flags = IORESOURCE_IO, + }, + /* + * + * Sysaudio Driver + * + * This driver requires: + * + * Arbitrary Based Buffers: + * DSP_Image_Buff - DSP code and data images (1MB) + * ADSC_CPU_PCM_Buff - ADSC CPU PCM buffer (40KB) + * ADSC_AUX_Buff - ADSC AUX buffer (16KB) + * ADSC_Main_Buff - ADSC Main buffer (16KB) + * + */ + { + .name = "DSP_Image_Buff", + .start = 0x00000000, + .end = 0x000FFFFF, + .flags = IORESOURCE_MEM, + }, + { + .name = "ADSC_CPU_PCM_Buff", + .start = 0x00000000, + .end = 0x00009FFF, + .flags = IORESOURCE_MEM, + }, + { + .name = "ADSC_AUX_Buff", + .start = 0x00000000, + .end = 0x00003FFF, + .flags = IORESOURCE_MEM, + }, + { + .name = "ADSC_Main_Buff", + .start = 0x00000000, + .end = 0x00003FFF, + .flags = IORESOURCE_MEM, + }, + /* + * + * STAVEM driver/STAPI + * + * This driver requires: + * + * Arbitrary Based Buffers: + * This memory area is used for allocating buffers for Video decoding + * purposes. Allocation/De-allocation within this buffer is managed + * by the STAVMEM driver of the STAPI. They could be Decimated + * Picture Buffers, Intermediate Buffers, as deemed necessary for + * video decoding purposes, for any video decoders on Zeus. + * + */ + { + .name = "AVMEMPartition0", + .start = 0x63580000, + .end = 0x64180000 - 1, /* 12 MB total */ + .flags = IORESOURCE_IO, + }, + /* + * + * DOCSIS Subsystem + * + * This driver requires: + * + * Arbitrary Based Buffers: + * Docsis - + * + */ + { + .name = "Docsis", + .start = 0x62000000, + .end = 0x62700000 - 1, /* 7 MB total */ + .flags = IORESOURCE_IO, + }, + /* + * + * GHW HAL Driver + * + * This driver requires: + * + * Arbitrary Based Buffers: + * GraphicsHeap - PowerTV Graphics Heap + * + */ + { + .name = "GraphicsHeap", + .start = 0x62700000, + .end = 0x63500000 - 1, /* 14 MB total */ + .flags = IORESOURCE_IO, + }, + /* + * + * multi com buffer area + * + * This driver requires: + * + * Arbitrary Based Buffers: + * Docsis - + * + */ + { + .name = "MulticomSHM", + .start = 0x26000000, + .end = 0x26020000 - 1, + .flags = IORESOURCE_MEM, + }, + /* + * + * DMA Ring buffer + * + * This driver requires: + * + * Arbitrary Based Buffers: + * Docsis - + * + */ + { + .name = "BMM_Buffer", + .start = 0x00000000, + .end = 0x000AA000 - 1, + .flags = IORESOURCE_MEM, + }, + /* + * + * Display bins buffer for unit0 + * + * This driver requires: + * + * Arbitrary Based Buffers: + * Display Bins for unit0 + * + */ + { + .name = "DisplayBins0", + .start = 0x00000000, + .end = 0x00000FFF, /* 4 KB total */ + .flags = IORESOURCE_MEM, + }, + /* + * + * Display bins buffer + * + * This driver requires: + * + * Arbitrary Based Buffers: + * Display Bins for unit1 + * + */ + { + .name = "DisplayBins1", + .start = 0x64AD4000, + .end = 0x64AD5000 - 1, /* 4 KB total */ + .flags = IORESOURCE_IO, + }, + /* + * + * AVFS: player HAL memory + * + * + */ + { + .name = "AvfsDmaMem", + .start = 0x6430E000, + .end = 0x645D2C00 - 1, /* 945K * 3 for playback */ + .flags = IORESOURCE_IO, + }, + /* + * + * PMEM + * + * This driver requires: + * + * Arbitrary Based Buffers: + * Persistent memory for diagnostics. + * + */ + { + .name = "DiagPersistentMemory", + .start = 0x00000000, + .end = 0x10000 - 1, + .flags = IORESOURCE_MEM, + }, + /* + * + * Smartcard + * + * This driver requires: + * + * Arbitrary Based Buffers: + * Read and write buffers for Internal/External cards + * + */ + { + .name = "SmartCardInfo", + .start = 0x64AD1000, + .end = 0x64AD3800 - 1, + .flags = IORESOURCE_IO, + }, + /* + * + * KAVNET + * NP Reset Vector - must be of the form xxCxxxxx + * NP Image - must be video bank 1 + * NP IPC - must be video bank 2 + */ + { + .name = "NP_Reset_Vector", + .start = 0x27c00000, + .end = 0x27c01000 - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "NP_Image", + .start = 0x27020000, + .end = 0x27060000 - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "NP_IPC", + .start = 0x63500000, + .end = 0x63580000 - 1, + .flags = IORESOURCE_IO, + }, + { }, +}; diff --git a/arch/mips/powertv/asic/prealloc-cronuslite.c b/arch/mips/powertv/asic/prealloc-cronuslite.c new file mode 100644 index 0000000..23a9056 --- /dev/null +++ b/arch/mips/powertv/asic/prealloc-cronuslite.c @@ -0,0 +1,290 @@ +/* + * Memory pre-allocations for Cronus Lite boxes. + * + * Copyright (C) 2005-2009 Scientific-Atlanta, Inc. + * + * 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 + * + * Author: Ken Eppinett + * David Schleef + */ + +#include +#include + +/* + * NON_DVR_CAPABLE CRONUSLITE RESOURCES + */ +struct resource non_dvr_cronuslite_resources[] __initdata = +{ + /* + * + * VIDEO2 / LX2 + * + */ + { + .name = "ST231aImage", /* Delta-Mu 2 image and ram */ + .start = 0x60000000, + .end = 0x601FFFFF, /* 2MiB */ + .flags = IORESOURCE_IO, + }, + { + .name = "ST231aMonitor", /* 8KiB block ST231b monitor */ + .start = 0x60200000, + .end = 0x60201FFF, + .flags = IORESOURCE_IO, + }, + { + .name = "MediaMemory1", + .start = 0x60202000, + .end = 0x61FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */ + .flags = IORESOURCE_IO, + }, + /* + * + * Sysaudio Driver + * + * This driver requires: + * + * Arbitrary Based Buffers: + * DSP_Image_Buff - DSP code and data images (1MB) + * ADSC_CPU_PCM_Buff - ADSC CPU PCM buffer (40KB) + * ADSC_AUX_Buff - ADSC AUX buffer (16KB) + * ADSC_Main_Buff - ADSC Main buffer (16KB) + * + */ + { + .name = "DSP_Image_Buff", + .start = 0x00000000, + .end = 0x000FFFFF, + .flags = IORESOURCE_MEM, + }, + { + .name = "ADSC_CPU_PCM_Buff", + .start = 0x00000000, + .end = 0x00009FFF, + .flags = IORESOURCE_MEM, + }, + { + .name = "ADSC_AUX_Buff", + .start = 0x00000000, + .end = 0x00003FFF, + .flags = IORESOURCE_MEM, + }, + { + .name = "ADSC_Main_Buff", + .start = 0x00000000, + .end = 0x00003FFF, + .flags = IORESOURCE_MEM, + }, + /* + * + * STAVEM driver/STAPI + * + * This driver requires: + * + * Arbitrary Based Buffers: + * This memory area is used for allocating buffers for Video decoding + * purposes. Allocation/De-allocation within this buffer is managed + * by the STAVMEM driver of the STAPI. They could be Decimated + * Picture Buffers, Intermediate Buffers, as deemed necessary for + * video decoding purposes, for any video decoders on Zeus. + * + */ + { + .name = "AVMEMPartition0", + .start = 0x63580000, + .end = 0x63B80000 - 1, /* 6 MB total */ + .flags = IORESOURCE_IO, + }, + /* + * + * DOCSIS Subsystem + * + * This driver requires: + * + * Arbitrary Based Buffers: + * Docsis - + * + */ + { + .name = "Docsis", + .start = 0x62000000, + .end = 0x62700000 - 1, /* 7 MB total */ + .flags = IORESOURCE_IO, + }, + /* + * + * GHW HAL Driver + * + * This driver requires: + * + * Arbitrary Based Buffers: + * GraphicsHeap - PowerTV Graphics Heap + * + */ + { + .name = "GraphicsHeap", + .start = 0x62700000, + .end = 0x63500000 - 1, /* 14 MB total */ + .flags = IORESOURCE_IO, + }, + /* + * + * multi com buffer area + * + * This driver requires: + * + * Arbitrary Based Buffers: + * Docsis - + * + */ + { + .name = "MulticomSHM", + .start = 0x26000000, + .end = 0x26020000 - 1, + .flags = IORESOURCE_MEM, + }, + /* + * + * DMA Ring buffer + * + * This driver requires: + * + * Arbitrary Based Buffers: + * Docsis - + * + */ + { + .name = "BMM_Buffer", + .start = 0x00000000, + .end = 0x000AA000 - 1, + .flags = IORESOURCE_MEM, + }, + /* + * + * Display bins buffer for unit0 + * + * This driver requires: + * + * Arbitrary Based Buffers: + * Display Bins for unit0 + * + */ + { + .name = "DisplayBins0", + .start = 0x00000000, + .end = 0x00000FFF, /* 4 KB total */ + .flags = IORESOURCE_MEM, + }, + /* + * + * Display bins buffer + * + * This driver requires: + * + * Arbitrary Based Buffers: + * Display Bins for unit1 + * + */ + { + .name = "DisplayBins1", + .start = 0x63B83000, + .end = 0x63B84000 - 1, /* 4 KB total */ + .flags = IORESOURCE_IO, + }, + /* + * + * AVFS: player HAL memory + * + * + */ + { + .name = "AvfsDmaMem", + .start = 0x63B84000, + .end = 0x63E48C00 - 1, /* 945K * 3 for playback */ + .flags = IORESOURCE_IO, + }, + /* + * + * PMEM + * + * This driver requires: + * + * Arbitrary Based Buffers: + * Persistent memory for diagnostics. + * + */ + { + .name = "DiagPersistentMemory", + .start = 0x00000000, + .end = 0x10000 - 1, + .flags = IORESOURCE_MEM, + }, + /* + * + * Smartcard + * + * This driver requires: + * + * Arbitrary Based Buffers: + * Read and write buffers for Internal/External cards + * + */ + { + .name = "SmartCardInfo", + .start = 0x63B80000, + .end = 0x63B82800 - 1, + .flags = IORESOURCE_IO, + }, + /* + * + * KAVNET + * NP Reset Vector - must be of the form xxCxxxxx + * NP Image - must be video bank 1 + * NP IPC - must be video bank 2 + */ + { + .name = "NP_Reset_Vector", + .start = 0x27c00000, + .end = 0x27c01000 - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "NP_Image", + .start = 0x27020000, + .end = 0x27060000 - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "NP_IPC", + .start = 0x63500000, + .end = 0x63580000 - 1, + .flags = IORESOURCE_IO, + }, + /* + * NAND Flash + */ + { + .name = "NandFlash", + .start = NAND_FLASH_BASE, + .end = NAND_FLASH_BASE + 0x400 - 1, + .flags = IORESOURCE_IO, + }, + /* + * Add other resources here + */ + { }, +}; diff --git a/arch/mips/powertv/asic/prealloc-zeus.c b/arch/mips/powertv/asic/prealloc-zeus.c new file mode 100644 index 0000000..018d451 --- /dev/null +++ b/arch/mips/powertv/asic/prealloc-zeus.c @@ -0,0 +1,459 @@ +/* + * Memory pre-allocations for Zeus boxes. + * + * Copyright (C) 2005-2009 Scientific-Atlanta, Inc. + * + * 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 + * + * Author: Ken Eppinett + * David Schleef + */ + +#include +#include + +/* + * DVR_CAPABLE RESOURCES + */ +struct resource dvr_zeus_resources[] __initdata = +{ + /* + * + * VIDEO1 / LX1 + * + */ + { + .name = "ST231aImage", /* Delta-Mu 1 image and ram */ + .start = 0x20000000, + .end = 0x201FFFFF, /* 2MiB */ + .flags = IORESOURCE_IO, + }, + { + .name = "ST231aMonitor", /* 8KiB block ST231a monitor */ + .start = 0x20200000, + .end = 0x20201FFF, + .flags = IORESOURCE_IO, + }, + { + .name = "MediaMemory1", + .start = 0x20202000, + .end = 0x21FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */ + .flags = IORESOURCE_IO, + }, + /* + * + * VIDEO2 / LX2 + * + */ + { + .name = "ST231bImage", /* Delta-Mu 2 image and ram */ + .start = 0x30000000, + .end = 0x301FFFFF, /* 2MiB */ + .flags = IORESOURCE_IO, + }, + { + .name = "ST231bMonitor", /* 8KiB block ST231b monitor */ + .start = 0x30200000, + .end = 0x30201FFF, + .flags = IORESOURCE_IO, + }, + { + .name = "MediaMemory2", + .start = 0x30202000, + .end = 0x31FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */ + .flags = IORESOURCE_IO, + }, + /* + * + * Sysaudio Driver + * + * This driver requires: + * + * Arbitrary Based Buffers: + * DSP_Image_Buff - DSP code and data images (1MB) + * ADSC_CPU_PCM_Buff - ADSC CPU PCM buffer (40KB) + * ADSC_AUX_Buff - ADSC AUX buffer (16KB) + * ADSC_Main_Buff - ADSC Main buffer (16KB) + * + */ + { + .name = "DSP_Image_Buff", + .start = 0x00000000, + .end = 0x000FFFFF, + .flags = IORESOURCE_MEM, + }, + { + .name = "ADSC_CPU_PCM_Buff", + .start = 0x00000000, + .end = 0x00009FFF, + .flags = IORESOURCE_MEM, + }, + { + .name = "ADSC_AUX_Buff", + .start = 0x00000000, + .end = 0x00003FFF, + .flags = IORESOURCE_MEM, + }, + { + .name = "ADSC_Main_Buff", + .start = 0x00000000, + .end = 0x00003FFF, + .flags = IORESOURCE_MEM, + }, + /* + * + * STAVEM driver/STAPI + * + * This driver requires: + * + * Arbitrary Based Buffers: + * This memory area is used for allocating buffers for Video decoding + * purposes. Allocation/De-allocation within this buffer is managed + * by the STAVMEM driver of the STAPI. They could be Decimated + * Picture Buffers, Intermediate Buffers, as deemed necessary for + * video decoding purposes, for any video decoders on Zeus. + * + */ + { + .name = "AVMEMPartition0", + .start = 0x00000000, + .end = 0x00c00000 - 1, /* 12 MB total */ + .flags = IORESOURCE_MEM, + }, + /* + * + * DOCSIS Subsystem + * + * This driver requires: + * + * Arbitrary Based Buffers: + * Docsis - + * + */ + { + .name = "Docsis", + .start = 0x40100000, + .end = 0x407fffff, + .flags = IORESOURCE_MEM, + }, + /* + * + * GHW HAL Driver + * + * This driver requires: + * + * Arbitrary Based Buffers: + * GraphicsHeap - PowerTV Graphics Heap + * + */ + { + .name = "GraphicsHeap", + .start = 0x46900000, + .end = 0x47700000 - 1, /* 14 MB total */ + .flags = IORESOURCE_MEM, + }, + /* + * + * multi com buffer area + * + * This driver requires: + * + * Arbitrary Based Buffers: + * Docsis - + * + */ + { + .name = "MulticomSHM", + .start = 0x47900000, + .end = 0x47920000 - 1, + .flags = IORESOURCE_MEM, + }, + /* + * + * DMA Ring buffer + * + * This driver requires: + * + * Arbitrary Based Buffers: + * Docsis - + * + */ + { + .name = "BMM_Buffer", + .start = 0x00000000, + .end = 0x00280000 - 1, + .flags = IORESOURCE_MEM, + }, + /* + * + * Display bins buffer for unit0 + * + * This driver requires: + * + * Arbitrary Based Buffers: + * Display Bins for unit0 + * + */ + { + .name = "DisplayBins0", + .start = 0x00000000, + .end = 0x00000FFF, /* 4 KB total */ + .flags = IORESOURCE_MEM, + }, + /* + * + * Display bins buffer + * + * This driver requires: + * + * Arbitrary Based Buffers: + * Display Bins for unit1 + * + */ + { + .name = "DisplayBins1", + .start = 0x00000000, + .end = 0x00000FFF, /* 4 KB total */ + .flags = IORESOURCE_MEM, + }, + /* + * + * ITFS + * + * This driver requires: + * + * Arbitrary Based Buffers: + * Docsis - + * + */ + { + .name = "ITFS", + .start = 0x00000000, + /* 815,104 bytes each for 2 ITFS partitions. */ + .end = 0x0018DFFF, + .flags = IORESOURCE_MEM, + }, + /* + * + * AVFS + * + * This driver requires: + * + * Arbitrary Based Buffers: + * Docsis - + * + */ + { + .name = "AvfsDmaMem", + .start = 0x00000000, + /* (945K * 8) = (128K * 3) 5 playbacks / 3 server */ + .end = 0x007c2000 - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "AvfsFileSys", + .start = 0x00000000, + .end = 0x00001000 - 1, /* 4K */ + .flags = IORESOURCE_MEM, + }, + /* + * + * PMEM + * + * This driver requires: + * + * Arbitrary Based Buffers: + * Persistent memory for diagnostics. + * + */ + { + .name = "DiagPersistentMemory", + .start = 0x00000000, + .end = 0x10000 - 1, + .flags = IORESOURCE_MEM, + }, + /* + * + * Smartcard + * + * This driver requires: + * + * Arbitrary Based Buffers: + * Read and write buffers for Internal/External cards + * + */ + { + .name = "SmartCardInfo", + .start = 0x00000000, + .end = 0x2800 - 1, + .flags = IORESOURCE_MEM, + }, + /* + * Add other resources here + */ + { }, +}; + +/* + * NON_DVR_CAPABLE ZEUS RESOURCES + */ +struct resource non_dvr_zeus_resources[] __initdata = +{ + /* + * VIDEO1 / LX1 + */ + { + .name = "ST231aImage", /* Delta-Mu 1 image and ram */ + .start = 0x20000000, + .end = 0x201FFFFF, /* 2MiB */ + .flags = IORESOURCE_IO, + }, + { + .name = "ST231aMonitor", /* 8KiB block ST231a monitor */ + .start = 0x20200000, + .end = 0x20201FFF, + .flags = IORESOURCE_IO, + }, + { + .name = "MediaMemory1", + .start = 0x20202000, + .end = 0x21FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */ + .flags = IORESOURCE_IO, + }, + /* + * Sysaudio Driver + */ + { + .name = "DSP_Image_Buff", + .start = 0x00000000, + .end = 0x000FFFFF, + .flags = IORESOURCE_MEM, + }, + { + .name = "ADSC_CPU_PCM_Buff", + .start = 0x00000000, + .end = 0x00009FFF, + .flags = IORESOURCE_MEM, + }, + { + .name = "ADSC_AUX_Buff", + .start = 0x00000000, + .end = 0x00003FFF, + .flags = IORESOURCE_MEM, + }, + { + .name = "ADSC_Main_Buff", + .start = 0x00000000, + .end = 0x00003FFF, + .flags = IORESOURCE_MEM, + }, + /* + * STAVEM driver/STAPI + */ + { + .name = "AVMEMPartition0", + .start = 0x00000000, + .end = 0x00600000 - 1, /* 6 MB total */ + .flags = IORESOURCE_MEM, + }, + /* + * DOCSIS Subsystem + */ + { + .name = "Docsis", + .start = 0x40100000, + .end = 0x407fffff, + .flags = IORESOURCE_MEM, + }, + /* + * GHW HAL Driver + */ + { + .name = "GraphicsHeap", + .start = 0x46900000, + .end = 0x47700000 - 1, /* 14 MB total */ + .flags = IORESOURCE_MEM, + }, + /* + * multi com buffer area + */ + { + .name = "MulticomSHM", + .start = 0x47900000, + .end = 0x47920000 - 1, + .flags = IORESOURCE_MEM, + }, + /* + * DMA Ring buffer + */ + { + .name = "BMM_Buffer", + .start = 0x00000000, + .end = 0x00280000 - 1, + .flags = IORESOURCE_MEM, + }, + /* + * Display bins buffer for unit0 + */ + { + .name = "DisplayBins0", + .start = 0x00000000, + .end = 0x00000FFF, /* 4 KB total */ + .flags = IORESOURCE_MEM, + }, + /* + * + * AVFS: player HAL memory + * + * + */ + { + .name = "AvfsDmaMem", + .start = 0x00000000, + .end = 0x002c4c00 - 1, /* 945K * 3 for playback */ + .flags = IORESOURCE_MEM, + }, + /* + * PMEM + */ + { + .name = "DiagPersistentMemory", + .start = 0x00000000, + .end = 0x10000 - 1, + .flags = IORESOURCE_MEM, + }, + /* + * Smartcard + */ + { + .name = "SmartCardInfo", + .start = 0x00000000, + .end = 0x2800 - 1, + .flags = IORESOURCE_MEM, + }, + /* + * NAND Flash + */ + { + .name = "NandFlash", + .start = NAND_FLASH_BASE, + .end = NAND_FLASH_BASE + 0x400 - 1, + .flags = IORESOURCE_IO, + }, + /* + * Add other resources here + */ + { }, +}; diff --git a/arch/mips/powertv/cmdline.c b/arch/mips/powertv/cmdline.c new file mode 100644 index 0000000..98d73cb --- /dev/null +++ b/arch/mips/powertv/cmdline.c @@ -0,0 +1,52 @@ +/* + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * Portions copyright (C) 2009 Cisco Systems, Inc. + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Kernel command line creation using the prom monitor (YAMON) argc/argv. + */ +#include +#include + +#include + +#include "init.h" + +/* + * YAMON (32-bit PROM) pass arguments and environment as 32-bit pointer. + * This macro take care of sign extension. + */ +#define prom_argv(index) ((char *)(long)_prom_argv[(index)]) + +char * __init prom_getcmdline(void) +{ + return &(arcs_cmdline[0]); +} + +void __init prom_init_cmdline(void) +{ + int len; + + if (prom_argc != 1) + return; + + len = strlen(arcs_cmdline); + + arcs_cmdline[len] = ' '; + + strlcpy(arcs_cmdline + len + 1, (char *)_prom_argv, + COMMAND_LINE_SIZE - len - 1); +} diff --git a/arch/mips/powertv/init.c b/arch/mips/powertv/init.c new file mode 100644 index 0000000..5f4e4c3 --- /dev/null +++ b/arch/mips/powertv/init.c @@ -0,0 +1,128 @@ +/* + * Copyright (C) 1999, 2000, 2004, 2005 MIPS Technologies, Inc. + * All rights reserved. + * Authors: Carsten Langgaard + * Maciej W. Rozycki + * Portions copyright (C) 2009 Cisco Systems, Inc. + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * PROM library initialisation code. + */ +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "init.h" + +int prom_argc; +int *_prom_argv, *_prom_envp; +unsigned long _prom_memsize; + +/* + * YAMON (32-bit PROM) pass arguments and environment as 32-bit pointer. + * This macro take care of sign extension, if running in 64-bit mode. + */ +#define prom_envp(index) ((char *)(long)_prom_envp[(index)]) + +char *prom_getenv(char *envname) +{ + char *result = NULL; + + if (_prom_envp != NULL) { + /* + * Return a pointer to the given environment variable. + * In 64-bit mode: we're using 64-bit pointers, but all pointers + * in the PROM structures are only 32-bit, so we need some + * workarounds, if we are running in 64-bit mode. + */ + int i, index = 0; + + i = strlen(envname); + + while (prom_envp(index)) { + if (strncmp(envname, prom_envp(index), i) == 0) { + result = prom_envp(index + 1); + break; + } + index += 2; + } + } + + return result; +} + +/* TODO: Verify on linux-mips mailing list that the following two */ +/* functions are correct */ +/* TODO: Copy NMI and EJTAG exception vectors to memory from the */ +/* BootROM exception vectors. Flush their cache entries. test it. */ + +static void __init mips_nmi_setup(void) +{ + void *base; +#if defined(CONFIG_CPU_MIPS32_R1) + base = cpu_has_veic ? + (void *)(CAC_BASE + 0xa80) : + (void *)(CAC_BASE + 0x380); +#elif defined(CONFIG_CPU_MIPS32_R2) + base = (void *)0xbfc00000; +#else +#error NMI exception handler address not defined +#endif +} + +static void __init mips_ejtag_setup(void) +{ + void *base; + +#if defined(CONFIG_CPU_MIPS32_R1) + base = cpu_has_veic ? + (void *)(CAC_BASE + 0xa00) : + (void *)(CAC_BASE + 0x300); +#elif defined(CONFIG_CPU_MIPS32_R2) + base = (void *)0xbfc00480; +#else +#error EJTAG exception handler address not defined +#endif +} + +void __init prom_init(void) +{ + prom_argc = fw_arg0; + _prom_argv = (int *) fw_arg1; + _prom_envp = (int *) fw_arg2; + _prom_memsize = (unsigned long) fw_arg3; + + board_nmi_handler_setup = mips_nmi_setup; + board_ejtag_handler_setup = mips_ejtag_setup; + + pr_info("\nLINUX started...\n"); + prom_init_cmdline(); + configure_platform(); + prom_meminit(); + +#ifndef CONFIG_BOOTLOADER_DRIVER + pr_info("\nBootloader driver isn't loaded...\n"); +#endif +} diff --git a/arch/mips/powertv/init.h b/arch/mips/powertv/init.h new file mode 100644 index 0000000..7af6bf2 --- /dev/null +++ b/arch/mips/powertv/init.h @@ -0,0 +1,28 @@ +/* + * Definitions from powertv init.c file + * + * Copyright (C) 2009 Cisco Systems, Inc. + * + * 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 + * + * Author: David VomLehn + */ + +#ifndef _POWERTV_INIT_H +#define _POWERTV_INIT_H +extern int prom_argc; +extern int *_prom_argv; +extern unsigned long _prom_memsize; +#endif diff --git a/arch/mips/powertv/memory.c b/arch/mips/powertv/memory.c new file mode 100644 index 0000000..28d0660 --- /dev/null +++ b/arch/mips/powertv/memory.c @@ -0,0 +1,186 @@ +/* + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * Portions copyright (C) 2009 Cisco Systems, Inc. + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Apparently originally from arch/mips/malta-memory.c. Modified to work + * with the PowerTV bootloader. + */ +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "init.h" + +/* Memory constants */ +#define KIBIBYTE(n) ((n) * 1024) /* Number of kibibytes */ +#define MEBIBYTE(n) ((n) * KIBIBYTE(1024)) /* Number of mebibytes */ +#define DEFAULT_MEMSIZE MEBIBYTE(256) /* If no memsize provided */ +#define LOW_MEM_MAX MEBIBYTE(252) /* Max usable low mem */ +#define RES_BOOTLDR_MEMSIZE MEBIBYTE(1) /* Memory reserved for bldr */ +#define BOOT_MEM_SIZE KIBIBYTE(256) /* Memory reserved for bldr */ +#define PHYS_MEM_START 0x10000000 /* Start of physical memory */ + +unsigned long ptv_memsize; + +char __initdata cmdline[COMMAND_LINE_SIZE]; + +void __init prom_meminit(void) +{ + char *memsize_str; + unsigned long memsize = 0; + unsigned int physend; + char *ptr; + int low_mem; + int high_mem; + + /* Check the command line first for a memsize directive */ + strcpy(cmdline, arcs_cmdline); + ptr = strstr(cmdline, "memsize="); + if (ptr && (ptr != cmdline) && (*(ptr - 1) != ' ')) + ptr = strstr(ptr, " memsize="); + + if (ptr) { + memsize = memparse(ptr + 8, &ptr); + } else { + /* otherwise look in the environment */ + memsize_str = prom_getenv("memsize"); + + if (memsize_str != NULL) { + pr_info("prom memsize = %s\n", memsize_str); + memsize = simple_strtol(memsize_str, NULL, 0); + } + + if (memsize == 0) { + if (_prom_memsize != 0) { + memsize = _prom_memsize; + pr_info("_prom_memsize = 0x%lx\n", memsize); + /* add in memory that the bootloader doesn't + * report */ + memsize += BOOT_MEM_SIZE; + } else { + memsize = DEFAULT_MEMSIZE; + pr_info("Memsize not passed by bootloader, " + "defaulting to 0x%lx\n", memsize); + } + } + } + + /* Store memsize for diagnostic purposes */ + ptv_memsize = memsize; + + physend = PFN_ALIGN(&_end) - 0x80000000; + if (memsize > LOW_MEM_MAX) { + low_mem = LOW_MEM_MAX; + high_mem = memsize - low_mem; + } else { + low_mem = memsize; + high_mem = 0; + } + +/* + * TODO: We will use the hard code for memory configuration until + * the bootloader releases their device tree to us. + */ + /* + * Add the memory reserved for use by the bootloader to the + * memory map. + */ + add_memory_region(PHYS_MEM_START, RES_BOOTLDR_MEMSIZE, + BOOT_MEM_RESERVED); +#ifdef CONFIG_HIGHMEM_256_128 + /* + * Add memory in low for general use by the kernel and its friends + * (like drivers, applications, etc). + */ + add_memory_region(PHYS_MEM_START + RES_BOOTLDR_MEMSIZE, + LOW_MEM_MAX - RES_BOOTLDR_MEMSIZE, BOOT_MEM_RAM); + /* + * Add the memory reserved for reset vector. + */ + add_memory_region(0x1fc00000, MEBIBYTE(4), BOOT_MEM_RESERVED); + /* + * Add the memory reserved. + */ + add_memory_region(0x20000000, MEBIBYTE(1024 + 75), BOOT_MEM_RESERVED); + /* + * Add memory in high for general use by the kernel and its friends + * (like drivers, applications, etc). + * + * 75MB is reserved for devices which are using the memory in high. + */ + add_memory_region(0x60000000 + MEBIBYTE(75), MEBIBYTE(128 - 75), + BOOT_MEM_RAM); +#elif defined CONFIG_HIGHMEM_128_128 + /* + * Add memory in low for general use by the kernel and its friends + * (like drivers, applications, etc). + */ + add_memory_region(PHYS_MEM_START + RES_BOOTLDR_MEMSIZE, + MEBIBYTE(128) - RES_BOOTLDR_MEMSIZE, BOOT_MEM_RAM); + /* + * Add the memory reserved. + */ + add_memory_region(PHYS_MEM_START + MEBIBYTE(128), + MEBIBYTE(128 + 1024 + 75), BOOT_MEM_RESERVED); + /* + * Add memory in high for general use by the kernel and its friends + * (like drivers, applications, etc). + * + * 75MB is reserved for devices which are using the memory in high. + */ + add_memory_region(0x60000000 + MEBIBYTE(75), MEBIBYTE(128 - 75), + BOOT_MEM_RAM); +#else + /* Add low memory regions for either: + * - no-highmemory configuration case -OR- + * - highmemory "HIGHMEM_LOWBANK_ONLY" case + */ + /* + * Add memory for general use by the kernel and its friends + * (like drivers, applications, etc). + */ + add_memory_region(PHYS_MEM_START + RES_BOOTLDR_MEMSIZE, + low_mem - RES_BOOTLDR_MEMSIZE, BOOT_MEM_RAM); + /* + * Add the memory reserved for reset vector. + */ + add_memory_region(0x1fc00000, MEBIBYTE(4), BOOT_MEM_RESERVED); +#endif +} + +void __init prom_free_prom_memory(void) +{ + unsigned long addr; + int i; + + for (i = 0; i < boot_mem_map.nr_map; i++) { + if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA) + continue; + + addr = boot_mem_map.map[i].addr; + free_init_pages("prom memory", + addr, addr + boot_mem_map.map[i].size); + } +} diff --git a/arch/mips/powertv/pci/Makefile b/arch/mips/powertv/pci/Makefile new file mode 100644 index 0000000..f5c6246 --- /dev/null +++ b/arch/mips/powertv/pci/Makefile @@ -0,0 +1,21 @@ +# +# Copyright (C) 2009 Scientific-Atlanta, Inc. +# +# 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 +# + +obj-$(CONFIG_PCI) += fixup-powertv.o + +EXTRA_CFLAGS += -Wall -Werror diff --git a/arch/mips/powertv/pci/fixup-powertv.c b/arch/mips/powertv/pci/fixup-powertv.c new file mode 100644 index 0000000..726bc2e --- /dev/null +++ b/arch/mips/powertv/pci/fixup-powertv.c @@ -0,0 +1,36 @@ +#include +#include +#include +#include "powertv-pci.h" + +int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +{ + return asic_pcie_map_irq(dev, slot, pin); +} + +/* Do platform specific device initialization at pci_enable_device() time */ +int pcibios_plat_dev_init(struct pci_dev *dev) +{ + return 0; +} + +/* + * asic_pcie_map_irq + * + * Parameters: + * *dev - pointer to a pci_dev structure (not used) + * slot - slot number (not used) + * pin - pin number (not used) + * + * Return Value: + * Returns: IRQ number (always the PCI Express IRQ number) + * + * Description: + * asic_pcie_map_irq will return the IRQ number of the PCI Express interrupt. + * + */ +int asic_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +{ + return irq_pciexp; +} +EXPORT_SYMBOL(asic_pcie_map_irq); diff --git a/arch/mips/powertv/pci/powertv-pci.h b/arch/mips/powertv/pci/powertv-pci.h new file mode 100644 index 0000000..1b5886b --- /dev/null +++ b/arch/mips/powertv/pci/powertv-pci.h @@ -0,0 +1,31 @@ +/* + * powertv-pci.c + * + * Copyright (C) 2009 Cisco Systems, Inc. + * + * 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 + */ +/* + * Local definitions for the powertv PCI code + */ + +#ifndef _POWERTV_PCI_POWERTV_PCI_H_ +#define _POWERTV_PCI_POWERTV_PCI_H_ +extern int asic_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin); +extern int asic_pcie_init(void); +extern int asic_pcie_init(void); + +extern int log_level; +#endif diff --git a/arch/mips/powertv/powertv-clock.h b/arch/mips/powertv/powertv-clock.h new file mode 100644 index 0000000..d94c543 --- /dev/null +++ b/arch/mips/powertv/powertv-clock.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2009 Cisco Systems, Inc. + * + * 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 + * + * Author: David VomLehn + */ + +#ifndef _POWERTV_POWERTV_CLOCK_H +#define _POWERTV_POWERTV_CLOCK_H +extern int powertv_clockevent_init(void); +extern void powertv_clocksource_init(void); +extern unsigned int mips_get_pll_freq(void); +#endif diff --git a/arch/mips/powertv/powertv_setup.c b/arch/mips/powertv/powertv_setup.c new file mode 100644 index 0000000..bd8ebf1 --- /dev/null +++ b/arch/mips/powertv/powertv_setup.c @@ -0,0 +1,351 @@ +/* + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. + * Portions copyright (C) 2009 Cisco Systems, Inc. + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "reset.h" + +#define VAL(n) STR(n) + +/* + * Macros for loading addresses and storing registers: + * PTR_LA Load the address into a register + * LONG_S Store the full width of the given register. + * LONG_L Load the full width of the given register + * PTR_ADDIU Add a constant value to a register used as a pointer + * REG_SIZE Number of 8-bit bytes in a full width register + */ +#ifdef CONFIG_64BIT +#warning TODO: 64-bit code needs to be verified +#define PTR_LA "dla " +#define LONG_S "sd " +#define LONG_L "ld " +#define PTR_ADDIU "daddiu " +#define REG_SIZE "8" /* In bytes */ +#endif + +#ifdef CONFIG_32BIT +#define PTR_LA "la " +#define LONG_S "sw " +#define LONG_L "lw " +#define PTR_ADDIU "addiu " +#define REG_SIZE "4" /* In bytes */ +#endif + +static struct pt_regs die_regs; +static bool have_die_regs; + +static void register_panic_notifier(void); +static int panic_handler(struct notifier_block *notifier_block, + unsigned long event, void *cause_string); + +const char *get_system_type(void) +{ + return "PowerTV"; +} + +void __init plat_mem_setup(void) +{ + panic_on_oops = 1; + register_panic_notifier(); + +#if 0 + mips_pcibios_init(); +#endif + mips_reboot_setup(); +} + +/* + * Install a panic notifier for platform-specific diagnostics + */ +static void register_panic_notifier() +{ + static struct notifier_block panic_notifier = { + .notifier_call = panic_handler, + .next = NULL, + .priority = INT_MAX + }; + atomic_notifier_chain_register(&panic_notifier_list, &panic_notifier); +} + +static int panic_handler(struct notifier_block *notifier_block, + unsigned long event, void *cause_string) +{ + struct pt_regs my_regs; + + /* Save all of the registers */ + { + unsigned long at, v0, v1; /* Must be on the stack */ + + /* Start by saving $at and v0 on the stack. We use $at + * ourselves, but it looks like the compiler may use v0 or v1 + * to load the address of the pt_regs structure. We'll come + * back later to store the registers in the pt_regs + * structure. */ + __asm__ __volatile__ ( + ".set noat\n" + LONG_S "$at, %[at]\n" + LONG_S "$2, %[v0]\n" + LONG_S "$3, %[v1]\n" + : + [at] "=m" (at), + [v0] "=m" (v0), + [v1] "=m" (v1) + : + : "at" + ); + + __asm__ __volatile__ ( + ".set noat\n" + "move $at, %[pt_regs]\n" + + /* Argument registers */ + LONG_S "$4, " VAL(PT_R4) "($at)\n" + LONG_S "$5, " VAL(PT_R5) "($at)\n" + LONG_S "$6, " VAL(PT_R6) "($at)\n" + LONG_S "$7, " VAL(PT_R7) "($at)\n" + + /* Temporary regs */ + LONG_S "$8, " VAL(PT_R8) "($at)\n" + LONG_S "$9, " VAL(PT_R9) "($at)\n" + LONG_S "$10, " VAL(PT_R10) "($at)\n" + LONG_S "$11, " VAL(PT_R11) "($at)\n" + LONG_S "$12, " VAL(PT_R12) "($at)\n" + LONG_S "$13, " VAL(PT_R13) "($at)\n" + LONG_S "$14, " VAL(PT_R14) "($at)\n" + LONG_S "$15, " VAL(PT_R15) "($at)\n" + + /* "Saved" registers */ + LONG_S "$16, " VAL(PT_R16) "($at)\n" + LONG_S "$17, " VAL(PT_R17) "($at)\n" + LONG_S "$18, " VAL(PT_R18) "($at)\n" + LONG_S "$19, " VAL(PT_R19) "($at)\n" + LONG_S "$20, " VAL(PT_R20) "($at)\n" + LONG_S "$21, " VAL(PT_R21) "($at)\n" + LONG_S "$22, " VAL(PT_R22) "($at)\n" + LONG_S "$23, " VAL(PT_R23) "($at)\n" + + /* Add'l temp regs */ + LONG_S "$24, " VAL(PT_R24) "($at)\n" + LONG_S "$25, " VAL(PT_R25) "($at)\n" + + /* Kernel temp regs */ + LONG_S "$26, " VAL(PT_R26) "($at)\n" + LONG_S "$27, " VAL(PT_R27) "($at)\n" + + /* Global pointer, stack pointer, frame pointer and + * return address */ + LONG_S "$gp, " VAL(PT_R28) "($at)\n" + LONG_S "$sp, " VAL(PT_R29) "($at)\n" + LONG_S "$fp, " VAL(PT_R30) "($at)\n" + LONG_S "$ra, " VAL(PT_R31) "($at)\n" + + /* Now we can get the $at and v0 registers back and + * store them */ + LONG_L "$8, %[at]\n" + LONG_S "$8, " VAL(PT_R1) "($at)\n" + LONG_L "$8, %[v0]\n" + LONG_S "$8, " VAL(PT_R2) "($at)\n" + LONG_L "$8, %[v1]\n" + LONG_S "$8, " VAL(PT_R3) "($at)\n" + : + : + [at] "m" (at), + [v0] "m" (v0), + [v1] "m" (v1), + [pt_regs] "r" (&my_regs) + : "at", "t0" + ); + + /* Set the current EPC value to be the current location in this + * function */ + __asm__ __volatile__ ( + ".set noat\n" + "1:\n" + PTR_LA "$at, 1b\n" + LONG_S "$at, %[cp0_epc]\n" + : + [cp0_epc] "=m" (my_regs.cp0_epc) + : + : "at" + ); + + my_regs.cp0_cause = read_c0_cause(); + my_regs.cp0_status = read_c0_status(); + } + +#ifdef CONFIG_DIAGNOSTICS + failure_report((char *) cause_string, + have_die_regs ? &die_regs : &my_regs); + have_die_regs = false; +#else + pr_crit("I'm feeling a bit sleepy. hmmmmm... perhaps a nap would... " + "zzzz... \n"); +#endif + + return NOTIFY_DONE; +} + +/** + * Platform-specific handling of oops + * @str: Pointer to the oops string + * @regs: Pointer to the oops registers + * All we do here is to save the registers for subsequent printing through + * the panic notifier. + */ +void platform_die(const char *str, const struct pt_regs *regs) +{ + /* If we already have saved registers, don't overwrite them as they + * they apply to the initial fault */ + + if (!have_die_regs) { + have_die_regs = true; + die_regs = *regs; + } +} + +/* Information about the RF MAC address, if one was supplied on the + * command line. */ +static bool have_rfmac; +static u8 rfmac[ETH_ALEN]; + +static int rfmac_param(char *p) +{ + u8 *q; + bool is_high_nibble; + int c; + + /* Skip a leading "0x", if present */ + if (*p == '0' && *(p+1) == 'x') + p += 2; + + q = rfmac; + is_high_nibble = true; + + for (c = (unsigned char) *p++; + isxdigit(c) && q - rfmac < ETH_ALEN; + c = (unsigned char) *p++) { + int nibble; + + nibble = (isdigit(c) ? (c - '0') : + (isupper(c) ? c - 'A' + 10 : c - 'a' + 10)); + + if (is_high_nibble) + *q = nibble << 4; + else + *q++ |= nibble; + + is_high_nibble = !is_high_nibble; + } + + /* If we parsed all the way to the end of the parameter value and + * parsed all ETH_ALEN bytes, we have a usable RF MAC address */ + have_rfmac = (c == '\0' && q - rfmac == ETH_ALEN); + + return 0; +} + +early_param("rfmac", rfmac_param); + +/* + * Generate an Ethernet MAC address that has a good chance of being unique. + * @addr: Pointer to six-byte array containing the Ethernet address + * Generates an Ethernet MAC address that is highly likely to be unique for + * this particular system on a network with other systems of the same type. + * + * The problem we are solving is that, when random_ether_addr() is used to + * generate MAC addresses at startup, there isn't much entropy for the random + * number generator to use and the addresses it produces are fairly likely to + * be the same as those of other identical systems on the same local network. + * This is true even for relatively small numbers of systems (for the reason + * why, see the Wikipedia entry for "Birthday problem" at: + * http://en.wikipedia.org/wiki/Birthday_problem + * + * The good news is that we already have a MAC address known to be unique, the + * RF MAC address. The bad news is that this address is already in use on the + * RF interface. Worse, the obvious trick, taking the RF MAC address and + * turning on the locally managed bit, has already been used for other devices. + * Still, this does give us something to work with. + * + * The approach we take is: + * 1. If we can't get the RF MAC Address, just call random_ether_addr. + * 2. Use the 24-bit NIC-specific bits of the RF MAC address as the last 24 + * bits of the new address. This is very likely to be unique, except for + * the current box. + * 3. To avoid using addresses already on the current box, we set the top + * six bits of the address with a value different from any currently + * registered Scientific Atlanta organizationally unique identifyer + * (OUI). This avoids duplication with any addresses on the system that + * were generated from valid Scientific Atlanta-registered address by + * simply flipping the locally managed bit. + * 4. We aren't generating a multicast address, so we leave the multicast + * bit off. Since we aren't using a registered address, we have to set + * the locally managed bit. + * 5. We then randomly generate the remaining 16-bits. This does two + * things: + * a. It allows us to call this function for more than one device + * in this system + * b. It ensures that things will probably still work even if + * some device on the device network has a locally managed + * address that matches the top six bits from step 2. + */ +void platform_random_ether_addr(u8 addr[ETH_ALEN]) +{ + const int num_random_bytes = 2; + const unsigned char non_sciatl_oui_bits = 0xc0u; + const unsigned char mac_addr_locally_managed = (1 << 1); + + if (!have_rfmac) { + pr_warning("rfmac not available on command line; " + "generating random MAC address\n"); + random_ether_addr(addr); + } + + else { + int i; + + /* Set the first byte to something that won't match a Scientific + * Atlanta OUI, is locally managed, and isn't a multicast + * address */ + addr[0] = non_sciatl_oui_bits | mac_addr_locally_managed; + + /* Get some bytes of random address information */ + get_random_bytes(&addr[1], num_random_bytes); + + /* Copy over the NIC-specific bits of the RF MAC address */ + for (i = 1 + num_random_bytes; i < ETH_ALEN; i++) + addr[i] = rfmac[i]; + } +} diff --git a/arch/mips/powertv/reset.c b/arch/mips/powertv/reset.c new file mode 100644 index 0000000..494c652 --- /dev/null +++ b/arch/mips/powertv/reset.c @@ -0,0 +1,65 @@ +/* + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * Portions copyright (C) 2009 Cisco Systems, Inc. + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + */ +#include + +#include +#include /* Not included by linux/reboot.h */ + +#ifdef CONFIG_BOOTLOADER_DRIVER +#include +#endif + +#include +#include "reset.h" + +static void mips_machine_restart(char *command); +static void mips_machine_halt(void); + +static void mips_machine_restart(char *command) +{ +#ifdef CONFIG_BOOTLOADER_DRIVER + /* + * Call the bootloader's reset function to ensure + * that persistent data is flushed before hard reset + */ + kbldr_SetCauseAndReset(); +#else + writel(0x1, asic_reg_addr(watchdog)); +#endif +} + +static void mips_machine_halt(void) +{ +#ifdef CONFIG_BOOTLOADER_DRIVER + /* + * Call the bootloader's reset function to ensure + * that persistent data is flushed before hard reset + */ + kbldr_SetCauseAndReset(); +#else + writel(0x1, asic_reg_addr(watchdog)); +#endif +} + +void mips_reboot_setup(void) +{ + _machine_restart = mips_machine_restart; + _machine_halt = mips_machine_halt; + pm_power_off = mips_machine_halt; +} diff --git a/arch/mips/powertv/reset.h b/arch/mips/powertv/reset.h new file mode 100644 index 0000000..888fd09 --- /dev/null +++ b/arch/mips/powertv/reset.h @@ -0,0 +1,26 @@ +/* + * Definitions from powertv reset.c file + * + * Copyright (C) 2009 Cisco Systems, Inc. + * + * 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 + * + * Author: David VomLehn + */ + +#ifndef _POWERTV_POWERTV_RESET_H +#define _POWERTV_POWERTV_RESET_H +extern void mips_reboot_setup(void); +#endif diff --git a/arch/mips/powertv/time.c b/arch/mips/powertv/time.c new file mode 100644 index 0000000..1e0a5ef --- /dev/null +++ b/arch/mips/powertv/time.c @@ -0,0 +1,37 @@ +/* + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * Portions copyright (C) 2009 Cisco Systems, Inc. + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Setting up the clock on the MIPS boards. + */ + +#include +#include +#include + +#include "powertv-clock.h" + +unsigned int __cpuinit get_c0_compare_int(void) +{ + return irq_mips_timer; +} + +void __init plat_time_init(void) +{ + powertv_clocksource_init(); + r4k_clockevent_init(); +} -- cgit v0.10.2 From e13fb77661b62f49170ef30d707272c568f81681 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Tue, 17 Nov 2009 00:58:14 +0800 Subject: MIPS: Lemote 2F: Add NAS support Kernel support for this machine is almost the same as Fuloong 2F; the only difference is that it uses the serial port provided by Loongson 2F processor as Yeeloong 2F does. Signed-off-by: Wu Zhangjin Cc: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/656/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/include/asm/bootinfo.h b/arch/mips/include/asm/bootinfo.h index 07d4115..be28e3b 100644 --- a/arch/mips/include/asm/bootinfo.h +++ b/arch/mips/include/asm/bootinfo.h @@ -67,7 +67,8 @@ #define MACH_LEMOTE_ML2F7 3 #define MACH_LEMOTE_YL2F89 4 #define MACH_DEXXON_GDIUM2F10 5 -#define MACH_LOONGSON_END 6 +#define MACH_LEMOTE_NAS 6 +#define MACH_LOONGSON_END 7 extern char *system_type; const char *get_system_type(void); diff --git a/arch/mips/loongson/common/machtype.c b/arch/mips/loongson/common/machtype.c index 7545fe6..d57e1f4 100644 --- a/arch/mips/loongson/common/machtype.c +++ b/arch/mips/loongson/common/machtype.c @@ -25,6 +25,7 @@ static const char *system_types[] = { [MACH_LEMOTE_ML2F7] "lemote-mengloong-2f-7inches", [MACH_LEMOTE_YL2F89] "lemote-yeeloong-2f-8.9inches", [MACH_DEXXON_GDIUM2F10] "dexxon-gidum-2f-10inches", + [MACH_LEMOTE_NAS] "lemote-nas-2f", [MACH_LOONGSON_END] NULL, }; diff --git a/arch/mips/loongson/common/serial.c b/arch/mips/loongson/common/serial.c index dc6488c..45601e4 100644 --- a/arch/mips/loongson/common/serial.c +++ b/arch/mips/loongson/common/serial.c @@ -45,6 +45,7 @@ static struct plat_serial8250_port uart8250_data[][2] = { [MACH_LEMOTE_ML2F7] {PORT_M(3), {} }, [MACH_LEMOTE_YL2F89] {PORT_M(3), {} }, [MACH_DEXXON_GDIUM2F10] {PORT_M(3), {} }, + [MACH_LEMOTE_NAS] {PORT_M(3), {} }, [MACH_LOONGSON_END] {}, }; diff --git a/arch/mips/loongson/common/uart_base.c b/arch/mips/loongson/common/uart_base.c index 233c708..e34d699 100644 --- a/arch/mips/loongson/common/uart_base.c +++ b/arch/mips/loongson/common/uart_base.c @@ -23,6 +23,7 @@ unsigned long __maybe_unused uart8250_base[] = { [MACH_LEMOTE_ML2F7] (LOONGSON_LIO1_BASE + 0x3f8), [MACH_LEMOTE_YL2F89] (LOONGSON_LIO1_BASE + 0x3f8), [MACH_DEXXON_GDIUM2F10] (LOONGSON_LIO1_BASE + 0x3f8), + [MACH_LEMOTE_NAS] (LOONGSON_LIO1_BASE + 0x3f8), [MACH_LOONGSON_END] 0, }; EXPORT_SYMBOL(uart8250_base); diff --git a/arch/mips/loongson/lemote-2f/reset.c b/arch/mips/loongson/lemote-2f/reset.c index 0458a1c..980299d 100644 --- a/arch/mips/loongson/lemote-2f/reset.c +++ b/arch/mips/loongson/lemote-2f/reset.c @@ -141,6 +141,7 @@ void mach_prepare_reboot(void) { switch (mips_machtype) { case MACH_LEMOTE_FL2F: + case MACH_LEMOTE_NAS: fl2f_reboot(); break; case MACH_LEMOTE_ML2F7: @@ -158,6 +159,7 @@ void mach_prepare_shutdown(void) { switch (mips_machtype) { case MACH_LEMOTE_FL2F: + case MACH_LEMOTE_NAS: fl2f_shutdown(); break; case MACH_LEMOTE_ML2F7: -- cgit v0.10.2 From 6e552c9b3aa7ba3be57b9569ec92a38af5c65e48 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Tue, 17 Nov 2009 00:58:15 +0800 Subject: MIPS: Lemote 2F: Add Lynloong support Add a new machtype and kernel options for the Lynloong. Signed-off-by: Wu Zhangjin Cc: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/657/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/include/asm/bootinfo.h b/arch/mips/include/asm/bootinfo.h index be28e3b..09eee09 100644 --- a/arch/mips/include/asm/bootinfo.h +++ b/arch/mips/include/asm/bootinfo.h @@ -68,7 +68,8 @@ #define MACH_LEMOTE_YL2F89 4 #define MACH_DEXXON_GDIUM2F10 5 #define MACH_LEMOTE_NAS 6 -#define MACH_LOONGSON_END 7 +#define MACH_LEMOTE_LL2F 7 +#define MACH_LOONGSON_END 8 extern char *system_type; const char *get_system_type(void); diff --git a/arch/mips/loongson/common/machtype.c b/arch/mips/loongson/common/machtype.c index d57e1f4..0ed52b3 100644 --- a/arch/mips/loongson/common/machtype.c +++ b/arch/mips/loongson/common/machtype.c @@ -26,6 +26,7 @@ static const char *system_types[] = { [MACH_LEMOTE_YL2F89] "lemote-yeeloong-2f-8.9inches", [MACH_DEXXON_GDIUM2F10] "dexxon-gidum-2f-10inches", [MACH_LEMOTE_NAS] "lemote-nas-2f", + [MACH_LEMOTE_LL2F] "lemote-lynloong-2f", [MACH_LOONGSON_END] NULL, }; diff --git a/arch/mips/loongson/common/serial.c b/arch/mips/loongson/common/serial.c index 45601e4..ea29db0 100644 --- a/arch/mips/loongson/common/serial.c +++ b/arch/mips/loongson/common/serial.c @@ -46,6 +46,7 @@ static struct plat_serial8250_port uart8250_data[][2] = { [MACH_LEMOTE_YL2F89] {PORT_M(3), {} }, [MACH_DEXXON_GDIUM2F10] {PORT_M(3), {} }, [MACH_LEMOTE_NAS] {PORT_M(3), {} }, + [MACH_LEMOTE_LL2F] {PORT(3), {} }, [MACH_LOONGSON_END] {}, }; diff --git a/arch/mips/loongson/common/uart_base.c b/arch/mips/loongson/common/uart_base.c index e34d699..1d636f4 100644 --- a/arch/mips/loongson/common/uart_base.c +++ b/arch/mips/loongson/common/uart_base.c @@ -24,6 +24,7 @@ unsigned long __maybe_unused uart8250_base[] = { [MACH_LEMOTE_YL2F89] (LOONGSON_LIO1_BASE + 0x3f8), [MACH_DEXXON_GDIUM2F10] (LOONGSON_LIO1_BASE + 0x3f8), [MACH_LEMOTE_NAS] (LOONGSON_LIO1_BASE + 0x3f8), + [MACH_LEMOTE_LL2F] (LOONGSON_PCIIO_BASE + 0x2f8), [MACH_LOONGSON_END] 0, }; EXPORT_SYMBOL(uart8250_base); diff --git a/arch/mips/loongson/lemote-2f/reset.c b/arch/mips/loongson/lemote-2f/reset.c index 980299d..44bb984 100644 --- a/arch/mips/loongson/lemote-2f/reset.c +++ b/arch/mips/loongson/lemote-2f/reset.c @@ -142,6 +142,7 @@ void mach_prepare_reboot(void) switch (mips_machtype) { case MACH_LEMOTE_FL2F: case MACH_LEMOTE_NAS: + case MACH_LEMOTE_LL2F: fl2f_reboot(); break; case MACH_LEMOTE_ML2F7: @@ -160,6 +161,7 @@ void mach_prepare_shutdown(void) switch (mips_machtype) { case MACH_LEMOTE_FL2F: case MACH_LEMOTE_NAS: + case MACH_LEMOTE_LL2F: fl2f_shutdown(); break; case MACH_LEMOTE_ML2F7: -- cgit v0.10.2 From 916daba8a9f2617ded8b9255e6b39f066ef60178 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Tue, 17 Nov 2009 01:32:57 +0800 Subject: MIPS: Lemote 2F: Add cs5536 MFGPT timer support CPUFreq support for Loongson 2F requires an external timer. Because the frequency of the MIPS Timer is related to the CPU frequency which itself is variable another timer of constant frequency is required. Export the mfgpt0 counter disable / enable operations for the coming suspend support to suspend / resume the timer. Signed-off-by: Wu Zhangjin Cc: linux-mips@linux-mips.org Cc: cpufreq@vger.kernel.org, Cc: Dave Jones , Cc: Dominik Brodowski , Cc: yanh@lemote.com Cc: huhb@lemote.com, Patchwork: http://patchwork.linux-mips.org/patch/658/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h b/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h new file mode 100644 index 0000000..4b493d6 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h @@ -0,0 +1,35 @@ +/* + * cs5536 mfgpt header file + */ + +#ifndef _CS5536_MFGPT_H +#define _CS5536_MFGPT_H + +#include +#include + +#ifdef CONFIG_CS5536_MFGPT +extern void setup_mfgpt0_timer(void); +extern void disable_mfgpt0_counter(void); +extern void enable_mfgpt0_counter(void); +#else +static inline void __maybe_unused setup_mfgpt0_timer(void) +{ +} +static inline void __maybe_unused disable_mfgpt0_counter(void) +{ +} +static inline void __maybe_unused enable_mfgpt0_counter(void) +{ +} +#endif + +#define MFGPT_TICK_RATE 14318000 +#define COMPARE ((MFGPT_TICK_RATE + HZ/2) / HZ) + +#define MFGPT_BASE mfgpt_base +#define MFGPT0_CMP2 (MFGPT_BASE + 2) +#define MFGPT0_CNT (MFGPT_BASE + 4) +#define MFGPT0_SETUP (MFGPT_BASE + 6) + +#endif /*!_CS5536_MFGPT_H */ diff --git a/arch/mips/loongson/Kconfig b/arch/mips/loongson/Kconfig index 17e72fd..8b5cc13 100644 --- a/arch/mips/loongson/Kconfig +++ b/arch/mips/loongson/Kconfig @@ -62,6 +62,17 @@ endchoice config CS5536 bool +config CS5536_MFGPT + bool "CS5536 MFGPT Timer" + depends on CS5536 + help + This option enables the mfgpt0 timer of AMD CS5536. + + If you want to enable the Loongson2 CPUFreq Driver, Please enable + this option at first, otherwise, You will get wrong system time. + + If unsure, say Yes. + config LOONGSON_SUSPEND bool default y diff --git a/arch/mips/loongson/common/cs5536/Makefile b/arch/mips/loongson/common/cs5536/Makefile index 31657ee..510d4cd 100644 --- a/arch/mips/loongson/common/cs5536/Makefile +++ b/arch/mips/loongson/common/cs5536/Makefile @@ -5,4 +5,9 @@ obj-$(CONFIG_CS5536) += cs5536_pci.o cs5536_ide.o cs5536_acc.o cs5536_ohci.o \ cs5536_isa.o cs5536_ehci.o +# +# Enable cs5536 mfgpt Timer +# +obj-$(CONFIG_CS5536_MFGPT) += cs5536_mfgpt.o + EXTRA_CFLAGS += -Werror diff --git a/arch/mips/loongson/common/cs5536/cs5536_mfgpt.c b/arch/mips/loongson/common/cs5536/cs5536_mfgpt.c new file mode 100644 index 0000000..6cb44db --- /dev/null +++ b/arch/mips/loongson/common/cs5536/cs5536_mfgpt.c @@ -0,0 +1,217 @@ +/* + * CS5536 General timer functions + * + * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology + * Author: Yanhua, yanh@lemote.com + * + * Copyright (C) 2009 Lemote Inc. + * Author: Wu zhangjin, wuzj@lemote.com + * + * Reference: AMD Geode(TM) CS5536 Companion Device Data Book + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +DEFINE_SPINLOCK(mfgpt_lock); +EXPORT_SYMBOL(mfgpt_lock); + +static u32 mfgpt_base; + +/* + * Initialize the MFGPT timer. + * + * This is also called after resume to bring the MFGPT into operation again. + */ + +/* disable counter */ +void disable_mfgpt0_counter(void) +{ + outw(inw(MFGPT0_SETUP) & 0x7fff, MFGPT0_SETUP); +} +EXPORT_SYMBOL(disable_mfgpt0_counter); + +/* enable counter, comparator2 to event mode, 14.318MHz clock */ +void enable_mfgpt0_counter(void) +{ + outw(0xe310, MFGPT0_SETUP); +} +EXPORT_SYMBOL(enable_mfgpt0_counter); + +static void init_mfgpt_timer(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + spin_lock(&mfgpt_lock); + + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + outw(COMPARE, MFGPT0_CMP2); /* set comparator2 */ + outw(0, MFGPT0_CNT); /* set counter to 0 */ + enable_mfgpt0_counter(); + break; + + case CLOCK_EVT_MODE_SHUTDOWN: + case CLOCK_EVT_MODE_UNUSED: + if (evt->mode == CLOCK_EVT_MODE_PERIODIC || + evt->mode == CLOCK_EVT_MODE_ONESHOT) + disable_mfgpt0_counter(); + break; + + case CLOCK_EVT_MODE_ONESHOT: + /* The oneshot mode have very high deviation, Not use it! */ + break; + + case CLOCK_EVT_MODE_RESUME: + /* Nothing to do here */ + break; + } + spin_unlock(&mfgpt_lock); +} + +static struct clock_event_device mfgpt_clockevent = { + .name = "mfgpt", + .features = CLOCK_EVT_FEAT_PERIODIC, + .set_mode = init_mfgpt_timer, + .irq = CS5536_MFGPT_INTR, +}; + +static irqreturn_t timer_interrupt(int irq, void *dev_id) +{ + u32 basehi; + + /* + * get MFGPT base address + * + * NOTE: do not remove me, it's need for the value of mfgpt_base is + * variable + */ + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), &basehi, &mfgpt_base); + + /* ack */ + outw(inw(MFGPT0_SETUP) | 0x4000, MFGPT0_SETUP); + + mfgpt_clockevent.event_handler(&mfgpt_clockevent); + + return IRQ_HANDLED; +} + +static struct irqaction irq5 = { + .handler = timer_interrupt, + .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_TIMER, + .name = "timer" +}; + +/* + * Initialize the conversion factor and the min/max deltas of the clock event + * structure and register the clock event source with the framework. + */ +void __init setup_mfgpt0_timer(void) +{ + u32 basehi; + struct clock_event_device *cd = &mfgpt_clockevent; + unsigned int cpu = smp_processor_id(); + + cd->cpumask = cpumask_of(cpu); + clockevent_set_clock(cd, MFGPT_TICK_RATE); + cd->max_delta_ns = clockevent_delta2ns(0xffff, cd); + cd->min_delta_ns = clockevent_delta2ns(0xf, cd); + + /* Enable MFGPT0 Comparator 2 Output to the Interrupt Mapper */ + _wrmsr(DIVIL_MSR_REG(MFGPT_IRQ), 0, 0x100); + + /* Enable Interrupt Gate 5 */ + _wrmsr(DIVIL_MSR_REG(PIC_ZSEL_LOW), 0, 0x50000); + + /* get MFGPT base address */ + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), &basehi, &mfgpt_base); + + clockevents_register_device(cd); + + setup_irq(CS5536_MFGPT_INTR, &irq5); +} + +/* + * Since the MFGPT overflows every tick, its not very useful + * to just read by itself. So use jiffies to emulate a free + * running counter: + */ +static cycle_t mfgpt_read(struct clocksource *cs) +{ + unsigned long flags; + int count; + u32 jifs; + static int old_count; + static u32 old_jifs; + + spin_lock_irqsave(&mfgpt_lock, flags); + /* + * Although our caller may have the read side of xtime_lock, + * this is now a seqlock, and we are cheating in this routine + * by having side effects on state that we cannot undo if + * there is a collision on the seqlock and our caller has to + * retry. (Namely, old_jifs and old_count.) So we must treat + * jiffies as volatile despite the lock. We read jiffies + * before latching the timer count to guarantee that although + * the jiffies value might be older than the count (that is, + * the counter may underflow between the last point where + * jiffies was incremented and the point where we latch the + * count), it cannot be newer. + */ + jifs = jiffies; + /* read the count */ + count = inw(MFGPT0_CNT); + + /* + * It's possible for count to appear to go the wrong way for this + * reason: + * + * The timer counter underflows, but we haven't handled the resulting + * interrupt and incremented jiffies yet. + * + * Previous attempts to handle these cases intelligently were buggy, so + * we just do the simple thing now. + */ + if (count < old_count && jifs == old_jifs) + count = old_count; + + old_count = count; + old_jifs = jifs; + + spin_unlock_irqrestore(&mfgpt_lock, flags); + + return (cycle_t) (jifs * COMPARE) + count; +} + +static struct clocksource clocksource_mfgpt = { + .name = "mfgpt", + .rating = 120, /* Functional for real use, but not desired */ + .read = mfgpt_read, + .mask = CLOCKSOURCE_MASK(32), + .mult = 0, + .shift = 22, +}; + +int __init init_mfgpt_clocksource(void) +{ + if (num_possible_cpus() > 1) /* MFGPT does not scale! */ + return 0; + + clocksource_mfgpt.mult = clocksource_hz2mult(MFGPT_TICK_RATE, 22); + return clocksource_register(&clocksource_mfgpt); +} + +arch_initcall(init_mfgpt_clocksource); diff --git a/arch/mips/loongson/common/time.c b/arch/mips/loongson/common/time.c index 6e08c82..35f0b66 100644 --- a/arch/mips/loongson/common/time.c +++ b/arch/mips/loongson/common/time.c @@ -14,11 +14,14 @@ #include #include +#include void __init plat_time_init(void) { /* setup mips r4k timer */ mips_hpt_frequency = cpu_clock_freq / 2; + + setup_mfgpt0_timer(); } void read_persistent_clock(struct timespec *ts) -- cgit v0.10.2 From 9726b43a4d7aaa5b30f559e78768aeb3d17bc224 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Tue, 17 Nov 2009 01:32:58 +0800 Subject: MIPS: Add basic CPUFreq options. This patch adds basic options for MIPS CPUFreq support. Since the cp0 timer's frequency is based on the processor clockrate it can not be used with CPUFReq; an additional external timer is required. Signed-off-by: Wu Zhangjin Cc: linux-mips@linux-mips.org Cc: cpufreq@vger.kernel.org, Cc: Dave Jones , Cc: Dominik Brodowski , Cc: yanh@lemote.com Cc: huhb@lemote.com, Patchwork: http://patchwork.linux-mips.org/patch/659/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index e7f3854..435838e 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -2161,6 +2161,7 @@ config MMU config I8253 bool + select MIPS_EXTERNAL_TIMER config ZONE_DMA32 bool @@ -2237,6 +2238,8 @@ source "kernel/power/Kconfig" endmenu +source "arch/mips/kernel/cpufreq/Kconfig" + source "net/Kconfig" source "drivers/Kconfig" diff --git a/arch/mips/kernel/cpufreq/Kconfig b/arch/mips/kernel/cpufreq/Kconfig new file mode 100644 index 0000000..37983a1 --- /dev/null +++ b/arch/mips/kernel/cpufreq/Kconfig @@ -0,0 +1,27 @@ +# +# CPU Frequency scaling +# + +config MIPS_EXTERNAL_TIMER + bool + +config MIPS_CPUFREQ + bool + default y + depends on CPU_SUPPORTS_CPUFREQ && MIPS_EXTERNAL_TIMER + +if MIPS_CPUFREQ + +menu "CPU Frequency scaling" + +source "drivers/cpufreq/Kconfig" + +if CPU_FREQ + +comment "CPUFreq processor drivers" + +endif # CPU_FREQ + +endmenu + +endif # MIPS_CPUFREQ -- cgit v0.10.2 From f8ede0f700f5478851f242f291d203cde54ca6cf Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Tue, 17 Nov 2009 01:32:59 +0800 Subject: MIPS: Loongson 2F: Add CPU frequency scaling support Loongson 2F supports CPU clock scaling. When put it into wait mode by setting the frequency as ZERO it will stay in this mode until an external interrupt wakes the CPU again. To enable clock scaling support, an external timer of a known stable rate is required. Signed-off-by: Wu Zhangjin Cc: linux-mips@linux-mips.org Cc: cpufreq@vger.kernel.org, Cc: Dave Jones , Cc: Dominik Brodowski , Cc: yanh@lemote.com Cc: huhb@lemote.com, Patchwork: http://patchwork.linux-mips.org/patch/660/ Patchwork: http://patchwork.linux-mips.org/patch/751/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/include/asm/clock.h b/arch/mips/include/asm/clock.h new file mode 100644 index 0000000..83894aa --- /dev/null +++ b/arch/mips/include/asm/clock.h @@ -0,0 +1,64 @@ +#ifndef __ASM_MIPS_CLOCK_H +#define __ASM_MIPS_CLOCK_H + +#include +#include +#include +#include + +extern void (*cpu_wait) (void); + +struct clk; + +struct clk_ops { + void (*init) (struct clk *clk); + void (*enable) (struct clk *clk); + void (*disable) (struct clk *clk); + void (*recalc) (struct clk *clk); + int (*set_rate) (struct clk *clk, unsigned long rate, int algo_id); + long (*round_rate) (struct clk *clk, unsigned long rate); +}; + +struct clk { + struct list_head node; + const char *name; + int id; + struct module *owner; + + struct clk *parent; + struct clk_ops *ops; + + struct kref kref; + + unsigned long rate; + unsigned long flags; +}; + +#define CLK_ALWAYS_ENABLED (1 << 0) +#define CLK_RATE_PROPAGATES (1 << 1) + +/* Should be defined by processor-specific code */ +void arch_init_clk_ops(struct clk_ops **, int type); + +int clk_init(void); + +int __clk_enable(struct clk *); +void __clk_disable(struct clk *); + +void clk_recalc_rate(struct clk *); + +int clk_register(struct clk *); +void clk_unregister(struct clk *); + +/* the exported API, in addition to clk_set_rate */ +/** + * clk_set_rate_ex - set the clock rate for a clock source, with additional parameter + * @clk: clock source + * @rate: desired clock rate in Hz + * @algo_id: algorithm id to be passed down to ops->set_rate + * + * Returns success (0) or negative errno. + */ +int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id); + +#endif /* __ASM_MIPS_CLOCK_H */ diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h index 4b96d1a..cf373a9 100644 --- a/arch/mips/include/asm/cpu.h +++ b/arch/mips/include/asm/cpu.h @@ -154,6 +154,8 @@ #define PRID_REV_VR4181A 0x0070 /* Same as VR4122 */ #define PRID_REV_VR4130 0x0080 #define PRID_REV_34K_V1_0_2 0x0022 +#define PRID_REV_LOONGSON2E 0x0002 +#define PRID_REV_LOONGSON2F 0x0003 /* * Older processors used to encode processor version and revision in two diff --git a/arch/mips/include/asm/mach-loongson/loongson.h b/arch/mips/include/asm/mach-loongson/loongson.h index 9bccdb5..a7fa66e 100644 --- a/arch/mips/include/asm/mach-loongson/loongson.h +++ b/arch/mips/include/asm/mach-loongson/loongson.h @@ -226,8 +226,12 @@ extern void mach_irq_dispatch(unsigned int pending); #define LOONGSON_PCIMAP_WIN(WIN, ADDR) \ ((((ADDR)>>26) & LOONGSON_PCIMAP_PCIMAP_LO0) << ((WIN)*6)) -/* Chip Config */ #ifdef CONFIG_CPU_SUPPORTS_CPUFREQ +#include +extern void loongson2_cpu_wait(void); +extern struct cpufreq_frequency_table loongson2_clockmod_table[]; + +/* Chip Config */ #define LOONGSON_CHIPCFG0 LOONGSON_REG(LOONGSON_REGBASE + 0x80) #endif diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index a446aa2..f442de8 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -93,4 +93,6 @@ CFLAGS_cpu-bugs64.o = $(shell if $(CC) $(KBUILD_CFLAGS) -Wa,-mdaddi -c -o /dev/n obj-$(CONFIG_HAVE_STD_PC_SERIAL_PORT) += 8250-platform.o +obj-$(CONFIG_MIPS_CPUFREQ) += cpufreq/ + EXTRA_CFLAGS += -Werror diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index 7a51866..80e202e 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -32,6 +33,7 @@ * the CPU very much. */ void (*cpu_wait)(void); +EXPORT_SYMBOL(cpu_wait); static void r3081_wait(void) { diff --git a/arch/mips/kernel/cpufreq/Kconfig b/arch/mips/kernel/cpufreq/Kconfig index 37983a1..58c601e 100644 --- a/arch/mips/kernel/cpufreq/Kconfig +++ b/arch/mips/kernel/cpufreq/Kconfig @@ -20,6 +20,20 @@ if CPU_FREQ comment "CPUFreq processor drivers" +config LOONGSON2_CPUFREQ + tristate "Loongson2 CPUFreq Driver" + select CPU_FREQ_TABLE + depends on MIPS_CPUFREQ + help + This option adds a CPUFreq driver for loongson processors which + support software configurable cpu frequency. + + Loongson2F and it's successors support this feature. + + For details, take a look at . + + If in doubt, say N. + endif # CPU_FREQ endmenu diff --git a/arch/mips/kernel/cpufreq/Makefile b/arch/mips/kernel/cpufreq/Makefile new file mode 100644 index 0000000..c3479a43 --- /dev/null +++ b/arch/mips/kernel/cpufreq/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for the Linux/MIPS cpufreq. +# + +obj-$(CONFIG_LOONGSON2_CPUFREQ) += loongson2_cpufreq.o loongson2_clock.o diff --git a/arch/mips/kernel/cpufreq/loongson2_clock.c b/arch/mips/kernel/cpufreq/loongson2_clock.c new file mode 100644 index 0000000..d7ca256 --- /dev/null +++ b/arch/mips/kernel/cpufreq/loongson2_clock.c @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2006 - 2008 Lemote Inc. & Insititute of Computing Technology + * Author: Yanhua, yanh@lemote.com + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include +#include + +#include + +#include + +static LIST_HEAD(clock_list); +static DEFINE_SPINLOCK(clock_lock); +static DEFINE_MUTEX(clock_list_sem); + +/* Minimum CLK support */ +enum { + DC_ZERO, DC_25PT = 2, DC_37PT, DC_50PT, DC_62PT, DC_75PT, + DC_87PT, DC_DISABLE, DC_RESV +}; + +struct cpufreq_frequency_table loongson2_clockmod_table[] = { + {DC_RESV, CPUFREQ_ENTRY_INVALID}, + {DC_ZERO, CPUFREQ_ENTRY_INVALID}, + {DC_25PT, 0}, + {DC_37PT, 0}, + {DC_50PT, 0}, + {DC_62PT, 0}, + {DC_75PT, 0}, + {DC_87PT, 0}, + {DC_DISABLE, 0}, + {DC_RESV, CPUFREQ_TABLE_END}, +}; +EXPORT_SYMBOL_GPL(loongson2_clockmod_table); + +static struct clk cpu_clk = { + .name = "cpu_clk", + .flags = CLK_ALWAYS_ENABLED | CLK_RATE_PROPAGATES, + .rate = 800000000, +}; + +struct clk *clk_get(struct device *dev, const char *id) +{ + return &cpu_clk; +} +EXPORT_SYMBOL(clk_get); + +static void propagate_rate(struct clk *clk) +{ + struct clk *clkp; + + list_for_each_entry(clkp, &clock_list, node) { + if (likely(clkp->parent != clk)) + continue; + if (likely(clkp->ops && clkp->ops->recalc)) + clkp->ops->recalc(clkp); + if (unlikely(clkp->flags & CLK_RATE_PROPAGATES)) + propagate_rate(clkp); + } +} + +int clk_enable(struct clk *clk) +{ + return 0; +} +EXPORT_SYMBOL(clk_enable); + +void clk_disable(struct clk *clk) +{ +} +EXPORT_SYMBOL(clk_disable); + +unsigned long clk_get_rate(struct clk *clk) +{ + return (unsigned long)clk->rate; +} +EXPORT_SYMBOL(clk_get_rate); + +void clk_put(struct clk *clk) +{ +} +EXPORT_SYMBOL(clk_put); + +int clk_set_rate(struct clk *clk, unsigned long rate) +{ + return clk_set_rate_ex(clk, rate, 0); +} +EXPORT_SYMBOL_GPL(clk_set_rate); + +int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id) +{ + int ret = 0; + int regval; + int i; + + if (likely(clk->ops && clk->ops->set_rate)) { + unsigned long flags; + + spin_lock_irqsave(&clock_lock, flags); + ret = clk->ops->set_rate(clk, rate, algo_id); + spin_unlock_irqrestore(&clock_lock, flags); + } + + if (unlikely(clk->flags & CLK_RATE_PROPAGATES)) + propagate_rate(clk); + + for (i = 0; loongson2_clockmod_table[i].frequency != CPUFREQ_TABLE_END; + i++) { + if (loongson2_clockmod_table[i].frequency == + CPUFREQ_ENTRY_INVALID) + continue; + if (rate == loongson2_clockmod_table[i].frequency) + break; + } + if (rate != loongson2_clockmod_table[i].frequency) + return -ENOTSUPP; + + clk->rate = rate; + + regval = LOONGSON_CHIPCFG0; + regval = (regval & ~0x7) | (loongson2_clockmod_table[i].index - 1); + LOONGSON_CHIPCFG0 = regval; + + return ret; +} +EXPORT_SYMBOL_GPL(clk_set_rate_ex); + +long clk_round_rate(struct clk *clk, unsigned long rate) +{ + if (likely(clk->ops && clk->ops->round_rate)) { + unsigned long flags, rounded; + + spin_lock_irqsave(&clock_lock, flags); + rounded = clk->ops->round_rate(clk, rate); + spin_unlock_irqrestore(&clock_lock, flags); + + return rounded; + } + + return rate; +} +EXPORT_SYMBOL_GPL(clk_round_rate); + +/* + * This is the simple version of Loongson-2 wait, Maybe we need do this in + * interrupt disabled content + */ + +DEFINE_SPINLOCK(loongson2_wait_lock); +void loongson2_cpu_wait(void) +{ + u32 cpu_freq; + unsigned long flags; + + spin_lock_irqsave(&loongson2_wait_lock, flags); + cpu_freq = LOONGSON_CHIPCFG0; + LOONGSON_CHIPCFG0 &= ~0x7; /* Put CPU into wait mode */ + LOONGSON_CHIPCFG0 = cpu_freq; /* Restore CPU state */ + spin_unlock_irqrestore(&loongson2_wait_lock, flags); +} +EXPORT_SYMBOL_GPL(loongson2_cpu_wait); diff --git a/arch/mips/kernel/cpufreq/loongson2_cpufreq.c b/arch/mips/kernel/cpufreq/loongson2_cpufreq.c new file mode 100644 index 0000000..2f6a0b1 --- /dev/null +++ b/arch/mips/kernel/cpufreq/loongson2_cpufreq.c @@ -0,0 +1,227 @@ +/* + * Cpufreq driver for the loongson-2 processors + * + * The 2E revision of loongson processor not support this feature. + * + * Copyright (C) 2006 - 2008 Lemote Inc. & Insititute of Computing Technology + * Author: Yanhua, yanh@lemote.com + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include /* set_cpus_allowed() */ +#include +#include + +#include + +#include + +static uint nowait; + +static struct clk *cpuclk; + +static void (*saved_cpu_wait) (void); + +static int loongson2_cpu_freq_notifier(struct notifier_block *nb, + unsigned long val, void *data); + +static struct notifier_block loongson2_cpufreq_notifier_block = { + .notifier_call = loongson2_cpu_freq_notifier +}; + +static int loongson2_cpu_freq_notifier(struct notifier_block *nb, + unsigned long val, void *data) +{ + if (val == CPUFREQ_POSTCHANGE) + current_cpu_data.udelay_val = loops_per_jiffy; + + return 0; +} + +static unsigned int loongson2_cpufreq_get(unsigned int cpu) +{ + return clk_get_rate(cpuclk); +} + +/* + * Here we notify other drivers of the proposed change and the final change. + */ +static int loongson2_cpufreq_target(struct cpufreq_policy *policy, + unsigned int target_freq, + unsigned int relation) +{ + unsigned int cpu = policy->cpu; + unsigned int newstate = 0; + cpumask_t cpus_allowed; + struct cpufreq_freqs freqs; + unsigned int freq; + + if (!cpu_online(cpu)) + return -ENODEV; + + cpus_allowed = current->cpus_allowed; + set_cpus_allowed(current, cpumask_of_cpu(cpu)); + + if (cpufreq_frequency_table_target + (policy, &loongson2_clockmod_table[0], target_freq, relation, + &newstate)) + return -EINVAL; + + freq = + ((cpu_clock_freq / 1000) * + loongson2_clockmod_table[newstate].index) / 8; + if (freq < policy->min || freq > policy->max) + return -EINVAL; + + pr_debug("cpufreq: requested frequency %u Hz\n", target_freq * 1000); + + freqs.cpu = cpu; + freqs.old = loongson2_cpufreq_get(cpu); + freqs.new = freq; + freqs.flags = 0; + + if (freqs.new == freqs.old) + return 0; + + /* notifiers */ + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); + + set_cpus_allowed(current, cpus_allowed); + + /* setting the cpu frequency */ + clk_set_rate(cpuclk, freq); + + /* notifiers */ + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); + + pr_debug("cpufreq: set frequency %u kHz\n", freq); + + return 0; +} + +static int loongson2_cpufreq_cpu_init(struct cpufreq_policy *policy) +{ + int i; + + if (!cpu_online(policy->cpu)) + return -ENODEV; + + cpuclk = clk_get(NULL, "cpu_clk"); + if (IS_ERR(cpuclk)) { + printk(KERN_ERR "cpufreq: couldn't get CPU clk\n"); + return PTR_ERR(cpuclk); + } + + cpuclk->rate = cpu_clock_freq / 1000; + if (!cpuclk->rate) + return -EINVAL; + + /* clock table init */ + for (i = 2; + (loongson2_clockmod_table[i].frequency != CPUFREQ_TABLE_END); + i++) + loongson2_clockmod_table[i].frequency = (cpuclk->rate * i) / 8; + + policy->cur = loongson2_cpufreq_get(policy->cpu); + + cpufreq_frequency_table_get_attr(&loongson2_clockmod_table[0], + policy->cpu); + + return cpufreq_frequency_table_cpuinfo(policy, + &loongson2_clockmod_table[0]); +} + +static int loongson2_cpufreq_verify(struct cpufreq_policy *policy) +{ + return cpufreq_frequency_table_verify(policy, + &loongson2_clockmod_table[0]); +} + +static int loongson2_cpufreq_exit(struct cpufreq_policy *policy) +{ + clk_put(cpuclk); + return 0; +} + +static struct freq_attr *loongson2_table_attr[] = { + &cpufreq_freq_attr_scaling_available_freqs, + NULL, +}; + +static struct cpufreq_driver loongson2_cpufreq_driver = { + .owner = THIS_MODULE, + .name = "loongson2", + .init = loongson2_cpufreq_cpu_init, + .verify = loongson2_cpufreq_verify, + .target = loongson2_cpufreq_target, + .get = loongson2_cpufreq_get, + .exit = loongson2_cpufreq_exit, + .attr = loongson2_table_attr, +}; + +static struct platform_device_id platform_device_ids[] = { + { + .name = "loongson2_cpufreq", + }, + {} +}; + +MODULE_DEVICE_TABLE(platform, platform_device_ids); + +static struct platform_driver platform_driver = { + .driver = { + .name = "loongson2_cpufreq", + .owner = THIS_MODULE, + }, + .id_table = platform_device_ids, +}; + +static int __init cpufreq_init(void) +{ + int ret; + + /* Register platform stuff */ + ret = platform_driver_register(&platform_driver); + if (ret) + return ret; + + pr_info("cpufreq: Loongson-2F CPU frequency driver.\n"); + + cpufreq_register_notifier(&loongson2_cpufreq_notifier_block, + CPUFREQ_TRANSITION_NOTIFIER); + + ret = cpufreq_register_driver(&loongson2_cpufreq_driver); + + if (!ret && !nowait) { + saved_cpu_wait = cpu_wait; + cpu_wait = loongson2_cpu_wait; + } + + return ret; +} + +static void __exit cpufreq_exit(void) +{ + if (!nowait && saved_cpu_wait) + cpu_wait = saved_cpu_wait; + cpufreq_unregister_driver(&loongson2_cpufreq_driver); + cpufreq_unregister_notifier(&loongson2_cpufreq_notifier_block, + CPUFREQ_TRANSITION_NOTIFIER); + + platform_driver_unregister(&platform_driver); +} + +module_init(cpufreq_init); +module_exit(cpufreq_exit); + +module_param(nowait, uint, 0644); +MODULE_PARM_DESC(nowait, "Disable Loongson-2F specific wait"); + +MODULE_AUTHOR("Yanhua "); +MODULE_DESCRIPTION("cpufreq driver for Loongson2F"); +MODULE_LICENSE("GPL"); diff --git a/arch/mips/loongson/Kconfig b/arch/mips/loongson/Kconfig index 8b5cc13..7a86987 100644 --- a/arch/mips/loongson/Kconfig +++ b/arch/mips/loongson/Kconfig @@ -34,10 +34,10 @@ config LEMOTE_MACH2F select ARCH_SPARSEMEM_ENABLE select BOARD_SCACHE select BOOT_ELF32 - select CEVT_R4K + select CEVT_R4K if ! MIPS_EXTERNAL_TIMER select CPU_HAS_WB select CS5536 - select CSRC_R4K + select CSRC_R4K if ! MIPS_EXTERNAL_TIMER select DMA_NONCOHERENT select GENERIC_HARDIRQS_NO__DO_IRQ select GENERIC_ISA_DMA_SUPPORT_BROKEN @@ -65,6 +65,7 @@ config CS5536 config CS5536_MFGPT bool "CS5536 MFGPT Timer" depends on CS5536 + select MIPS_EXTERNAL_TIMER help This option enables the mfgpt0 timer of AMD CS5536. diff --git a/arch/mips/loongson/common/Makefile b/arch/mips/loongson/common/Makefile index a21724d..8d71892 100644 --- a/arch/mips/loongson/common/Makefile +++ b/arch/mips/loongson/common/Makefile @@ -3,7 +3,7 @@ # obj-y += setup.o init.o cmdline.o env.o time.o reset.o irq.o \ - pci.o bonito-irq.o mem.o machtype.o uart_base.o + pci.o bonito-irq.o mem.o machtype.o platform.o uart_base.o # # Early printk support diff --git a/arch/mips/loongson/common/env.c b/arch/mips/loongson/common/env.c index b9ef503..196d947 100644 --- a/arch/mips/loongson/common/env.c +++ b/arch/mips/loongson/common/env.c @@ -17,11 +17,14 @@ * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. */ +#include + #include #include unsigned long bus_clock, cpu_clock_freq; +EXPORT_SYMBOL(cpu_clock_freq); unsigned long memsize, highmemsize; /* pmon passes arguments in 32bit pointers */ diff --git a/arch/mips/loongson/common/platform.c b/arch/mips/loongson/common/platform.c new file mode 100644 index 0000000..be81777 --- /dev/null +++ b/arch/mips/loongson/common/platform.c @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2009 Lemote Inc. + * Author: Wu Zhangjin, wuzj@lemote.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. + */ + +#include +#include + +static struct platform_device loongson2_cpufreq_device = { + .name = "loongson2_cpufreq", + .id = -1, +}; + +static int __init loongson2_cpufreq_init(void) +{ + struct cpuinfo_mips *c = ¤t_cpu_data; + + /* Only 2F revision and it's successors support CPUFreq */ + if ((c->processor_id & PRID_REV_MASK) >= PRID_REV_LOONGSON2F) + return platform_device_register(&loongson2_cpufreq_device); + + return -ENODEV; +} + +arch_initcall(loongson2_cpufreq_init); -- cgit v0.10.2 From 8922f79ee56e9dab6fc144defc0bc901ff0a7f8a Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 17 Nov 2009 22:51:03 +0000 Subject: MIPS: Fixup last users of irq_chip->typename The typename member of struct irq_chip was kept for migration purposes and is obsolete since more than 2 years. Fix up the leftovers. Signed-off-by: Thomas Gleixner Cc: linux-mips@linux-mips.org To: LKML Cc: Ingo Molnar Patchwork: http://patchwork.linux-mips.org/patch/661/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/nxp/pnx833x/common/interrupts.c b/arch/mips/nxp/pnx833x/common/interrupts.c index 30533ba..3a467c0 100644 --- a/arch/mips/nxp/pnx833x/common/interrupts.c +++ b/arch/mips/nxp/pnx833x/common/interrupts.c @@ -295,7 +295,7 @@ static int pnx833x_set_type_gpio_irq(unsigned int irq, unsigned int flow_type) } static struct irq_chip pnx833x_pic_irq_type = { - .typename = "PNX-PIC", + .name = "PNX-PIC", .startup = pnx833x_startup_pic_irq, .shutdown = pnx833x_shutdown_pic_irq, .enable = pnx833x_enable_pic_irq, @@ -305,7 +305,7 @@ static struct irq_chip pnx833x_pic_irq_type = { }; static struct irq_chip pnx833x_gpio_irq_type = { - .typename = "PNX-GPIO", + .name = "PNX-GPIO", .startup = pnx833x_startup_gpio_irq, .shutdown = pnx833x_disable_gpio_irq, .enable = pnx833x_enable_gpio_irq, diff --git a/arch/mips/sni/a20r.c b/arch/mips/sni/a20r.c index 7dd76fb..e698089 100644 --- a/arch/mips/sni/a20r.c +++ b/arch/mips/sni/a20r.c @@ -188,7 +188,7 @@ static void end_a20r_irq(unsigned int irq) } static struct irq_chip a20r_irq_type = { - .typename = "A20R", + .name = "A20R", .ack = mask_a20r_irq, .mask = mask_a20r_irq, .mask_ack = mask_a20r_irq, diff --git a/arch/mips/sni/pcimt.c b/arch/mips/sni/pcimt.c index 74e6c67..51e62bb 100644 --- a/arch/mips/sni/pcimt.c +++ b/arch/mips/sni/pcimt.c @@ -214,7 +214,7 @@ static void end_pcimt_irq(unsigned int irq) } static struct irq_chip pcimt_irq_type = { - .typename = "PCIMT", + .name = "PCIMT", .ack = disable_pcimt_irq, .mask = disable_pcimt_irq, .mask_ack = disable_pcimt_irq, diff --git a/arch/mips/sni/pcit.c b/arch/mips/sni/pcit.c index 071a957..f4699d3 100644 --- a/arch/mips/sni/pcit.c +++ b/arch/mips/sni/pcit.c @@ -176,7 +176,7 @@ void end_pcit_irq(unsigned int irq) } static struct irq_chip pcit_irq_type = { - .typename = "PCIT", + .name = "PCIT", .ack = disable_pcit_irq, .mask = disable_pcit_irq, .mask_ack = disable_pcit_irq, diff --git a/arch/mips/sni/rm200.c b/arch/mips/sni/rm200.c index 5e68781..46f0069 100644 --- a/arch/mips/sni/rm200.c +++ b/arch/mips/sni/rm200.c @@ -449,7 +449,7 @@ void end_rm200_irq(unsigned int irq) } static struct irq_chip rm200_irq_type = { - .typename = "RM200", + .name = "RM200", .ack = disable_rm200_irq, .mask = disable_rm200_irq, .mask_ack = disable_rm200_irq, -- cgit v0.10.2 From d2bb0762993e11363d8343127516b8fe88f9006f Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Fri, 20 Nov 2009 20:34:29 +0800 Subject: MIPS: Tracing: Add static function tracer support for MIPS If -pg of gcc is enabled with CONFIG_FUNCTION_TRACER=y. a calling to _mcount will be inserted into each kernel function. so, there is a possibility to trace the kernel functions in _mcount. This patch add the MIPS specific _mcount support for static function tracing. by default, ftrace_trace_function is initialized as ftrace_stub(an empty function), so, the default _mcount will introduce very little overhead. after enabling ftrace in user-space, it will jump to a real tracing function and do static function tracing for us. and -ffunction-sections is incompatible with -pg, so, disable it when ftracer is enabled. Signed-off-by: Wu Zhangjin Reviewed-by: Steven Rostedt Cc: Nicholas Mc Guire Cc: zhangfx@lemote.com Cc: Wu Zhangjin Cc: Ingo Molnar Cc: Thomas Gleixner Cc: Frederic Weisbecker Cc: linux-kernel@vger.kernel.org Cc: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/672/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 435838e..632dba2 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -5,6 +5,7 @@ config MIPS select HAVE_IDE select HAVE_OPROFILE select HAVE_ARCH_KGDB + select HAVE_FUNCTION_TRACER # Horrible source of confusion. Die, die, die ... select EMBEDDED select RTC_LIB if !MACH_LOONGSON diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 0a7e614..3725ee9 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -48,7 +48,9 @@ ifneq ($(SUBARCH),$(ARCH)) endif endif +ifndef CONFIG_FUNCTION_TRACER cflags-y := -ffunction-sections +endif cflags-y += $(call cc-option, -mno-check-zero-division) ifdef CONFIG_32BIT diff --git a/arch/mips/include/asm/ftrace.h b/arch/mips/include/asm/ftrace.h index 40a8c17..5f8ebcf 100644 --- a/arch/mips/include/asm/ftrace.h +++ b/arch/mips/include/asm/ftrace.h @@ -1 +1,24 @@ -/* empty */ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive for + * more details. + * + * Copyright (C) 2009 DSLab, Lanzhou University, China + * Author: Wu Zhangjin + */ + +#ifndef _ASM_MIPS_FTRACE_H +#define _ASM_MIPS_FTRACE_H + +#ifdef CONFIG_FUNCTION_TRACER + +#define MCOUNT_ADDR ((unsigned long)(_mcount)) +#define MCOUNT_INSN_SIZE 4 /* sizeof mcount call */ + +#ifndef __ASSEMBLY__ +extern void _mcount(void); +#define mcount _mcount + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_FUNCTION_TRACER */ +#endif /* _ASM_MIPS_FTRACE_H */ diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index f442de8..1340ba3 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -10,6 +10,10 @@ obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \ ptrace.o reset.o setup.o signal.o syscall.o \ time.o topology.o traps.o unaligned.o watch.o +ifdef CONFIG_FUNCTION_TRACER +CFLAGS_REMOVE_early_printk.o = -pg +endif + obj-$(CONFIG_CEVT_BCM1480) += cevt-bcm1480.o obj-$(CONFIG_CEVT_R4K_LIB) += cevt-r4k.o obj-$(CONFIG_MIPS_MT_SMTC) += cevt-smtc.o @@ -27,6 +31,8 @@ obj-$(CONFIG_SYNC_R4K) += sync-r4k.o obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-$(CONFIG_MODULES) += mips_ksyms.o module.o +obj-$(CONFIG_FUNCTION_TRACER) += mcount.o + obj-$(CONFIG_CPU_LOONGSON2) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_MIPS32) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_MIPS64) += r4k_fpu.o r4k_switch.o diff --git a/arch/mips/kernel/mcount.S b/arch/mips/kernel/mcount.S new file mode 100644 index 0000000..cebcc3c --- /dev/null +++ b/arch/mips/kernel/mcount.S @@ -0,0 +1,83 @@ +/* + * MIPS specific _mcount support + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive for + * more details. + * + * Copyright (C) 2009 Lemote Inc. & DSLab, Lanzhou University, China + * Author: Wu Zhangjin + */ + +#include +#include +#include + + .text + .set noreorder + .set noat + + .macro MCOUNT_SAVE_REGS + PTR_SUBU sp, PT_SIZE + PTR_S ra, PT_R31(sp) + PTR_S AT, PT_R1(sp) + PTR_S a0, PT_R4(sp) + PTR_S a1, PT_R5(sp) + PTR_S a2, PT_R6(sp) + PTR_S a3, PT_R7(sp) +#ifdef CONFIG_64BIT + PTR_S a4, PT_R8(sp) + PTR_S a5, PT_R9(sp) + PTR_S a6, PT_R10(sp) + PTR_S a7, PT_R11(sp) +#endif + .endm + + .macro MCOUNT_RESTORE_REGS + PTR_L ra, PT_R31(sp) + PTR_L AT, PT_R1(sp) + PTR_L a0, PT_R4(sp) + PTR_L a1, PT_R5(sp) + PTR_L a2, PT_R6(sp) + PTR_L a3, PT_R7(sp) +#ifdef CONFIG_64BIT + PTR_L a4, PT_R8(sp) + PTR_L a5, PT_R9(sp) + PTR_L a6, PT_R10(sp) + PTR_L a7, PT_R11(sp) +#endif +#ifdef CONFIG_64BIT + PTR_ADDIU sp, PT_SIZE +#else + PTR_ADDIU sp, (PT_SIZE + 8) +#endif +.endm + + .macro RETURN_BACK + jr ra + move ra, AT + .endm + +NESTED(_mcount, PT_SIZE, ra) + PTR_LA t0, ftrace_stub + PTR_L t1, ftrace_trace_function /* Prepare t1 for (1) */ + bne t0, t1, static_trace + nop + b ftrace_stub + nop + +static_trace: + MCOUNT_SAVE_REGS + + move a0, ra /* arg1: next ip, selfaddr */ + jalr t1 /* (1) call *ftrace_trace_function */ + move a1, AT /* arg2: the caller's next ip, parent */ + + MCOUNT_RESTORE_REGS + .globl ftrace_stub +ftrace_stub: + RETURN_BACK + END(_mcount) + + .set at + .set reorder diff --git a/arch/mips/kernel/mips_ksyms.c b/arch/mips/kernel/mips_ksyms.c index 225755d..1d04807 100644 --- a/arch/mips/kernel/mips_ksyms.c +++ b/arch/mips/kernel/mips_ksyms.c @@ -13,6 +13,7 @@ #include #include #include +#include extern void *__bzero(void *__s, size_t __count); extern long __strncpy_from_user_nocheck_asm(char *__to, @@ -51,3 +52,7 @@ EXPORT_SYMBOL(csum_partial_copy_nocheck); EXPORT_SYMBOL(__csum_partial_copy_user); EXPORT_SYMBOL(invalid_pte_table); +#ifdef CONFIG_FUNCTION_TRACER +/* _mcount is defined in arch/mips/kernel/mcount.S */ +EXPORT_SYMBOL(_mcount); +#endif -- cgit v0.10.2 From 69a7d1b3ec64786cfc8a16ef3e8585d1f93d3944 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Fri, 20 Nov 2009 20:34:30 +0800 Subject: MIPS: Tracing: Enable HAVE_FUNCTION_TRACE_MCOUNT_TEST for MIPS There is an exisiting common ftrace_test_stop_func() in kernel/trace/ftrace.c, which is used to check the global variable ftrace_trace_stop to determine whether stop the function tracing. This patch implepment the MIPS specific one to speedup the procedure. Thanks goes to Zhang Le for Cleaning it up. Signed-off-by: Wu Zhangjin Cc: Steven Rostedt Cc: Nicholas Mc Guire Cc: zhangfx@lemote.com Cc: Wu Zhangjin Cc: Ingo Molnar Cc: Thomas Gleixner Cc: Frederic Weisbecker Cc: linux-kernel@vger.kernel.org Cc: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/673/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 632dba2..d203dbf 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -6,6 +6,7 @@ config MIPS select HAVE_OPROFILE select HAVE_ARCH_KGDB select HAVE_FUNCTION_TRACER + select HAVE_FUNCTION_TRACE_MCOUNT_TEST # Horrible source of confusion. Die, die, die ... select EMBEDDED select RTC_LIB if !MACH_LOONGSON diff --git a/arch/mips/kernel/mcount.S b/arch/mips/kernel/mcount.S index cebcc3c..cbb45ed 100644 --- a/arch/mips/kernel/mcount.S +++ b/arch/mips/kernel/mcount.S @@ -59,6 +59,9 @@ .endm NESTED(_mcount, PT_SIZE, ra) + lw t0, function_trace_stop + bnez t0, ftrace_stub + nop PTR_LA t0, ftrace_stub PTR_L t1, ftrace_trace_function /* Prepare t1 for (1) */ bne t0, t1, static_trace -- cgit v0.10.2 From e6299d2677e600f6a0bf93bbb89f20d3de5252de Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Fri, 20 Nov 2009 20:34:31 +0800 Subject: MIPS: Tracing: Add an endian argument to scripts/recordmcount.pl MIPS and some other architectures need this argument to handle big/little endian respectively. Signed-off-by: Wu Zhangjin Cc: Nicholas Mc Guire Cc: zhangfx@lemote.com Cc: Wu Zhangjin Cc: Ingo Molnar Cc: Thomas Gleixner Cc: Frederic Weisbecker Cc: linux-kernel@vger.kernel.org Cc: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/674/ Acked-by: Steven Rostedt Signed-off-by: Ralf Baechle diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 341b589..0b94d2f 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -207,6 +207,7 @@ endif ifdef CONFIG_FTRACE_MCOUNT_RECORD cmd_record_mcount = set -e ; perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" \ + "$(if $(CONFIG_CPU_BIG_ENDIAN),big,little)" \ "$(if $(CONFIG_64BIT),64,32)" \ "$(OBJDUMP)" "$(OBJCOPY)" "$(CC)" "$(LD)" "$(NM)" "$(RM)" "$(MV)" \ "$(if $(part-of-module),1,0)" "$(@)"; diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl index 9cf0a6f..ab368e8 100755 --- a/scripts/recordmcount.pl +++ b/scripts/recordmcount.pl @@ -113,13 +113,13 @@ $P =~ s@.*/@@g; my $V = '0.1'; -if ($#ARGV != 10) { - print "usage: $P arch bits objdump objcopy cc ld nm rm mv is_module inputfile\n"; +if ($#ARGV != 11) { + print "usage: $P arch endian bits objdump objcopy cc ld nm rm mv is_module inputfile\n"; print "version: $V\n"; exit(1); } -my ($arch, $bits, $objdump, $objcopy, $cc, +my ($arch, $endian, $bits, $objdump, $objcopy, $cc, $ld, $nm, $rm, $mv, $is_module, $inputfile) = @ARGV; # This file refers to mcount and shouldn't be ftraced, so lets' ignore it -- cgit v0.10.2 From 538f19526e40ce7a5a296fad6a3121409c890adc Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Fri, 20 Nov 2009 20:34:32 +0800 Subject: MIPS: Tracing: Add dynamic function tracer support With dynamic function tracer, by default, _mcount is defined as an "empty" function, it returns directly without any more action . When enabling it in user-space, it will jump to a real tracing function(ftrace_caller), and do the real job for us. Differ from the static function tracer, dynamic function tracer provides two functions ftrace_make_call()/ftrace_make_nop() to enable/disable the tracing of some indicated kernel functions(set_ftrace_filter). In the -v4 version, the implementation of this support is basically the same as X86 version does: _mcount is implemented as an empty function and ftrace_caller is implemented as a real tracing function respectively. But in this version, to support module tracing with the help of -mlong-calls in arch/mips/Makefile: MODFLAGS += -mlong-calls. The stuff becomes a little more complex. We need to cope with two different type of calling to _mcount. For the kernel part, the calling to _mcount(result of "objdump -hdr vmlinux"). is like this: 108: 03e0082d move at,ra 10c: 0c000000 jal 0 10c: R_MIPS_26 _mcount 10c: R_MIPS_NONE *ABS* 10c: R_MIPS_NONE *ABS* 110: 00020021 nop For the module with -mlong-calls, it looks like this: c: 3c030000 lui v1,0x0 c: R_MIPS_HI16 _mcount c: R_MIPS_NONE *ABS* c: R_MIPS_NONE *ABS* 10: 64630000 daddiu v1,v1,0 10: R_MIPS_LO16 _mcount 10: R_MIPS_NONE *ABS* 10: R_MIPS_NONE *ABS* 14: 03e0082d move at,ra 18: 0060f809 jalr v1 In the kernel version, there is only one "_mcount" string for every kernel function, so, we just need to match this one in mcount_regex of scripts/recordmcount.pl, but in the module version, we need to choose one of the two to match. Herein, I choose the first one with "R_MIPS_HI16 _mcount". and In the kernel verion, without module tracing support, we just need to replace "jal _mcount" by "jal ftrace_caller" to do real tracing, and filter the tracing of some kernel functions via replacing it by a nop instruction. but as we have described before, the instruction "jal ftrace_caller" only left 32bit length for the address of ftrace_caller, it will fail when calling from the module space. so, herein, we must replace something else. the basic idea is loading the address of ftrace_caller to v1 via changing these two instructions: lui v1,0x0 addiu v1,v1,0 If we want to enable the tracing, we need to replace the above instructions to: lui v1, HI_16BIT_ftrace_caller addiu v1, v1, LOW_16BIT_ftrace_caller If we want to stop the tracing of the indicated kernel functions, we just need to replace the "jalr v1" to a nop instruction. but we need to replace two instructions and encode the above two instructions oursevles. Is there a simpler solution? Yes! Here it is, in this version, we put _mcount and ftrace_caller together, which means the address of _mcount and ftrace_caller is the same: _mcount: ftrace_caller: j ftrace_stub nop ...(do real tracing here)... ftrace_stub: jr ra move ra, at By default, the kernel functions call _mcount, and then jump to ftrace_stub and return. and when we want to do real tracing, we just need to remove that "j ftrace_stub", and it will run through the two "nop" instructions and then do the real tracing job. what about filtering job? we just need to do this: lui v1, hi_16bit_of_mcount <--> b 1f (0x10000004) addiu v1, v1, low_16bit_of_mcount move at, ra jalr v1 nop 1f: (rec->ip + 12) In linux-mips64, there will be some local symbols, whose name are prefixed by $L, which need to be filtered. thanks goes to Steven for writing the mips64-specific function_regex. In a conclusion, with RISC, things becomes easier with such a "stupid" trick, RISC is something like K.I.S.S, and also, there are lots of "simple" tricks in the whole ftrace support, thanks goes to Steven and the other folks for providing such a wonderful tracing framework! Signed-off-by: Wu Zhangjin Cc: Nicholas Mc Guire Cc: zhangfx@lemote.com Cc: Wu Zhangjin Cc: Ingo Molnar Cc: Thomas Gleixner Cc: Frederic Weisbecker Cc: linux-kernel@vger.kernel.org Cc: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/675/ Acked-by: Steven Rostedt Signed-off-by: Ralf Baechle diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index d203dbf..af6940c 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -7,6 +7,8 @@ config MIPS select HAVE_ARCH_KGDB select HAVE_FUNCTION_TRACER select HAVE_FUNCTION_TRACE_MCOUNT_TEST + select HAVE_DYNAMIC_FTRACE + select HAVE_FTRACE_MCOUNT_RECORD # Horrible source of confusion. Die, die, die ... select EMBEDDED select RTC_LIB if !MACH_LOONGSON diff --git a/arch/mips/include/asm/ftrace.h b/arch/mips/include/asm/ftrace.h index 5f8ebcf..7094a40 100644 --- a/arch/mips/include/asm/ftrace.h +++ b/arch/mips/include/asm/ftrace.h @@ -19,6 +19,15 @@ extern void _mcount(void); #define mcount _mcount +#ifdef CONFIG_DYNAMIC_FTRACE +static inline unsigned long ftrace_call_adjust(unsigned long addr) +{ + return addr; +} + +struct dyn_arch_ftrace { +}; +#endif /* CONFIG_DYNAMIC_FTRACE */ #endif /* __ASSEMBLY__ */ #endif /* CONFIG_FUNCTION_TRACER */ #endif /* _ASM_MIPS_FTRACE_H */ diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index 1340ba3..8dda214 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -11,6 +11,7 @@ obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \ time.o topology.o traps.o unaligned.o watch.o ifdef CONFIG_FUNCTION_TRACER +CFLAGS_REMOVE_ftrace.o = -pg CFLAGS_REMOVE_early_printk.o = -pg endif @@ -31,7 +32,7 @@ obj-$(CONFIG_SYNC_R4K) += sync-r4k.o obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-$(CONFIG_MODULES) += mips_ksyms.o module.o -obj-$(CONFIG_FUNCTION_TRACER) += mcount.o +obj-$(CONFIG_FUNCTION_TRACER) += mcount.o ftrace.o obj-$(CONFIG_CPU_LOONGSON2) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_MIPS32) += r4k_fpu.o r4k_switch.o diff --git a/arch/mips/kernel/ftrace.c b/arch/mips/kernel/ftrace.c new file mode 100644 index 0000000..5459a78 --- /dev/null +++ b/arch/mips/kernel/ftrace.c @@ -0,0 +1,112 @@ +/* + * Code for replacing ftrace calls with jumps. + * + * Copyright (C) 2007-2008 Steven Rostedt + * Copyright (C) 2009 DSLab, Lanzhou University, China + * Author: Wu Zhangjin + * + * Thanks goes to Steven Rostedt for writing the original x86 version. + */ + +#include +#include +#include + +#include + +#ifdef CONFIG_DYNAMIC_FTRACE + +#define JAL 0x0c000000 /* jump & link: ip --> ra, jump to target */ +#define ADDR_MASK 0x03ffffff /* op_code|addr : 31...26|25 ....0 */ +#define jump_insn_encode(op_code, addr) \ + ((unsigned int)((op_code) | (((addr) >> 2) & ADDR_MASK))) + +static unsigned int ftrace_nop = 0x00000000; + +static int ftrace_modify_code(unsigned long ip, unsigned int new_code) +{ + *(unsigned int *)ip = new_code; + + flush_icache_range(ip, ip + 8); + + return 0; +} + +static int lui_v1; +static int jal_mcount; + +int ftrace_make_nop(struct module *mod, + struct dyn_ftrace *rec, unsigned long addr) +{ + unsigned int new; + unsigned long ip = rec->ip; + + /* We have compiled module with -mlong-calls, but compiled the kernel + * without it, we need to cope with them respectively. */ + if (ip & 0x40000000) { + /* record it for ftrace_make_call */ + if (lui_v1 == 0) + lui_v1 = *(unsigned int *)ip; + + /* lui v1, hi_16bit_of_mcount --> b 1f (0x10000004) + * addiu v1, v1, low_16bit_of_mcount + * move at, ra + * jalr v1 + * nop + * 1f: (ip + 12) + */ + new = 0x10000004; + } else { + /* record/calculate it for ftrace_make_call */ + if (jal_mcount == 0) { + /* We can record it directly like this: + * jal_mcount = *(unsigned int *)ip; + * Herein, jump over the first two nop instructions */ + jal_mcount = jump_insn_encode(JAL, (MCOUNT_ADDR + 8)); + } + + /* move at, ra + * jalr v1 --> nop + */ + new = ftrace_nop; + } + return ftrace_modify_code(ip, new); +} + +static int modified; /* initialized as 0 by default */ + +int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) +{ + unsigned int new; + unsigned long ip = rec->ip; + + /* We just need to remove the "b ftrace_stub" at the fist time! */ + if (modified == 0) { + modified = 1; + ftrace_modify_code(addr, ftrace_nop); + } + /* ip, module: 0xc0000000, kernel: 0x80000000 */ + new = (ip & 0x40000000) ? lui_v1 : jal_mcount; + + return ftrace_modify_code(ip, new); +} + +#define FTRACE_CALL_IP ((unsigned long)(&ftrace_call)) + +int ftrace_update_ftrace_func(ftrace_func_t func) +{ + unsigned int new; + + new = jump_insn_encode(JAL, (unsigned long)func); + + return ftrace_modify_code(FTRACE_CALL_IP, new); +} + +int __init ftrace_dyn_arch_init(void *data) +{ + /* The return code is retured via data */ + *(unsigned long *)data = 0; + + return 0; +} +#endif /* CONFIG_DYNAMIC_FTRACE */ diff --git a/arch/mips/kernel/mcount.S b/arch/mips/kernel/mcount.S index cbb45ed..ffc4259 100644 --- a/arch/mips/kernel/mcount.S +++ b/arch/mips/kernel/mcount.S @@ -58,6 +58,33 @@ move ra, AT .endm +#ifdef CONFIG_DYNAMIC_FTRACE + +NESTED(ftrace_caller, PT_SIZE, ra) + .globl _mcount +_mcount: + b ftrace_stub + nop + lw t0, function_trace_stop + bnez t0, ftrace_stub + nop + + MCOUNT_SAVE_REGS + + move a0, ra /* arg1: next ip, selfaddr */ + .globl ftrace_call +ftrace_call: + nop /* a placeholder for the call to a real tracing function */ + move a1, AT /* arg2: the caller's next ip, parent */ + + MCOUNT_RESTORE_REGS + .globl ftrace_stub +ftrace_stub: + RETURN_BACK + END(ftrace_caller) + +#else /* ! CONFIG_DYNAMIC_FTRACE */ + NESTED(_mcount, PT_SIZE, ra) lw t0, function_trace_stop bnez t0, ftrace_stub @@ -82,5 +109,7 @@ ftrace_stub: RETURN_BACK END(_mcount) +#endif /* ! CONFIG_DYNAMIC_FTRACE */ + .set at .set reorder diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl index ab368e8..92f09fe 100755 --- a/scripts/recordmcount.pl +++ b/scripts/recordmcount.pl @@ -295,6 +295,58 @@ if ($arch eq "x86_64") { $ld .= " -m elf64_sparc"; $cc .= " -m64"; $objcopy .= " -O elf64-sparc"; +} elsif ($arch eq "mips") { + # To enable module support, we need to enable the -mlong-calls option + # of gcc for module, after using this option, we can not get the real + # offset of the calling to _mcount, but the offset of the lui + # instruction or the addiu one. herein, we record the address of the + # first one, and then we can replace this instruction by a branch + # instruction to jump over the profiling function to filter the + # indicated functions, or swith back to the lui instruction to trace + # them, which means dynamic tracing. + # + # c: 3c030000 lui v1,0x0 + # c: R_MIPS_HI16 _mcount + # c: R_MIPS_NONE *ABS* + # c: R_MIPS_NONE *ABS* + # 10: 64630000 daddiu v1,v1,0 + # 10: R_MIPS_LO16 _mcount + # 10: R_MIPS_NONE *ABS* + # 10: R_MIPS_NONE *ABS* + # 14: 03e0082d move at,ra + # 18: 0060f809 jalr v1 + # + # for the kernel: + # + # 10: 03e0082d move at,ra + # 14: 0c000000 jal 0 + # 14: R_MIPS_26 _mcount + # 14: R_MIPS_NONE *ABS* + # 14: R_MIPS_NONE *ABS* + # 18: 00020021 nop + if ($is_module eq "0") { + $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s_mcount\$"; + } else { + $mcount_regex = "^\\s*([0-9a-fA-F]+): R_MIPS_HI16\\s+_mcount\$"; + } + $objdump .= " -Melf-trad".$endian."mips "; + + if ($endian eq "big") { + $endian = " -EB "; + $ld .= " -melf".$bits."btsmip"; + } else { + $endian = " -EL "; + $ld .= " -melf".$bits."ltsmip"; + } + + $cc .= " -mno-abicalls -fno-pic -mabi=" . $bits . $endian; + $ld .= $endian; + + if ($bits == 64) { + $function_regex = + "^([0-9a-fA-F]+)\\s+<(.|[^\$]L.*?|\$[^L].*?|[^\$][^L].*?)>:"; + $type = ".dword"; + } } elsif ($arch eq "microblaze") { # Microblaze calls '_mcount' instead of plain 'mcount'. $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s_mcount\$"; -- cgit v0.10.2 From 8f99a162653531ef25a3dd0f92bfb6332cd2b295 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Fri, 20 Nov 2009 20:34:33 +0800 Subject: MIPS: Tracing: Add IRQENTRY_EXIT section for MIPS This patch add a new section for MIPS to record the block of the hardirq handling for function graph tracer(print_graph_irq) via adding the __irq_entry annotation to the the entrypoints of the hardirqs(the block with irq_enter()...irq_exit()). Thanks goes to Steven & Frederic Weisbecker for their feedbacks. Signed-off-by: Wu Zhangjin Cc: Steven Rostedt Cc: Nicholas Mc Guire Cc: zhangfx@lemote.com Cc: Wu Zhangjin Cc: Ingo Molnar Cc: Thomas Gleixner Cc: Frederic Weisbecker Cc: linux-kernel@vger.kernel.org Cc: linux-mips@linux-mips.org Reviewed-by: Frederic Weisbecker Patchwork: http://patchwork.linux-mips.org/patch/676/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/include/asm/irq.h b/arch/mips/include/asm/irq.h index 09b08d0..0696036 100644 --- a/arch/mips/include/asm/irq.h +++ b/arch/mips/include/asm/irq.h @@ -113,36 +113,11 @@ do { \ #endif -/* - * do_IRQ handles all normal device IRQ's (the special - * SMP cross-CPU interrupts have their own specific - * handlers). - * - * Ideally there should be away to get this into kernel/irq/handle.c to - * avoid the overhead of a call for just a tiny function ... - */ -#define do_IRQ(irq) \ -do { \ - irq_enter(); \ - __DO_IRQ_SMTC_HOOK(irq); \ - generic_handle_irq(irq); \ - irq_exit(); \ -} while (0) +extern void do_IRQ(unsigned int irq); #ifdef CONFIG_MIPS_MT_SMTC_IRQAFF -/* - * To avoid inefficient and in some cases pathological re-checking of - * IRQ affinity, we have this variant that skips the affinity check. - */ - -#define do_IRQ_no_affinity(irq) \ -do { \ - irq_enter(); \ - __NO_AFFINITY_IRQ_SMTC_HOOK(irq); \ - generic_handle_irq(irq); \ - irq_exit(); \ -} while (0) +extern void do_IRQ_no_affinity(unsigned int irq); #endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */ diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c index 8b0b418..981f86c 100644 --- a/arch/mips/kernel/irq.c +++ b/arch/mips/kernel/irq.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -150,3 +151,32 @@ void __init init_IRQ(void) kgdb_early_setup = 1; #endif } + +/* + * do_IRQ handles all normal device IRQ's (the special + * SMP cross-CPU interrupts have their own specific + * handlers). + */ +void __irq_entry do_IRQ(unsigned int irq) +{ + irq_enter(); + __DO_IRQ_SMTC_HOOK(irq); + generic_handle_irq(irq); + irq_exit(); +} + +#ifdef CONFIG_MIPS_MT_SMTC_IRQAFF +/* + * To avoid inefficient and in some cases pathological re-checking of + * IRQ affinity, we have this variant that skips the affinity check. + */ + +void __irq_entry do_IRQ_no_affinity(unsigned int irq) +{ + irq_enter(); + __NO_AFFINITY_IRQ_SMTC_HOOK(irq); + generic_handle_irq(irq); + irq_exit(); +} + +#endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */ diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index e72e684..6cdca19 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -130,7 +131,7 @@ asmlinkage __cpuinit void start_secondary(void) /* * Call into both interrupt handlers, as we share the IPI for them */ -void smp_call_function_interrupt(void) +void __irq_entry smp_call_function_interrupt(void) { irq_enter(); generic_smp_call_function_single_interrupt(); diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c index a38e3ee..23499b5 100644 --- a/arch/mips/kernel/smtc.c +++ b/arch/mips/kernel/smtc.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -939,23 +940,29 @@ static void ipi_call_interrupt(void) DECLARE_PER_CPU(struct clock_event_device, mips_clockevent_device); -void ipi_decode(struct smtc_ipi *pipi) +static void __irq_entry smtc_clock_tick_interrupt(void) { unsigned int cpu = smp_processor_id(); struct clock_event_device *cd; + int irq = MIPS_CPU_IRQ_BASE + 1; + + irq_enter(); + kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq)); + cd = &per_cpu(mips_clockevent_device, cpu); + cd->event_handler(cd); + irq_exit(); +} + +void ipi_decode(struct smtc_ipi *pipi) +{ void *arg_copy = pipi->arg; int type_copy = pipi->type; - int irq = MIPS_CPU_IRQ_BASE + 1; smtc_ipi_nq(&freeIPIq, pipi); switch (type_copy) { case SMTC_CLOCK_TICK: - irq_enter(); - kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq)); - cd = &per_cpu(mips_clockevent_device, cpu); - cd->event_handler(cd); - irq_exit(); + smtc_clock_tick_interrupt(); break; case LINUX_SMP_IPI: diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S index 162b299..f25df73 100644 --- a/arch/mips/kernel/vmlinux.lds.S +++ b/arch/mips/kernel/vmlinux.lds.S @@ -46,6 +46,7 @@ SECTIONS SCHED_TEXT LOCK_TEXT KPROBES_TEXT + IRQENTRY_TEXT *(.text.*) *(.fixup) *(.gnu.warning) diff --git a/arch/mips/sgi-ip22/ip22-int.c b/arch/mips/sgi-ip22/ip22-int.c index 0ecd5fe..383f11d 100644 --- a/arch/mips/sgi-ip22/ip22-int.c +++ b/arch/mips/sgi-ip22/ip22-int.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -150,7 +151,7 @@ static void indy_local1_irqdispatch(void) extern void ip22_be_interrupt(int irq); -static void indy_buserror_irq(void) +static void __irq_entry indy_buserror_irq(void) { int irq = SGI_BUSERR_IRQ; diff --git a/arch/mips/sgi-ip22/ip22-time.c b/arch/mips/sgi-ip22/ip22-time.c index c8f7d23..603fc91 100644 --- a/arch/mips/sgi-ip22/ip22-time.c +++ b/arch/mips/sgi-ip22/ip22-time.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -115,7 +116,7 @@ __init void plat_time_init(void) } /* Generic SGI handler for (spurious) 8254 interrupts */ -void indy_8254timer_irq(void) +void __irq_entry indy_8254timer_irq(void) { int irq = SGI_8254_0_IRQ; ULONG cnt; -- cgit v0.10.2 From 29c5d3462f7c8f17bb9e0a29f0a299036468074d Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Fri, 20 Nov 2009 20:34:34 +0800 Subject: MIPS: Tracing: Add function graph tracer support for MIPS The implementation of function graph tracer for MIPS is a little different from X86. in MIPS, gcc(with -pg) only transfer the caller's return address(at) and the _mcount's return address(ra) to us. For the kernel part without -mlong-calls: move at, ra jal _mcount For the module part with -mlong-calls: lui v1, hi16bit_of_mcount addiu v1, v1, low16bit_of_mcount move at, ra jal _mcount Without -mlong-calls, if the function is a leaf, it will not save the return address(ra): ffffffff80101298 : ffffffff80101298: 67bdfff0 daddiu sp,sp,-16 ffffffff8010129c: ffbe0008 sd s8,8(sp) ffffffff801012a0: 03a0f02d move s8,sp ffffffff801012a4: 03e0082d move at,ra ffffffff801012a8: 0c042930 jal ffffffff8010a4c0 <_mcount> ffffffff801012ac: 00020021 nop so, we can hijack it directly in _mcount, but if the function is non-leaf, the return address is saved in the stack. ffffffff80133030 : ffffffff80133030: 67bdff50 daddiu sp,sp,-176 ffffffff80133034: ffbe00a0 sd s8,160(sp) ffffffff80133038: 03a0f02d move s8,sp ffffffff8013303c: ffbf00a8 sd ra,168(sp) ffffffff80133040: ffb70098 sd s7,152(sp) ffffffff80133044: ffb60090 sd s6,144(sp) ffffffff80133048: ffb50088 sd s5,136(sp) ffffffff8013304c: ffb40080 sd s4,128(sp) ffffffff80133050: ffb30078 sd s3,120(sp) ffffffff80133054: ffb20070 sd s2,112(sp) ffffffff80133058: ffb10068 sd s1,104(sp) ffffffff8013305c: ffb00060 sd s0,96(sp) ffffffff80133060: 03e0082d move at,ra ffffffff80133064: 0c042930 jal ffffffff8010a4c0 <_mcount> ffffffff80133068: 00020021 nop but we can not get the exact stack address(which saved ra) directly in _mcount, we need to search the content of at register in the stack space or search the "s{d,w} ra, offset(sp)" instruction in the text. 'Cause we can not prove there is only a match in the stack space, so, we search the text instead. as we can see, if the first instruction above "move at, ra" is not a store instruction, there should be a leaf function, so we hijack the at register directly via putting &return_to_handler into it, otherwise, we search the "s{d,w} ra, offset(sp)" instruction to get the stack offset, and then the stack address. we use the above copy_process() as an example, we at last find "ffbf00a8", 0xa8 is the stack offset, we plus it with s8(fp), that is the stack address, we hijack the content via writing the &return_to_handler in. If with -mlong-calls, since there are two more instructions above "move at, ra", so, we can move the pointer to the position above "lui v1, hi16bit_of_mcount". Signed-off-by: Wu Zhangjin Cc: Steven Rostedt Cc: Nicholas Mc Guire Cc: zhangfx@lemote.com Cc: Wu Zhangjin Cc: Ingo Molnar Cc: Thomas Gleixner Cc: Frederic Weisbecker Cc: linux-kernel@vger.kernel.org Cc: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/677/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index af6940c..2906ae5 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -9,6 +9,7 @@ config MIPS select HAVE_FUNCTION_TRACE_MCOUNT_TEST select HAVE_DYNAMIC_FTRACE select HAVE_FTRACE_MCOUNT_RECORD + select HAVE_FUNCTION_GRAPH_TRACER # Horrible source of confusion. Die, die, die ... select EMBEDDED select RTC_LIB if !MACH_LOONGSON diff --git a/arch/mips/kernel/ftrace.c b/arch/mips/kernel/ftrace.c index 5459a78..65a3f8a 100644 --- a/arch/mips/kernel/ftrace.c +++ b/arch/mips/kernel/ftrace.c @@ -13,6 +13,8 @@ #include #include +#include +#include #ifdef CONFIG_DYNAMIC_FTRACE @@ -110,3 +112,107 @@ int __init ftrace_dyn_arch_init(void *data) return 0; } #endif /* CONFIG_DYNAMIC_FTRACE */ + +#ifdef CONFIG_FUNCTION_GRAPH_TRACER + +#define S_RA_SP (0xafbf << 16) /* s{d,w} ra, offset(sp) */ +#define S_R_SP (0xafb0 << 16) /* s{d,w} R, offset(sp) */ +#define OFFSET_MASK 0xffff /* stack offset range: 0 ~ PT_SIZE */ + +unsigned long ftrace_get_parent_addr(unsigned long self_addr, + unsigned long parent, + unsigned long parent_addr, + unsigned long fp) +{ + unsigned long sp, ip, ra; + unsigned int code; + + /* in module or kernel? */ + if (self_addr & 0x40000000) { + /* module: move to the instruction "lui v1, HI_16BIT_OF_MCOUNT" */ + ip = self_addr - 20; + } else { + /* kernel: move to the instruction "move ra, at" */ + ip = self_addr - 12; + } + + /* search the text until finding the non-store instruction or "s{d,w} + * ra, offset(sp)" instruction */ + do { + ip -= 4; + + /* get the code at "ip" */ + code = *(unsigned int *)ip; + + /* If we hit the non-store instruction before finding where the + * ra is stored, then this is a leaf function and it does not + * store the ra on the stack. */ + if ((code & S_R_SP) != S_R_SP) + return parent_addr; + + } while (((code & S_RA_SP) != S_RA_SP)); + + sp = fp + (code & OFFSET_MASK); + ra = *(unsigned long *)sp; + + if (ra == parent) + return sp; + + return 0; +} + +/* + * Hook the return address and push it in the stack of return addrs + * in current thread info. + */ +void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr, + unsigned long fp) +{ + unsigned long old; + struct ftrace_graph_ent trace; + unsigned long return_hooker = (unsigned long) + &return_to_handler; + + if (unlikely(atomic_read(¤t->tracing_graph_pause))) + return; + + /* "parent" is the stack address saved the return address of the caller + * of _mcount, for a leaf function not save the return address in the + * stack address, so, we "emulate" one in _mcount's stack space, and + * hijack it directly, but for a non-leaf function, it will save the + * return address to the its stack space, so, we can not hijack the + * "parent" directly, but need to find the real stack address, + * ftrace_get_parent_addr() does it! + */ + + old = *parent; + + parent = (unsigned long *)ftrace_get_parent_addr(self_addr, old, + (unsigned long)parent, + fp); + + /* If fails when getting the stack address of the non-leaf function's + * ra, stop function graph tracer and return */ + if (parent == 0) { + ftrace_graph_stop(); + WARN_ON(1); + return; + } + + *parent = return_hooker; + + if (ftrace_push_return_trace(old, self_addr, &trace.depth, fp) == + -EBUSY) { + *parent = old; + return; + } + + trace.func = self_addr; + + /* Only trace if the calling function expects to */ + if (!ftrace_graph_entry(&trace)) { + current->curr_ret_stack--; + *parent = old; + } +} +#endif /* CONFIG_FUNCTION_GRAPH_TRACER */ diff --git a/arch/mips/kernel/mcount.S b/arch/mips/kernel/mcount.S index ffc4259..b50e38d8 100644 --- a/arch/mips/kernel/mcount.S +++ b/arch/mips/kernel/mcount.S @@ -93,6 +93,16 @@ NESTED(_mcount, PT_SIZE, ra) PTR_L t1, ftrace_trace_function /* Prepare t1 for (1) */ bne t0, t1, static_trace nop + +#ifdef CONFIG_FUNCTION_GRAPH_TRACER + PTR_L t2, ftrace_graph_return + bne t0, t2, ftrace_graph_caller + nop + PTR_LA t0, ftrace_graph_entry_stub + PTR_L t2, ftrace_graph_entry + bne t0, t2, ftrace_graph_caller + nop +#endif b ftrace_stub nop @@ -111,5 +121,37 @@ ftrace_stub: #endif /* ! CONFIG_DYNAMIC_FTRACE */ +#ifdef CONFIG_FUNCTION_GRAPH_TRACER + +NESTED(ftrace_graph_caller, PT_SIZE, ra) + MCOUNT_SAVE_REGS + + PTR_LA a0, PT_R1(sp) /* arg1: &AT -> a0 */ + move a1, ra /* arg2: next ip, selfaddr */ + jal prepare_ftrace_return + move a2, fp /* arg3: frame pointer */ + + MCOUNT_RESTORE_REGS + RETURN_BACK + END(ftrace_graph_caller) + + .align 2 + .globl return_to_handler +return_to_handler: + PTR_SUBU sp, PT_SIZE + PTR_S v0, PT_R2(sp) + + jal ftrace_return_to_handler + PTR_S v1, PT_R3(sp) + + /* restore the real parent address: v0 -> ra */ + move ra, v0 + + PTR_L v0, PT_R2(sp) + PTR_L v1, PT_R3(sp) + jr ra + PTR_ADDIU sp, PT_SIZE +#endif /* CONFIG_FUNCTION_GRAPH_TRACER */ + .set at .set reorder -- cgit v0.10.2 From e17ff5fec65a0213416efbe7ceae5f2f9887dda2 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Fri, 20 Nov 2009 20:34:35 +0800 Subject: MIPS: Tracing: Add dynamic function graph tracer for MIPS This patch make function graph tracer work with dynamic function tracer. To share the source code of dynamic function tracer(MCOUNT_SAVE_REGS), and avoid restoring the whole saved registers, we need to restore the ra register from the stack. (NOTE: This not work with 32bit! need to ensure why!) Signed-off-by: Wu Zhangjin Cc: Steven Rostedt Cc: Nicholas Mc Guire Cc: zhangfx@lemote.com Cc: Wu Zhangjin Cc: Ingo Molnar Cc: Thomas Gleixner Cc: Frederic Weisbecker Cc: linux-kernel@vger.kernel.org Cc: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/678/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/kernel/ftrace.c b/arch/mips/kernel/ftrace.c index 65a3f8a..e981a49 100644 --- a/arch/mips/kernel/ftrace.c +++ b/arch/mips/kernel/ftrace.c @@ -115,6 +115,27 @@ int __init ftrace_dyn_arch_init(void *data) #ifdef CONFIG_FUNCTION_GRAPH_TRACER +#ifdef CONFIG_DYNAMIC_FTRACE + +extern void ftrace_graph_call(void); +#define JMP 0x08000000 /* jump to target directly */ +#define CALL_FTRACE_GRAPH_CALLER \ + jump_insn_encode(JMP, (unsigned long)(&ftrace_graph_caller)) +#define FTRACE_GRAPH_CALL_IP ((unsigned long)(&ftrace_graph_call)) + +int ftrace_enable_ftrace_graph_caller(void) +{ + return ftrace_modify_code(FTRACE_GRAPH_CALL_IP, + CALL_FTRACE_GRAPH_CALLER); +} + +int ftrace_disable_ftrace_graph_caller(void) +{ + return ftrace_modify_code(FTRACE_GRAPH_CALL_IP, ftrace_nop); +} + +#endif /* !CONFIG_DYNAMIC_FTRACE */ + #define S_RA_SP (0xafbf << 16) /* s{d,w} ra, offset(sp) */ #define S_R_SP (0xafb0 << 16) /* s{d,w} R, offset(sp) */ #define OFFSET_MASK 0xffff /* stack offset range: 0 ~ PT_SIZE */ diff --git a/arch/mips/kernel/mcount.S b/arch/mips/kernel/mcount.S index b50e38d8..98d4690 100644 --- a/arch/mips/kernel/mcount.S +++ b/arch/mips/kernel/mcount.S @@ -77,6 +77,13 @@ ftrace_call: nop /* a placeholder for the call to a real tracing function */ move a1, AT /* arg2: the caller's next ip, parent */ +#ifdef CONFIG_FUNCTION_GRAPH_TRACER + .globl ftrace_graph_call +ftrace_graph_call: + nop + nop +#endif + MCOUNT_RESTORE_REGS .globl ftrace_stub ftrace_stub: @@ -124,10 +131,13 @@ ftrace_stub: #ifdef CONFIG_FUNCTION_GRAPH_TRACER NESTED(ftrace_graph_caller, PT_SIZE, ra) +#ifdef CONFIG_DYNAMIC_FTRACE + PTR_L a1, PT_R31(sp) /* load the original ra from the stack */ +#else MCOUNT_SAVE_REGS - - PTR_LA a0, PT_R1(sp) /* arg1: &AT -> a0 */ move a1, ra /* arg2: next ip, selfaddr */ +#endif + PTR_LA a0, PT_R1(sp) /* arg1: &AT -> a0 */ jal prepare_ftrace_return move a2, fp /* arg3: frame pointer */ -- cgit v0.10.2 From 046199cae714a7f9e88f5a7940b077f4515f48cb Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Fri, 20 Nov 2009 20:34:36 +0800 Subject: MIPS: Tracing: Make ftrace for MIPS work without -fno-omit-frame-pointer When remove the -fno-omit-frame-pointer, gcc will not save the frame pointer for us, we need to save one ourselves. Signed-off-by: Wu Zhangjin Cc: Steven Rostedt Cc: Nicholas Mc Guire Cc: zhangfx@lemote.com Cc: Wu Zhangjin Cc: Ingo Molnar Cc: Thomas Gleixner Cc: Frederic Weisbecker Cc: linux-kernel@vger.kernel.org Cc: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/679/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/include/asm/ftrace.h b/arch/mips/include/asm/ftrace.h index 7094a40..3986cd8 100644 --- a/arch/mips/include/asm/ftrace.h +++ b/arch/mips/include/asm/ftrace.h @@ -19,6 +19,62 @@ extern void _mcount(void); #define mcount _mcount +#define safe_load(load, src, dst, error) \ +do { \ + asm volatile ( \ + "1: " load " %[" STR(dst) "], 0(%[" STR(src) "])\n"\ + " li %[" STR(error) "], 0\n" \ + "2:\n" \ + \ + ".section .fixup, \"ax\"\n" \ + "3: li %[" STR(error) "], 1\n" \ + " j 2b\n" \ + ".previous\n" \ + \ + ".section\t__ex_table,\"a\"\n\t" \ + STR(PTR) "\t1b, 3b\n\t" \ + ".previous\n" \ + \ + : [dst] "=&r" (dst), [error] "=r" (error)\ + : [src] "r" (src) \ + : "memory" \ + ); \ +} while (0) + +#define safe_store(store, src, dst, error) \ +do { \ + asm volatile ( \ + "1: " store " %[" STR(src) "], 0(%[" STR(dst) "])\n"\ + " li %[" STR(error) "], 0\n" \ + "2:\n" \ + \ + ".section .fixup, \"ax\"\n" \ + "3: li %[" STR(error) "], 1\n" \ + " j 2b\n" \ + ".previous\n" \ + \ + ".section\t__ex_table,\"a\"\n\t"\ + STR(PTR) "\t1b, 3b\n\t" \ + ".previous\n" \ + \ + : [error] "=r" (error) \ + : [dst] "r" (dst), [src] "r" (src)\ + : "memory" \ + ); \ +} while (0) + +#define safe_load_code(dst, src, error) \ + safe_load(STR(lw), src, dst, error) +#define safe_store_code(src, dst, error) \ + safe_store(STR(sw), src, dst, error) + +#define safe_load_stack(dst, src, error) \ + safe_load(STR(PTR_L), src, dst, error) + +#define safe_store_stack(src, dst, error) \ + safe_store(STR(PTR_S), src, dst, error) + + #ifdef CONFIG_DYNAMIC_FTRACE static inline unsigned long ftrace_call_adjust(unsigned long addr) { @@ -27,6 +83,7 @@ static inline unsigned long ftrace_call_adjust(unsigned long addr) struct dyn_arch_ftrace { }; + #endif /* CONFIG_DYNAMIC_FTRACE */ #endif /* __ASSEMBLY__ */ #endif /* CONFIG_FUNCTION_TRACER */ diff --git a/arch/mips/kernel/ftrace.c b/arch/mips/kernel/ftrace.c index e981a49..e363fc6 100644 --- a/arch/mips/kernel/ftrace.c +++ b/arch/mips/kernel/ftrace.c @@ -27,7 +27,13 @@ static unsigned int ftrace_nop = 0x00000000; static int ftrace_modify_code(unsigned long ip, unsigned int new_code) { - *(unsigned int *)ip = new_code; + int faulted; + + /* *(unsigned int *)ip = new_code; */ + safe_store_code(new_code, ip, faulted); + + if (unlikely(faulted)) + return -EFAULT; flush_icache_range(ip, ip + 8); @@ -41,14 +47,20 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, unsigned long addr) { unsigned int new; + int faulted; unsigned long ip = rec->ip; /* We have compiled module with -mlong-calls, but compiled the kernel * without it, we need to cope with them respectively. */ if (ip & 0x40000000) { /* record it for ftrace_make_call */ - if (lui_v1 == 0) - lui_v1 = *(unsigned int *)ip; + if (lui_v1 == 0) { + /* lui_v1 = *(unsigned int *)ip; */ + safe_load_code(lui_v1, ip, faulted); + + if (unlikely(faulted)) + return -EFAULT; + } /* lui v1, hi_16bit_of_mcount --> b 1f (0x10000004) * addiu v1, v1, low_16bit_of_mcount @@ -147,6 +159,7 @@ unsigned long ftrace_get_parent_addr(unsigned long self_addr, { unsigned long sp, ip, ra; unsigned int code; + int faulted; /* in module or kernel? */ if (self_addr & 0x40000000) { @@ -162,8 +175,11 @@ unsigned long ftrace_get_parent_addr(unsigned long self_addr, do { ip -= 4; - /* get the code at "ip" */ - code = *(unsigned int *)ip; + /* get the code at "ip": code = *(unsigned int *)ip; */ + safe_load_code(code, ip, faulted); + + if (unlikely(faulted)) + return 0; /* If we hit the non-store instruction before finding where the * ra is stored, then this is a leaf function and it does not @@ -174,11 +190,14 @@ unsigned long ftrace_get_parent_addr(unsigned long self_addr, } while (((code & S_RA_SP) != S_RA_SP)); sp = fp + (code & OFFSET_MASK); - ra = *(unsigned long *)sp; + + /* ra = *(unsigned long *)sp; */ + safe_load_stack(ra, sp, faulted); + if (unlikely(faulted)) + return 0; if (ra == parent) return sp; - return 0; } @@ -193,6 +212,7 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr, struct ftrace_graph_ent trace; unsigned long return_hooker = (unsigned long) &return_to_handler; + int faulted; if (unlikely(atomic_read(¤t->tracing_graph_pause))) return; @@ -206,21 +226,23 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr, * ftrace_get_parent_addr() does it! */ - old = *parent; + /* old = *parent; */ + safe_load_stack(old, parent, faulted); + if (unlikely(faulted)) + goto out; parent = (unsigned long *)ftrace_get_parent_addr(self_addr, old, (unsigned long)parent, fp); - /* If fails when getting the stack address of the non-leaf function's * ra, stop function graph tracer and return */ - if (parent == 0) { - ftrace_graph_stop(); - WARN_ON(1); - return; - } + if (parent == 0) + goto out; - *parent = return_hooker; + /* *parent = return_hooker; */ + safe_store_stack(return_hooker, parent, faulted); + if (unlikely(faulted)) + goto out; if (ftrace_push_return_trace(old, self_addr, &trace.depth, fp) == -EBUSY) { @@ -235,5 +257,9 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr, current->curr_ret_stack--; *parent = old; } + return; +out: + ftrace_graph_stop(); + WARN_ON(1); } #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ diff --git a/arch/mips/kernel/mcount.S b/arch/mips/kernel/mcount.S index 98d4690..bdfef2c 100644 --- a/arch/mips/kernel/mcount.S +++ b/arch/mips/kernel/mcount.S @@ -139,7 +139,15 @@ NESTED(ftrace_graph_caller, PT_SIZE, ra) #endif PTR_LA a0, PT_R1(sp) /* arg1: &AT -> a0 */ jal prepare_ftrace_return +#ifdef CONFIG_FRAME_POINTER move a2, fp /* arg3: frame pointer */ +#else +#ifdef CONFIG_64BIT + PTR_LA a2, PT_SIZE(sp) +#else + PTR_LA a2, (PT_SIZE+8)(sp) +#endif +#endif MCOUNT_RESTORE_REGS RETURN_BACK -- cgit v0.10.2 From fc49a3be2be7a0cd44fcd3b37557d6d92cae59b1 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Fri, 20 Nov 2009 20:34:37 +0800 Subject: MIPS: Tracing: Reserve $12(t0) for mcount-ra-address of gcc 4.5 A new option -mmcount-ra-address for gcc 4.5 have been sent by David Daney in the thread "MIPS: Add option to pass return address location to _mcount", which help to record the location of the return address(ra) for the function graph tracer of MIPS to hijack the return address easier and safer. that option used the $12(t0) register by default, so, we reserve it for it, and use t1,t2,t3 instead of t0,t1,t2. Signed-off-by: Wu Zhangjin Cc: Steven Rostedt Cc: Nicholas Mc Guire Cc: zhangfx@lemote.com Cc: Wu Zhangjin Cc: Ingo Molnar Cc: Thomas Gleixner Cc: Frederic Weisbecker Cc: linux-kernel@vger.kernel.org Cc: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/680/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/kernel/mcount.S b/arch/mips/kernel/mcount.S index bdfef2c..522e91c 100644 --- a/arch/mips/kernel/mcount.S +++ b/arch/mips/kernel/mcount.S @@ -65,8 +65,8 @@ NESTED(ftrace_caller, PT_SIZE, ra) _mcount: b ftrace_stub nop - lw t0, function_trace_stop - bnez t0, ftrace_stub + lw t1, function_trace_stop + bnez t1, ftrace_stub nop MCOUNT_SAVE_REGS @@ -93,21 +93,21 @@ ftrace_stub: #else /* ! CONFIG_DYNAMIC_FTRACE */ NESTED(_mcount, PT_SIZE, ra) - lw t0, function_trace_stop - bnez t0, ftrace_stub + lw t1, function_trace_stop + bnez t1, ftrace_stub nop - PTR_LA t0, ftrace_stub - PTR_L t1, ftrace_trace_function /* Prepare t1 for (1) */ - bne t0, t1, static_trace + PTR_LA t1, ftrace_stub + PTR_L t2, ftrace_trace_function /* Prepare t2 for (1) */ + bne t1, t2, static_trace nop #ifdef CONFIG_FUNCTION_GRAPH_TRACER - PTR_L t2, ftrace_graph_return - bne t0, t2, ftrace_graph_caller + PTR_L t3, ftrace_graph_return + bne t1, t3, ftrace_graph_caller nop - PTR_LA t0, ftrace_graph_entry_stub - PTR_L t2, ftrace_graph_entry - bne t0, t2, ftrace_graph_caller + PTR_LA t1, ftrace_graph_entry_stub + PTR_L t3, ftrace_graph_entry + bne t1, t3, ftrace_graph_caller nop #endif b ftrace_stub @@ -117,7 +117,7 @@ static_trace: MCOUNT_SAVE_REGS move a0, ra /* arg1: next ip, selfaddr */ - jalr t1 /* (1) call *ftrace_trace_function */ + jalr t2 /* (1) call *ftrace_trace_function */ move a1, AT /* arg2: the caller's next ip, parent */ MCOUNT_RESTORE_REGS -- cgit v0.10.2 From 7326c4e567b50e689d13c04d58aeffa515277ebb Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Fri, 20 Nov 2009 20:34:38 +0800 Subject: MIPS: Tracing: Make function graph tracer work with -mmcount-ra-address That thread "MIPS: Add option to pass return address location to _mcount" from "David Daney " have added a new option -mmcount-ra-address to gcc(4.5) for MIPS to transfer the location of the return address to _mcount. Benefit from this new feature, function graph tracer on MIPS will be easier and safer to hijack the return address of the kernel function, which will save some overhead and make the whole thing more reliable. In this patch, at first, try to enable the option -mmcount-ra-address in arch/mips/Makefile with cc-option, if gcc support it, it will be enabled, otherwise, no side effect. and then, we need to support this new option of gcc 4.5 and also support the old gcc versions. with _mcount in the old gcc versions, it's not easy to get the location of return address(tracing: add function graph tracer support for MIPS), so, we do it in a C function: ftrace_get_parent_addr(ftrace.c), but with -mmcount-ra-address, only several instructions need to get what we want, so, I put into asm(mcount.S). and also, as the $12(t0) is used by -mmcount-ra-address for transferring the localtion of return address to _mcount, we need to save it into the stack and restore it when enabled dynamic function tracer, 'Cause we have called "ftrace_call" before "ftrace_graph_caller", which may destroy $12(t0). (Thanks to David for providing that -mcount-ra-address and giving the idea of KBUILD_MCOUNT_RA_ADDRESS, both of them have made the whole thing more beautiful!) Signed-off-by: Wu Zhangjin Cc: Steven Rostedt Cc: Nicholas Mc Guire Cc: zhangfx@lemote.com Cc: Wu Zhangjin Cc: Ingo Molnar Cc: Thomas Gleixner Cc: Frederic Weisbecker Cc: linux-kernel@vger.kernel.org Cc: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/681/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 3725ee9..d2c39fd 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -51,6 +51,13 @@ endif ifndef CONFIG_FUNCTION_TRACER cflags-y := -ffunction-sections endif +ifdef CONFIG_FUNCTION_GRAPH_TRACER + ifndef KBUILD_MCOUNT_RA_ADDRESS + ifeq ($(call cc-option-yn,-mmcount-ra-address), y) + cflags-y += -mmcount-ra-address -DKBUILD_MCOUNT_RA_ADDRESS + endif + endif +endif cflags-y += $(call cc-option, -mno-check-zero-division) ifdef CONFIG_32BIT diff --git a/arch/mips/kernel/ftrace.c b/arch/mips/kernel/ftrace.c index e363fc6..68b0670 100644 --- a/arch/mips/kernel/ftrace.c +++ b/arch/mips/kernel/ftrace.c @@ -148,6 +148,7 @@ int ftrace_disable_ftrace_graph_caller(void) #endif /* !CONFIG_DYNAMIC_FTRACE */ +#ifndef KBUILD_MCOUNT_RA_ADDRESS #define S_RA_SP (0xafbf << 16) /* s{d,w} ra, offset(sp) */ #define S_R_SP (0xafb0 << 16) /* s{d,w} R, offset(sp) */ #define OFFSET_MASK 0xffff /* stack offset range: 0 ~ PT_SIZE */ @@ -201,6 +202,8 @@ unsigned long ftrace_get_parent_addr(unsigned long self_addr, return 0; } +#endif + /* * Hook the return address and push it in the stack of return addrs * in current thread info. @@ -218,19 +221,26 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr, return; /* "parent" is the stack address saved the return address of the caller - * of _mcount, for a leaf function not save the return address in the - * stack address, so, we "emulate" one in _mcount's stack space, and - * hijack it directly, but for a non-leaf function, it will save the - * return address to the its stack space, so, we can not hijack the - * "parent" directly, but need to find the real stack address, + * of _mcount. + * + * if the gcc < 4.5, a leaf function does not save the return address + * in the stack address, so, we "emulate" one in _mcount's stack space, + * and hijack it directly, but for a non-leaf function, it save the + * return address to the its own stack space, we can not hijack it + * directly, but need to find the real stack address, * ftrace_get_parent_addr() does it! + * + * if gcc>= 4.5, with the new -mmcount-ra-address option, for a + * non-leaf function, the location of the return address will be saved + * to $12 for us, and for a leaf function, only put a zero into $12. we + * do it in ftrace_graph_caller of mcount.S. */ /* old = *parent; */ safe_load_stack(old, parent, faulted); if (unlikely(faulted)) goto out; - +#ifndef KBUILD_MCOUNT_RA_ADDRESS parent = (unsigned long *)ftrace_get_parent_addr(self_addr, old, (unsigned long)parent, fp); @@ -238,7 +248,7 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr, * ra, stop function graph tracer and return */ if (parent == 0) goto out; - +#endif /* *parent = return_hooker; */ safe_store_stack(return_hooker, parent, faulted); if (unlikely(faulted)) diff --git a/arch/mips/kernel/mcount.S b/arch/mips/kernel/mcount.S index 522e91c..0a9cfdb 100644 --- a/arch/mips/kernel/mcount.S +++ b/arch/mips/kernel/mcount.S @@ -70,6 +70,9 @@ _mcount: nop MCOUNT_SAVE_REGS +#ifdef KBUILD_MCOUNT_RA_ADDRESS + PTR_S t0, PT_R12(sp) /* t0 saved the location of the return address(at) by -mmcount-ra-address */ +#endif move a0, ra /* arg1: next ip, selfaddr */ .globl ftrace_call @@ -133,11 +136,22 @@ ftrace_stub: NESTED(ftrace_graph_caller, PT_SIZE, ra) #ifdef CONFIG_DYNAMIC_FTRACE PTR_L a1, PT_R31(sp) /* load the original ra from the stack */ +#ifdef KBUILD_MCOUNT_RA_ADDRESS + PTR_L t0, PT_R12(sp) /* load the original t0 from the stack */ +#endif #else MCOUNT_SAVE_REGS move a1, ra /* arg2: next ip, selfaddr */ #endif + +#ifdef KBUILD_MCOUNT_RA_ADDRESS + bnez t0, 1f /* non-leaf func: t0 saved the location of the return address */ + nop + PTR_LA t0, PT_R1(sp) /* leaf func: get the location of at(old ra) from our own stack */ +1: move a0, t0 /* arg1: the location of the return address */ +#else PTR_LA a0, PT_R1(sp) /* arg1: &AT -> a0 */ +#endif jal prepare_ftrace_return #ifdef CONFIG_FRAME_POINTER move a2, fp /* arg3: frame pointer */ -- cgit v0.10.2 From 599a89459f316499446fdb5c817a0a4835681bae Mon Sep 17 00:00:00 2001 From: Dmitri Vorobiev Date: Mon, 23 Nov 2009 13:53:37 +0200 Subject: MIPS: Move several variables from .bss to .init.data Several static uninitialized variables are used in the scope of __init functions but are themselves not marked as __initdata. This patch is to put those variables to where they belong and to reduce the memory footprint a little bit. Also, a couple of lines with spaces instead of tabs were fixed. Signed-off-by: Dmitri Vorobiev Cc: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/698/ Acked-by: Florian Fainelli Signed-off-by: Ralf Baechle diff --git a/arch/mips/ar7/platform.c b/arch/mips/ar7/platform.c index 835f3f0..85169c0 100644 --- a/arch/mips/ar7/platform.c +++ b/arch/mips/ar7/platform.c @@ -505,7 +505,7 @@ static int __init ar7_register_devices(void) int res; u32 *bootcr, val; #ifdef CONFIG_SERIAL_8250 - static struct uart_port uart_port[2]; + static struct uart_port uart_port[2] __initdata; memset(uart_port, 0, sizeof(struct uart_port) * 2); diff --git a/arch/mips/sgi-ip22/ip22-eisa.c b/arch/mips/sgi-ip22/ip22-eisa.c index 1617241..da44ccb 100644 --- a/arch/mips/sgi-ip22/ip22-eisa.c +++ b/arch/mips/sgi-ip22/ip22-eisa.c @@ -50,9 +50,9 @@ static char __init *decode_eisa_sig(unsigned long addr) { - static char sig_str[EISA_SIG_LEN]; + static char sig_str[EISA_SIG_LEN] __initdata; u8 sig[4]; - u16 rev; + u16 rev; int i; for (i = 0; i < 4; i++) { diff --git a/arch/mips/sgi-ip22/ip22-setup.c b/arch/mips/sgi-ip22/ip22-setup.c index b9a9313..5deeb68 100644 --- a/arch/mips/sgi-ip22/ip22-setup.c +++ b/arch/mips/sgi-ip22/ip22-setup.c @@ -67,7 +67,7 @@ void __init plat_mem_setup(void) cserial = ArcGetEnvironmentVariable("ConsoleOut"); if ((ctype && *ctype == 'd') || (cserial && *cserial == 's')) { - static char options[8]; + static char options[8] __initdata; char *baud = ArcGetEnvironmentVariable("dbaud"); if (baud) strcpy(options, baud); diff --git a/arch/mips/sgi-ip32/ip32-setup.c b/arch/mips/sgi-ip32/ip32-setup.c index c5a5d4a..3abd146 100644 --- a/arch/mips/sgi-ip32/ip32-setup.c +++ b/arch/mips/sgi-ip32/ip32-setup.c @@ -90,7 +90,7 @@ void __init plat_mem_setup(void) { char* con = ArcGetEnvironmentVariable("console"); if (con && *con == 'd') { - static char options[8]; + static char options[8] __initdata; char *baud = ArcGetEnvironmentVariable("dbaud"); if (baud) strcpy(options, baud); diff --git a/arch/mips/sni/setup.c b/arch/mips/sni/setup.c index a49272c..d16b462 100644 --- a/arch/mips/sni/setup.c +++ b/arch/mips/sni/setup.c @@ -60,7 +60,7 @@ static void __init sni_console_setup(void) char *cdev; char *baud; int port; - static char options[8]; + static char options[8] __initdata; cdev = prom_getenv("console_dev"); if (strncmp(cdev, "tty", 3) == 0) { -- cgit v0.10.2 From ec614d80b58677de30b876a16fdd3fde85bebdc1 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Sat, 21 Nov 2009 19:05:23 +0800 Subject: MIPS: Yeeloong 2F: Add basic EC operations YeeLoong2F has a KB3310b embedded controller. Add basic operations for future related drivers and board support. Signed-off-by: Wu Zhangjin Cc: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/684/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/loongson/lemote-2f/Makefile b/arch/mips/loongson/lemote-2f/Makefile index 5add7b2..4d84b27 100644 --- a/arch/mips/loongson/lemote-2f/Makefile +++ b/arch/mips/loongson/lemote-2f/Makefile @@ -2,7 +2,7 @@ # Makefile for lemote loongson2f family machines # -obj-y += irq.o reset.o +obj-y += irq.o reset.o ec_kb3310b.o # # Suspend Support diff --git a/arch/mips/loongson/lemote-2f/ec_kb3310b.c b/arch/mips/loongson/lemote-2f/ec_kb3310b.c new file mode 100644 index 0000000..4d84111 --- /dev/null +++ b/arch/mips/loongson/lemote-2f/ec_kb3310b.c @@ -0,0 +1,130 @@ +/* + * Basic KB3310B Embedded Controller support for the YeeLoong 2F netbook + * + * Copyright (C) 2008 Lemote Inc. + * Author: liujl , 2008-04-20 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include + +#include "ec_kb3310b.h" + +static DEFINE_SPINLOCK(index_access_lock); +static DEFINE_SPINLOCK(port_access_lock); + +unsigned char ec_read(unsigned short addr) +{ + unsigned char value; + unsigned long flags; + + spin_lock_irqsave(&index_access_lock, flags); + outb((addr & 0xff00) >> 8, EC_IO_PORT_HIGH); + outb((addr & 0x00ff), EC_IO_PORT_LOW); + value = inb(EC_IO_PORT_DATA); + spin_unlock_irqrestore(&index_access_lock, flags); + + return value; +} +EXPORT_SYMBOL_GPL(ec_read); + +void ec_write(unsigned short addr, unsigned char val) +{ + unsigned long flags; + + spin_lock_irqsave(&index_access_lock, flags); + outb((addr & 0xff00) >> 8, EC_IO_PORT_HIGH); + outb((addr & 0x00ff), EC_IO_PORT_LOW); + outb(val, EC_IO_PORT_DATA); + /* flush the write action */ + inb(EC_IO_PORT_DATA); + spin_unlock_irqrestore(&index_access_lock, flags); + + return; +} +EXPORT_SYMBOL_GPL(ec_write); + +/* + * This function is used for EC command writes and corresponding status queries. + */ +int ec_query_seq(unsigned char cmd) +{ + int timeout; + unsigned char status; + unsigned long flags; + int ret = 0; + + spin_lock_irqsave(&port_access_lock, flags); + + /* make chip goto reset mode */ + udelay(EC_REG_DELAY); + outb(cmd, EC_CMD_PORT); + udelay(EC_REG_DELAY); + + /* check if the command is received by ec */ + timeout = EC_CMD_TIMEOUT; + status = inb(EC_STS_PORT); + while (timeout-- && (status & (1 << 1))) { + status = inb(EC_STS_PORT); + udelay(EC_REG_DELAY); + } + + if (timeout <= 0) { + printk(KERN_ERR "%s: deadable error : timeout...\n", __func__); + ret = -EINVAL; + } else + printk(KERN_INFO + "(%x/%d)ec issued command %d status : 0x%x\n", + timeout, EC_CMD_TIMEOUT - timeout, cmd, status); + + spin_unlock_irqrestore(&port_access_lock, flags); + + return ret; +} +EXPORT_SYMBOL_GPL(ec_query_seq); + +/* + * Send query command to EC to get the proper event number + */ +int ec_query_event_num(void) +{ + return ec_query_seq(CMD_GET_EVENT_NUM); +} +EXPORT_SYMBOL(ec_query_event_num); + +/* + * Get event number from EC + * + * NOTE: This routine must follow the query_event_num function in the + * interrupt. + */ +int ec_get_event_num(void) +{ + int timeout = 100; + unsigned char value; + unsigned char status; + + udelay(EC_REG_DELAY); + status = inb(EC_STS_PORT); + udelay(EC_REG_DELAY); + while (timeout-- && !(status & (1 << 0))) { + status = inb(EC_STS_PORT); + udelay(EC_REG_DELAY); + } + if (timeout <= 0) { + pr_info("%s: get event number timeout.\n", __func__); + + return -EINVAL; + } + value = inb(EC_DAT_PORT); + udelay(EC_REG_DELAY); + + return value; +} +EXPORT_SYMBOL(ec_get_event_num); diff --git a/arch/mips/loongson/lemote-2f/ec_kb3310b.h b/arch/mips/loongson/lemote-2f/ec_kb3310b.h new file mode 100644 index 0000000..1595a21 --- /dev/null +++ b/arch/mips/loongson/lemote-2f/ec_kb3310b.h @@ -0,0 +1,188 @@ +/* + * KB3310B Embedded Controller + * + * Copyright (C) 2008 Lemote Inc. + * Author: liujl , 2008-03-14 + * + * 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 _EC_KB3310B_H +#define _EC_KB3310B_H + +extern unsigned char ec_read(unsigned short addr); +extern void ec_write(unsigned short addr, unsigned char val); +extern int ec_query_seq(unsigned char cmd); +extern int ec_query_event_num(void); +extern int ec_get_event_num(void); + +typedef int (*sci_handler) (int status); +extern sci_handler yeeloong_report_lid_status; + +#define SCI_IRQ_NUM 0x0A + +/* + * The following registers are determined by the EC index configuration. + * 1, fill the PORT_HIGH as EC register high part. + * 2, fill the PORT_LOW as EC register low part. + * 3, fill the PORT_DATA as EC register write data or get the data from it. + */ +#define EC_IO_PORT_HIGH 0x0381 +#define EC_IO_PORT_LOW 0x0382 +#define EC_IO_PORT_DATA 0x0383 + +/* + * EC delay time is 500us for register and status access + */ +#define EC_REG_DELAY 500 /* unit : us */ +#define EC_CMD_TIMEOUT 0x1000 + +/* + * EC access port for SCI communication + */ +#define EC_CMD_PORT 0x66 +#define EC_STS_PORT 0x66 +#define EC_DAT_PORT 0x62 +#define CMD_INIT_IDLE_MODE 0xdd +#define CMD_EXIT_IDLE_MODE 0xdf +#define CMD_INIT_RESET_MODE 0xd8 +#define CMD_REBOOT_SYSTEM 0x8c +#define CMD_GET_EVENT_NUM 0x84 +#define CMD_PROGRAM_PIECE 0xda + +/* temperature & fan registers */ +#define REG_TEMPERATURE_VALUE 0xF458 +#define REG_FAN_AUTO_MAN_SWITCH 0xF459 +#define BIT_FAN_AUTO 0 +#define BIT_FAN_MANUAL 1 +#define REG_FAN_CONTROL 0xF4D2 +#define BIT_FAN_CONTROL_ON (1 << 0) +#define BIT_FAN_CONTROL_OFF (0 << 0) +#define REG_FAN_STATUS 0xF4DA +#define BIT_FAN_STATUS_ON (1 << 0) +#define BIT_FAN_STATUS_OFF (0 << 0) +#define REG_FAN_SPEED_HIGH 0xFE22 +#define REG_FAN_SPEED_LOW 0xFE23 +#define REG_FAN_SPEED_LEVEL 0xF4CC +/* fan speed divider */ +#define FAN_SPEED_DIVIDER 480000 /* (60*1000*1000/62.5/2)*/ + +/* battery registers */ +#define REG_BAT_DESIGN_CAP_HIGH 0xF77D +#define REG_BAT_DESIGN_CAP_LOW 0xF77E +#define REG_BAT_FULLCHG_CAP_HIGH 0xF780 +#define REG_BAT_FULLCHG_CAP_LOW 0xF781 +#define REG_BAT_DESIGN_VOL_HIGH 0xF782 +#define REG_BAT_DESIGN_VOL_LOW 0xF783 +#define REG_BAT_CURRENT_HIGH 0xF784 +#define REG_BAT_CURRENT_LOW 0xF785 +#define REG_BAT_VOLTAGE_HIGH 0xF786 +#define REG_BAT_VOLTAGE_LOW 0xF787 +#define REG_BAT_TEMPERATURE_HIGH 0xF788 +#define REG_BAT_TEMPERATURE_LOW 0xF789 +#define REG_BAT_RELATIVE_CAP_HIGH 0xF492 +#define REG_BAT_RELATIVE_CAP_LOW 0xF493 +#define REG_BAT_VENDOR 0xF4C4 +#define FLAG_BAT_VENDOR_SANYO 0x01 +#define FLAG_BAT_VENDOR_SIMPLO 0x02 +#define REG_BAT_CELL_COUNT 0xF4C6 +#define FLAG_BAT_CELL_3S1P 0x03 +#define FLAG_BAT_CELL_3S2P 0x06 +#define REG_BAT_CHARGE 0xF4A2 +#define FLAG_BAT_CHARGE_DISCHARGE 0x01 +#define FLAG_BAT_CHARGE_CHARGE 0x02 +#define FLAG_BAT_CHARGE_ACPOWER 0x00 +#define REG_BAT_STATUS 0xF4B0 +#define BIT_BAT_STATUS_LOW (1 << 5) +#define BIT_BAT_STATUS_DESTROY (1 << 2) +#define BIT_BAT_STATUS_FULL (1 << 1) +#define BIT_BAT_STATUS_IN (1 << 0) +#define REG_BAT_CHARGE_STATUS 0xF4B1 +#define BIT_BAT_CHARGE_STATUS_OVERTEMP (1 << 2) +#define BIT_BAT_CHARGE_STATUS_PRECHG (1 << 1) +#define REG_BAT_STATE 0xF482 +#define BIT_BAT_STATE_CHARGING (1 << 1) +#define BIT_BAT_STATE_DISCHARGING (1 << 0) +#define REG_BAT_POWER 0xF440 +#define BIT_BAT_POWER_S3 (1 << 2) +#define BIT_BAT_POWER_ON (1 << 1) +#define BIT_BAT_POWER_ACIN (1 << 0) + +/* other registers */ +/* Audio: rd/wr */ +#define REG_AUDIO_VOLUME 0xF46C +#define REG_AUDIO_MUTE 0xF4E7 +#define REG_AUDIO_BEEP 0xF4D0 +/* USB port power or not: rd/wr */ +#define REG_USB0_FLAG 0xF461 +#define REG_USB1_FLAG 0xF462 +#define REG_USB2_FLAG 0xF463 +#define BIT_USB_FLAG_ON 1 +#define BIT_USB_FLAG_OFF 0 +/* LID */ +#define REG_LID_DETECT 0xF4BD +#define BIT_LID_DETECT_ON 1 +#define BIT_LID_DETECT_OFF 0 +/* CRT */ +#define REG_CRT_DETECT 0xF4AD +#define BIT_CRT_DETECT_PLUG 1 +#define BIT_CRT_DETECT_UNPLUG 0 +/* LCD backlight brightness adjust: 9 levels */ +#define REG_DISPLAY_BRIGHTNESS 0xF4F5 +/* Black screen Status */ +#define BIT_DISPLAY_LCD_ON 1 +#define BIT_DISPLAY_LCD_OFF 0 +/* LCD backlight control: off/restore */ +#define REG_BACKLIGHT_CTRL 0xF7BD +#define BIT_BACKLIGHT_ON 1 +#define BIT_BACKLIGHT_OFF 0 +/* Reset the machine auto-clear: rd/wr */ +#define REG_RESET 0xF4EC +#define BIT_RESET_ON 1 +/* Light the led: rd/wr */ +#define REG_LED 0xF4C8 +#define BIT_LED_RED_POWER (1 << 0) +#define BIT_LED_ORANGE_POWER (1 << 1) +#define BIT_LED_GREEN_CHARGE (1 << 2) +#define BIT_LED_RED_CHARGE (1 << 3) +#define BIT_LED_NUMLOCK (1 << 4) +/* Test led mode, all led on/off */ +#define REG_LED_TEST 0xF4C2 +#define BIT_LED_TEST_IN 1 +#define BIT_LED_TEST_OUT 0 +/* Camera on/off */ +#define REG_CAMERA_STATUS 0xF46A +#define BIT_CAMERA_STATUS_ON 1 +#define BIT_CAMERA_STATUS_OFF 0 +#define REG_CAMERA_CONTROL 0xF7B7 +#define BIT_CAMERA_CONTROL_OFF 0 +#define BIT_CAMERA_CONTROL_ON 1 +/* Wlan Status */ +#define REG_WLAN 0xF4FA +#define BIT_WLAN_ON 1 +#define BIT_WLAN_OFF 0 +#define REG_DISPLAY_LCD 0xF79F + +/* SCI Event Number from EC */ +enum { + EVENT_LID = 0x23, /* LID open/close */ + EVENT_DISPLAY_TOGGLE, /* Fn+F3 for display switch */ + EVENT_SLEEP, /* Fn+F1 for entering sleep mode */ + EVENT_OVERTEMP, /* Over-temperature happened */ + EVENT_CRT_DETECT, /* CRT is connected */ + EVENT_CAMERA, /* Camera on/off */ + EVENT_USB_OC2, /* USB2 Over Current occurred */ + EVENT_USB_OC0, /* USB0 Over Current occurred */ + EVENT_BLACK_SCREEN, /* Turn on/off backlight */ + EVENT_AUDIO_MUTE, /* Mute on/off */ + EVENT_DISPLAY_BRIGHTNESS,/* LCD backlight brightness adjust */ + EVENT_AC_BAT, /* AC & Battery relative issue */ + EVENT_AUDIO_VOLUME, /* Volume adjust */ + EVENT_WLAN, /* Wlan on/off */ + EVENT_END +}; + +#endif /* !_EC_KB3310B_H */ -- cgit v0.10.2 From cb1ed9e117098269de3c0dfff816dff453dd4b59 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Sat, 21 Nov 2009 19:05:24 +0800 Subject: MIPS: Yeeloong 2F: Add LID open event as the wakeup event Yeeloong 2F netbook has an KB3310B embedded controller to manage the LID action. When the LID is closed or opened a SCI interrupt is sent out and the corresponding event is saved to an EC register for later query. Allow the LID open interrupt to wake the processor from wait mode if it is in the suspend mode. Signed-off-by: Wu Zhangjin Cc: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/685/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/include/asm/mach-loongson/loongson.h b/arch/mips/include/asm/mach-loongson/loongson.h index a7fa66e..06c28f3 100644 --- a/arch/mips/include/asm/mach-loongson/loongson.h +++ b/arch/mips/include/asm/mach-loongson/loongson.h @@ -41,6 +41,7 @@ extern void __init bonito_irq_init(void); extern void __init set_irq_trigger_mode(void); extern void __init mach_init_irq(void); extern void mach_irq_dispatch(unsigned int pending); +extern int mach_i8259_irq(void); /* We need this in some places... */ #define delay() ({ \ diff --git a/arch/mips/loongson/lemote-2f/irq.c b/arch/mips/loongson/lemote-2f/irq.c index 50e7bb6..77d32f9 100644 --- a/arch/mips/loongson/lemote-2f/irq.c +++ b/arch/mips/loongson/lemote-2f/irq.c @@ -9,6 +9,7 @@ */ #include +#include #include #include @@ -30,7 +31,7 @@ * The generic i8259_irq() make the kernel hang on booting. Since we cannot * get the irq via the IRR directly, we access the ISR instead. */ -static inline int mach_i8259_irq(void) +int mach_i8259_irq(void) { int irq, isr; @@ -60,6 +61,7 @@ static inline int mach_i8259_irq(void) return irq; } +EXPORT_SYMBOL(mach_i8259_irq); static void i8259_irqdispatch(void) { diff --git a/arch/mips/loongson/lemote-2f/pm.c b/arch/mips/loongson/lemote-2f/pm.c index 8090d05..81c0641 100644 --- a/arch/mips/loongson/lemote-2f/pm.c +++ b/arch/mips/loongson/lemote-2f/pm.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -21,6 +22,8 @@ #include +#include "ec_kb3310b.h" + #define I8042_KBD_IRQ 1 #define I8042_CTR_KBDINT 0x01 #define I8042_CTR_KBDDIS 0x10 @@ -49,9 +52,6 @@ static int i8042_enable_kbd_port(void) return 0; } -/* - * The i8042 is connnected to i8259A - */ void setup_wakeup_events(void) { int irq_mask; @@ -65,9 +65,74 @@ void setup_wakeup_events(void) /* enable keyboard port */ i8042_enable_kbd_port(); + + /* Wakeup CPU via SCI lid open event */ + outb(irq_mask & ~(1 << PIC_CASCADE_IR), PIC_MASTER_IMR); + inb(PIC_MASTER_IMR); + outb(0xff & ~(1 << (SCI_IRQ_NUM - 8)), PIC_SLAVE_IMR); + inb(PIC_SLAVE_IMR); + break; default: break; } } + +static struct delayed_work lid_task; +static int initialized; +/* yeeloong_report_lid_status will be implemented in yeeloong_laptop.c */ +sci_handler yeeloong_report_lid_status; +EXPORT_SYMBOL(yeeloong_report_lid_status); +static void yeeloong_lid_update_task(struct work_struct *work) +{ + if (yeeloong_report_lid_status) + yeeloong_report_lid_status(BIT_LID_DETECT_ON); +} + +int wakeup_loongson(void) +{ + int irq; + + /* query the interrupt number */ + irq = mach_i8259_irq(); + if (irq < 0) + return 0; + + printk(KERN_INFO "%s: irq = %d\n", __func__, irq); + + if (irq == I8042_KBD_IRQ) + return 1; + else if (irq == SCI_IRQ_NUM) { + int ret, sci_event; + /* query the event number */ + ret = ec_query_seq(CMD_GET_EVENT_NUM); + if (ret < 0) + return 0; + sci_event = ec_get_event_num(); + if (sci_event < 0) + return 0; + if (sci_event == EVENT_LID) { + int lid_status; + /* check the LID status */ + lid_status = ec_read(REG_LID_DETECT); + /* wakeup cpu when people open the LID */ + if (lid_status == BIT_LID_DETECT_ON) { + /* If we call it directly here, the WARNING + * will be sent out by getnstimeofday + * via "WARN_ON(timekeeping_suspended);" + * because we can not schedule in suspend mode. + */ + if (initialized == 0) { + INIT_DELAYED_WORK(&lid_task, + yeeloong_lid_update_task); + initialized = 1; + } + schedule_delayed_work(&lid_task, 1); + return 1; + } + } + } + + return 0; +} -- cgit v0.10.2 From 70ab711df44ada438973ceba0213121afeb8e8b3 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Sat, 21 Nov 2009 19:05:25 +0800 Subject: MIPS: Yeeloong 2F: Cleanup reset logic using the new ec_write function Signed-off-by: Wu Zhangjin Cc: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/683/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/loongson/lemote-2f/reset.c b/arch/mips/loongson/lemote-2f/reset.c index 44bb984..51d1a60 100644 --- a/arch/mips/loongson/lemote-2f/reset.c +++ b/arch/mips/loongson/lemote-2f/reset.c @@ -20,6 +20,7 @@ #include #include +#include "ec_kb3310b.h" static void reset_cpu(void) { @@ -75,30 +76,12 @@ static void fl2f_shutdown(void) /* reset support for yeeloong2f and mengloong2f notebook */ -/* - * The following registers are determined by the EC index configuration. - * 1. fill the PORT_HIGH as EC register high part. - * 2. fill the PORT_LOW as EC register low part. - * 3. fill the PORT_DATA as EC register write data or get the data from it. - */ - -#define EC_IO_PORT_HIGH 0x0381 -#define EC_IO_PORT_LOW 0x0382 -#define EC_IO_PORT_DATA 0x0383 -#define REG_RESET_HIGH 0xF4 /* reset the machine auto-clear : rd/wr */ -#define REG_RESET_LOW 0xEC -#define BIT_RESET_ON (1 << 0) - void ml2f_reboot(void) { reset_cpu(); /* sending an reset signal to EC(embedded controller) */ - outb(REG_RESET_HIGH, EC_IO_PORT_HIGH); - outb(REG_RESET_LOW, EC_IO_PORT_LOW); - mmiowb(); - outb(BIT_RESET_ON, EC_IO_PORT_DATA); - mmiowb(); + ec_write(REG_RESET, BIT_RESET_ON); } #define yl2f89_reboot ml2f_reboot -- cgit v0.10.2 From 4dd92e15b316d1a782772f16074571a70ceb9184 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 17 Dec 2009 01:57:30 +0000 Subject: MIPS: Move EARLY_PRINTK to Kconfig.debug Signed-off-by: Ralf Baechle diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 2906ae5..0be245d 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -837,20 +837,6 @@ config DMA_NONCOHERENT config DMA_NEED_PCI_MAP_STATE bool -config EARLY_PRINTK - bool "Early printk" if EMBEDDED && DEBUG_KERNEL - depends on SYS_HAS_EARLY_PRINTK - default y - help - This option enables special console drivers which allow the kernel - to print messages very early in the bootup process. - - This is useful for kernel debugging when your machine crashes very - early before the console code is initialized. For normal operation, - it is not recommended because it looks ugly on some machines and - doesn't cooperate with an X server. You should normally say N here, - unless you want to debug such a crash. - config SYS_HAS_EARLY_PRINTK bool diff --git a/arch/mips/Kconfig.debug b/arch/mips/Kconfig.debug index 364ca89..23817bc 100644 --- a/arch/mips/Kconfig.debug +++ b/arch/mips/Kconfig.debug @@ -6,6 +6,20 @@ config TRACE_IRQFLAGS_SUPPORT source "lib/Kconfig.debug" +config EARLY_PRINTK + bool "Early printk" if EMBEDDED + depends on SYS_HAS_EARLY_PRINTK + default y + help + This option enables special console drivers which allow the kernel + to print messages very early in the bootup process. + + This is useful for kernel debugging when your machine crashes very + early before the console code is initialized. For normal operation, + it is not recommended because it looks ugly on some machines and + doesn't cooperate with an X server. You should normally say N here, + unless you want to debug such a crash. + config CMDLINE string "Default kernel command string" default "" -- cgit v0.10.2 From 69f3a7de1f1ec935924b1b13f83812f8b30e92ce Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 24 Nov 2009 01:24:58 +0000 Subject: MIPS: Modularize COP2 handling Away with the daemons of ifdef; get ready for future COP2 users. Signed-off-by: Ralf Baechle Patchwork: http://patchwork.linux-mips.org/patch/708/ diff --git a/arch/mips/cavium-octeon/Makefile b/arch/mips/cavium-octeon/Makefile index 1394362..3e98763 100644 --- a/arch/mips/cavium-octeon/Makefile +++ b/arch/mips/cavium-octeon/Makefile @@ -9,7 +9,7 @@ # Copyright (C) 2005-2009 Cavium Networks # -obj-y := setup.o serial.o octeon-platform.o octeon-irq.o csrc-octeon.o +obj-y := cpu.o setup.o serial.o octeon-platform.o octeon-irq.o csrc-octeon.o obj-y += dma-octeon.o flash_setup.o obj-y += octeon-memcpy.o diff --git a/arch/mips/cavium-octeon/cpu.c b/arch/mips/cavium-octeon/cpu.c new file mode 100644 index 0000000..b6df538 --- /dev/null +++ b/arch/mips/cavium-octeon/cpu.c @@ -0,0 +1,52 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2009 Wind River Systems, + * written by Ralf Baechle + */ +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +static int cnmips_cu2_call(struct notifier_block *nfb, unsigned long action, + void *data) +{ + unsigned long flags; + unsigned int status; + + switch (action) { + case CU2_EXCEPTION: + prefetch(¤t->thread.cp2); + local_irq_save(flags); + KSTK_STATUS(current) |= ST0_CU2; + status = read_c0_status(); + write_c0_status(status | ST0_CU2); + octeon_cop2_restore(&(current->thread.cp2)); + write_c0_status(status & ~ST0_CU2); + local_irq_restore(flags); + + return NOTIFY_BAD; /* Don't call default notifier */ + } + + return NOTIFY_OK; /* Let default notifier send signals */ +} + +static struct notifier_block cnmips_cu2_notifier = { + .notifier_call = cnmips_cu2_call, +}; + +static int cnmips_cu2_setup(void) +{ + return register_cu2_notifier(&cnmips_cu2_notifier); +} +early_initcall(cnmips_cu2_setup); diff --git a/arch/mips/include/asm/cop2.h b/arch/mips/include/asm/cop2.h new file mode 100644 index 0000000..6b04c98 --- /dev/null +++ b/arch/mips/include/asm/cop2.h @@ -0,0 +1,23 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2009 Wind River Systems, + * written by Ralf Baechle + */ +#ifndef __ASM_COP2_H +#define __ASM_COP2_H + +enum cu2_ops { + CU2_EXCEPTION, + CU2_LWC2_OP, + CU2_LDC2_OP, + CU2_SWC2_OP, + CU2_SDC2_OP, +}; + +extern int register_cu2_notifier(struct notifier_block *nb); +extern int cu2_notifier_call_chain(unsigned long val, void *v); + +#endif /* __ASM_COP2_H */ diff --git a/arch/mips/include/asm/octeon/octeon.h b/arch/mips/include/asm/octeon/octeon.h index cac9b1a..4d0a8c6 100644 --- a/arch/mips/include/asm/octeon/octeon.h +++ b/arch/mips/include/asm/octeon/octeon.h @@ -47,6 +47,7 @@ struct octeon_cop2_state; extern unsigned long octeon_crypto_enable(struct octeon_cop2_state *state); extern void octeon_crypto_disable(struct octeon_cop2_state *state, unsigned long flags); +extern asmlinkage void octeon_cop2_restore(struct octeon_cop2_state *task); extern void octeon_init_cvmcount(void); diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 0a18b4c..9fe21fb 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -25,10 +25,12 @@ #include #include #include +#include #include #include #include +#include #include #include #include @@ -79,10 +81,6 @@ extern asmlinkage void handle_reserved(void); extern int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx, int has_fpu); -#ifdef CONFIG_CPU_CAVIUM_OCTEON -extern asmlinkage void octeon_cop2_restore(struct octeon_cop2_state *task); -#endif - void (*board_be_init)(void); int (*board_be_handler)(struct pt_regs *regs, int is_fixup); void (*board_nmi_handler_setup)(void); @@ -857,6 +855,44 @@ static void mt_ase_fp_affinity(void) #endif /* CONFIG_MIPS_MT_FPAFF */ } +/* + * No lock; only written during early bootup by CPU 0. + */ +static RAW_NOTIFIER_HEAD(cu2_chain); + +int __ref register_cu2_notifier(struct notifier_block *nb) +{ + return raw_notifier_chain_register(&cu2_chain, nb); +} + +int cu2_notifier_call_chain(unsigned long val, void *v) +{ + return raw_notifier_call_chain(&cu2_chain, val, v); +} + +static int default_cu2_call(struct notifier_block *nfb, unsigned long action, + void *data) +{ + struct pt_regs *regs = data; + + switch (action) { + default: + die_if_kernel("Unhandled kernel unaligned access or invalid " + "instruction", regs); + /* Fall through */ + + case CU2_EXCEPTION: + force_sig(SIGILL, current); + } + + return NOTIFY_OK; +} + +static struct notifier_block default_cu2_notifier = { + .notifier_call = default_cu2_call, + .priority = 0x80000000, /* Run last */ +}; + asmlinkage void do_cpu(struct pt_regs *regs) { unsigned int __user *epc; @@ -920,17 +956,9 @@ asmlinkage void do_cpu(struct pt_regs *regs) return; case 2: -#ifdef CONFIG_CPU_CAVIUM_OCTEON - prefetch(¤t->thread.cp2); - local_irq_save(flags); - KSTK_STATUS(current) |= ST0_CU2; - status = read_c0_status(); - write_c0_status(status | ST0_CU2); - octeon_cop2_restore(&(current->thread.cp2)); - write_c0_status(status & ~ST0_CU2); - local_irq_restore(flags); - return; -#endif + raw_notifier_call_chain(&cu2_chain, CU2_EXCEPTION, regs); + break; + case 3: break; } @@ -1760,4 +1788,6 @@ void __init trap_init(void) flush_tlb_handlers(); sort_extable(__start___dbe_table, __stop___dbe_table); + + register_cu2_notifier(&default_cu2_notifier); } diff --git a/arch/mips/kernel/unaligned.c b/arch/mips/kernel/unaligned.c index 67bd626..69b039c 100644 --- a/arch/mips/kernel/unaligned.c +++ b/arch/mips/kernel/unaligned.c @@ -81,6 +81,7 @@ #include #include #include +#include #include #include #include @@ -451,17 +452,27 @@ static void emulate_load_store_insn(struct pt_regs *regs, */ goto sigbus; + /* + * COP2 is available to implementor for application specific use. + * It's up to applications to register a notifier chain and do + * whatever they have to do, including possible sending of signals. + */ case lwc2_op: + cu2_notifier_call_chain(CU2_LWC2_OP, regs); + break; + case ldc2_op: + cu2_notifier_call_chain(CU2_LDC2_OP, regs); + break; + case swc2_op: + cu2_notifier_call_chain(CU2_SWC2_OP, regs); + break; + case sdc2_op: - /* - * These are the coprocessor 2 load/stores. The current - * implementations don't use cp2 and cp2 should always be - * disabled in c0_status. So send SIGILL. - * (No longer true: The Sony Praystation uses cp2 for - * 3D matrix operations. Dunno if that thingy has a MMU ...) - */ + cu2_notifier_call_chain(CU2_SDC2_OP, regs); + break; + default: /* * Pheeee... We encountered an yet unknown instruction or -- cgit v0.10.2 From 137f6f3e284e8215a940cf20dbf2aef449fe5a60 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 24 Nov 2009 19:35:41 +0000 Subject: MIPS: Cleanup signal code initialization Signed-off-by: Ralf Baechle Cc: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/709/ diff --git a/arch/mips/include/asm/fpu.h b/arch/mips/include/asm/fpu.h index 8a3ef24..7fcef8e 100644 --- a/arch/mips/include/asm/fpu.h +++ b/arch/mips/include/asm/fpu.h @@ -28,15 +28,7 @@ struct sigcontext; struct sigcontext32; -extern asmlinkage int (*save_fp_context)(struct sigcontext __user *sc); -extern asmlinkage int (*restore_fp_context)(struct sigcontext __user *sc); - -extern asmlinkage int (*save_fp_context32)(struct sigcontext32 __user *sc); -extern asmlinkage int (*restore_fp_context32)(struct sigcontext32 __user *sc); - extern void fpu_emulator_init_fpu(void); -extern int fpu_emulator_save_context(struct sigcontext __user *sc); -extern int fpu_emulator_restore_context(struct sigcontext __user *sc); extern void _init_fpu(void); extern void _save_fp(struct task_struct *); extern void _restore_fp(struct task_struct *); diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c index 6254041..d0c68b5 100644 --- a/arch/mips/kernel/signal.c +++ b/arch/mips/kernel/signal.c @@ -35,6 +35,15 @@ #include "signal-common.h" +static int (*save_fp_context)(struct sigcontext __user *sc); +static int (*restore_fp_context)(struct sigcontext __user *sc); + +extern asmlinkage int _save_fp_context(struct sigcontext __user *sc); +extern asmlinkage int _restore_fp_context(struct sigcontext __user *sc); + +extern asmlinkage int fpu_emulator_save_context(struct sigcontext __user *sc); +extern asmlinkage int fpu_emulator_restore_context(struct sigcontext __user *sc); + /* * Horribly complicated - with the bloody RM9000 workarounds enabled * the signal trampolines is moving to the end of the structure so we can @@ -709,3 +718,40 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, void *unused, key_replace_session_keyring(); } } + +#ifdef CONFIG_SMP +static int smp_save_fp_context(struct sigcontext __user *sc) +{ + return raw_cpu_has_fpu + ? _save_fp_context(sc) + : fpu_emulator_save_context(sc); +} + +static int smp_restore_fp_context(struct sigcontext __user *sc) +{ + return raw_cpu_has_fpu + ? _restore_fp_context(sc) + : fpu_emulator_restore_context(sc); +} +#endif + +static int signal_setup(void) +{ +#ifdef CONFIG_SMP + /* For now just do the cpu_has_fpu check when the functions are invoked */ + save_fp_context = smp_save_fp_context; + restore_fp_context = smp_restore_fp_context; +#else + if (cpu_has_fpu) { + save_fp_context = _save_fp_context; + restore_fp_context = _restore_fp_context; + } else { + save_fp_context = fpu_emulator_save_context; + restore_fp_context = fpu_emulator_restore_context; + } +#endif + + return 0; +} + +arch_initcall(signal_setup); diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c index 2e74075..03abaf0 100644 --- a/arch/mips/kernel/signal32.c +++ b/arch/mips/kernel/signal32.c @@ -35,6 +35,15 @@ #include "signal-common.h" +static int (*save_fp_context32)(struct sigcontext32 __user *sc); +static int (*restore_fp_context32)(struct sigcontext32 __user *sc); + +extern asmlinkage int _save_fp_context32(struct sigcontext32 __user *sc); +extern asmlinkage int _restore_fp_context32(struct sigcontext32 __user *sc); + +extern asmlinkage int fpu_emulator_save_context32(struct sigcontext32 __user *sc); +extern asmlinkage int fpu_emulator_restore_context32(struct sigcontext32 __user *sc); + /* * Including would give use the 64-bit syscall numbers ... */ @@ -828,3 +837,18 @@ SYSCALL_DEFINE5(32_waitid, int, which, compat_pid_t, pid, info.si_code |= __SI_CHLD; return copy_siginfo_to_user32(uinfo, &info); } + +static int signal32_init(void) +{ + if (cpu_has_fpu) { + save_fp_context32 = _save_fp_context32; + restore_fp_context32 = _restore_fp_context32; + } else { + save_fp_context32 = fpu_emulator_save_context32; + restore_fp_context32 = fpu_emulator_restore_context32; + } + + return 0; +} + +arch_initcall(signal32_init); diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 9fe21fb..308e434 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -1395,77 +1395,6 @@ void *set_vi_handler(int n, vi_handler_t addr) return set_vi_srs_handler(n, addr, 0); } -/* - * This is used by native signal handling - */ -asmlinkage int (*save_fp_context)(struct sigcontext __user *sc); -asmlinkage int (*restore_fp_context)(struct sigcontext __user *sc); - -extern asmlinkage int _save_fp_context(struct sigcontext __user *sc); -extern asmlinkage int _restore_fp_context(struct sigcontext __user *sc); - -extern asmlinkage int fpu_emulator_save_context(struct sigcontext __user *sc); -extern asmlinkage int fpu_emulator_restore_context(struct sigcontext __user *sc); - -#ifdef CONFIG_SMP -static int smp_save_fp_context(struct sigcontext __user *sc) -{ - return raw_cpu_has_fpu - ? _save_fp_context(sc) - : fpu_emulator_save_context(sc); -} - -static int smp_restore_fp_context(struct sigcontext __user *sc) -{ - return raw_cpu_has_fpu - ? _restore_fp_context(sc) - : fpu_emulator_restore_context(sc); -} -#endif - -static inline void signal_init(void) -{ -#ifdef CONFIG_SMP - /* For now just do the cpu_has_fpu check when the functions are invoked */ - save_fp_context = smp_save_fp_context; - restore_fp_context = smp_restore_fp_context; -#else - if (cpu_has_fpu) { - save_fp_context = _save_fp_context; - restore_fp_context = _restore_fp_context; - } else { - save_fp_context = fpu_emulator_save_context; - restore_fp_context = fpu_emulator_restore_context; - } -#endif -} - -#ifdef CONFIG_MIPS32_COMPAT - -/* - * This is used by 32-bit signal stuff on the 64-bit kernel - */ -asmlinkage int (*save_fp_context32)(struct sigcontext32 __user *sc); -asmlinkage int (*restore_fp_context32)(struct sigcontext32 __user *sc); - -extern asmlinkage int _save_fp_context32(struct sigcontext32 __user *sc); -extern asmlinkage int _restore_fp_context32(struct sigcontext32 __user *sc); - -extern asmlinkage int fpu_emulator_save_context32(struct sigcontext32 __user *sc); -extern asmlinkage int fpu_emulator_restore_context32(struct sigcontext32 __user *sc); - -static inline void signal32_init(void) -{ - if (cpu_has_fpu) { - save_fp_context32 = _save_fp_context32; - restore_fp_context32 = _restore_fp_context32; - } else { - save_fp_context32 = fpu_emulator_save_context32; - restore_fp_context32 = fpu_emulator_restore_context32; - } -} -#endif - extern void cpu_cache_init(void); extern void tlb_init(void); extern void flush_tlb_handlers(void); @@ -1779,11 +1708,6 @@ void __init trap_init(void) else memcpy((void *)(ebase + 0x080), &except_vec3_generic, 0x80); - signal_init(); -#ifdef CONFIG_MIPS32_COMPAT - signal32_init(); -#endif - local_flush_icache_range(ebase, ebase + 0x400); flush_tlb_handlers(); -- cgit v0.10.2 From c0b4abdd529d8256acc4cf0094db385877f34ae6 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Fri, 27 Nov 2009 09:55:03 +0300 Subject: MIPS: Lasat: Convert to proc_fops / seq_file Signed-off-by: Alexey Dobriyan Cc: akpm@linux-foundation.org Cc: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/725/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/lasat/picvue_proc.c b/arch/mips/lasat/picvue_proc.c index 0bb6037..8e388da 100644 --- a/arch/mips/lasat/picvue_proc.c +++ b/arch/mips/lasat/picvue_proc.c @@ -4,12 +4,14 @@ * Brian Murphy * */ +#include #include #include #include #include #include +#include #include #include @@ -38,12 +40,9 @@ static void pvc_display(unsigned long data) static DECLARE_TASKLET(pvc_display_tasklet, &pvc_display, 0); -static int pvc_proc_read_line(char *page, char **start, - off_t off, int count, - int *eof, void *data) +static int pvc_line_proc_show(struct seq_file *m, void *v) { - char *origpage = page; - int lineno = *(int *)data; + int lineno = *(int *)m->private; if (lineno < 0 || lineno > PVC_NLINES) { printk(KERN_WARNING "proc_read_line: invalid lineno %d\n", lineno); @@ -51,45 +50,66 @@ static int pvc_proc_read_line(char *page, char **start, } mutex_lock(&pvc_mutex); - page += sprintf(page, "%s\n", pvc_lines[lineno]); + seq_printf(m, "%s\n", pvc_lines[lineno]); mutex_unlock(&pvc_mutex); - return page - origpage; + return 0; } -static int pvc_proc_write_line(struct file *file, const char *buffer, - unsigned long count, void *data) +static int pvc_line_proc_open(struct inode *inode, struct file *file) { - int origcount = count; - int lineno = *(int *)data; + return single_open(file, pvc_line_proc_show, PDE(inode)->data); +} - if (lineno < 0 || lineno > PVC_NLINES) { - printk(KERN_WARNING "proc_write_line: invalid lineno %d\n", - lineno); - return origcount; - } +static ssize_t pvc_line_proc_write(struct file *file, const char __user *buf, + size_t count, loff_t *pos) +{ + int lineno = *(int *)PDE(file->f_path.dentry->d_inode)->data; + char kbuf[PVC_LINELEN]; + size_t len; + + BUG_ON(lineno < 0 || lineno > PVC_NLINES); - if (count > PVC_LINELEN) - count = PVC_LINELEN; + len = min(count, sizeof(kbuf) - 1); + if (copy_from_user(kbuf, buf, len)) + return -EFAULT; + kbuf[len] = '\0'; - if (buffer[count-1] == '\n') - count--; + if (len > 0 && kbuf[len - 1] == '\n') + len--; mutex_lock(&pvc_mutex); - strncpy(pvc_lines[lineno], buffer, count); - pvc_lines[lineno][count] = '\0'; + strncpy(pvc_lines[lineno], kbuf, len); + pvc_lines[lineno][len] = '\0'; mutex_unlock(&pvc_mutex); tasklet_schedule(&pvc_display_tasklet); - return origcount; + return count; } -static int pvc_proc_write_scroll(struct file *file, const char *buffer, - unsigned long count, void *data) +static const struct file_operations pvc_line_proc_fops = { + .owner = THIS_MODULE, + .open = pvc_line_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = pvc_line_proc_write, +}; + +static ssize_t pvc_scroll_proc_write(struct file *file, const char __user *buf, + size_t count, loff_t *pos) { - int origcount = count; - int cmd = simple_strtol(buffer, NULL, 10); + char kbuf[42]; + size_t len; + int cmd; + + len = min(count, sizeof(kbuf) - 1); + if (copy_from_user(kbuf, buf, len)) + return -EFAULT; + kbuf[len] = '\0'; + + cmd = simple_strtol(kbuf, NULL, 10); mutex_lock(&pvc_mutex); if (scroll_interval != 0) @@ -110,22 +130,31 @@ static int pvc_proc_write_scroll(struct file *file, const char *buffer, } mutex_unlock(&pvc_mutex); - return origcount; + return count; } -static int pvc_proc_read_scroll(char *page, char **start, - off_t off, int count, - int *eof, void *data) +static int pvc_scroll_proc_show(struct seq_file *m, void *v) { - char *origpage = page; - mutex_lock(&pvc_mutex); - page += sprintf(page, "%d\n", scroll_dir * scroll_interval); + seq_printf(m, "%d\n", scroll_dir * scroll_interval); mutex_unlock(&pvc_mutex); - return page - origpage; + return 0; } +static int pvc_scroll_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, pvc_scroll_proc_show, NULL); +} + +static const struct file_operations pvc_scroll_proc_fops = { + .owner = THIS_MODULE, + .open = pvc_scroll_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = pvc_scroll_proc_write, +}; void pvc_proc_timerfunc(unsigned long data) { @@ -163,22 +192,16 @@ static int __init pvc_proc_init(void) pvc_linedata[i] = i; } for (i = 0; i < PVC_NLINES; i++) { - proc_entry = create_proc_entry(pvc_linename[i], 0644, - pvc_display_dir); + proc_entry = proc_create_data(pvc_linename[i], 0644, pvc_display_dir, + &pvc_line_proc_fops, &pvc_linedata[i]); if (proc_entry == NULL) goto error; - - proc_entry->read_proc = pvc_proc_read_line; - proc_entry->write_proc = pvc_proc_write_line; - proc_entry->data = &pvc_linedata[i]; } - proc_entry = create_proc_entry("scroll", 0644, pvc_display_dir); + proc_entry = proc_create("scroll", 0644, pvc_display_dir, + &pvc_scroll_proc_fops); if (proc_entry == NULL) goto error; - proc_entry->write_proc = pvc_proc_write_scroll; - proc_entry->read_proc = pvc_proc_read_scroll; - init_timer(&timer); timer.function = pvc_proc_timerfunc; -- cgit v0.10.2 From 59d4a91416957c12ccc4185d90a62eb1b44b2fc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 24 Nov 2009 22:07:01 +0100 Subject: MIPS: Excite: move iodev_remove to .devexit.text MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The function iodev_remove is used only wrapped by __devexit_p so define it using __devexit. Signed-off-by: Uwe Kleine-König Cc: Ming Lei Cc: Henrique de Moraes Holschuh Cc: Greg Kroah-Hartman Cc: David Brownell Cc: linux-kernel@vger.kernel.org Cc: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/710/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/basler/excite/excite_iodev.c b/arch/mips/basler/excite/excite_iodev.c index 938b1d0..733b242 100644 --- a/arch/mips/basler/excite/excite_iodev.c +++ b/arch/mips/basler/excite/excite_iodev.c @@ -34,7 +34,7 @@ static const struct resource *iodev_get_resource(struct platform_device *, const char *, unsigned int); static int __init iodev_probe(struct platform_device *); -static int __exit iodev_remove(struct platform_device *); +static int __devexit iodev_remove(struct platform_device *); static int iodev_open(struct inode *, struct file *); static int iodev_release(struct inode *, struct file *); static ssize_t iodev_read(struct file *, char __user *, size_t s, loff_t *); @@ -103,7 +103,7 @@ static int __init iodev_probe(struct platform_device *dev) -static int __exit iodev_remove(struct platform_device *dev) +static int __devexit iodev_remove(struct platform_device *dev) { return misc_deregister(&miscdev); } -- cgit v0.10.2 From c47a48d83a7a82c86ff3e74bdcabeee8f6e6b730 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Tue, 24 Nov 2009 21:48:36 +0800 Subject: MIPS: Lemote 2F: Suspend CS5536 MFGPT Timer Before putting the Loongson 2F into wait mode, suspend the MFGPT Timer and after wake-up resume it. This may save some power. Signed-off-by: Wu Zhangjin Cc: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/706/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/loongson/lemote-2f/pm.c b/arch/mips/loongson/lemote-2f/pm.c index 81c0641..d7af2e6 100644 --- a/arch/mips/loongson/lemote-2f/pm.c +++ b/arch/mips/loongson/lemote-2f/pm.c @@ -22,6 +22,7 @@ #include +#include #include "ec_kb3310b.h" #define I8042_KBD_IRQ 1 @@ -136,3 +137,13 @@ int wakeup_loongson(void) return 0; } + +void __weak mach_suspend(void) +{ + disable_mfgpt0_counter(); +} + +void __weak mach_resume(void) +{ + enable_mfgpt0_counter(); +} -- cgit v0.10.2 From c3d8d85019c9e4f6e4f23d194b6432a2c2464372 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Sat, 28 Nov 2009 14:21:50 +0800 Subject: MIPS: Loongson: Cleanups of serial port support This patchs uses a loongson_uart_base variable instead of the uart_base[] array and adds a new kernel option to avoid to compile uart_base.c all the time, which will save a little bit of memory for us. Signed-off-by: Wu Zhangjin Cc: linux-mips@linux-mips.org http://patchwork.linux-mips.org/patch/727/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/include/asm/mach-loongson/loongson.h b/arch/mips/include/asm/mach-loongson/loongson.h index 06c28f3..ee8bc83 100644 --- a/arch/mips/include/asm/mach-loongson/loongson.h +++ b/arch/mips/include/asm/mach-loongson/loongson.h @@ -31,9 +31,17 @@ extern void __init prom_init_memory(void); extern void __init prom_init_cmdline(void); extern void __init prom_init_machtype(void); extern void __init prom_init_env(void); -extern unsigned long _loongson_uart_base; -extern unsigned long uart8250_base[]; -extern void prom_init_uart_base(void); +#ifdef CONFIG_LOONGSON_UART_BASE +extern unsigned long _loongson_uart_base, loongson_uart_base; +extern void prom_init_loongson_uart_base(void); +#endif + +static inline void prom_init_uart_base(void) +{ +#ifdef CONFIG_LOONGSON_UART_BASE + prom_init_loongson_uart_base(); +#endif +} /* irq operation functions */ extern void bonito_irqdispatch(void); diff --git a/arch/mips/loongson/Kconfig b/arch/mips/loongson/Kconfig index 7a86987..3df1967 100644 --- a/arch/mips/loongson/Kconfig +++ b/arch/mips/loongson/Kconfig @@ -78,3 +78,8 @@ config LOONGSON_SUSPEND bool default y depends on CPU_SUPPORTS_CPUFREQ && SUSPEND + +config LOONGSON_UART_BASE + bool + default y + depends on EARLY_PRINTK || SERIAL_8250 diff --git a/arch/mips/loongson/common/Makefile b/arch/mips/loongson/common/Makefile index 8d71892..7668c4d 100644 --- a/arch/mips/loongson/common/Makefile +++ b/arch/mips/loongson/common/Makefile @@ -3,13 +3,14 @@ # obj-y += setup.o init.o cmdline.o env.o time.o reset.o irq.o \ - pci.o bonito-irq.o mem.o machtype.o platform.o uart_base.o + pci.o bonito-irq.o mem.o machtype.o platform.o # -# Early printk support +# Serial port support # obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-$(CONFIG_SERIAL_8250) += serial.o +obj-$(CONFIG_LOONGSON_UART_BASE) += uart_base.o # # Enable CS5536 Virtual Support Module(VSM) to virtulize the PCI configure diff --git a/arch/mips/loongson/common/init.c b/arch/mips/loongson/common/init.c index 2b92a23..a2abd93 100644 --- a/arch/mips/loongson/common/init.c +++ b/arch/mips/loongson/common/init.c @@ -31,9 +31,7 @@ void __init prom_init(void) prom_init_memory(); /*init the uart base address */ -#if defined(CONFIG_EARLY_PRINTK) || defined(CONFIG_SERIAL_8250) prom_init_uart_base(); -#endif } void __init prom_free_prom_memory(void) diff --git a/arch/mips/loongson/common/serial.c b/arch/mips/loongson/common/serial.c index ea29db0..23b66a5 100644 --- a/arch/mips/loongson/common/serial.c +++ b/arch/mips/loongson/common/serial.c @@ -57,12 +57,16 @@ static struct platform_device uart8250_device = { static int __init serial_init(void) { - if (uart8250_data[mips_machtype][0].iotype == UPIO_MEM) + unsigned char iotype; + + iotype = uart8250_data[mips_machtype][0].iotype; + + if (UPIO_MEM == iotype) uart8250_data[mips_machtype][0].membase = (void __iomem *)_loongson_uart_base; - else if (uart8250_data[mips_machtype][0].iotype == UPIO_PORT) + else if (UPIO_PORT == iotype) uart8250_data[mips_machtype][0].iobase = - uart8250_base[mips_machtype] - LOONGSON_PCIIO_BASE; + loongson_uart_base - LOONGSON_PCIIO_BASE; uart8250_device.dev.platform_data = uart8250_data[mips_machtype]; diff --git a/arch/mips/loongson/common/uart_base.c b/arch/mips/loongson/common/uart_base.c index 1d636f4..78ff66a 100644 --- a/arch/mips/loongson/common/uart_base.c +++ b/arch/mips/loongson/common/uart_base.c @@ -13,24 +13,33 @@ #include -unsigned long __maybe_unused _loongson_uart_base; +/* ioremapped */ +unsigned long _loongson_uart_base; EXPORT_SYMBOL(_loongson_uart_base); +/* raw */ +unsigned long loongson_uart_base; +EXPORT_SYMBOL(loongson_uart_base); -unsigned long __maybe_unused uart8250_base[] = { - [MACH_LOONGSON_UNKNOWN] 0, - [MACH_LEMOTE_FL2E] (LOONGSON_PCIIO_BASE + 0x3f8), - [MACH_LEMOTE_FL2F] (LOONGSON_PCIIO_BASE + 0x2f8), - [MACH_LEMOTE_ML2F7] (LOONGSON_LIO1_BASE + 0x3f8), - [MACH_LEMOTE_YL2F89] (LOONGSON_LIO1_BASE + 0x3f8), - [MACH_DEXXON_GDIUM2F10] (LOONGSON_LIO1_BASE + 0x3f8), - [MACH_LEMOTE_NAS] (LOONGSON_LIO1_BASE + 0x3f8), - [MACH_LEMOTE_LL2F] (LOONGSON_PCIIO_BASE + 0x2f8), - [MACH_LOONGSON_END] 0, -}; -EXPORT_SYMBOL(uart8250_base); - -void __maybe_unused prom_init_uart_base(void) +void prom_init_loongson_uart_base(void) { + switch (mips_machtype) { + case MACH_LEMOTE_FL2E: + loongson_uart_base = LOONGSON_PCIIO_BASE + 0x3f8; + break; + case MACH_LEMOTE_FL2F: + case MACH_LEMOTE_LL2F: + loongson_uart_base = LOONGSON_PCIIO_BASE + 0x2f8; + break; + case MACH_LEMOTE_ML2F7: + case MACH_LEMOTE_YL2F89: + case MACH_DEXXON_GDIUM2F10: + case MACH_LEMOTE_NAS: + default: + /* The CPU provided serial port */ + loongson_uart_base = LOONGSON_LIO1_BASE + 0x3f8; + break; + } + _loongson_uart_base = - (unsigned long)ioremap_nocache(uart8250_base[mips_machtype], 8); + (unsigned long)ioremap_nocache(loongson_uart_base, 8); } -- cgit v0.10.2 From de4148f3ef54b644a181ad75a6fb4b373f2b01f0 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 17 Dec 2009 01:57:35 +0000 Subject: MIPS: eXcite: Remove platform. The platform has never been fully merged Signed-off-by: Ralf Baechle Cc: Thomas Koeller Cc: David Woodhouse Cc: Wim Van Sebroeck Cc: linux-kernel@vger.kernel.org Cc: linux-mtd@lists.infradead.org Acked-by: David Woodhouse Acked-by: Wim Van Sebroeck diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 0be245d..f374cca 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -50,23 +50,6 @@ config AR7 Support for the Texas Instruments AR7 System-on-a-Chip family: TNETD7100, 7200 and 7300. -config BASLER_EXCITE - bool "Basler eXcite smart camera" - select CEVT_R4K - select CSRC_R4K - select DMA_COHERENT - select HW_HAS_PCI - select IRQ_CPU - select IRQ_CPU_RM7K - select IRQ_CPU_RM9K - select MIPS_RM9122 - select SYS_HAS_CPU_RM9000 - select SYS_SUPPORTS_32BIT_KERNEL - select SYS_SUPPORTS_BIG_ENDIAN - help - The eXcite is a smart camera platform manufactured by - Basler Vision Technologies AG. - config BCM47XX bool "BCM47XX based boards" select CEVT_R4K @@ -701,7 +684,6 @@ config CAVIUM_OCTEON_REFERENCE_BOARD endchoice source "arch/mips/alchemy/Kconfig" -source "arch/mips/basler/excite/Kconfig" source "arch/mips/bcm63xx/Kconfig" source "arch/mips/jazz/Kconfig" source "arch/mips/lasat/Kconfig" diff --git a/arch/mips/Makefile b/arch/mips/Makefile index d2c39fd..1893efd 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -369,13 +369,6 @@ cflags-$(CONFIG_PMC_YOSEMITE) += -I$(srctree)/arch/mips/include/asm/mach-yosemit load-$(CONFIG_PMC_YOSEMITE) += 0xffffffff80100000 # -# Basler eXcite -# -core-$(CONFIG_BASLER_EXCITE) += arch/mips/basler/excite/ -cflags-$(CONFIG_BASLER_EXCITE) += -I$(srctree)/arch/mips/include/asm/mach-excite -load-$(CONFIG_BASLER_EXCITE) += 0x80100000 - -# # LASAT platforms # core-$(CONFIG_LASAT) += arch/mips/lasat/ diff --git a/arch/mips/basler/excite/Kconfig b/arch/mips/basler/excite/Kconfig deleted file mode 100644 index ba50607..0000000 --- a/arch/mips/basler/excite/Kconfig +++ /dev/null @@ -1,9 +0,0 @@ -config BASLER_EXCITE_PROTOTYPE - bool "Support for pre-release units" - depends on BASLER_EXCITE - default n - help - Pre-series (prototype) units are different from later ones in - some ways. Select this option if you have one of these. Please - note that a kernel built with this option selected will not be - able to run on normal units. diff --git a/arch/mips/basler/excite/Makefile b/arch/mips/basler/excite/Makefile deleted file mode 100644 index cff29cf..0000000 --- a/arch/mips/basler/excite/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# -# Makefile for Basler eXcite -# - -obj-$(CONFIG_BASLER_EXCITE) += excite_irq.o excite_prom.o excite_setup.o \ - excite_device.o excite_procfs.o - -obj-m += excite_iodev.o diff --git a/arch/mips/basler/excite/excite_device.c b/arch/mips/basler/excite/excite_device.c deleted file mode 100644 index e00bc2d..0000000 --- a/arch/mips/basler/excite/excite_device.c +++ /dev/null @@ -1,403 +0,0 @@ -/* - * Copyright (C) 2004 by Basler Vision Technologies AG - * Author: Thomas Koeller - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "excite_iodev.h" - -#define RM9K_GE_UNIT 0 -#define XICAP_UNIT 0 -#define NAND_UNIT 0 - -#define DLL_TIMEOUT 3 /* seconds */ - - -#define RINIT(__start__, __end__, __name__, __parent__) { \ - .name = __name__ "_0", \ - .start = (__start__), \ - .end = (__end__), \ - .flags = 0, \ - .parent = (__parent__) \ -} - -#define RINIT_IRQ(__irq__, __name__) { \ - .name = __name__ "_0", \ - .start = (__irq__), \ - .end = (__irq__), \ - .flags = IORESOURCE_IRQ, \ - .parent = NULL \ -} - - - -enum { - slice_xicap, - slice_eth -}; - - - -static struct resource - excite_ctr_resource __maybe_unused = { - .name = "GPI counters", - .start = 0, - .end = 5, - .flags = 0, - .parent = NULL, - .sibling = NULL, - .child = NULL - }, - excite_gpislice_resource __maybe_unused = { - .name = "GPI slices", - .start = 0, - .end = 1, - .flags = 0, - .parent = NULL, - .sibling = NULL, - .child = NULL - }, - excite_mdio_channel_resource __maybe_unused = { - .name = "MDIO channels", - .start = 0, - .end = 1, - .flags = 0, - .parent = NULL, - .sibling = NULL, - .child = NULL - }, - excite_fifomem_resource __maybe_unused = { - .name = "FIFO memory", - .start = 0, - .end = 767, - .flags = 0, - .parent = NULL, - .sibling = NULL, - .child = NULL - }, - excite_scram_resource __maybe_unused = { - .name = "Scratch RAM", - .start = EXCITE_PHYS_SCRAM, - .end = EXCITE_PHYS_SCRAM + EXCITE_SIZE_SCRAM - 1, - .flags = IORESOURCE_MEM, - .parent = NULL, - .sibling = NULL, - .child = NULL - }, - excite_fpga_resource __maybe_unused = { - .name = "System FPGA", - .start = EXCITE_PHYS_FPGA, - .end = EXCITE_PHYS_FPGA + EXCITE_SIZE_FPGA - 1, - .flags = IORESOURCE_MEM, - .parent = NULL, - .sibling = NULL, - .child = NULL - }, - excite_nand_resource __maybe_unused = { - .name = "NAND flash control", - .start = EXCITE_PHYS_NAND, - .end = EXCITE_PHYS_NAND + EXCITE_SIZE_NAND - 1, - .flags = IORESOURCE_MEM, - .parent = NULL, - .sibling = NULL, - .child = NULL - }, - excite_titan_resource __maybe_unused = { - .name = "TITAN registers", - .start = EXCITE_PHYS_TITAN, - .end = EXCITE_PHYS_TITAN + EXCITE_SIZE_TITAN - 1, - .flags = IORESOURCE_MEM, - .parent = NULL, - .sibling = NULL, - .child = NULL - }; - - - -static void adjust_resources(struct resource *res, unsigned int n) -{ - struct resource *p; - const unsigned long mask = IORESOURCE_IO | IORESOURCE_MEM - | IORESOURCE_IRQ | IORESOURCE_DMA; - - for (p = res; p < res + n; p++) { - const struct resource * const parent = p->parent; - if (parent) { - p->start += parent->start; - p->end += parent->start; - p->flags = parent->flags & mask; - } - } -} - - - -#if defined(CONFIG_EXCITE_FCAP_GPI) || defined(CONFIG_EXCITE_FCAP_GPI_MODULE) -static struct resource xicap_rsrc[] = { - RINIT(0x4840, 0x486f, XICAP_RESOURCE_FIFO_RX, &excite_titan_resource), - RINIT(0x4940, 0x494b, XICAP_RESOURCE_FIFO_TX, &excite_titan_resource), - RINIT(0x5040, 0x5127, XICAP_RESOURCE_XDMA, &excite_titan_resource), - RINIT(0x1000, 0x112f, XICAP_RESOURCE_PKTPROC, &excite_titan_resource), - RINIT(0x1100, 0x110f, XICAP_RESOURCE_PKT_STREAM, &excite_fpga_resource), - RINIT(0x0800, 0x0bff, XICAP_RESOURCE_DMADESC, &excite_scram_resource), - RINIT(slice_xicap, slice_xicap, XICAP_RESOURCE_GPI_SLICE, &excite_gpislice_resource), - RINIT(0x0100, 0x02ff, XICAP_RESOURCE_FIFO_BLK, &excite_fifomem_resource), - RINIT_IRQ(TITAN_IRQ, XICAP_RESOURCE_IRQ) -}; - -static struct platform_device xicap_pdev = { - .name = XICAP_NAME, - .id = XICAP_UNIT, - .num_resources = ARRAY_SIZE(xicap_rsrc), - .resource = xicap_rsrc -}; - -/* - * Create a platform device for the GPI port that receives the - * image data from the embedded camera. - */ -static int __init xicap_devinit(void) -{ - unsigned long tend; - u32 reg; - int retval; - - adjust_resources(xicap_rsrc, ARRAY_SIZE(xicap_rsrc)); - - /* Power up the slice and configure it. */ - reg = titan_readl(CPTC1R); - reg &= ~(0x11100 << slice_xicap); - titan_writel(reg, CPTC1R); - - /* Enable slice & DLL. */ - reg= titan_readl(CPRR); - reg &= ~(0x00030003 << (slice_xicap * 2)); - titan_writel(reg, CPRR); - - /* Wait for DLLs to lock */ - tend = jiffies + DLL_TIMEOUT * HZ; - while (time_before(jiffies, tend)) { - if (!(~titan_readl(CPDSR) & (0x1 << (slice_xicap * 4)))) - break; - yield(); - } - - if (~titan_readl(CPDSR) & (0x1 << (slice_xicap * 4))) { - printk(KERN_ERR "%s: DLL not locked after %u seconds\n", - xicap_pdev.name, DLL_TIMEOUT); - retval = -ETIME; - } else { - /* Register platform device */ - retval = platform_device_register(&xicap_pdev); - } - - return retval; -} - -device_initcall(xicap_devinit); -#endif /* defined(CONFIG_EXCITE_FCAP_GPI) || defined(CONFIG_EXCITE_FCAP_GPI_MODULE) */ - - - -#if defined(CONFIG_WDT_RM9K_GPI) || defined(CONFIG_WDT_RM9K_GPI_MODULE) -static struct resource wdt_rsrc[] = { - RINIT(0, 0, WDT_RESOURCE_COUNTER, &excite_ctr_resource), - RINIT(0x0084, 0x008f, WDT_RESOURCE_REGS, &excite_titan_resource), - RINIT_IRQ(TITAN_IRQ, WDT_RESOURCE_IRQ) -}; - -static struct platform_device wdt_pdev = { - .name = WDT_NAME, - .id = -1, - .num_resources = ARRAY_SIZE(wdt_rsrc), - .resource = wdt_rsrc -}; - -/* - * Create a platform device for the GPI port that receives the - * image data from the embedded camera. - */ -static int __init wdt_devinit(void) -{ - adjust_resources(wdt_rsrc, ARRAY_SIZE(wdt_rsrc)); - return platform_device_register(&wdt_pdev); -} - -device_initcall(wdt_devinit); -#endif /* defined(CONFIG_WDT_RM9K_GPI) || defined(CONFIG_WDT_RM9K_GPI_MODULE) */ - - - -static struct resource excite_nandflash_rsrc[] = { - RINIT(0x2000, 0x201f, EXCITE_NANDFLASH_RESOURCE_REGS, &excite_nand_resource) -}; - -static struct platform_device excite_nandflash_pdev = { - .name = "excite_nand", - .id = NAND_UNIT, - .num_resources = ARRAY_SIZE(excite_nandflash_rsrc), - .resource = excite_nandflash_rsrc -}; - -/* - * Create a platform device for the access to the nand-flash - * port - */ -static int __init excite_nandflash_devinit(void) -{ - adjust_resources(excite_nandflash_rsrc, ARRAY_SIZE(excite_nandflash_rsrc)); - - /* nothing to be done here */ - - /* Register platform device */ - return platform_device_register(&excite_nandflash_pdev); -} - -device_initcall(excite_nandflash_devinit); - - - -static struct resource iodev_rsrc[] = { - RINIT_IRQ(FPGA1_IRQ, IODEV_RESOURCE_IRQ) -}; - -static struct platform_device io_pdev = { - .name = IODEV_NAME, - .id = -1, - .num_resources = ARRAY_SIZE(iodev_rsrc), - .resource = iodev_rsrc -}; - -/* - * Create a platform device for the external I/O ports. - */ -static int __init io_devinit(void) -{ - adjust_resources(iodev_rsrc, ARRAY_SIZE(iodev_rsrc)); - return platform_device_register(&io_pdev); -} - -device_initcall(io_devinit); - - - - -#if defined(CONFIG_RM9K_GE) || defined(CONFIG_RM9K_GE_MODULE) -static struct resource rm9k_ge_rsrc[] = { - RINIT(0x2200, 0x27ff, RM9K_GE_RESOURCE_MAC, &excite_titan_resource), - RINIT(0x1800, 0x1fff, RM9K_GE_RESOURCE_MSTAT, &excite_titan_resource), - RINIT(0x2000, 0x212f, RM9K_GE_RESOURCE_PKTPROC, &excite_titan_resource), - RINIT(0x5140, 0x5227, RM9K_GE_RESOURCE_XDMA, &excite_titan_resource), - RINIT(0x4870, 0x489f, RM9K_GE_RESOURCE_FIFO_RX, &excite_titan_resource), - RINIT(0x494c, 0x4957, RM9K_GE_RESOURCE_FIFO_TX, &excite_titan_resource), - RINIT(0x0000, 0x007f, RM9K_GE_RESOURCE_FIFOMEM_RX, &excite_fifomem_resource), - RINIT(0x0080, 0x00ff, RM9K_GE_RESOURCE_FIFOMEM_TX, &excite_fifomem_resource), - RINIT(0x0180, 0x019f, RM9K_GE_RESOURCE_PHY, &excite_titan_resource), - RINIT(0x0000, 0x03ff, RM9K_GE_RESOURCE_DMADESC_RX, &excite_scram_resource), - RINIT(0x0400, 0x07ff, RM9K_GE_RESOURCE_DMADESC_TX, &excite_scram_resource), - RINIT(slice_eth, slice_eth, RM9K_GE_RESOURCE_GPI_SLICE, &excite_gpislice_resource), - RINIT(0, 0, RM9K_GE_RESOURCE_MDIO_CHANNEL, &excite_mdio_channel_resource), - RINIT_IRQ(TITAN_IRQ, RM9K_GE_RESOURCE_IRQ_MAIN), - RINIT_IRQ(PHY_IRQ, RM9K_GE_RESOURCE_IRQ_PHY) -}; - -static struct platform_device rm9k_ge_pdev = { - .name = RM9K_GE_NAME, - .id = RM9K_GE_UNIT, - .num_resources = ARRAY_SIZE(rm9k_ge_rsrc), - .resource = rm9k_ge_rsrc -}; - - - -/* - * Create a platform device for the Ethernet port. - */ -static int __init rm9k_ge_devinit(void) -{ - u32 reg; - - adjust_resources(rm9k_ge_rsrc, ARRAY_SIZE(rm9k_ge_rsrc)); - - /* Power up the slice and configure it. */ - reg = titan_readl(CPTC1R); - reg &= ~(0x11000 << slice_eth); - reg |= 0x100 << slice_eth; - titan_writel(reg, CPTC1R); - - /* Take the MAC out of reset, reset the DLLs. */ - reg = titan_readl(CPRR); - reg &= ~(0x00030000 << (slice_eth * 2)); - reg |= 0x3 << (slice_eth * 2); - titan_writel(reg, CPRR); - - return platform_device_register(&rm9k_ge_pdev); -} - -device_initcall(rm9k_ge_devinit); -#endif /* defined(CONFIG_RM9K_GE) || defined(CONFIG_RM9K_GE_MODULE) */ - - - -static int __init excite_setup_devs(void) -{ - int res; - u32 reg; - - /* Enable xdma and fifo interrupts */ - reg = titan_readl(0x0050); - titan_writel(reg | 0x18000000, 0x0050); - - res = request_resource(&iomem_resource, &excite_titan_resource); - if (res) - return res; - res = request_resource(&iomem_resource, &excite_scram_resource); - if (res) - return res; - res = request_resource(&iomem_resource, &excite_fpga_resource); - if (res) - return res; - res = request_resource(&iomem_resource, &excite_nand_resource); - if (res) - return res; - excite_fpga_resource.flags = excite_fpga_resource.parent->flags & - ( IORESOURCE_IO | IORESOURCE_MEM - | IORESOURCE_IRQ | IORESOURCE_DMA); - excite_nand_resource.flags = excite_nand_resource.parent->flags & - ( IORESOURCE_IO | IORESOURCE_MEM - | IORESOURCE_IRQ | IORESOURCE_DMA); - - return 0; -} - -arch_initcall(excite_setup_devs); - diff --git a/arch/mips/basler/excite/excite_iodev.c b/arch/mips/basler/excite/excite_iodev.c deleted file mode 100644 index 733b242..0000000 --- a/arch/mips/basler/excite/excite_iodev.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (C) 2005 by Basler Vision Technologies AG - * Author: Thomas Koeller - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "excite_iodev.h" - - - -static const struct resource *iodev_get_resource(struct platform_device *, const char *, unsigned int); -static int __init iodev_probe(struct platform_device *); -static int __devexit iodev_remove(struct platform_device *); -static int iodev_open(struct inode *, struct file *); -static int iodev_release(struct inode *, struct file *); -static ssize_t iodev_read(struct file *, char __user *, size_t s, loff_t *); -static unsigned int iodev_poll(struct file *, struct poll_table_struct *); -static irqreturn_t iodev_irqhdl(int, void *); - - - -static const char iodev_name[] = "iodev"; -static unsigned int iodev_irq; -static DECLARE_WAIT_QUEUE_HEAD(wq); - - - -static const struct file_operations fops = -{ - .owner = THIS_MODULE, - .open = iodev_open, - .release = iodev_release, - .read = iodev_read, - .poll = iodev_poll -}; - -static struct miscdevice miscdev = -{ - .minor = MISC_DYNAMIC_MINOR, - .name = iodev_name, - .fops = &fops -}; - -static struct platform_driver iodev_driver = { - .driver = { - .name = iodev_name, - .owner = THIS_MODULE, - }, - .probe = iodev_probe, - .remove = __devexit_p(iodev_remove), -}; - - - -static const struct resource * -iodev_get_resource(struct platform_device *pdv, const char *name, - unsigned int type) -{ - char buf[80]; - if (snprintf(buf, sizeof buf, "%s_0", name) >= sizeof buf) - return NULL; - return platform_get_resource_byname(pdv, type, buf); -} - - - -/* No hotplugging on the platform bus - use __init */ -static int __init iodev_probe(struct platform_device *dev) -{ - const struct resource * const ri = - iodev_get_resource(dev, IODEV_RESOURCE_IRQ, IORESOURCE_IRQ); - - if (unlikely(!ri)) - return -ENXIO; - - iodev_irq = ri->start; - return misc_register(&miscdev); -} - - - -static int __devexit iodev_remove(struct platform_device *dev) -{ - return misc_deregister(&miscdev); -} - -static int iodev_open(struct inode *i, struct file *f) -{ - int ret; - - ret = request_irq(iodev_irq, iodev_irqhdl, IRQF_DISABLED, - iodev_name, &miscdev); - - return ret; -} - -static int iodev_release(struct inode *i, struct file *f) -{ - free_irq(iodev_irq, &miscdev); - return 0; -} - - - - -static ssize_t -iodev_read(struct file *f, char __user *d, size_t s, loff_t *o) -{ - ssize_t ret; - DEFINE_WAIT(w); - - prepare_to_wait(&wq, &w, TASK_INTERRUPTIBLE); - if (!signal_pending(current)) - schedule(); - ret = signal_pending(current) ? -ERESTARTSYS : 0; - finish_wait(&wq, &w); - return ret; -} - - -static unsigned int iodev_poll(struct file *f, struct poll_table_struct *p) -{ - poll_wait(f, &wq, p); - return POLLOUT | POLLWRNORM; -} - -static irqreturn_t iodev_irqhdl(int irq, void *ctxt) -{ - wake_up(&wq); - - return IRQ_HANDLED; -} - -static int __init iodev_init_module(void) -{ - return platform_driver_register(&iodev_driver); -} - - - -static void __exit iodev_cleanup_module(void) -{ - platform_driver_unregister(&iodev_driver); -} - -module_init(iodev_init_module); -module_exit(iodev_cleanup_module); - - - -MODULE_AUTHOR("Thomas Koeller "); -MODULE_DESCRIPTION("Basler eXcite i/o interrupt handler"); -MODULE_VERSION("0.0"); -MODULE_LICENSE("GPL"); diff --git a/arch/mips/basler/excite/excite_iodev.h b/arch/mips/basler/excite/excite_iodev.h deleted file mode 100644 index cbfbb5d..0000000 --- a/arch/mips/basler/excite/excite_iodev.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __EXCITE_IODEV_H__ -#define __EXCITE_IODEV_H__ - -/* Device name */ -#define IODEV_NAME "iodev" - -/* Resource names */ -#define IODEV_RESOURCE_IRQ "excite_iodev_irq" - -#endif /* __EXCITE_IODEV_H__ */ diff --git a/arch/mips/basler/excite/excite_irq.c b/arch/mips/basler/excite/excite_irq.c deleted file mode 100644 index 934e0a6..0000000 --- a/arch/mips/basler/excite/excite_irq.c +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (C) by Basler Vision Technologies AG - * Author: Thomas Koeller - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -extern asmlinkage void excite_handle_int(void); - -/* - * Initialize the interrupt handler - */ -void __init arch_init_irq(void) -{ - mips_cpu_irq_init(); - rm7k_cpu_irq_init(); - rm9k_cpu_irq_init(); -} - -asmlinkage void plat_irq_dispatch(void) -{ - const u32 - interrupts = read_c0_cause() >> 8, - mask = ((read_c0_status() >> 8) & 0x000000ff) | - (read_c0_intcontrol() & 0x0000ff00), - pending = interrupts & mask; - u32 msgintflags, msgintmask, msgint; - - /* process timer interrupt */ - if (pending & (1 << TIMER_IRQ)) { - do_IRQ(TIMER_IRQ); - return; - } - - /* Process PCI interrupts */ -#if USB_IRQ < 10 - msgintflags = ocd_readl(INTP0Status0 + (USB_MSGINT / 0x20 * 0x10)); - msgintmask = ocd_readl(INTP0Mask0 + (USB_MSGINT / 0x20 * 0x10)); - msgint = msgintflags & msgintmask & (0x1 << (USB_MSGINT % 0x20)); - if ((pending & (1 << USB_IRQ)) && msgint) { -#else - if (pending & (1 << USB_IRQ)) { -#endif - do_IRQ(USB_IRQ); - return; - } - - /* Process TITAN interrupts */ - msgintflags = ocd_readl(INTP0Status0 + (TITAN_MSGINT / 0x20 * 0x10)); - msgintmask = ocd_readl(INTP0Mask0 + (TITAN_MSGINT / 0x20 * 0x10)); - msgint = msgintflags & msgintmask & (0x1 << (TITAN_MSGINT % 0x20)); - if ((pending & (1 << TITAN_IRQ)) && msgint) { - ocd_writel(msgint, INTP0Clear0 + (TITAN_MSGINT / 0x20 * 0x10)); - do_IRQ(TITAN_IRQ); - return; - } - - /* Process FPGA line #0 interrupts */ - msgintflags = ocd_readl(INTP0Status0 + (FPGA0_MSGINT / 0x20 * 0x10)); - msgintmask = ocd_readl(INTP0Mask0 + (FPGA0_MSGINT / 0x20 * 0x10)); - msgint = msgintflags & msgintmask & (0x1 << (FPGA0_MSGINT % 0x20)); - if ((pending & (1 << FPGA0_IRQ)) && msgint) { - do_IRQ(FPGA0_IRQ); - return; - } - - /* Process FPGA line #1 interrupts */ - msgintflags = ocd_readl(INTP0Status0 + (FPGA1_MSGINT / 0x20 * 0x10)); - msgintmask = ocd_readl(INTP0Mask0 + (FPGA1_MSGINT / 0x20 * 0x10)); - msgint = msgintflags & msgintmask & (0x1 << (FPGA1_MSGINT % 0x20)); - if ((pending & (1 << FPGA1_IRQ)) && msgint) { - do_IRQ(FPGA1_IRQ); - return; - } - - /* Process PHY interrupts */ - msgintflags = ocd_readl(INTP0Status0 + (PHY_MSGINT / 0x20 * 0x10)); - msgintmask = ocd_readl(INTP0Mask0 + (PHY_MSGINT / 0x20 * 0x10)); - msgint = msgintflags & msgintmask & (0x1 << (PHY_MSGINT % 0x20)); - if ((pending & (1 << PHY_IRQ)) && msgint) { - do_IRQ(PHY_IRQ); - return; - } - - /* Process spurious interrupts */ - spurious_interrupt(); -} diff --git a/arch/mips/basler/excite/excite_procfs.c b/arch/mips/basler/excite/excite_procfs.c deleted file mode 100644 index 08923e6..0000000 --- a/arch/mips/basler/excite/excite_procfs.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2004, 2005 by Basler Vision Technologies AG - * Author: Thomas Koeller - * - * Procfs support for Basler eXcite - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -static int excite_unit_id_proc_show(struct seq_file *m, void *v) -{ - seq_printf(m, "%06x", unit_id); - return 0; -} - -static int excite_unit_id_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, excite_unit_id_proc_show, NULL); -} - -static const struct file_operations excite_unit_id_proc_fops = { - .owner = THIS_MODULE, - .open = excite_unit_id_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static int -excite_bootrom_read(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - void __iomem * src; - - if (off >= EXCITE_SIZE_BOOTROM) { - *eof = 1; - return 0; - } - - if ((off + count) > EXCITE_SIZE_BOOTROM) - count = EXCITE_SIZE_BOOTROM - off; - - src = ioremap(EXCITE_PHYS_BOOTROM + off, count); - if (src) { - memcpy_fromio(page, src, count); - iounmap(src); - *start = page; - } else { - count = -ENOMEM; - } - - return count; -} - -void excite_procfs_init(void) -{ - /* Create & populate /proc/excite */ - struct proc_dir_entry * const pdir = proc_mkdir("excite", NULL); - if (pdir) { - struct proc_dir_entry * e; - - e = proc_create("unit_id", S_IRUGO, pdir, - &excite_unit_id_proc_fops); - if (e) e->size = 6; - - e = create_proc_read_entry("bootrom", S_IRUGO, pdir, - excite_bootrom_read, NULL); - if (e) e->size = EXCITE_SIZE_BOOTROM; - } -} diff --git a/arch/mips/basler/excite/excite_prom.c b/arch/mips/basler/excite/excite_prom.c deleted file mode 100644 index 68d8bc5..0000000 --- a/arch/mips/basler/excite/excite_prom.c +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (C) 2004, 2005 by Thomas Koeller (thomas.koeller@baslerweb.com) - * Based on the PMC-Sierra Yosemite board support by Ralf Baechle and - * Manish Lachwani. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -/* This struct is used by Redboot to pass arguments to the kernel */ -typedef struct -{ - char *name; - char *val; -} t_env_var; - -struct parmblock { - t_env_var memsize; - t_env_var modetty0; - t_env_var ethaddr; - t_env_var env_end; - char *argv[2]; - char text[0]; -}; - -static unsigned int prom_argc; -static const char ** prom_argv; -static const t_env_var * prom_env; - -static void prom_halt(void) __attribute__((noreturn)); -static void prom_exit(void) __attribute__((noreturn)); - - - -const char *get_system_type(void) -{ - return "Basler eXcite"; -} - -/* - * Halt the system - */ -static void prom_halt(void) -{ - printk(KERN_NOTICE "\n** System halted.\n"); - while (1) - asm volatile ( - "\t.set\tmips3\n" - "\twait\n" - "\t.set\tmips0\n" - ); -} - -/* - * Reset the CPU and re-enter Redboot - */ -static void prom_exit(void) -{ - unsigned int i; - volatile unsigned char * const flg = - (volatile unsigned char *) (EXCITE_ADDR_FPGA + EXCITE_FPGA_DPR); - - /* Clear the watchdog reset flag, set the reboot flag */ - *flg &= ~0x01; - *flg |= 0x80; - - for (i = 0; i < 10; i++) { - *(volatile unsigned char *) (EXCITE_ADDR_FPGA + EXCITE_FPGA_SYSCTL) = 0x02; - iob(); - mdelay(1000); - } - - printk(KERN_NOTICE "Reset failed\n"); - prom_halt(); -} - -static const char __init *prom_getenv(char *name) -{ - const t_env_var * p; - for (p = prom_env; p->name != NULL; p++) - if(strcmp(name, p->name) == 0) - break; - return p->val; -} - -/* - * Init routine which accepts the variables from Redboot - */ -void __init prom_init(void) -{ - const struct parmblock * const pb = (struct parmblock *) fw_arg2; - - prom_argc = fw_arg0; - prom_argv = (const char **) fw_arg1; - prom_env = &pb->memsize; - - /* Callbacks for halt, restart */ - _machine_restart = (void (*)(char *)) prom_exit; - _machine_halt = prom_halt; - -#ifdef CONFIG_32BIT - /* copy command line */ - strcpy(arcs_cmdline, prom_argv[1]); - memsize = simple_strtol(prom_getenv("memsize"), NULL, 16); - strcpy(modetty, prom_getenv("modetty0")); -#endif /* CONFIG_32BIT */ - -#ifdef CONFIG_64BIT -# error 64 bit support not implemented -#endif /* CONFIG_64BIT */ -} - -/* This is called from free_initmem(), so we need to provide it */ -void __init prom_free_prom_memory(void) -{ - /* Nothing to do */ -} diff --git a/arch/mips/basler/excite/excite_setup.c b/arch/mips/basler/excite/excite_setup.c deleted file mode 100644 index d66b3b8..0000000 --- a/arch/mips/basler/excite/excite_setup.c +++ /dev/null @@ -1,302 +0,0 @@ -/* - * Copyright (C) 2004, 2005 by Basler Vision Technologies AG - * Author: Thomas Koeller - * Based on the PMC-Sierra Yosemite board support by Ralf Baechle and - * Manish Lachwani. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define TITAN_UART_CLK 25000000 - -#if 1 -/* normal serial port assignment */ -#define REGBASE_SER0 0x0208 -#define REGBASE_SER1 0x0238 -#define MASK_SER0 0x1 -#define MASK_SER1 0x2 -#else -/* serial ports swapped */ -#define REGBASE_SER0 0x0238 -#define REGBASE_SER1 0x0208 -#define MASK_SER0 0x2 -#define MASK_SER1 0x1 -#endif - -unsigned long memsize; -char modetty[30]; -unsigned int titan_irq = TITAN_IRQ; -static void __iomem * ctl_regs; -u32 unit_id; - -volatile void __iomem * const ocd_base = (void *) (EXCITE_ADDR_OCD); -volatile void __iomem * const titan_base = (void *) (EXCITE_ADDR_TITAN); - -/* Protect access to shared GPI registers */ -DEFINE_SPINLOCK(titan_lock); -int titan_irqflags; - - -/* - * The eXcite platform uses the alternate timer interrupt - * - * Fixme: At the time of this writing cevt-r4k.c doesn't yet know about how - * to handle the alternate timer interrupt of the RM9000. - */ -void __init plat_time_init(void) -{ - const u32 modebit5 = ocd_readl(0x00e4); - unsigned int mult = ((modebit5 >> 11) & 0x1f) + 2; - unsigned int div = ((modebit5 >> 16) & 0x1f) + 2; - - if (div == 33) - div = 1; - mips_hpt_frequency = EXCITE_CPU_EXT_CLOCK * mult / div / 2; -} - -static int __init excite_init_console(void) -{ -#if defined(CONFIG_SERIAL_8250) - static __initdata char serr[] = - KERN_ERR "Serial port #%u setup failed\n"; - struct uart_port up; - - /* Take the DUART out of reset */ - titan_writel(0x00ff1cff, CPRR); - -#if (CONFIG_SERIAL_8250_NR_UARTS > 1) - /* Enable both ports */ - titan_writel(MASK_SER0 | MASK_SER1, UACFG); -#else - /* Enable port #0 only */ - titan_writel(MASK_SER0, UACFG); -#endif - - /* - * Set up serial port #0. Do not use autodetection; the result is - * not what we want. - */ - memset(&up, 0, sizeof(up)); - up.membase = (char *) titan_addr(REGBASE_SER0); - up.irq = TITAN_IRQ; - up.uartclk = TITAN_UART_CLK; - up.regshift = 0; - up.iotype = UPIO_RM9000; - up.type = PORT_RM9000; - up.flags = UPF_SHARE_IRQ; - up.line = 0; - if (early_serial_setup(&up)) - printk(serr, up.line); - -#if CONFIG_SERIAL_8250_NR_UARTS > 1 - /* And now for port #1. */ - up.membase = (char *) titan_addr(REGBASE_SER1); - up.line = 1; - if (early_serial_setup(&up)) - printk(serr, up.line); -#endif /* CONFIG_SERIAL_8250_NR_UARTS > 1 */ -#else - /* Leave the DUART in reset */ - titan_writel(0x00ff3cff, CPRR); -#endif /* defined(CONFIG_SERIAL_8250) */ - - return 0; -} - -static int __init excite_platform_init(void) -{ - unsigned int i; - unsigned char buf[3]; - u8 reg; - void __iomem * dpr; - - /* BIU buffer allocations */ - ocd_writel(8, CPURSLMT); /* CPU */ - titan_writel(4, CPGRWL); /* GPI / Ethernet */ - - /* Map control registers located in FPGA */ - ctl_regs = ioremap_nocache(EXCITE_PHYS_FPGA + EXCITE_FPGA_SYSCTL, 16); - if (!ctl_regs) - panic("eXcite: failed to map platform control registers\n"); - memcpy_fromio(buf, ctl_regs + 2, ARRAY_SIZE(buf)); - unit_id = buf[0] | (buf[1] << 8) | (buf[2] << 16); - - /* Clear the reboot flag */ - dpr = ioremap_nocache(EXCITE_PHYS_FPGA + EXCITE_FPGA_DPR, 1); - reg = __raw_readb(dpr); - __raw_writeb(reg & 0x7f, dpr); - iounmap(dpr); - - /* Interrupt controller setup */ - for (i = INTP0Status0; i < INTP0Status0 + 0x80; i += 0x10) { - ocd_writel(0x00000000, i + 0x04); - ocd_writel(0xffffffff, i + 0x0c); - } - ocd_writel(0x2, NMICONFIG); - - ocd_writel(0x1 << (TITAN_MSGINT % 0x20), - INTP0Mask0 + (0x10 * (TITAN_MSGINT / 0x20))); - ocd_writel((0x1 << (FPGA0_MSGINT % 0x20)) - | ocd_readl(INTP0Mask0 + (0x10 * (FPGA0_MSGINT / 0x20))), - INTP0Mask0 + (0x10 * (FPGA0_MSGINT / 0x20))); - ocd_writel((0x1 << (FPGA1_MSGINT % 0x20)) - | ocd_readl(INTP0Mask0 + (0x10 * (FPGA1_MSGINT / 0x20))), - INTP0Mask0 + (0x10 * (FPGA1_MSGINT / 0x20))); - ocd_writel((0x1 << (PHY_MSGINT % 0x20)) - | ocd_readl(INTP0Mask0 + (0x10 * (PHY_MSGINT / 0x20))), - INTP0Mask0 + (0x10 * (PHY_MSGINT / 0x20))); -#if USB_IRQ < 10 - ocd_writel((0x1 << (USB_MSGINT % 0x20)) - | ocd_readl(INTP0Mask0 + (0x10 * (USB_MSGINT / 0x20))), - INTP0Mask0 + (0x10 * (USB_MSGINT / 0x20))); -#endif - /* Enable the packet FIFO, XDMA and XDMA arbiter */ - titan_writel(0x00ff18ff, CPRR); - - /* - * Set up the PADMUX. Power down all ethernet slices, - * they will be powered up and configured at device startup. - */ - titan_writel(0x00878206, CPTC1R); - titan_writel(0x00001100, CPTC0R); /* latch PADMUX, enable WCIMODE */ - - /* Reset and enable the FIFO block */ - titan_writel(0x00000001, SDRXFCIE); - titan_writel(0x00000001, SDTXFCIE); - titan_writel(0x00000100, SDRXFCIE); - titan_writel(0x00000000, SDTXFCIE); - - /* - * Initialize the common interrupt shared by all components of - * the GPI/Ethernet subsystem. - */ - titan_writel((EXCITE_PHYS_OCD >> 12), CPCFG0); - titan_writel(TITAN_MSGINT, CPCFG1); - - /* - * XDMA configuration. - * In order for the XDMA to be sharable among multiple drivers, - * the setup must be done here in the platform. The reason is that - * this setup can only be done while the XDMA is in reset. If this - * were done in a driver, it would interrupt all other drivers - * using the XDMA. - */ - titan_writel(0x80021dff, GXCFG); /* XDMA reset */ - titan_writel(0x00000000, CPXCISRA); - titan_writel(0x00000000, CPXCISRB); /* clear pending interrupts */ -#if defined(CONFIG_HIGHMEM) -# error change for HIGHMEM support! -#else - titan_writel(0x00000000, GXDMADRPFX); /* buffer address prefix */ -#endif - titan_writel(0, GXDMA_DESCADR); - - for (i = 0x5040; i <= 0x5300; i += 0x0040) - titan_writel(0x80080000, i); /* reset channel */ - - titan_writel((0x1 << 29) /* no sparse tx descr. */ - | (0x1 << 28) /* no sparse rx descr. */ - | (0x1 << 23) | (0x1 << 24) /* descriptor coherency */ - | (0x1 << 21) | (0x1 << 22) /* data coherency */ - | (0x1 << 17) - | 0x1dff, - GXCFG); - -#if defined(CONFIG_SMP) -# error No SMP support -#else - /* All interrupts go to core #0 only. */ - titan_writel(0x1f007fff, CPDST0A); - titan_writel(0x00000000, CPDST0B); - titan_writel(0x0000ff3f, CPDST1A); - titan_writel(0x00000000, CPDST1B); - titan_writel(0x00ffffff, CPXDSTA); - titan_writel(0x00000000, CPXDSTB); -#endif - - /* Enable DUART interrupts, disable everything else. */ - titan_writel(0x04000000, CPGIG0ER); - titan_writel(0x000000c0, CPGIG1ER); - - excite_procfs_init(); - return 0; -} - -void __init plat_mem_setup(void) -{ - volatile u32 * const boot_ocd_base = (u32 *) 0xbf7fc000; - - /* Announce RAM to system */ - add_memory_region(0x00000000, memsize, BOOT_MEM_RAM); - - /* Set up the peripheral address map */ - *(boot_ocd_base + (LKB9 / sizeof(u32))) = 0; - *(boot_ocd_base + (LKB10 / sizeof(u32))) = 0; - *(boot_ocd_base + (LKB11 / sizeof(u32))) = 0; - *(boot_ocd_base + (LKB12 / sizeof(u32))) = 0; - wmb(); - *(boot_ocd_base + (LKB0 / sizeof(u32))) = EXCITE_PHYS_OCD >> 4; - wmb(); - - ocd_writel((EXCITE_PHYS_TITAN >> 4) | 0x1UL, LKB5); - ocd_writel(((EXCITE_SIZE_TITAN >> 4) & 0x7fffff00) - 0x100, LKM5); - ocd_writel((EXCITE_PHYS_SCRAM >> 4) | 0x1UL, LKB13); - ocd_writel(((EXCITE_SIZE_SCRAM >> 4) & 0xffffff00) - 0x100, LKM13); - - /* Local bus slot #0 */ - ocd_writel(0x00040510, LDP0); - ocd_writel((EXCITE_PHYS_BOOTROM >> 4) | 0x1UL, LKB9); - ocd_writel(((EXCITE_SIZE_BOOTROM >> 4) & 0x03ffff00) - 0x100, LKM9); - - /* Local bus slot #2 */ - ocd_writel(0x00000330, LDP2); - ocd_writel((EXCITE_PHYS_FPGA >> 4) | 0x1, LKB11); - ocd_writel(((EXCITE_SIZE_FPGA >> 4) - 0x100) & 0x03ffff00, LKM11); - - /* Local bus slot #3 */ - ocd_writel(0x00123413, LDP3); - ocd_writel((EXCITE_PHYS_NAND >> 4) | 0x1, LKB12); - ocd_writel(((EXCITE_SIZE_NAND >> 4) - 0x100) & 0x03ffff00, LKM12); -} - - - -console_initcall(excite_init_console); -arch_initcall(excite_platform_init); - -EXPORT_SYMBOL(titan_lock); -EXPORT_SYMBOL(titan_irqflags); -EXPORT_SYMBOL(titan_irq); -EXPORT_SYMBOL(ocd_base); -EXPORT_SYMBOL(titan_base); diff --git a/arch/mips/configs/ar7_defconfig b/arch/mips/configs/ar7_defconfig index 2cb304a..1d5ec3c 100644 --- a/arch/mips/configs/ar7_defconfig +++ b/arch/mips/configs/ar7_defconfig @@ -10,7 +10,6 @@ CONFIG_MIPS=y # # CONFIG_MACH_ALCHEMY is not set CONFIG_AR7=y -# CONFIG_BASLER_EXCITE is not set # CONFIG_BCM47XX is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set diff --git a/arch/mips/configs/bcm47xx_defconfig b/arch/mips/configs/bcm47xx_defconfig index 94b7d57..8715de1 100644 --- a/arch/mips/configs/bcm47xx_defconfig +++ b/arch/mips/configs/bcm47xx_defconfig @@ -9,7 +9,6 @@ CONFIG_MIPS=y # Machine selection # # CONFIG_MACH_ALCHEMY is not set -# CONFIG_BASLER_EXCITE is not set CONFIG_BCM47XX=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set diff --git a/arch/mips/configs/bcm63xx_defconfig b/arch/mips/configs/bcm63xx_defconfig index ea00c18..efa6598 100644 --- a/arch/mips/configs/bcm63xx_defconfig +++ b/arch/mips/configs/bcm63xx_defconfig @@ -9,7 +9,6 @@ CONFIG_MIPS=y # Machine selection # # CONFIG_MACH_ALCHEMY is not set -# CONFIG_BASLER_EXCITE is not set # CONFIG_BCM47XX is not set CONFIG_BCM63XX=y # CONFIG_MIPS_COBALT is not set diff --git a/arch/mips/configs/bigsur_defconfig b/arch/mips/configs/bigsur_defconfig index 13d9eb4..1f0228d 100644 --- a/arch/mips/configs/bigsur_defconfig +++ b/arch/mips/configs/bigsur_defconfig @@ -9,7 +9,6 @@ CONFIG_MIPS=y # Machine selection # # CONFIG_MACH_ALCHEMY is not set -# CONFIG_BASLER_EXCITE is not set # CONFIG_BCM47XX is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set diff --git a/arch/mips/configs/capcella_defconfig b/arch/mips/configs/capcella_defconfig index 185df23..be81bf6 100644 --- a/arch/mips/configs/capcella_defconfig +++ b/arch/mips/configs/capcella_defconfig @@ -9,7 +9,6 @@ CONFIG_MIPS=y # Machine selection # # CONFIG_MACH_ALCHEMY is not set -# CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set diff --git a/arch/mips/configs/cavium-octeon_defconfig b/arch/mips/configs/cavium-octeon_defconfig index 1819a4c..22819d9 100644 --- a/arch/mips/configs/cavium-octeon_defconfig +++ b/arch/mips/configs/cavium-octeon_defconfig @@ -9,7 +9,6 @@ CONFIG_MIPS=y # Machine selection # # CONFIG_MACH_ALCHEMY is not set -# CONFIG_BASLER_EXCITE is not set # CONFIG_BCM47XX is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set diff --git a/arch/mips/configs/cobalt_defconfig b/arch/mips/configs/cobalt_defconfig index 6c8cca8..b150286 100644 --- a/arch/mips/configs/cobalt_defconfig +++ b/arch/mips/configs/cobalt_defconfig @@ -9,7 +9,6 @@ CONFIG_MIPS=y # Machine selection # # CONFIG_MACH_ALCHEMY is not set -# CONFIG_BASLER_EXCITE is not set # CONFIG_BCM47XX is not set CONFIG_MIPS_COBALT=y # CONFIG_MACH_DECSTATION is not set diff --git a/arch/mips/configs/db1000_defconfig b/arch/mips/configs/db1000_defconfig index dbdf3bb..63cdea2 100644 --- a/arch/mips/configs/db1000_defconfig +++ b/arch/mips/configs/db1000_defconfig @@ -23,7 +23,6 @@ CONFIG_MIPS_DB1000=y # CONFIG_MIPS_DB1550 is not set # CONFIG_MIPS_DB1200 is not set # CONFIG_MIPS_MIRAGE is not set -# CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set diff --git a/arch/mips/configs/db1100_defconfig b/arch/mips/configs/db1100_defconfig index fa68144..7ae0f9a 100644 --- a/arch/mips/configs/db1100_defconfig +++ b/arch/mips/configs/db1100_defconfig @@ -23,7 +23,6 @@ CONFIG_MIPS_DB1100=y # CONFIG_MIPS_DB1550 is not set # CONFIG_MIPS_DB1200 is not set # CONFIG_MIPS_MIRAGE is not set -# CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set diff --git a/arch/mips/configs/db1200_defconfig b/arch/mips/configs/db1200_defconfig index d73f1de..a6d9e1f 100644 --- a/arch/mips/configs/db1200_defconfig +++ b/arch/mips/configs/db1200_defconfig @@ -23,7 +23,6 @@ CONFIG_MACH_ALCHEMY=y # CONFIG_MIPS_DB1550 is not set CONFIG_MIPS_DB1200=y # CONFIG_MIPS_MIRAGE is not set -# CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set diff --git a/arch/mips/configs/db1500_defconfig b/arch/mips/configs/db1500_defconfig index ec3e028a..a3a462b 100644 --- a/arch/mips/configs/db1500_defconfig +++ b/arch/mips/configs/db1500_defconfig @@ -23,7 +23,6 @@ CONFIG_MIPS_DB1500=y # CONFIG_MIPS_DB1550 is not set # CONFIG_MIPS_DB1200 is not set # CONFIG_MIPS_MIRAGE is not set -# CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set diff --git a/arch/mips/configs/db1550_defconfig b/arch/mips/configs/db1550_defconfig index 7631dae..bfc962e 100644 --- a/arch/mips/configs/db1550_defconfig +++ b/arch/mips/configs/db1550_defconfig @@ -23,7 +23,6 @@ CONFIG_MACH_ALCHEMY=y CONFIG_MIPS_DB1550=y # CONFIG_MIPS_DB1200 is not set # CONFIG_MIPS_MIRAGE is not set -# CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set diff --git a/arch/mips/configs/decstation_defconfig b/arch/mips/configs/decstation_defconfig index 9e65e6a..7eb6d1b 100644 --- a/arch/mips/configs/decstation_defconfig +++ b/arch/mips/configs/decstation_defconfig @@ -22,7 +22,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_DB1550 is not set # CONFIG_MIPS_DB1200 is not set # CONFIG_MIPS_MIRAGE is not set -# CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set CONFIG_MACH_DECSTATION=y # CONFIG_MACH_JAZZ is not set diff --git a/arch/mips/configs/e55_defconfig b/arch/mips/configs/e55_defconfig index 1bd84d4..c6b1d6b 100644 --- a/arch/mips/configs/e55_defconfig +++ b/arch/mips/configs/e55_defconfig @@ -9,7 +9,6 @@ CONFIG_MIPS=y # Machine selection # # CONFIG_MACH_ALCHEMY is not set -# CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set diff --git a/arch/mips/configs/excite_defconfig b/arch/mips/configs/excite_defconfig deleted file mode 100644 index 1995d43..0000000 --- a/arch/mips/configs/excite_defconfig +++ /dev/null @@ -1,1335 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.20 -# Tue Feb 20 21:47:31 2007 -# -CONFIG_MIPS=y - -# -# Machine selection -# -CONFIG_ZONE_DMA=y -# CONFIG_MIPS_MTX1 is not set -# CONFIG_MIPS_BOSPORUS is not set -# CONFIG_MIPS_PB1000 is not set -# CONFIG_MIPS_PB1100 is not set -# CONFIG_MIPS_PB1500 is not set -# CONFIG_MIPS_PB1550 is not set -# CONFIG_MIPS_PB1200 is not set -# CONFIG_MIPS_DB1000 is not set -# CONFIG_MIPS_DB1100 is not set -# CONFIG_MIPS_DB1500 is not set -# CONFIG_MIPS_DB1550 is not set -# CONFIG_MIPS_DB1200 is not set -# CONFIG_MIPS_MIRAGE is not set -CONFIG_BASLER_EXCITE=y -# CONFIG_BASLER_EXCITE_PROTOTYPE is not set -# CONFIG_MIPS_COBALT is not set -# CONFIG_MACH_DECSTATION is not set -# CONFIG_MACH_JAZZ is not set -# CONFIG_MIPS_MALTA is not set -# CONFIG_WR_PPMC is not set -# CONFIG_MIPS_SIM is not set -# CONFIG_MOMENCO_JAGUAR_ATX is not set -# CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_JBS is not set -# CONFIG_PNX8550_STB810 is not set -# CONFIG_MACH_VR41XX is not set -# CONFIG_PMC_YOSEMITE is not set -# CONFIG_MARKEINS is not set -# CONFIG_SGI_IP22 is not set -# CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set -# CONFIG_SIBYTE_BIGSUR is not set -# CONFIG_SIBYTE_SWARM is not set -# CONFIG_SIBYTE_SENTOSA is not set -# CONFIG_SIBYTE_RHONE is not set -# CONFIG_SIBYTE_CARMEL is not set -# CONFIG_SIBYTE_LITTLESUR is not set -# CONFIG_SIBYTE_CRHINE is not set -# CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM is not set -# CONFIG_TOSHIBA_JMR3927 is not set -# CONFIG_TOSHIBA_RBTX4927 is not set -# CONFIG_TOSHIBA_RBTX4938 is not set -CONFIG_RWSEM_GENERIC_SPINLOCK=y -# CONFIG_ARCH_HAS_ILOG2_U32 is not set -# CONFIG_ARCH_HAS_ILOG2_U64 is not set -CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_TIME=y -CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set -CONFIG_DMA_COHERENT=y -CONFIG_CPU_BIG_ENDIAN=y -# CONFIG_CPU_LITTLE_ENDIAN is not set -CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y -CONFIG_IRQ_CPU=y -CONFIG_IRQ_CPU_RM7K=y -CONFIG_IRQ_CPU_RM9K=y -CONFIG_MIPS_RM9122=y -CONFIG_SERIAL_RM9000=y -CONFIG_GPI_RM9000=y -CONFIG_WDT_RM9000=y -CONFIG_MIPS_L1_CACHE_SHIFT=5 - -# -# CPU selection -# -# CONFIG_CPU_MIPS32_R1 is not set -# CONFIG_CPU_MIPS32_R2 is not set -# CONFIG_CPU_MIPS64_R1 is not set -# CONFIG_CPU_MIPS64_R2 is not set -# CONFIG_CPU_R3000 is not set -# CONFIG_CPU_TX39XX is not set -# CONFIG_CPU_VR41XX is not set -# CONFIG_CPU_R4300 is not set -# CONFIG_CPU_R4X00 is not set -# CONFIG_CPU_TX49XX is not set -# CONFIG_CPU_R5000 is not set -# CONFIG_CPU_R5432 is not set -# CONFIG_CPU_R6000 is not set -# CONFIG_CPU_NEVADA is not set -# CONFIG_CPU_R8000 is not set -# CONFIG_CPU_R10000 is not set -# CONFIG_CPU_RM7000 is not set -CONFIG_CPU_RM9000=y -# CONFIG_CPU_SB1 is not set -CONFIG_SYS_HAS_CPU_RM9000=y -CONFIG_WEAK_ORDERING=y -CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y -CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y -CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y -CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y - -# -# Kernel type -# -CONFIG_32BIT=y -# CONFIG_64BIT is not set -CONFIG_PAGE_SIZE_4KB=y -# CONFIG_PAGE_SIZE_8KB is not set -# CONFIG_PAGE_SIZE_16KB is not set -# CONFIG_PAGE_SIZE_64KB is not set -CONFIG_CPU_HAS_PREFETCH=y -CONFIG_MIPS_MT_DISABLED=y -# CONFIG_MIPS_MT_SMP is not set -# CONFIG_MIPS_MT_SMTC is not set -# CONFIG_MIPS_VPE_LOADER is not set -# CONFIG_64BIT_PHYS_ADDR is not set -CONFIG_CPU_HAS_SYNC=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_CPU_SUPPORTS_HIGHMEM=y -CONFIG_ARCH_FLATMEM_ENABLE=y -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set -CONFIG_ZONE_DMA_FLAG=1 -# CONFIG_HZ_48 is not set -# CONFIG_HZ_100 is not set -# CONFIG_HZ_128 is not set -# CONFIG_HZ_250 is not set -# CONFIG_HZ_256 is not set -CONFIG_HZ_1000=y -# CONFIG_HZ_1024 is not set -CONFIG_SYS_SUPPORTS_ARBIT_HZ=y -CONFIG_HZ=1000 -# CONFIG_PREEMPT_NONE is not set -# CONFIG_PREEMPT_VOLUNTARY is not set -CONFIG_PREEMPT=y -CONFIG_PREEMPT_BKL=y -# CONFIG_KEXEC is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_LOCK_KERNEL=y -CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# -CONFIG_LOCALVERSION="" -# CONFIG_LOCALVERSION_AUTO is not set -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set -CONFIG_SYSVIPC_SYSCTL=y -CONFIG_POSIX_MQUEUE=y -# CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set -# CONFIG_AUDIT is not set -# CONFIG_IKCONFIG is not set -CONFIG_SYSFS_DEPRECATED=y -# CONFIG_RELAY is not set -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_SYSCTL=y -CONFIG_EMBEDDED=y -CONFIG_SYSCTL_SYSCALL=y -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_EPOLL=y -CONFIG_SHMEM=y -CONFIG_SLAB=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set - -# -# Loadable module support -# -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_FORCE_UNLOAD is not set -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y - -# -# Block layer -# -CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" - -# -# Bus options (PCI, PCMCIA, EISA, ISA, TC) -# -CONFIG_HW_HAS_PCI=y -CONFIG_PCI=y -CONFIG_MMU=y - -# -# PCCARD (PCMCIA/CardBus) support -# -# CONFIG_PCCARD is not set - -# -# PCI Hotplug Support -# -# CONFIG_HOTPLUG_PCI is not set - -# -# Executable file formats -# -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_MISC is not set -CONFIG_TRAD_SIGNALS=y - -# -# Power management options -# -CONFIG_PM=y -# CONFIG_PM_LEGACY is not set -# CONFIG_PM_DEBUG is not set -# CONFIG_PM_SYSFS_DEPRECATED is not set - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -# CONFIG_NETDEBUG is not set -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set -CONFIG_XFRM_MIGRATE=y -# CONFIG_NET_KEY is not set -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -# CONFIG_IP_PNP_BOOTP is not set -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_INET_XFRM_MODE_TRANSPORT=m -CONFIG_INET_XFRM_MODE_TUNNEL=m -CONFIG_INET_XFRM_MODE_BEET=m -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -CONFIG_TCP_MD5SIG=y -# CONFIG_IPV6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set -CONFIG_NETWORK_SECMARK=y -# CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_IEEE80211 is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=m -# CONFIG_SYS_HYPERVISOR is not set - -# -# Connector - unified userspace <-> kernelspace linker -# -# CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# -CONFIG_MTD=y -# CONFIG_MTD_DEBUG is not set -# CONFIG_MTD_CONCAT is not set -CONFIG_MTD_PARTITIONS=y -# CONFIG_MTD_REDBOOT_PARTS is not set -# CONFIG_MTD_CMDLINE_PARTS is not set - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLKDEVS=y -CONFIG_MTD_BLOCK=y -# CONFIG_FTL is not set -# CONFIG_NFTL is not set -# CONFIG_INFTL is not set -# CONFIG_RFD_FTL is not set -# CONFIG_SSFDC is not set - -# -# RAM/ROM/Flash chip drivers -# -# CONFIG_MTD_CFI is not set -# CONFIG_MTD_JEDECPROBE is not set -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -CONFIG_MTD_MAP_BANK_WIDTH_4=y -# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -# CONFIG_MTD_RAM is not set -# CONFIG_MTD_ROM is not set -# CONFIG_MTD_ABSENT is not set -# CONFIG_MTD_OBSOLETE_CHIPS is not set - -# -# Mapping drivers for chip access -# -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -# CONFIG_MTD_PLATRAM is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_PMC551 is not set -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLOCK2MTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOC2001PLUS is not set - -# -# NAND Flash Device Drivers -# -CONFIG_MTD_NAND=y -CONFIG_MTD_NAND_VERIFY_WRITE=y -# CONFIG_MTD_NAND_ECC_SMC is not set -CONFIG_MTD_NAND_IDS=y -# CONFIG_MTD_NAND_DISKONCHIP is not set -# CONFIG_MTD_NAND_BASLER_EXCITE is not set -# CONFIG_MTD_NAND_CAFE is not set -# CONFIG_MTD_NAND_NANDSIM is not set - -# -# OneNAND Flash Device Drivers -# -# CONFIG_MTD_ONENAND is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# -# CONFIG_PNPACPI is not set - -# -# Block devices -# -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=m -# CONFIG_BLK_DEV_CRYPTOLOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_SX8 is not set -# CONFIG_BLK_DEV_UB is not set -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_BLK_DEV_INITRD is not set -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set - -# -# Misc devices -# -CONFIG_SGI_IOC4=m -# CONFIG_TIFM_CORE is not set - -# -# ATA/ATAPI/MFM/RLL support -# -# CONFIG_IDE is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -CONFIG_SCSI=y -CONFIG_SCSI_TGT=m -# CONFIG_SCSI_NETLINK is not set -# CONFIG_SCSI_PROC_FS is not set - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set -# CONFIG_BLK_DEV_SR is not set -# CONFIG_CHR_DEV_SG is not set -# CONFIG_CHR_DEV_SCH is not set - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -# CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_CONSTANTS is not set -# CONFIG_SCSI_LOGGING is not set -CONFIG_SCSI_SCAN_ASYNC=y - -# -# SCSI Transports -# -# CONFIG_SCSI_SPI_ATTRS is not set -# CONFIG_SCSI_FC_ATTRS is not set -# CONFIG_SCSI_ISCSI_ATTRS is not set -CONFIG_SCSI_SAS_ATTRS=m -CONFIG_SCSI_SAS_LIBSAS=m -# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set - -# -# SCSI low-level drivers -# -# CONFIG_ISCSI_TCP is not set -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_SCSI_3W_9XXX is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AACRAID is not set -# CONFIG_SCSI_AIC7XXX is not set -# CONFIG_SCSI_AIC7XXX_OLD is not set -# CONFIG_SCSI_AIC79XX is not set -CONFIG_SCSI_AIC94XX=m -# CONFIG_AIC94XX_DEBUG is not set -# CONFIG_SCSI_DPT_I2O is not set -# CONFIG_SCSI_ARCMSR is not set -# CONFIG_MEGARAID_NEWGEN is not set -# CONFIG_MEGARAID_LEGACY is not set -# CONFIG_MEGARAID_SAS is not set -# CONFIG_SCSI_HPTIOP is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_IPS is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_STEX is not set -# CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_QLOGIC_1280 is not set -# CONFIG_SCSI_QLA_FC is not set -# CONFIG_SCSI_QLA_ISCSI is not set -# CONFIG_SCSI_LPFC is not set -# CONFIG_SCSI_DC395x is not set -# CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_NSP32 is not set -# CONFIG_SCSI_DEBUG is not set -# CONFIG_SCSI_SRP is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# -# CONFIG_ATA is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set -# CONFIG_FUSION_SPI is not set -# CONFIG_FUSION_FC is not set -# CONFIG_FUSION_SAS is not set - -# -# IEEE 1394 (FireWire) support -# -# CONFIG_IEEE1394 is not set - -# -# I2O device support -# -# CONFIG_I2O is not set - -# -# Network device support -# -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set - -# -# PHY device support -# - -# -# Ethernet (10 or 100Mbit) -# -# CONFIG_NET_ETHERNET is not set - -# -# Ethernet (1000 Mbit) -# -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_E1000 is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_R8169 is not set -# CONFIG_SIS190 is not set -# CONFIG_SKGE is not set -# CONFIG_SKY2 is not set -# CONFIG_SK98LIN is not set -# CONFIG_TIGON3 is not set -# CONFIG_BNX2 is not set -CONFIG_QLA3XXX=m -# CONFIG_ATL1 is not set - -# -# Ethernet (10000 Mbit) -# -# CONFIG_CHELSIO_T1 is not set -CONFIG_CHELSIO_T3=m -# CONFIG_IXGB is not set -# CONFIG_S2IO is not set -# CONFIG_MYRI10GE is not set -CONFIG_NETXEN_NIC=m - -# -# Token Ring devices -# -# CONFIG_TR is not set - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_NET_FC is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Telephony Support -# -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=m -CONFIG_INPUT_MOUSEDEV_PSAUX=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set -CONFIG_INPUT_EVDEV=m -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -# CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -CONFIG_VT_HW_CONSOLE_BINDING=y -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_PCI=y -CONFIG_SERIAL_8250_NR_UARTS=2 -CONFIG_SERIAL_8250_RUNTIME_UARTS=2 -CONFIG_SERIAL_8250_EXTENDED=y -# CONFIG_SERIAL_8250_MANY_PORTS is not set -CONFIG_SERIAL_8250_SHARE_IRQ=y -# CONFIG_SERIAL_8250_DETECT_IRQ is not set -# CONFIG_SERIAL_8250_RSA is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_JSM is not set -CONFIG_UNIX98_PTYS=y -# CONFIG_LEGACY_PTYS is not set - -# -# IPMI -# -# CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -CONFIG_WATCHDOG=y -# CONFIG_WATCHDOG_NOWAYOUT is not set - -# -# Watchdog Device Drivers -# -# CONFIG_SOFT_WATCHDOG is not set -CONFIG_WDT_RM9K_GPI=m - -# -# PCI-based Watchdog Cards -# -# CONFIG_PCIPCWATCHDOG is not set -# CONFIG_WDTPCI is not set - -# -# USB-based Watchdog Cards -# -# CONFIG_USBPCWATCHDOG is not set -# CONFIG_HW_RANDOM is not set -# CONFIG_RTC is not set -# CONFIG_GEN_RTC is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set -# CONFIG_DRM is not set -# CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# -# CONFIG_TCG_TPM is not set - -# -# I2C support -# -# CONFIG_I2C is not set - -# -# SPI support -# -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set - -# -# Dallas's 1-wire bus -# -# CONFIG_W1 is not set - -# -# Hardware Monitoring support -# -# CONFIG_HWMON is not set -# CONFIG_HWMON_VID is not set - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set -# CONFIG_USB_DABUSB is not set - -# -# Graphics support -# -# CONFIG_FIRMWARE_EDID is not set -CONFIG_FB=y -# CONFIG_FB_CFB_FILLRECT is not set -# CONFIG_FB_CFB_COPYAREA is not set -# CONFIG_FB_CFB_IMAGEBLIT is not set -# CONFIG_FB_SVGALIB is not set -# CONFIG_FB_MACMODES is not set -# CONFIG_FB_BACKLIGHT is not set -# CONFIG_FB_MODE_HELPERS is not set -# CONFIG_FB_TILEBLITTING is not set -# CONFIG_FB_CIRRUS is not set -# CONFIG_FB_PM2 is not set -# CONFIG_FB_CYBER2000 is not set -# CONFIG_FB_ASILIANT is not set -# CONFIG_FB_IMSTT is not set -# CONFIG_FB_S1D13XXX is not set -# CONFIG_FB_NVIDIA is not set -# CONFIG_FB_RIVA is not set -# CONFIG_FB_MATROX is not set -# CONFIG_FB_RADEON is not set -# CONFIG_FB_ATY128 is not set -# CONFIG_FB_ATY is not set -# CONFIG_FB_S3 is not set -# CONFIG_FB_SAVAGE is not set -# CONFIG_FB_SIS is not set -# CONFIG_FB_NEOMAGIC is not set -# CONFIG_FB_KYRO is not set -# CONFIG_FB_3DFX is not set -# CONFIG_FB_VOODOO1 is not set -# CONFIG_FB_SMIVGX is not set -# CONFIG_FB_TRIDENT is not set -# CONFIG_FB_VIRTUAL is not set - -# -# Console display driver support -# -# CONFIG_VGA_CONSOLE is not set -CONFIG_DUMMY_CONSOLE=y -CONFIG_FRAMEBUFFER_CONSOLE=m -# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set -# CONFIG_FONTS is not set -CONFIG_FONT_8x8=y -CONFIG_FONT_8x16=y - -# -# Logo configuration -# -# CONFIG_LOGO is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# HID Devices -# -CONFIG_HID=y -# CONFIG_HID_DEBUG is not set - -# -# USB support -# -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -CONFIG_USB_ARCH_HAS_EHCI=y -CONFIG_USB=y -# CONFIG_USB_DEBUG is not set - -# -# Miscellaneous USB options -# -CONFIG_USB_DEVICEFS=y -# CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_SUSPEND is not set -# CONFIG_USB_OTG is not set - -# -# USB Host Controller Drivers -# -CONFIG_USB_EHCI_HCD=y -# CONFIG_USB_EHCI_SPLIT_ISO is not set -# CONFIG_USB_EHCI_ROOT_HUB_TT is not set -# CONFIG_USB_EHCI_TT_NEWSCHED is not set -# CONFIG_USB_EHCI_BIG_ENDIAN_MMIO is not set -# CONFIG_USB_ISP116X_HCD is not set -CONFIG_USB_OHCI_HCD=y -# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set -# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set -CONFIG_USB_OHCI_LITTLE_ENDIAN=y -# CONFIG_USB_UHCI_HCD is not set -# CONFIG_USB_SL811_HCD is not set - -# -# USB Device Class drivers -# -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# may also be needed; see USB_STORAGE Help for more information -# -CONFIG_USB_STORAGE=y -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_USBAT is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_SDDR55 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_STORAGE_ALAUDA is not set -# CONFIG_USB_STORAGE_KARMA is not set -# CONFIG_USB_LIBUSUAL is not set - -# -# USB Input Devices -# -CONFIG_USB_HID=m -# CONFIG_USB_HIDINPUT_POWERBOOK is not set -# CONFIG_HID_FF is not set -# CONFIG_USB_HIDDEV is not set - -# -# USB HID Boot Protocol drivers -# -# CONFIG_USB_KBD is not set -# CONFIG_USB_MOUSE is not set -# CONFIG_USB_AIPTEK is not set -# CONFIG_USB_WACOM is not set -# CONFIG_USB_ACECAD is not set -# CONFIG_USB_KBTAB is not set -# CONFIG_USB_POWERMATE is not set -# CONFIG_USB_TOUCHSCREEN is not set -# CONFIG_USB_YEALINK is not set -# CONFIG_USB_XPAD is not set -# CONFIG_USB_ATI_REMOTE is not set -# CONFIG_USB_ATI_REMOTE2 is not set -# CONFIG_USB_KEYSPAN_REMOTE is not set -# CONFIG_USB_APPLETOUCH is not set -# CONFIG_USB_GTCO is not set - -# -# USB Imaging devices -# -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_MICROTEK is not set - -# -# USB Network Adapters -# -# CONFIG_USB_CATC is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RTL8150 is not set -# CONFIG_USB_USBNET_MII is not set -# CONFIG_USB_USBNET is not set -# CONFIG_USB_MON is not set - -# -# USB port drivers -# - -# -# USB Serial Converter support -# -# CONFIG_USB_SERIAL is not set - -# -# USB Miscellaneous drivers -# -# CONFIG_USB_EMI62 is not set -# CONFIG_USB_EMI26 is not set -# CONFIG_USB_ADUTUX is not set -# CONFIG_USB_AUERSWALD is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_LEGOTOWER is not set -# CONFIG_USB_LCD is not set -# CONFIG_USB_BERRY_CHARGE is not set -# CONFIG_USB_LED is not set -# CONFIG_USB_CYPRESS_CY7C63 is not set -# CONFIG_USB_CYTHERM is not set -# CONFIG_USB_PHIDGET is not set -# CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_FTDI_ELAN is not set -# CONFIG_USB_APPLEDISPLAY is not set -# CONFIG_USB_SISUSBVGA is not set -# CONFIG_USB_LD is not set -# CONFIG_USB_TRANCEVIBRATOR is not set -# CONFIG_USB_TEST is not set - -# -# USB DSL modem support -# - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# -# CONFIG_MMC is not set - -# -# LED devices -# -# CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers -# - -# -# InfiniBand support -# -# CONFIG_INFINIBAND is not set - -# -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) -# - -# -# Real Time Clock -# -# CONFIG_RTC_CLASS is not set - -# -# DMA Engine support -# -# CONFIG_DMA_ENGINE is not set - -# -# DMA Clients -# - -# -# DMA Devices -# - -# -# Auxiliary Display support -# - -# -# Virtualization -# - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XIP is not set -# CONFIG_EXT3_FS is not set -# CONFIG_EXT4DEV_FS is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -CONFIG_FS_POSIX_ACL=y -# CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y -# CONFIG_QUOTA is not set -# CONFIG_DNOTIFY is not set -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set -CONFIG_GENERIC_ACL=y - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -CONFIG_FAT_FS=m -CONFIG_MSDOS_FS=m -CONFIG_VFAT_FS=m -CONFIG_FAT_DEFAULT_CODEPAGE=437 -CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_KCORE=y -CONFIG_PROC_SYSCTL=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -CONFIG_TMPFS_POSIX_ACL=y -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y -CONFIG_CONFIGFS_FS=m - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -CONFIG_JFFS2_FS=y -CONFIG_JFFS2_FS_DEBUG=0 -CONFIG_JFFS2_FS_WRITEBUFFER=y -# CONFIG_JFFS2_SUMMARY is not set -# CONFIG_JFFS2_FS_XATTR is not set -# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set -CONFIG_JFFS2_ZLIB=y -CONFIG_JFFS2_RTIME=y -# CONFIG_JFFS2_RUBIN is not set -# CONFIG_CRAMFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Network File Systems -# -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set -# CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set -# CONFIG_NFSD is not set -CONFIG_ROOT_NFS=y -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -# CONFIG_MAC_PARTITION is not set -CONFIG_MSDOS_PARTITION=y -# CONFIG_BSD_DISKLABEL is not set -# CONFIG_MINIX_SUBPARTITION is not set -# CONFIG_SOLARIS_X86_PARTITION is not set -# CONFIG_UNIXWARE_DISKLABEL is not set -# CONFIG_LDM_PARTITION is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_KARMA_PARTITION is not set -# CONFIG_EFI_PARTITION is not set - -# -# Native Language Support -# -CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=m -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -CONFIG_NLS_CODEPAGE_850=m -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -# CONFIG_NLS_ASCII is not set -CONFIG_NLS_ISO8859_1=m -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -# CONFIG_NLS_UTF8 is not set - -# -# Distributed Lock Manager -# -CONFIG_DLM=m -CONFIG_DLM_TCP=y -# CONFIG_DLM_SCTP is not set -# CONFIG_DLM_DEBUG is not set - -# -# Profiling support -# -# CONFIG_PROFILING is not set - -# -# Kernel hacking -# -CONFIG_TRACE_IRQFLAGS_SUPPORT=y -# CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_MUST_CHECK=y -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_FS is not set -# CONFIG_HEADERS_CHECK is not set -# CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_CROSSCOMPILE=y -CONFIG_CMDLINE="" - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -CONFIG_CRYPTO=y -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_BLKCIPHER=m -CONFIG_CRYPTO_HASH=m -CONFIG_CRYPTO_MANAGER=m -# CONFIG_CRYPTO_HMAC is not set -CONFIG_CRYPTO_XCBC=m -# CONFIG_CRYPTO_NULL is not set -# CONFIG_CRYPTO_MD4 is not set -CONFIG_CRYPTO_MD5=y -# CONFIG_CRYPTO_SHA1 is not set -# CONFIG_CRYPTO_SHA256 is not set -# CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_WP512 is not set -# CONFIG_CRYPTO_TGR192 is not set -CONFIG_CRYPTO_GF128MUL=m -CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_CBC=m -CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_LRW=m -# CONFIG_CRYPTO_DES is not set -CONFIG_CRYPTO_FCRYPT=m -# CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_TWOFISH is not set -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_AES is not set -# CONFIG_CRYPTO_CAST5 is not set -# CONFIG_CRYPTO_CAST6 is not set -# CONFIG_CRYPTO_TEA is not set -# CONFIG_CRYPTO_ARC4 is not set -# CONFIG_CRYPTO_KHAZAD is not set -# CONFIG_CRYPTO_ANUBIS is not set -# CONFIG_CRYPTO_DEFLATE is not set -# CONFIG_CRYPTO_MICHAEL_MIC is not set -# CONFIG_CRYPTO_CRC32C is not set -CONFIG_CRYPTO_CAMELLIA=m -# CONFIG_CRYPTO_TEST is not set - -# -# Hardware crypto devices -# - -# -# Library routines -# -CONFIG_BITREVERSE=y -# CONFIG_CRC_CCITT is not set -# CONFIG_CRC16 is not set -CONFIG_CRC32=y -# CONFIG_LIBCRC32C is not set -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y -CONFIG_PLIST=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y diff --git a/arch/mips/configs/fuloong2e_defconfig b/arch/mips/configs/fuloong2e_defconfig index b3626de..17341a0 100644 --- a/arch/mips/configs/fuloong2e_defconfig +++ b/arch/mips/configs/fuloong2e_defconfig @@ -10,7 +10,6 @@ CONFIG_MIPS=y # # CONFIG_MACH_ALCHEMY is not set # CONFIG_AR7 is not set -# CONFIG_BASLER_EXCITE is not set # CONFIG_BCM47XX is not set # CONFIG_BCM63XX is not set # CONFIG_MIPS_COBALT is not set diff --git a/arch/mips/configs/ip22_defconfig b/arch/mips/configs/ip22_defconfig index f14d38b..3471ac9 100644 --- a/arch/mips/configs/ip22_defconfig +++ b/arch/mips/configs/ip22_defconfig @@ -9,7 +9,6 @@ CONFIG_MIPS=y # Machine selection # # CONFIG_MACH_ALCHEMY is not set -# CONFIG_BASLER_EXCITE is not set # CONFIG_BCM47XX is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set diff --git a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig index 1fc73aa..26127a8 100644 --- a/arch/mips/configs/ip27_defconfig +++ b/arch/mips/configs/ip27_defconfig @@ -9,7 +9,6 @@ CONFIG_MIPS=y # Machine selection # # CONFIG_MACH_ALCHEMY is not set -# CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set diff --git a/arch/mips/configs/ip28_defconfig b/arch/mips/configs/ip28_defconfig index 539dccb..ac6c850 100644 --- a/arch/mips/configs/ip28_defconfig +++ b/arch/mips/configs/ip28_defconfig @@ -9,7 +9,6 @@ CONFIG_MIPS=y # Machine selection # # CONFIG_MACH_ALCHEMY is not set -# CONFIG_BASLER_EXCITE is not set # CONFIG_BCM47XX is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set diff --git a/arch/mips/configs/ip32_defconfig b/arch/mips/configs/ip32_defconfig index d934bde..56553b1 100644 --- a/arch/mips/configs/ip32_defconfig +++ b/arch/mips/configs/ip32_defconfig @@ -9,7 +9,6 @@ CONFIG_MIPS=y # Machine selection # # CONFIG_MACH_ALCHEMY is not set -# CONFIG_BASLER_EXCITE is not set # CONFIG_BCM47XX is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set diff --git a/arch/mips/configs/jazz_defconfig b/arch/mips/configs/jazz_defconfig index d22df61..9db23fd 100644 --- a/arch/mips/configs/jazz_defconfig +++ b/arch/mips/configs/jazz_defconfig @@ -22,7 +22,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_DB1550 is not set # CONFIG_MIPS_DB1200 is not set # CONFIG_MIPS_MIRAGE is not set -# CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set CONFIG_MACH_JAZZ=y diff --git a/arch/mips/configs/jmr3927_defconfig b/arch/mips/configs/jmr3927_defconfig index 5380f1f..11fec0e 100644 --- a/arch/mips/configs/jmr3927_defconfig +++ b/arch/mips/configs/jmr3927_defconfig @@ -9,7 +9,6 @@ CONFIG_MIPS=y # Machine selection # # CONFIG_MACH_ALCHEMY is not set -# CONFIG_BASLER_EXCITE is not set # CONFIG_BCM47XX is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set diff --git a/arch/mips/configs/lasat_defconfig b/arch/mips/configs/lasat_defconfig index 044074d..2fe15a5 100644 --- a/arch/mips/configs/lasat_defconfig +++ b/arch/mips/configs/lasat_defconfig @@ -9,7 +9,6 @@ CONFIG_MIPS=y # Machine selection # # CONFIG_MACH_ALCHEMY is not set -# CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set diff --git a/arch/mips/configs/lemote2f_defconfig b/arch/mips/configs/lemote2f_defconfig index 89e88a0..ddb1c92 100644 --- a/arch/mips/configs/lemote2f_defconfig +++ b/arch/mips/configs/lemote2f_defconfig @@ -10,7 +10,6 @@ CONFIG_MIPS=y # # CONFIG_MACH_ALCHEMY is not set # CONFIG_AR7 is not set -# CONFIG_BASLER_EXCITE is not set # CONFIG_BCM47XX is not set # CONFIG_BCM63XX is not set # CONFIG_MIPS_COBALT is not set diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig index 3f01870..38d9873 100644 --- a/arch/mips/configs/malta_defconfig +++ b/arch/mips/configs/malta_defconfig @@ -10,7 +10,6 @@ CONFIG_MIPS=y # CONFIG_ZONE_DMA=y # CONFIG_MACH_ALCHEMY is not set -# CONFIG_BASLER_EXCITE is not set # CONFIG_BCM47XX is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set diff --git a/arch/mips/configs/markeins_defconfig b/arch/mips/configs/markeins_defconfig index d001f7e8..9137571 100644 --- a/arch/mips/configs/markeins_defconfig +++ b/arch/mips/configs/markeins_defconfig @@ -22,7 +22,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_DB1550 is not set # CONFIG_MIPS_DB1200 is not set # CONFIG_MIPS_MIRAGE is not set -# CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set diff --git a/arch/mips/configs/mipssim_defconfig b/arch/mips/configs/mipssim_defconfig index 7358454..513e9a4 100644 --- a/arch/mips/configs/mipssim_defconfig +++ b/arch/mips/configs/mipssim_defconfig @@ -9,7 +9,6 @@ CONFIG_MIPS=y # Machine selection # # CONFIG_MACH_ALCHEMY is not set -# CONFIG_BASLER_EXCITE is not set # CONFIG_BCM47XX is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set diff --git a/arch/mips/configs/mpc30x_defconfig b/arch/mips/configs/mpc30x_defconfig index 8c720e5..b893f9d 100644 --- a/arch/mips/configs/mpc30x_defconfig +++ b/arch/mips/configs/mpc30x_defconfig @@ -9,7 +9,6 @@ CONFIG_MIPS=y # Machine selection # # CONFIG_MACH_ALCHEMY is not set -# CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set diff --git a/arch/mips/configs/msp71xx_defconfig b/arch/mips/configs/msp71xx_defconfig index ecbc030..89d2b6a 100644 --- a/arch/mips/configs/msp71xx_defconfig +++ b/arch/mips/configs/msp71xx_defconfig @@ -22,7 +22,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_DB1550 is not set # CONFIG_MIPS_DB1200 is not set # CONFIG_MIPS_MIRAGE is not set -# CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set diff --git a/arch/mips/configs/mtx1_defconfig b/arch/mips/configs/mtx1_defconfig index 9477f04..3199668 100644 --- a/arch/mips/configs/mtx1_defconfig +++ b/arch/mips/configs/mtx1_defconfig @@ -9,7 +9,6 @@ CONFIG_MIPS=y # Machine selection # CONFIG_MACH_ALCHEMY=y -# CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set diff --git a/arch/mips/configs/pb1100_defconfig b/arch/mips/configs/pb1100_defconfig index be8091e..c36e859 100644 --- a/arch/mips/configs/pb1100_defconfig +++ b/arch/mips/configs/pb1100_defconfig @@ -23,7 +23,6 @@ CONFIG_MIPS_PB1100=y # CONFIG_MIPS_DB1550 is not set # CONFIG_MIPS_DB1200 is not set # CONFIG_MIPS_MIRAGE is not set -# CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set diff --git a/arch/mips/configs/pb1500_defconfig b/arch/mips/configs/pb1500_defconfig index e74ba79..4b43e36 100644 --- a/arch/mips/configs/pb1500_defconfig +++ b/arch/mips/configs/pb1500_defconfig @@ -23,7 +23,6 @@ CONFIG_MIPS_PB1500=y # CONFIG_MIPS_DB1550 is not set # CONFIG_MIPS_DB1200 is not set # CONFIG_MIPS_MIRAGE is not set -# CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set diff --git a/arch/mips/configs/pb1550_defconfig b/arch/mips/configs/pb1550_defconfig index 1d896fd..7c8d351 100644 --- a/arch/mips/configs/pb1550_defconfig +++ b/arch/mips/configs/pb1550_defconfig @@ -23,7 +23,6 @@ CONFIG_MIPS_PB1550=y # CONFIG_MIPS_DB1550 is not set # CONFIG_MIPS_DB1200 is not set # CONFIG_MIPS_MIRAGE is not set -# CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set diff --git a/arch/mips/configs/pnx8335-stb225_defconfig b/arch/mips/configs/pnx8335-stb225_defconfig index fef4d31..77a75f0 100644 --- a/arch/mips/configs/pnx8335-stb225_defconfig +++ b/arch/mips/configs/pnx8335-stb225_defconfig @@ -9,7 +9,6 @@ CONFIG_MIPS=y # Machine selection # # CONFIG_MACH_ALCHEMY is not set -# CONFIG_BASLER_EXCITE is not set # CONFIG_BCM47XX is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set diff --git a/arch/mips/configs/pnx8550-jbs_defconfig b/arch/mips/configs/pnx8550-jbs_defconfig index e10c711..945b27e 100644 --- a/arch/mips/configs/pnx8550-jbs_defconfig +++ b/arch/mips/configs/pnx8550-jbs_defconfig @@ -22,7 +22,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_DB1550 is not set # CONFIG_MIPS_DB1200 is not set # CONFIG_MIPS_MIRAGE is not set -# CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set diff --git a/arch/mips/configs/pnx8550-stb810_defconfig b/arch/mips/configs/pnx8550-stb810_defconfig index 5ed3c8d..ff0fc0b 100644 --- a/arch/mips/configs/pnx8550-stb810_defconfig +++ b/arch/mips/configs/pnx8550-stb810_defconfig @@ -22,7 +22,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_DB1550 is not set # CONFIG_MIPS_DB1200 is not set # CONFIG_MIPS_MIRAGE is not set -# CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set diff --git a/arch/mips/configs/powertv_defconfig b/arch/mips/configs/powertv_defconfig index 3aff69ab..86c8007 100644 --- a/arch/mips/configs/powertv_defconfig +++ b/arch/mips/configs/powertv_defconfig @@ -10,7 +10,6 @@ CONFIG_MIPS=y # # CONFIG_MACH_ALCHEMY is not set # CONFIG_AR7 is not set -# CONFIG_BASLER_EXCITE is not set # CONFIG_BCM47XX is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set diff --git a/arch/mips/configs/rb532_defconfig b/arch/mips/configs/rb532_defconfig index f40c3a0..a9408db 100644 --- a/arch/mips/configs/rb532_defconfig +++ b/arch/mips/configs/rb532_defconfig @@ -9,7 +9,6 @@ CONFIG_MIPS=y # Machine selection # # CONFIG_MACH_ALCHEMY is not set -# CONFIG_BASLER_EXCITE is not set # CONFIG_BCM47XX is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set diff --git a/arch/mips/configs/rbtx49xx_defconfig b/arch/mips/configs/rbtx49xx_defconfig index 4f3b970..1c9a542 100644 --- a/arch/mips/configs/rbtx49xx_defconfig +++ b/arch/mips/configs/rbtx49xx_defconfig @@ -10,7 +10,6 @@ CONFIG_MIPS=y # # CONFIG_MACH_ALCHEMY is not set # CONFIG_AR7 is not set -# CONFIG_BASLER_EXCITE is not set # CONFIG_BCM47XX is not set # CONFIG_BCM63XX is not set # CONFIG_MIPS_COBALT is not set diff --git a/arch/mips/configs/rm200_defconfig b/arch/mips/configs/rm200_defconfig index e53b8d0..5873fc5 100644 --- a/arch/mips/configs/rm200_defconfig +++ b/arch/mips/configs/rm200_defconfig @@ -22,7 +22,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_DB1550 is not set # CONFIG_MIPS_DB1200 is not set # CONFIG_MIPS_MIRAGE is not set -# CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set diff --git a/arch/mips/configs/sb1250-swarm_defconfig b/arch/mips/configs/sb1250-swarm_defconfig index 7f38c0b..5244716 100644 --- a/arch/mips/configs/sb1250-swarm_defconfig +++ b/arch/mips/configs/sb1250-swarm_defconfig @@ -9,7 +9,6 @@ CONFIG_MIPS=y # Machine selection # # CONFIG_MACH_ALCHEMY is not set -# CONFIG_BASLER_EXCITE is not set # CONFIG_BCM47XX is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set diff --git a/arch/mips/configs/tb0219_defconfig b/arch/mips/configs/tb0219_defconfig index b505988..937b47c 100644 --- a/arch/mips/configs/tb0219_defconfig +++ b/arch/mips/configs/tb0219_defconfig @@ -9,7 +9,6 @@ CONFIG_MIPS=y # Machine selection # # CONFIG_MACH_ALCHEMY is not set -# CONFIG_BASLER_EXCITE is not set # CONFIG_BCM47XX is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set diff --git a/arch/mips/configs/tb0226_defconfig b/arch/mips/configs/tb0226_defconfig index b06a716..da73584 100644 --- a/arch/mips/configs/tb0226_defconfig +++ b/arch/mips/configs/tb0226_defconfig @@ -9,7 +9,6 @@ CONFIG_MIPS=y # Machine selection # # CONFIG_MACH_ALCHEMY is not set -# CONFIG_BASLER_EXCITE is not set # CONFIG_BCM47XX is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set diff --git a/arch/mips/configs/tb0287_defconfig b/arch/mips/configs/tb0287_defconfig index 46512cf..99a0d21 100644 --- a/arch/mips/configs/tb0287_defconfig +++ b/arch/mips/configs/tb0287_defconfig @@ -9,7 +9,6 @@ CONFIG_MIPS=y # Machine selection # # CONFIG_MACH_ALCHEMY is not set -# CONFIG_BASLER_EXCITE is not set # CONFIG_BCM47XX is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set diff --git a/arch/mips/configs/workpad_defconfig b/arch/mips/configs/workpad_defconfig index b437eb7..d3646ea 100644 --- a/arch/mips/configs/workpad_defconfig +++ b/arch/mips/configs/workpad_defconfig @@ -9,7 +9,6 @@ CONFIG_MIPS=y # Machine selection # # CONFIG_MACH_ALCHEMY is not set -# CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set diff --git a/arch/mips/configs/wrppmc_defconfig b/arch/mips/configs/wrppmc_defconfig index 06acc74..c137831 100644 --- a/arch/mips/configs/wrppmc_defconfig +++ b/arch/mips/configs/wrppmc_defconfig @@ -22,7 +22,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_DB1550 is not set # CONFIG_MIPS_DB1200 is not set # CONFIG_MIPS_MIRAGE is not set -# CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set diff --git a/arch/mips/configs/yosemite_defconfig b/arch/mips/configs/yosemite_defconfig index 69feaf8..4a04f0c 100644 --- a/arch/mips/configs/yosemite_defconfig +++ b/arch/mips/configs/yosemite_defconfig @@ -22,7 +22,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_DB1550 is not set # CONFIG_MIPS_DB1200 is not set # CONFIG_MIPS_MIRAGE is not set -# CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set diff --git a/arch/mips/include/asm/mach-excite/cpu-feature-overrides.h b/arch/mips/include/asm/mach-excite/cpu-feature-overrides.h deleted file mode 100644 index 107104c..0000000 --- a/arch/mips/include/asm/mach-excite/cpu-feature-overrides.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2004 Thomas Koeller - * Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.org) - */ -#ifndef __ASM_MACH_EXCITE_CPU_FEATURE_OVERRIDES_H -#define __ASM_MACH_EXCITE_CPU_FEATURE_OVERRIDES_H - -/* - * Basler eXcite has an RM9122 processor. - */ -#define cpu_has_watch 1 -#define cpu_has_mips16 0 -#define cpu_has_divec 0 -#define cpu_has_vce 0 -#define cpu_has_cache_cdex_p 0 -#define cpu_has_cache_cdex_s 0 -#define cpu_has_prefetch 1 -#define cpu_has_mcheck 0 -#define cpu_has_ejtag 0 - -#define cpu_has_llsc 1 -#define cpu_has_vtag_icache 0 -#define cpu_has_dc_aliases 0 -#define cpu_has_ic_fills_f_dc 0 -#define cpu_has_dsp 0 -#define cpu_icache_snoops_remote_store 0 -#define cpu_has_mipsmt 0 -#define cpu_has_userlocal 0 - -#define cpu_has_nofpuex 0 -#define cpu_has_64bits 1 - -#define cpu_has_mips32r1 0 -#define cpu_has_mips32r2 0 -#define cpu_has_mips64r1 0 -#define cpu_has_mips64r2 0 - -#define cpu_has_inclusive_pcaches 0 - -#define cpu_dcache_line_size() 32 -#define cpu_icache_line_size() 32 -#define cpu_scache_line_size() 32 - -#endif /* __ASM_MACH_EXCITE_CPU_FEATURE_OVERRIDES_H */ diff --git a/arch/mips/include/asm/mach-excite/excite.h b/arch/mips/include/asm/mach-excite/excite.h deleted file mode 100644 index 4c29ba4..0000000 --- a/arch/mips/include/asm/mach-excite/excite.h +++ /dev/null @@ -1,154 +0,0 @@ -#ifndef __EXCITE_H__ -#define __EXCITE_H__ - -#include -#include -#include - -#define EXCITE_CPU_EXT_CLOCK 100000000 - -#if !defined(__ASSEMBLY__) -void __init excite_kgdb_init(void); -void excite_procfs_init(void); -extern unsigned long memsize; -extern char modetty[]; -extern u32 unit_id; -#endif - -/* Base name for XICAP devices */ -#define XICAP_NAME "xicap_gpi" - -/* OCD register offsets */ -#define LKB0 0x0038 -#define LKB5 0x0128 -#define LKM5 0x012C -#define LKB7 0x0138 -#define LKM7 0x013c -#define LKB8 0x0140 -#define LKM8 0x0144 -#define LKB9 0x0148 -#define LKM9 0x014c -#define LKB10 0x0150 -#define LKM10 0x0154 -#define LKB11 0x0158 -#define LKM11 0x015c -#define LKB12 0x0160 -#define LKM12 0x0164 -#define LKB13 0x0168 -#define LKM13 0x016c -#define LDP0 0x0200 -#define LDP1 0x0210 -#define LDP2 0x0220 -#define LDP3 0x0230 -#define INTPIN0 0x0A40 -#define INTPIN1 0x0A44 -#define INTPIN2 0x0A48 -#define INTPIN3 0x0A4C -#define INTPIN4 0x0A50 -#define INTPIN5 0x0A54 -#define INTPIN6 0x0A58 -#define INTPIN7 0x0A5C - - - - -/* TITAN register offsets */ -#define CPRR 0x0004 -#define CPDSR 0x0008 -#define CPTC0R 0x000c -#define CPTC1R 0x0010 -#define CPCFG0 0x0020 -#define CPCFG1 0x0024 -#define CPDST0A 0x0028 -#define CPDST0B 0x002c -#define CPDST1A 0x0030 -#define CPDST1B 0x0034 -#define CPXDSTA 0x0038 -#define CPXDSTB 0x003c -#define CPXCISRA 0x0048 -#define CPXCISRB 0x004c -#define CPGIG0ER 0x0050 -#define CPGIG1ER 0x0054 -#define CPGRWL 0x0068 -#define CPURSLMT 0x00f8 -#define UACFG 0x0200 -#define UAINTS 0x0204 -#define SDRXFCIE 0x4828 -#define SDTXFCIE 0x4928 -#define INTP0Status0 0x1B00 -#define INTP0Mask0 0x1B04 -#define INTP0Set0 0x1B08 -#define INTP0Clear0 0x1B0C -#define GXCFG 0x5000 -#define GXDMADRPFX 0x5018 -#define GXDMA_DESCADR 0x501c -#define GXCH0TDESSTRT 0x5054 - -/* IRQ definitions */ -#define NMICONFIG 0xac0 -#define TITAN_MSGINT 0xc4 -#define TITAN_IRQ ((TITAN_MSGINT / 0x20) + 2) -#define FPGA0_MSGINT 0x5a -#define FPGA0_IRQ ((FPGA0_MSGINT / 0x20) + 2) -#define FPGA1_MSGINT 0x7b -#define FPGA1_IRQ ((FPGA1_MSGINT / 0x20) + 2) -#define PHY_MSGINT 0x9c -#define PHY_IRQ ((PHY_MSGINT / 0x20) + 2) - -#if defined(CONFIG_BASLER_EXCITE_PROTOTYPE) -/* Pre-release units used interrupt pin #9 */ -#define USB_IRQ 11 -#else -/* Re-designed units use interrupt pin #1 */ -#define USB_MSGINT 0x39 -#define USB_IRQ ((USB_MSGINT / 0x20) + 2) -#endif -#define TIMER_IRQ 12 - - -/* Device address ranges */ -#define EXCITE_OFFS_OCD 0x1fffc000 -#define EXCITE_SIZE_OCD (16 * 1024) -#define EXCITE_PHYS_OCD CPHYSADDR(EXCITE_OFFS_OCD) -#define EXCITE_ADDR_OCD CKSEG1ADDR(EXCITE_OFFS_OCD) - -#define EXCITE_OFFS_SCRAM 0x1fffa000 -#define EXCITE_SIZE_SCRAM (8 << 10) -#define EXCITE_PHYS_SCRAM CPHYSADDR(EXCITE_OFFS_SCRAM) -#define EXCITE_ADDR_SCRAM CKSEG1ADDR(EXCITE_OFFS_SCRAM) - -#define EXCITE_OFFS_PCI_IO 0x1fff8000 -#define EXCITE_SIZE_PCI_IO (8 << 10) -#define EXCITE_PHYS_PCI_IO CPHYSADDR(EXCITE_OFFS_PCI_IO) -#define EXCITE_ADDR_PCI_IO CKSEG1ADDR(EXCITE_OFFS_PCI_IO) - -#define EXCITE_OFFS_TITAN 0x1fff0000 -#define EXCITE_SIZE_TITAN (32 << 10) -#define EXCITE_PHYS_TITAN CPHYSADDR(EXCITE_OFFS_TITAN) -#define EXCITE_ADDR_TITAN CKSEG1ADDR(EXCITE_OFFS_TITAN) - -#define EXCITE_OFFS_PCI_MEM 0x1ffe0000 -#define EXCITE_SIZE_PCI_MEM (64 << 10) -#define EXCITE_PHYS_PCI_MEM CPHYSADDR(EXCITE_OFFS_PCI_MEM) -#define EXCITE_ADDR_PCI_MEM CKSEG1ADDR(EXCITE_OFFS_PCI_MEM) - -#define EXCITE_OFFS_FPGA 0x1ffdc000 -#define EXCITE_SIZE_FPGA (16 << 10) -#define EXCITE_PHYS_FPGA CPHYSADDR(EXCITE_OFFS_FPGA) -#define EXCITE_ADDR_FPGA CKSEG1ADDR(EXCITE_OFFS_FPGA) - -#define EXCITE_OFFS_NAND 0x1ffd8000 -#define EXCITE_SIZE_NAND (16 << 10) -#define EXCITE_PHYS_NAND CPHYSADDR(EXCITE_OFFS_NAND) -#define EXCITE_ADDR_NAND CKSEG1ADDR(EXCITE_OFFS_NAND) - -#define EXCITE_OFFS_BOOTROM 0x1f000000 -#define EXCITE_SIZE_BOOTROM (8 << 20) -#define EXCITE_PHYS_BOOTROM CPHYSADDR(EXCITE_OFFS_BOOTROM) -#define EXCITE_ADDR_BOOTROM CKSEG1ADDR(EXCITE_OFFS_BOOTROM) - -/* FPGA address offsets */ -#define EXCITE_FPGA_DPR 0x0104 /* dual-ported ram */ -#define EXCITE_FPGA_SYSCTL 0x0200 /* system control register block */ - -#endif /* __EXCITE_H__ */ diff --git a/arch/mips/include/asm/mach-excite/excite_fpga.h b/arch/mips/include/asm/mach-excite/excite_fpga.h deleted file mode 100644 index 0a1ef69..0000000 --- a/arch/mips/include/asm/mach-excite/excite_fpga.h +++ /dev/null @@ -1,80 +0,0 @@ -#ifndef EXCITE_FPGA_H_INCLUDED -#define EXCITE_FPGA_H_INCLUDED - - -/** - * Address alignment of the individual FPGA bytes. - * The address arrangement of the individual bytes of the FPGA is two - * byte aligned at the embedded MK2 platform. - */ -#ifdef EXCITE_CCI_FPGA_MK2 -typedef unsigned char excite_cci_fpga_align_t __attribute__ ((aligned(2))); -#else -typedef unsigned char excite_cci_fpga_align_t; -#endif - - -/** - * Size of Dual Ported RAM. - */ -#define EXCITE_DPR_SIZE 263 - - -/** - * Size of Reserved Status Fields in Dual Ported RAM. - */ -#define EXCITE_DPR_STATUS_SIZE 7 - - - -/** - * FPGA. - * Hardware register layout of the FPGA interface. The FPGA must accessed - * byte wise solely. - * @see EXCITE_CCI_DPR_MK2 - */ -typedef struct excite_fpga { - - /** - * Dual Ported RAM. - */ - excite_cci_fpga_align_t dpr[EXCITE_DPR_SIZE]; - - /** - * Status. - */ - excite_cci_fpga_align_t status[EXCITE_DPR_STATUS_SIZE]; - -#ifdef EXCITE_CCI_FPGA_MK2 - /** - * RM9000 Interrupt. - * Write access initiates interrupt at the RM9000 (MIPS) processor of the eXcite. - */ - excite_cci_fpga_align_t rm9k_int; -#else - /** - * MK2 Interrupt. - * Write access initiates interrupt at the ARM processor of the MK2. - */ - excite_cci_fpga_align_t mk2_int; - - excite_cci_fpga_align_t gap[0x1000-0x10f]; - - /** - * IRQ Source/Acknowledge. - */ - excite_cci_fpga_align_t rm9k_irq_src; - - /** - * IRQ Mask. - * Set bits enable the related interrupt. - */ - excite_cci_fpga_align_t rm9k_irq_mask; -#endif - - -} excite_fpga; - - - -#endif /* ndef EXCITE_FPGA_H_INCLUDED */ diff --git a/arch/mips/include/asm/mach-excite/excite_nandflash.h b/arch/mips/include/asm/mach-excite/excite_nandflash.h deleted file mode 100644 index c4cf614..0000000 --- a/arch/mips/include/asm/mach-excite/excite_nandflash.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __EXCITE_NANDFLASH_H__ -#define __EXCITE_NANDFLASH_H__ - -/* Resource names */ -#define EXCITE_NANDFLASH_RESOURCE_REGS "excite_nandflash_regs" - -#endif /* __EXCITE_NANDFLASH_H__ */ diff --git a/arch/mips/include/asm/mach-excite/rm9k_eth.h b/arch/mips/include/asm/mach-excite/rm9k_eth.h deleted file mode 100644 index 94705a4..0000000 --- a/arch/mips/include/asm/mach-excite/rm9k_eth.h +++ /dev/null @@ -1,23 +0,0 @@ -#if !defined(__RM9K_ETH_H__) -#define __RM9K_ETH_H__ - -#define RM9K_GE_NAME "rm9k_ge" - -/* Resource names */ -#define RM9K_GE_RESOURCE_MAC "rm9k_ge_mac" -#define RM9K_GE_RESOURCE_MSTAT "rm9k_ge_mstat" -#define RM9K_GE_RESOURCE_PKTPROC "rm9k_ge_pktproc" -#define RM9K_GE_RESOURCE_XDMA "rm9k_ge_xdma" -#define RM9K_GE_RESOURCE_FIFO_RX "rm9k_ge_fifo_rx" -#define RM9K_GE_RESOURCE_FIFO_TX "rm9k_ge_fifo_tx" -#define RM9K_GE_RESOURCE_FIFOMEM_RX "rm9k_ge_fifo_memory_rx" -#define RM9K_GE_RESOURCE_FIFOMEM_TX "rm9k_ge_fifo_memory_tx" -#define RM9K_GE_RESOURCE_PHY "rm9k_ge_phy" -#define RM9K_GE_RESOURCE_DMADESC_RX "rm9k_ge_dmadesc_rx" -#define RM9K_GE_RESOURCE_DMADESC_TX "rm9k_ge_dmadesc_tx" -#define RM9K_GE_RESOURCE_IRQ_MAIN "rm9k_ge_irq_main" -#define RM9K_GE_RESOURCE_IRQ_PHY "rm9k_ge_irq_phy" -#define RM9K_GE_RESOURCE_GPI_SLICE "rm9k_ge_gpi_slice" -#define RM9K_GE_RESOURCE_MDIO_CHANNEL "rm9k_ge_mdio_channel" - -#endif /* !defined(__RM9K_ETH_H__) */ diff --git a/arch/mips/include/asm/mach-excite/rm9k_wdt.h b/arch/mips/include/asm/mach-excite/rm9k_wdt.h deleted file mode 100644 index 3fa3c08..0000000 --- a/arch/mips/include/asm/mach-excite/rm9k_wdt.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef __RM9K_WDT_H__ -#define __RM9K_WDT_H__ - -/* Device name */ -#define WDT_NAME "wdt_gpi" - -/* Resource names */ -#define WDT_RESOURCE_REGS "excite_watchdog_regs" -#define WDT_RESOURCE_IRQ "excite_watchdog_irq" -#define WDT_RESOURCE_COUNTER "excite_watchdog_counter" - -#endif /* __RM9K_WDT_H__ */ diff --git a/arch/mips/include/asm/mach-excite/rm9k_xicap.h b/arch/mips/include/asm/mach-excite/rm9k_xicap.h deleted file mode 100644 index 0095777..0000000 --- a/arch/mips/include/asm/mach-excite/rm9k_xicap.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef __EXCITE_XICAP_H__ -#define __EXCITE_XICAP_H__ - - -/* Resource names */ -#define XICAP_RESOURCE_FIFO_RX "xicap_fifo_rx" -#define XICAP_RESOURCE_FIFO_TX "xicap_fifo_tx" -#define XICAP_RESOURCE_XDMA "xicap_xdma" -#define XICAP_RESOURCE_DMADESC "xicap_dmadesc" -#define XICAP_RESOURCE_PKTPROC "xicap_pktproc" -#define XICAP_RESOURCE_IRQ "xicap_irq" -#define XICAP_RESOURCE_GPI_SLICE "xicap_gpi_slice" -#define XICAP_RESOURCE_FIFO_BLK "xicap_fifo_blocks" -#define XICAP_RESOURCE_PKT_STREAM "xicap_pkt_stream" - -#endif /* __EXCITE_XICAP_H__ */ diff --git a/arch/mips/include/asm/mach-excite/war.h b/arch/mips/include/asm/mach-excite/war.h deleted file mode 100644 index 1f82180..0000000 --- a/arch/mips/include/asm/mach-excite/war.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2002, 2004, 2007 by Ralf Baechle - */ -#ifndef __ASM_MIPS_MACH_EXCITE_WAR_H -#define __ASM_MIPS_MACH_EXCITE_WAR_H - -#define R4600_V1_INDEX_ICACHEOP_WAR 0 -#define R4600_V1_HIT_CACHEOP_WAR 0 -#define R4600_V2_HIT_CACHEOP_WAR 0 -#define R5432_CP0_INTERRUPT_WAR 0 -#define BCM1250_M3_WAR 0 -#define SIBYTE_1956_WAR 0 -#define MIPS4K_ICACHE_REFILL_WAR 0 -#define MIPS_CACHE_SYNC_WAR 0 -#define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define RM9000_CDEX_SMP_WAR 1 -#define ICACHE_REFILLS_WORKAROUND_WAR 1 -#define R10000_LLSC_WAR 0 -#define MIPS34K_MISSED_ITLB_WAR 0 - -#endif /* __ASM_MIPS_MACH_EXCITE_WAR_H */ diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index c9a0dc1..c9209ca 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile @@ -22,7 +22,6 @@ obj-$(CONFIG_BCM63XX) += pci-bcm63xx.o fixup-bcm63xx.o \ # # These are still pretty much in the old state, watch, go blind. # -obj-$(CONFIG_BASLER_EXCITE) += ops-titan.o pci-excite.o fixup-excite.o obj-$(CONFIG_LASAT) += pci-lasat.o obj-$(CONFIG_MIPS_COBALT) += fixup-cobalt.o obj-$(CONFIG_SOC_AU1500) += fixup-au1000.o ops-au1000.o diff --git a/arch/mips/pci/fixup-excite.c b/arch/mips/pci/fixup-excite.c deleted file mode 100644 index cd64d9f..0000000 --- a/arch/mips/pci/fixup-excite.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2004 by Basler Vision Technologies AG - * Author: Thomas Koeller - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#include -#include -#include -#include - -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) -{ - if (pin == 0) - return -1; - - return USB_IRQ; /* USB controller is the only PCI device */ -} - -/* Do platform specific device initialization at pci_enable_device() time */ -int pcibios_plat_dev_init(struct pci_dev *dev) -{ - return 0; -} diff --git a/arch/mips/pci/pci-excite.c b/arch/mips/pci/pci-excite.c deleted file mode 100644 index 8a56876..0000000 --- a/arch/mips/pci/pci-excite.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (C) 2004 by Basler Vision Technologies AG - * Author: Thomas Koeller - * Based on the PMC-Sierra Yosemite board support by Ralf Baechle. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#include -#include -#include -#include -#include -#include -#include - - -extern struct pci_ops titan_pci_ops; - - -static struct resource - mem_resource = { - .name = "PCI memory", - .start = EXCITE_PHYS_PCI_MEM, - .end = EXCITE_PHYS_PCI_MEM + EXCITE_SIZE_PCI_MEM - 1, - .flags = IORESOURCE_MEM - }, - io_resource = { - .name = "PCI I/O", - .start = EXCITE_PHYS_PCI_IO, - .end = EXCITE_PHYS_PCI_IO + EXCITE_SIZE_PCI_IO - 1, - .flags = IORESOURCE_IO - }; - - -static struct pci_controller bx_controller = { - .pci_ops = &titan_pci_ops, - .mem_resource = &mem_resource, - .mem_offset = 0x00000000UL, - .io_resource = &io_resource, - .io_offset = 0x00000000UL -}; - - -static char - iopage_failed[] __initdata = "Cannot allocate PCI I/O page", - modebits_no_pci[] __initdata = "PCI is not configured in mode bits"; - -#define RM9000x2_OCD_HTSC 0x0604 -#define RM9000x2_OCD_HTBHL 0x060c -#define RM9000x2_OCD_PCIHRST 0x078c - -#define RM9K_OCD_MODEBIT1 0x00d4 /* (MODEBIT1) Mode Bit 1 */ -#define RM9K_OCD_CPHDCR 0x00f4 /* CPU-PCI/HT Data Control. */ - -#define PCISC_FB2B 0x00000200 -#define PCISC_MWICG 0x00000010 -#define PCISC_EMC 0x00000004 -#define PCISC_ERMA 0x00000002 - - - -static int __init basler_excite_pci_setup(void) -{ - const unsigned int fullbars = memsize / (256 << 20); - unsigned int i; - - /* Check modebits to see if PCI is really enabled. */ - if (!((ocd_readl(RM9K_OCD_MODEBIT1) >> (47-32)) & 0x1)) - panic(modebits_no_pci); - - if (NULL == request_mem_region(EXCITE_PHYS_PCI_IO, EXCITE_SIZE_PCI_IO, - "Memory-mapped PCI I/O page")) - panic(iopage_failed); - - /* Enable PCI 0 as master for config cycles */ - ocd_writel(PCISC_EMC | PCISC_ERMA, RM9000x2_OCD_HTSC); - - - /* Set up latency timer */ - ocd_writel(0x8008, RM9000x2_OCD_HTBHL); - - /* Setup host IO and Memory space */ - ocd_writel((EXCITE_PHYS_PCI_IO >> 4) | 1, LKB7); - ocd_writel(((EXCITE_SIZE_PCI_IO >> 4) & 0x7fffff00) - 0x100, LKM7); - ocd_writel((EXCITE_PHYS_PCI_MEM >> 4) | 1, LKB8); - ocd_writel(((EXCITE_SIZE_PCI_MEM >> 4) & 0x7fffff00) - 0x100, LKM8); - - /* Set up PCI BARs to map all installed memory */ - for (i = 0; i < 6; i++) { - const unsigned int bar = 0x610 + i * 4; - - if (i < fullbars) { - ocd_writel(0x10000000 * i, bar); - ocd_writel(0x01000000 * i, bar + 0x140); - ocd_writel(0x0ffff029, bar + 0x100); - continue; - } - - if (i == fullbars) { - int o; - u32 mask; - - const unsigned long rem = memsize - i * 0x10000000; - if (!rem) { - ocd_writel(0x00000000, bar + 0x100); - continue; - } - - o = ffs(rem) - 1; - if (rem & ~(0x1 << o)) - o++; - mask = ((0x1 << o) & 0x0ffff000) - 0x1000; - ocd_writel(0x10000000 * i, bar); - ocd_writel(0x01000000 * i, bar + 0x140); - ocd_writel(0x00000029 | mask, bar + 0x100); - continue; - } - - ocd_writel(0x00000000, bar + 0x100); - } - - /* Finally, enable the PCI interrupt */ -#if USB_IRQ > 7 - set_c0_intcontrol(1 << USB_IRQ); -#else - set_c0_status(1 << (USB_IRQ + 8)); -#endif - - ioport_resource.start = EXCITE_PHYS_PCI_IO; - ioport_resource.end = EXCITE_PHYS_PCI_IO + EXCITE_SIZE_PCI_IO - 1; - set_io_port_base((unsigned long) ioremap_nocache(EXCITE_PHYS_PCI_IO, EXCITE_SIZE_PCI_IO)); - register_pci_controller(&bx_controller); - return 0; -} - - -arch_initcall(basler_excite_pci_setup); diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 7678538..677cd53 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -291,14 +291,6 @@ config MTD_NAND_SHARPSL tristate "Support for NAND Flash on Sharp SL Series (C7xx + others)" depends on ARCH_PXA -config MTD_NAND_BASLER_EXCITE - tristate "Support for NAND Flash on Basler eXcite" - depends on BASLER_EXCITE - help - This enables the driver for the NAND flash device found on the - Basler eXcite Smart Camera. If built as a module, the driver - will be named excite_nandflash. - config MTD_NAND_CAFE tristate "NAND support for OLPC CAFÉ chip" depends on PCI diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index 460a1f3..1407bd1 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile @@ -27,7 +27,6 @@ obj-$(CONFIG_MTD_NAND_ATMEL) += atmel_nand.o obj-$(CONFIG_MTD_NAND_GPIO) += gpio.o obj-$(CONFIG_MTD_NAND_OMAP2) += omap2.o obj-$(CONFIG_MTD_NAND_CM_X270) += cmx270_nand.o -obj-$(CONFIG_MTD_NAND_BASLER_EXCITE) += excite_nandflash.o obj-$(CONFIG_MTD_NAND_PXA3xx) += pxa3xx_nand.o obj-$(CONFIG_MTD_NAND_TMIO) += tmio_nand.o obj-$(CONFIG_MTD_NAND_PLATFORM) += plat_nand.o diff --git a/drivers/mtd/nand/excite_nandflash.c b/drivers/mtd/nand/excite_nandflash.c deleted file mode 100644 index af6a6a5..0000000 --- a/drivers/mtd/nand/excite_nandflash.c +++ /dev/null @@ -1,248 +0,0 @@ -/* -* Copyright (C) 2005 - 2007 by Basler Vision Technologies AG -* Author: Thomas Koeller -* Original code by Thies Moeller -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -#include - -#define EXCITE_NANDFLASH_VERSION "0.1" - -/* I/O register offsets */ -#define EXCITE_NANDFLASH_DATA_BYTE 0x00 -#define EXCITE_NANDFLASH_STATUS_BYTE 0x0c -#define EXCITE_NANDFLASH_ADDR_BYTE 0x10 -#define EXCITE_NANDFLASH_CMD_BYTE 0x14 - -/* prefix for debug output */ -static const char module_id[] = "excite_nandflash"; - -/* - * partition definition - */ -static const struct mtd_partition partition_info[] = { - { - .name = "eXcite RootFS", - .offset = 0, - .size = MTDPART_SIZ_FULL - } -}; - -static inline const struct resource * -excite_nand_get_resource(struct platform_device *d, unsigned long flags, - const char *basename) -{ - char buf[80]; - - if (snprintf(buf, sizeof buf, "%s_%u", basename, d->id) >= sizeof buf) - return NULL; - return platform_get_resource_byname(d, flags, buf); -} - -static inline void __iomem * -excite_nand_map_regs(struct platform_device *d, const char *basename) -{ - void *result = NULL; - const struct resource *const r = - excite_nand_get_resource(d, IORESOURCE_MEM, basename); - - if (r) - result = ioremap_nocache(r->start, r->end + 1 - r->start); - return result; -} - -/* controller and mtd information */ -struct excite_nand_drvdata { - struct mtd_info board_mtd; - struct nand_chip board_chip; - void __iomem *regs; - void __iomem *tgt; -}; - -/* Control function */ -static void excite_nand_control(struct mtd_info *mtd, int cmd, - unsigned int ctrl) -{ - struct excite_nand_drvdata * const d = - container_of(mtd, struct excite_nand_drvdata, board_mtd); - - switch (ctrl) { - case NAND_CTRL_CHANGE | NAND_CTRL_CLE: - d->tgt = d->regs + EXCITE_NANDFLASH_CMD_BYTE; - break; - case NAND_CTRL_CHANGE | NAND_CTRL_ALE: - d->tgt = d->regs + EXCITE_NANDFLASH_ADDR_BYTE; - break; - case NAND_CTRL_CHANGE | NAND_NCE: - d->tgt = d->regs + EXCITE_NANDFLASH_DATA_BYTE; - break; - } - - if (cmd != NAND_CMD_NONE) - __raw_writeb(cmd, d->tgt); -} - -/* Return 0 if flash is busy, 1 if ready */ -static int excite_nand_devready(struct mtd_info *mtd) -{ - struct excite_nand_drvdata * const drvdata = - container_of(mtd, struct excite_nand_drvdata, board_mtd); - - return __raw_readb(drvdata->regs + EXCITE_NANDFLASH_STATUS_BYTE); -} - -/* - * Called by device layer to remove the driver. - * The binding to the mtd and all allocated - * resources are released. - */ -static int __devexit excite_nand_remove(struct platform_device *dev) -{ - struct excite_nand_drvdata * const this = platform_get_drvdata(dev); - - platform_set_drvdata(dev, NULL); - - if (unlikely(!this)) { - printk(KERN_ERR "%s: called %s without private data!!", - module_id, __func__); - return -EINVAL; - } - - /* first thing we need to do is release our mtd - * then go through freeing the resource used - */ - nand_release(&this->board_mtd); - - /* free the common resources */ - iounmap(this->regs); - kfree(this); - - DEBUG(MTD_DEBUG_LEVEL1, "%s: removed\n", module_id); - return 0; -} - -/* - * Called by device layer when it finds a device matching - * one our driver can handle. This code checks to see if - * it can allocate all necessary resources then calls the - * nand layer to look for devices. -*/ -static int __init excite_nand_probe(struct platform_device *pdev) -{ - struct excite_nand_drvdata *drvdata; /* private driver data */ - struct nand_chip *board_chip; /* private flash chip data */ - struct mtd_info *board_mtd; /* mtd info for this board */ - int scan_res; - - drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL); - if (unlikely(!drvdata)) { - printk(KERN_ERR "%s: no memory for drvdata\n", - module_id); - return -ENOMEM; - } - - /* bind private data into driver */ - platform_set_drvdata(pdev, drvdata); - - /* allocate and map the resource */ - drvdata->regs = - excite_nand_map_regs(pdev, EXCITE_NANDFLASH_RESOURCE_REGS); - - if (unlikely(!drvdata->regs)) { - printk(KERN_ERR "%s: cannot reserve register region\n", - module_id); - kfree(drvdata); - return -ENXIO; - } - - drvdata->tgt = drvdata->regs + EXCITE_NANDFLASH_DATA_BYTE; - - /* initialise our chip */ - board_chip = &drvdata->board_chip; - board_chip->IO_ADDR_R = board_chip->IO_ADDR_W = - drvdata->regs + EXCITE_NANDFLASH_DATA_BYTE; - board_chip->cmd_ctrl = excite_nand_control; - board_chip->dev_ready = excite_nand_devready; - board_chip->chip_delay = 25; - board_chip->ecc.mode = NAND_ECC_SOFT; - - /* link chip to mtd */ - board_mtd = &drvdata->board_mtd; - board_mtd->priv = board_chip; - - DEBUG(MTD_DEBUG_LEVEL2, "%s: device scan\n", module_id); - scan_res = nand_scan(&drvdata->board_mtd, 1); - - if (likely(!scan_res)) { - DEBUG(MTD_DEBUG_LEVEL2, "%s: register partitions\n", module_id); - add_mtd_partitions(&drvdata->board_mtd, partition_info, - ARRAY_SIZE(partition_info)); - } else { - iounmap(drvdata->regs); - kfree(drvdata); - printk(KERN_ERR "%s: device scan failed\n", module_id); - return -EIO; - } - return 0; -} - -static struct platform_driver excite_nand_driver = { - .driver = { - .name = "excite_nand", - .owner = THIS_MODULE, - }, - .probe = excite_nand_probe, - .remove = __devexit_p(excite_nand_remove) -}; - -static int __init excite_nand_init(void) -{ - pr_info("Basler eXcite nand flash driver Version " - EXCITE_NANDFLASH_VERSION "\n"); - return platform_driver_register(&excite_nand_driver); -} - -static void __exit excite_nand_exit(void) -{ - platform_driver_unregister(&excite_nand_driver); -} - -module_init(excite_nand_init); -module_exit(excite_nand_exit); - -MODULE_AUTHOR("Thomas Koeller "); -MODULE_DESCRIPTION("Basler eXcite NAND-Flash driver"); -MODULE_LICENSE("GPL"); -MODULE_VERSION(EXCITE_NANDFLASH_VERSION) diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index d958b76..da84fd0 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -815,16 +815,6 @@ config PNX833X_WDT timer has expired and no process has written to /dev/watchdog during that time. -config WDT_RM9K_GPI - tristate "RM9000/GPI hardware watchdog" - depends on CPU_RM9000 - help - Watchdog implementation using the GPI hardware found on - PMC-Sierra RM9xxx CPUs. - - To compile this driver as a module, choose M here: the - module will be called rm9k_wdt. - config SIBYTE_WDOG tristate "Sibyte SoC hardware watchdog" depends on CPU_SB1 diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 89c045d..475c611 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -109,7 +109,6 @@ obj-$(CONFIG_RC32434_WDT) += rc32434_wdt.o obj-$(CONFIG_INDYDOG) += indydog.o obj-$(CONFIG_WDT_MTX1) += mtx-1_wdt.o obj-$(CONFIG_PNX833X_WDT) += pnx833x_wdt.o -obj-$(CONFIG_WDT_RM9K_GPI) += rm9k_wdt.o obj-$(CONFIG_SIBYTE_WDOG) += sb_wdog.o obj-$(CONFIG_AR7_WDT) += ar7_wdt.o obj-$(CONFIG_TXX9_WDT) += txx9wdt.o diff --git a/drivers/watchdog/rm9k_wdt.c b/drivers/watchdog/rm9k_wdt.c deleted file mode 100644 index bb66958..0000000 --- a/drivers/watchdog/rm9k_wdt.c +++ /dev/null @@ -1,419 +0,0 @@ -/* - * Watchdog implementation for GPI h/w found on PMC-Sierra RM9xxx - * chips. - * - * Copyright (C) 2004 by Basler Vision Technologies AG - * Author: Thomas Koeller - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - - -#define CLOCK 125000000 -#define MAX_TIMEOUT_SECONDS 32 -#define CPCCR 0x0080 -#define CPGIG1SR 0x0044 -#define CPGIG1ER 0x0054 - - -/* Function prototypes */ -static irqreturn_t wdt_gpi_irqhdl(int, void *); -static void wdt_gpi_start(void); -static void wdt_gpi_stop(void); -static void wdt_gpi_set_timeout(unsigned int); -static int wdt_gpi_open(struct inode *, struct file *); -static int wdt_gpi_release(struct inode *, struct file *); -static ssize_t wdt_gpi_write(struct file *, const char __user *, size_t, - loff_t *); -static long wdt_gpi_ioctl(struct file *, unsigned int, unsigned long); -static int wdt_gpi_notify(struct notifier_block *, unsigned long, void *); -static const struct resource *wdt_gpi_get_resource(struct platform_device *, - const char *, unsigned int); -static int __init wdt_gpi_probe(struct platform_device *); -static int __exit wdt_gpi_remove(struct platform_device *); - - -static const char wdt_gpi_name[] = "wdt_gpi"; -static atomic_t opencnt; -static int expect_close; -static int locked; - - -/* These are set from device resources */ -static void __iomem *wd_regs; -static unsigned int wd_irq, wd_ctr; - - -/* Module arguments */ -static int timeout = MAX_TIMEOUT_SECONDS; -module_param(timeout, int, 0444); -MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds"); - -static unsigned long resetaddr = 0xbffdc200; -module_param(resetaddr, ulong, 0444); -MODULE_PARM_DESC(resetaddr, "Address to write to to force a reset"); - -static unsigned long flagaddr = 0xbffdc104; -module_param(flagaddr, ulong, 0444); -MODULE_PARM_DESC(flagaddr, "Address to write to boot flags to"); - -static int powercycle; -module_param(powercycle, bool, 0444); -MODULE_PARM_DESC(powercycle, "Cycle power if watchdog expires"); - -static int nowayout = WATCHDOG_NOWAYOUT; -module_param(nowayout, bool, 0444); -MODULE_PARM_DESC(nowayout, "Watchdog cannot be disabled once started"); - - -/* Kernel interfaces */ -static const struct file_operations fops = { - .owner = THIS_MODULE, - .open = wdt_gpi_open, - .release = wdt_gpi_release, - .write = wdt_gpi_write, - .unlocked_ioctl = wdt_gpi_ioctl, -}; - -static struct miscdevice miscdev = { - .minor = WATCHDOG_MINOR, - .name = wdt_gpi_name, - .fops = &fops, -}; - -static struct notifier_block wdt_gpi_shutdown = { - .notifier_call = wdt_gpi_notify, -}; - - -/* Interrupt handler */ -static irqreturn_t wdt_gpi_irqhdl(int irq, void *ctxt) -{ - if (!unlikely(__raw_readl(wd_regs + 0x0008) & 0x1)) - return IRQ_NONE; - __raw_writel(0x1, wd_regs + 0x0008); - - - printk(KERN_CRIT "%s: watchdog expired - resetting system\n", - wdt_gpi_name); - - *(volatile char *) flagaddr |= 0x01; - *(volatile char *) resetaddr = powercycle ? 0x01 : 0x2; - iob(); - while (1) - cpu_relax(); -} - - -/* Watchdog functions */ -static void wdt_gpi_start(void) -{ - u32 reg; - - lock_titan_regs(); - reg = titan_readl(CPGIG1ER); - titan_writel(reg | (0x100 << wd_ctr), CPGIG1ER); - iob(); - unlock_titan_regs(); -} - -static void wdt_gpi_stop(void) -{ - u32 reg; - - lock_titan_regs(); - reg = titan_readl(CPCCR) & ~(0xf << (wd_ctr * 4)); - titan_writel(reg, CPCCR); - reg = titan_readl(CPGIG1ER); - titan_writel(reg & ~(0x100 << wd_ctr), CPGIG1ER); - iob(); - unlock_titan_regs(); -} - -static void wdt_gpi_set_timeout(unsigned int to) -{ - u32 reg; - const u32 wdval = (to * CLOCK) & ~0x0000000f; - - lock_titan_regs(); - reg = titan_readl(CPCCR) & ~(0xf << (wd_ctr * 4)); - titan_writel(reg, CPCCR); - wmb(); - __raw_writel(wdval, wd_regs + 0x0000); - wmb(); - titan_writel(reg | (0x2 << (wd_ctr * 4)), CPCCR); - wmb(); - titan_writel(reg | (0x5 << (wd_ctr * 4)), CPCCR); - iob(); - unlock_titan_regs(); -} - - -/* /dev/watchdog operations */ -static int wdt_gpi_open(struct inode *inode, struct file *file) -{ - int res; - - if (unlikely(atomic_dec_if_positive(&opencnt) < 0)) - return -EBUSY; - - expect_close = 0; - if (locked) { - module_put(THIS_MODULE); - free_irq(wd_irq, &miscdev); - locked = 0; - } - - res = request_irq(wd_irq, wdt_gpi_irqhdl, IRQF_SHARED | IRQF_DISABLED, - wdt_gpi_name, &miscdev); - if (unlikely(res)) - return res; - - wdt_gpi_set_timeout(timeout); - wdt_gpi_start(); - - printk(KERN_INFO "%s: watchdog started, timeout = %u seconds\n", - wdt_gpi_name, timeout); - return nonseekable_open(inode, file); -} - -static int wdt_gpi_release(struct inode *inode, struct file *file) -{ - if (nowayout) { - printk(KERN_INFO "%s: no way out - watchdog left running\n", - wdt_gpi_name); - __module_get(THIS_MODULE); - locked = 1; - } else { - if (expect_close) { - wdt_gpi_stop(); - free_irq(wd_irq, &miscdev); - printk(KERN_INFO "%s: watchdog stopped\n", - wdt_gpi_name); - } else { - printk(KERN_CRIT "%s: unexpected close() -" - " watchdog left running\n", - wdt_gpi_name); - wdt_gpi_set_timeout(timeout); - __module_get(THIS_MODULE); - locked = 1; - } - } - - atomic_inc(&opencnt); - return 0; -} - -static ssize_t wdt_gpi_write(struct file *f, const char __user *d, size_t s, - loff_t *o) -{ - char val; - - wdt_gpi_set_timeout(timeout); - expect_close = (s > 0) && !get_user(val, d) && (val == 'V'); - return s ? 1 : 0; -} - -static long wdt_gpi_ioctl(struct file *f, unsigned int cmd, unsigned long arg) -{ - long res = -ENOTTY; - const long size = _IOC_SIZE(cmd); - int stat; - void __user *argp = (void __user *)arg; - static struct watchdog_info wdinfo = { - .identity = "RM9xxx/GPI watchdog", - .firmware_version = 0, - .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING - }; - - if (unlikely(_IOC_TYPE(cmd) != WATCHDOG_IOCTL_BASE)) - return -ENOTTY; - - if ((_IOC_DIR(cmd) & _IOC_READ) - && !access_ok(VERIFY_WRITE, arg, size)) - return -EFAULT; - - if ((_IOC_DIR(cmd) & _IOC_WRITE) - && !access_ok(VERIFY_READ, arg, size)) - return -EFAULT; - - expect_close = 0; - - switch (cmd) { - case WDIOC_GETSUPPORT: - wdinfo.options = nowayout ? - WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING : - WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | - WDIOF_MAGICCLOSE; - res = __copy_to_user(argp, &wdinfo, size) ? -EFAULT : size; - break; - - case WDIOC_GETSTATUS: - break; - - case WDIOC_GETBOOTSTATUS: - stat = (*(volatile char *) flagaddr & 0x01) - ? WDIOF_CARDRESET : 0; - res = __copy_to_user(argp, &stat, size) ? - -EFAULT : size; - break; - - case WDIOC_SETOPTIONS: - break; - - case WDIOC_KEEPALIVE: - wdt_gpi_set_timeout(timeout); - res = size; - break; - - case WDIOC_SETTIMEOUT: - { - int val; - if (unlikely(__copy_from_user(&val, argp, size))) { - res = -EFAULT; - break; - } - - if (val > MAX_TIMEOUT_SECONDS) - val = MAX_TIMEOUT_SECONDS; - timeout = val; - wdt_gpi_set_timeout(val); - res = size; - printk(KERN_INFO "%s: timeout set to %u seconds\n", - wdt_gpi_name, timeout); - } - break; - - case WDIOC_GETTIMEOUT: - res = __copy_to_user(argp, &timeout, size) ? - -EFAULT : size; - break; - } - - return res; -} - - -/* Shutdown notifier */ -static int wdt_gpi_notify(struct notifier_block *this, unsigned long code, - void *unused) -{ - if (code == SYS_DOWN || code == SYS_HALT) - wdt_gpi_stop(); - - return NOTIFY_DONE; -} - - -/* Init & exit procedures */ -static const struct resource *wdt_gpi_get_resource(struct platform_device *pdv, - const char *name, unsigned int type) -{ - char buf[80]; - if (snprintf(buf, sizeof(buf), "%s_0", name) >= sizeof(buf)) - return NULL; - return platform_get_resource_byname(pdv, type, buf); -} - -/* No hotplugging on the platform bus - use __devinit */ -static int __devinit wdt_gpi_probe(struct platform_device *pdv) -{ - int res; - const struct resource - * const rr = wdt_gpi_get_resource(pdv, WDT_RESOURCE_REGS, - IORESOURCE_MEM), - * const ri = wdt_gpi_get_resource(pdv, WDT_RESOURCE_IRQ, - IORESOURCE_IRQ), - * const rc = wdt_gpi_get_resource(pdv, WDT_RESOURCE_COUNTER, - 0); - - if (unlikely(!rr || !ri || !rc)) - return -ENXIO; - - wd_regs = ioremap_nocache(rr->start, rr->end + 1 - rr->start); - if (unlikely(!wd_regs)) - return -ENOMEM; - wd_irq = ri->start; - wd_ctr = rc->start; - res = misc_register(&miscdev); - if (res) - iounmap(wd_regs); - else - register_reboot_notifier(&wdt_gpi_shutdown); - return res; -} - -static int __devexit wdt_gpi_remove(struct platform_device *dev) -{ - int res; - - unregister_reboot_notifier(&wdt_gpi_shutdown); - res = misc_deregister(&miscdev); - iounmap(wd_regs); - wd_regs = NULL; - return res; -} - - -/* Device driver init & exit */ -static struct platform_driver wgt_gpi_driver = { - .driver = { - .name = wdt_gpi_name, - .owner = THIS_MODULE, - }, - .probe = wdt_gpi_probe, - .remove = __devexit_p(wdt_gpi_remove), -}; - -static int __init wdt_gpi_init_module(void) -{ - atomic_set(&opencnt, 1); - if (timeout > MAX_TIMEOUT_SECONDS) - timeout = MAX_TIMEOUT_SECONDS; - return platform_driver_register(&wdt_gpi_driver); -} - -static void __exit wdt_gpi_cleanup_module(void) -{ - platform_driver_unregister(&wdt_gpi_driver); -} - -module_init(wdt_gpi_init_module); -module_exit(wdt_gpi_cleanup_module); - -MODULE_AUTHOR("Thomas Koeller "); -MODULE_DESCRIPTION("Basler eXcite watchdog driver for gpi devices"); -MODULE_VERSION("0.1"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); - -- cgit v0.10.2 From 6acc7d485c24c00e111c61b2e6dff9180faebcae Mon Sep 17 00:00:00 2001 From: Dmitri Vorobiev Date: Sat, 21 Nov 2009 22:34:41 +0200 Subject: MIPS: Fix and enhance built-in kernel command line Currently, MIPS kernels silently overwrite kernel command-line parameters hardcoded in CONFIG_CMDLINE by the ones received from firmware. Therefore, using firmware remains the only reliable method to transfer the command-line parameters, which is not always desirable or convenient, and the CONFIG_CMDLINE option is thereby effectively rendered useless. This patch fixes the problem described above and introduces a more flexible scheme of handling the kernel command line, in a manner identical to what is currently used for x86. The default behavior, i.e. when CONFIG_CMDLINE_BOOL is not defined, retains the existing semantics, and firmware command-line arguments override the hardcoded ones. [Ralf: I fixed up all the defconfig files so the stay unaffected by this change.] Signed-off-by: Dmitri Vorobiev Cc: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/689/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/Kconfig.debug b/arch/mips/Kconfig.debug index 23817bc..d2b88a0 100644 --- a/arch/mips/Kconfig.debug +++ b/arch/mips/Kconfig.debug @@ -20,15 +20,52 @@ config EARLY_PRINTK doesn't cooperate with an X server. You should normally say N here, unless you want to debug such a crash. +config CMDLINE_BOOL + bool "Built-in kernel command line" + default n + help + For most systems, it is firmware or second stage bootloader that + by default specifies the kernel command line options. However, + it might be necessary or advantageous to either override the + default kernel command line or add a few extra options to it. + For such cases, this option allows you to hardcode your own + command line options directly into the kernel. For that, you + should choose 'Y' here, and fill in the extra boot arguments + in CONFIG_CMDLINE. + + The built-in options will be concatenated to the default command + line if CMDLINE_OVERRIDE is set to 'N'. Otherwise, the default + command line will be ignored and replaced by the built-in string. + + Most MIPS systems will normally expect 'N' here and rely upon + the command line from the firmware or the second-stage bootloader. + config CMDLINE string "Default kernel command string" + depends on CMDLINE_BOOL default "" help On some platforms, there is currently no way for the boot loader to - pass arguments to the kernel. For these platforms, you can supply - some command-line options at build time by entering them here. In - other cases you can specify kernel args so that you don't have - to set them up in board prom initialization routines. + pass arguments to the kernel. For these platforms, and for the cases + when you want to add some extra options to the command line or ignore + the default command line, you can supply some command-line options at + build time by entering them here. In other cases you can specify + kernel args so that you don't have to set them up in board prom + initialization routines. + + For more information, see the CMDLINE_BOOL and CMDLINE_OVERRIDE + options. + +config CMDLINE_OVERRIDE + bool "Built-in command line overrides firware arguments" + default n + depends on CMDLINE_BOOL + help + By setting this option to 'Y' you will have your kernel ignore + command line arguments from firmware or second stage bootloader. + Instead, the built-in command line will be used exclusively. + + Normally, you will choose 'N' here. config DEBUG_STACK_USAGE bool "Enable stack utilization instrumentation" diff --git a/arch/mips/configs/ar7_defconfig b/arch/mips/configs/ar7_defconfig index 1d5ec3c..5a5b6ba 100644 --- a/arch/mips/configs/ar7_defconfig +++ b/arch/mips/configs/ar7_defconfig @@ -1051,7 +1051,9 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_DYNAMIC_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y +CONFIG_CMDLINE_BOOL=y CONFIG_CMDLINE="rootfstype=squashfs,jffs2" +# CONFIG_CMDLINE_OVERRIDE is not set # # Security options diff --git a/arch/mips/configs/bcm47xx_defconfig b/arch/mips/configs/bcm47xx_defconfig index 8715de1..267bd46 100644 --- a/arch/mips/configs/bcm47xx_defconfig +++ b/arch/mips/configs/bcm47xx_defconfig @@ -1852,7 +1852,7 @@ CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set # CONFIG_SAMPLES is not set -CONFIG_CMDLINE="" +# CONFIG_CMDLINE_BOOL is not set # # Security options diff --git a/arch/mips/configs/bcm63xx_defconfig b/arch/mips/configs/bcm63xx_defconfig index efa6598..7fee027 100644 --- a/arch/mips/configs/bcm63xx_defconfig +++ b/arch/mips/configs/bcm63xx_defconfig @@ -941,7 +941,9 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y +CONFIG_CMDLINE_BOOL=y CONFIG_CMDLINE="console=ttyS0,115200" +# CONFIG_CMDLINE_OVERRIDE is not set # # Security options diff --git a/arch/mips/configs/bigsur_defconfig b/arch/mips/configs/bigsur_defconfig index 1f0228d..c2f06e3 100644 --- a/arch/mips/configs/bigsur_defconfig +++ b/arch/mips/configs/bigsur_defconfig @@ -1236,7 +1236,7 @@ CONFIG_DEBUG_MUTEXES=y # CONFIG_BACKTRACE_SELF_TEST is not set # CONFIG_FAULT_INJECTION is not set # CONFIG_SAMPLES is not set -CONFIG_CMDLINE="" +# CONFIG_CMDLINE_BOOL is not set # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_SB1XXX_CORELIS is not set # CONFIG_RUNTIME_DEBUG is not set diff --git a/arch/mips/configs/capcella_defconfig b/arch/mips/configs/capcella_defconfig index be81bf6..72b7e45 100644 --- a/arch/mips/configs/capcella_defconfig +++ b/arch/mips/configs/capcella_defconfig @@ -782,7 +782,9 @@ CONFIG_ENABLE_MUST_CHECK=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set CONFIG_CROSSCOMPILE=y +CONFIG_CMDLINE_BOOL=y CONFIG_CMDLINE="mem=32M console=ttyVR0,38400" +# CONFIG_CMDLINE_OVERRIDE is not set # # Security options diff --git a/arch/mips/configs/cavium-octeon_defconfig b/arch/mips/configs/cavium-octeon_defconfig index 22819d9..c8507bc 100644 --- a/arch/mips/configs/cavium-octeon_defconfig +++ b/arch/mips/configs/cavium-octeon_defconfig @@ -820,7 +820,7 @@ CONFIG_SYSCTL_SYSCALL_CHECK=y # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set -CONFIG_CMDLINE="" +# CONFIG_CMDLINE_BOOL is not set # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_RUNTIME_DEBUG is not set diff --git a/arch/mips/configs/cobalt_defconfig b/arch/mips/configs/cobalt_defconfig index b150286..49e6131 100644 --- a/arch/mips/configs/cobalt_defconfig +++ b/arch/mips/configs/cobalt_defconfig @@ -1125,7 +1125,7 @@ CONFIG_FRAME_WARN=1024 # CONFIG_SLUB_STATS is not set # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_SAMPLES is not set -CONFIG_CMDLINE="" +# CONFIG_CMDLINE_BOOL is not set # # Security options diff --git a/arch/mips/configs/db1000_defconfig b/arch/mips/configs/db1000_defconfig index 63cdea2..68e90cd 100644 --- a/arch/mips/configs/db1000_defconfig +++ b/arch/mips/configs/db1000_defconfig @@ -1089,7 +1089,7 @@ CONFIG_ENABLE_MUST_CHECK=y # CONFIG_DEBUG_KERNEL is not set CONFIG_LOG_BUF_SHIFT=14 CONFIG_CROSSCOMPILE=y -CONFIG_CMDLINE="" +# CONFIG_CMDLINE_BOOL is not set # # Security options diff --git a/arch/mips/configs/db1100_defconfig b/arch/mips/configs/db1100_defconfig index 7ae0f9a..9081283 100644 --- a/arch/mips/configs/db1100_defconfig +++ b/arch/mips/configs/db1100_defconfig @@ -1089,7 +1089,7 @@ CONFIG_ENABLE_MUST_CHECK=y # CONFIG_DEBUG_KERNEL is not set CONFIG_LOG_BUF_SHIFT=14 CONFIG_CROSSCOMPILE=y -CONFIG_CMDLINE="" +# CONFIG_CMDLINE_BOOL is not set # # Security options diff --git a/arch/mips/configs/db1200_defconfig b/arch/mips/configs/db1200_defconfig index a6d9e1f..dabf030 100644 --- a/arch/mips/configs/db1200_defconfig +++ b/arch/mips/configs/db1200_defconfig @@ -1171,7 +1171,9 @@ CONFIG_ENABLE_MUST_CHECK=y # CONFIG_DEBUG_KERNEL is not set CONFIG_LOG_BUF_SHIFT=14 CONFIG_CROSSCOMPILE=y +CONFIG_CMDLINE_BOOL=y CONFIG_CMDLINE="mem=48M" +# CONFIG_CMDLINE_OVERRIDE is not set # # Security options diff --git a/arch/mips/configs/db1500_defconfig b/arch/mips/configs/db1500_defconfig index a3a462b..a151313 100644 --- a/arch/mips/configs/db1500_defconfig +++ b/arch/mips/configs/db1500_defconfig @@ -1389,7 +1389,7 @@ CONFIG_ENABLE_MUST_CHECK=y # CONFIG_DEBUG_KERNEL is not set CONFIG_LOG_BUF_SHIFT=14 CONFIG_CROSSCOMPILE=y -CONFIG_CMDLINE="" +# CONFIG_CMDLINE_BOOL is not set # # Security options diff --git a/arch/mips/configs/db1550_defconfig b/arch/mips/configs/db1550_defconfig index bfc962e..6b64339 100644 --- a/arch/mips/configs/db1550_defconfig +++ b/arch/mips/configs/db1550_defconfig @@ -1206,7 +1206,7 @@ CONFIG_ENABLE_MUST_CHECK=y # CONFIG_DEBUG_KERNEL is not set CONFIG_LOG_BUF_SHIFT=14 CONFIG_CROSSCOMPILE=y -CONFIG_CMDLINE="" +# CONFIG_CMDLINE_BOOL is not set # # Security options diff --git a/arch/mips/configs/decstation_defconfig b/arch/mips/configs/decstation_defconfig index 7eb6d1b..cbb4d86 100644 --- a/arch/mips/configs/decstation_defconfig +++ b/arch/mips/configs/decstation_defconfig @@ -881,7 +881,7 @@ CONFIG_MAGIC_SYSRQ=y # CONFIG_DEBUG_KERNEL is not set CONFIG_LOG_BUF_SHIFT=14 CONFIG_CROSSCOMPILE=y -CONFIG_CMDLINE="" +# CONFIG_CMDLINE_BOOL is not set # # Security options diff --git a/arch/mips/configs/e55_defconfig b/arch/mips/configs/e55_defconfig index c6b1d6b..52968c4 100644 --- a/arch/mips/configs/e55_defconfig +++ b/arch/mips/configs/e55_defconfig @@ -560,7 +560,9 @@ CONFIG_ENABLE_MUST_CHECK=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set CONFIG_CROSSCOMPILE=y +CONFIG_CMDLINE_BOOL=y CONFIG_CMDLINE="console=ttyVR0,19200 ide0=0x1f0,0x3f6,40 mem=8M" +# CONFIG_CMDLINE_OVERRIDE is not set # # Security options diff --git a/arch/mips/configs/fuloong2e_defconfig b/arch/mips/configs/fuloong2e_defconfig index 17341a0..a09dd03 100644 --- a/arch/mips/configs/fuloong2e_defconfig +++ b/arch/mips/configs/fuloong2e_defconfig @@ -1710,7 +1710,7 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_DYNAMIC_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y -CONFIG_CMDLINE="" +# CONFIG_CMDLINE_BOOL is not set # # Security options diff --git a/arch/mips/configs/ip22_defconfig b/arch/mips/configs/ip22_defconfig index 3471ac9..222d7ec 100644 --- a/arch/mips/configs/ip22_defconfig +++ b/arch/mips/configs/ip22_defconfig @@ -1187,7 +1187,7 @@ CONFIG_DEBUG_MEMORY_INIT=y CONFIG_DYNAMIC_PRINTK_DEBUG=y # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y -CONFIG_CMDLINE="" +# CONFIG_CMDLINE_BOOL is not set # # Security options diff --git a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig index 26127a8..ed84b4c 100644 --- a/arch/mips/configs/ip27_defconfig +++ b/arch/mips/configs/ip27_defconfig @@ -939,7 +939,7 @@ CONFIG_ENABLE_MUST_CHECK=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set CONFIG_CROSSCOMPILE=y -CONFIG_CMDLINE="" +# CONFIG_CMDLINE_BOOL is not set # # Security options diff --git a/arch/mips/configs/ip28_defconfig b/arch/mips/configs/ip28_defconfig index ac6c850..dab2e5a 100644 --- a/arch/mips/configs/ip28_defconfig +++ b/arch/mips/configs/ip28_defconfig @@ -815,7 +815,7 @@ CONFIG_MAGIC_SYSRQ=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set # CONFIG_SAMPLES is not set -CONFIG_CMDLINE="" +# CONFIG_CMDLINE_BOOL is not set # # Security options diff --git a/arch/mips/configs/ip32_defconfig b/arch/mips/configs/ip32_defconfig index 56553b1..1841c88 100644 --- a/arch/mips/configs/ip32_defconfig +++ b/arch/mips/configs/ip32_defconfig @@ -1125,7 +1125,7 @@ CONFIG_SYSCTL_SYSCALL_CHECK=y # CONFIG_DYNAMIC_PRINTK_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y -CONFIG_CMDLINE="" +# CONFIG_CMDLINE_BOOL is not set # # Security options diff --git a/arch/mips/configs/jazz_defconfig b/arch/mips/configs/jazz_defconfig index 9db23fd..14c2ab3 100644 --- a/arch/mips/configs/jazz_defconfig +++ b/arch/mips/configs/jazz_defconfig @@ -1373,7 +1373,7 @@ CONFIG_ENABLE_MUST_CHECK=y # CONFIG_DEBUG_KERNEL is not set CONFIG_LOG_BUF_SHIFT=14 CONFIG_CROSSCOMPILE=y -CONFIG_CMDLINE="" +# CONFIG_CMDLINE_BOOL is not set # # Security options diff --git a/arch/mips/configs/jmr3927_defconfig b/arch/mips/configs/jmr3927_defconfig index 11fec0e..4d66c44 100644 --- a/arch/mips/configs/jmr3927_defconfig +++ b/arch/mips/configs/jmr3927_defconfig @@ -834,7 +834,7 @@ CONFIG_SYSCTL_SYSCALL_CHECK=y # CONFIG_DYNAMIC_PRINTK_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y -CONFIG_CMDLINE="" +# CONFIG_CMDLINE_BOOL is not set # # Security options diff --git a/arch/mips/configs/lasat_defconfig b/arch/mips/configs/lasat_defconfig index 2fe15a5..08d481e 100644 --- a/arch/mips/configs/lasat_defconfig +++ b/arch/mips/configs/lasat_defconfig @@ -797,7 +797,7 @@ CONFIG_MAGIC_SYSRQ=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set CONFIG_CROSSCOMPILE=y -CONFIG_CMDLINE="" +# CONFIG_CMDLINE_BOOL is not set # # Security options diff --git a/arch/mips/configs/lemote2f_defconfig b/arch/mips/configs/lemote2f_defconfig index ddb1c92..b71a0a4 100644 --- a/arch/mips/configs/lemote2f_defconfig +++ b/arch/mips/configs/lemote2f_defconfig @@ -1707,7 +1707,7 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_FTRACE is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y -CONFIG_CMDLINE="" +# CONFIG_CMDLINE_BOOL is not set # # Security options diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig index 38d9873..d3c6012 100644 --- a/arch/mips/configs/malta_defconfig +++ b/arch/mips/configs/malta_defconfig @@ -1590,7 +1590,7 @@ CONFIG_FRAME_WARN=1024 # CONFIG_DYNAMIC_PRINTK_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y -CONFIG_CMDLINE="" +# CONFIG_CMDLINE_BOOL is not set # # Security options diff --git a/arch/mips/configs/markeins_defconfig b/arch/mips/configs/markeins_defconfig index 9137571..6a325c0 100644 --- a/arch/mips/configs/markeins_defconfig +++ b/arch/mips/configs/markeins_defconfig @@ -1365,7 +1365,9 @@ CONFIG_ENABLE_MUST_CHECK=y # CONFIG_DEBUG_KERNEL is not set CONFIG_LOG_BUF_SHIFT=14 CONFIG_CROSSCOMPILE=y +CONFIG_CMDLINE_BOOL=y CONFIG_CMDLINE="console=ttyS0,115200 mem=192m ip=bootp root=/dev/nfs rw" +# CONFIG_CMDLINE_OVERRIDE is not set # # Security options diff --git a/arch/mips/configs/mipssim_defconfig b/arch/mips/configs/mipssim_defconfig index 513e9a4..f77a34e 100644 --- a/arch/mips/configs/mipssim_defconfig +++ b/arch/mips/configs/mipssim_defconfig @@ -634,7 +634,9 @@ CONFIG_FORCED_INLINING=y # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_FAULT_INJECTION is not set CONFIG_CROSSCOMPILE=y +CONFIG_CMDLINE_BOOL=y CONFIG_CMDLINE="nfsroot=192.168.192.169:/u1/mipsel,timeo=20 ip=dhcp" +# CONFIG_CMDLINE_OVERRIDE is not set # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_RUNTIME_DEBUG is not set diff --git a/arch/mips/configs/mpc30x_defconfig b/arch/mips/configs/mpc30x_defconfig index b893f9d..1720305 100644 --- a/arch/mips/configs/mpc30x_defconfig +++ b/arch/mips/configs/mpc30x_defconfig @@ -816,7 +816,9 @@ CONFIG_ENABLE_MUST_CHECK=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set CONFIG_CROSSCOMPILE=y +CONFIG_CMDLINE_BOOL=y CONFIG_CMDLINE="mem=32M console=ttyVR0,19200 ide0=0x170,0x376,73" +# CONFIG_CMDLINE_OVERRIDE is not set # # Security options diff --git a/arch/mips/configs/msp71xx_defconfig b/arch/mips/configs/msp71xx_defconfig index 89d2b6a..000d185 100644 --- a/arch/mips/configs/msp71xx_defconfig +++ b/arch/mips/configs/msp71xx_defconfig @@ -1411,7 +1411,7 @@ CONFIG_FORCED_INLINING=y # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_FAULT_INJECTION is not set CONFIG_CROSSCOMPILE=y -CONFIG_CMDLINE="" +# CONFIG_CMDLINE_BOOL is not set # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_RUNTIME_DEBUG is not set # CONFIG_MIPS_UNCACHED is not set diff --git a/arch/mips/configs/mtx1_defconfig b/arch/mips/configs/mtx1_defconfig index 3199668..144b94d 100644 --- a/arch/mips/configs/mtx1_defconfig +++ b/arch/mips/configs/mtx1_defconfig @@ -3017,7 +3017,7 @@ CONFIG_MAGIC_SYSRQ=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set CONFIG_CROSSCOMPILE=y -CONFIG_CMDLINE="" +# CONFIG_CMDLINE_BOOL is not set # # Security options diff --git a/arch/mips/configs/pb1100_defconfig b/arch/mips/configs/pb1100_defconfig index c36e859..ddf67f6 100644 --- a/arch/mips/configs/pb1100_defconfig +++ b/arch/mips/configs/pb1100_defconfig @@ -1082,7 +1082,7 @@ CONFIG_ENABLE_MUST_CHECK=y # CONFIG_DEBUG_KERNEL is not set CONFIG_LOG_BUF_SHIFT=14 CONFIG_CROSSCOMPILE=y -CONFIG_CMDLINE="" +# CONFIG_CMDLINE_BOOL is not set # # Security options diff --git a/arch/mips/configs/pb1500_defconfig b/arch/mips/configs/pb1500_defconfig index 4b43e36..5ec6083 100644 --- a/arch/mips/configs/pb1500_defconfig +++ b/arch/mips/configs/pb1500_defconfig @@ -1199,7 +1199,7 @@ CONFIG_ENABLE_MUST_CHECK=y # CONFIG_DEBUG_KERNEL is not set CONFIG_LOG_BUF_SHIFT=14 CONFIG_CROSSCOMPILE=y -CONFIG_CMDLINE="" +# CONFIG_CMDLINE_BOOL is not set # # Security options diff --git a/arch/mips/configs/pb1550_defconfig b/arch/mips/configs/pb1550_defconfig index 7c8d351..6647642 100644 --- a/arch/mips/configs/pb1550_defconfig +++ b/arch/mips/configs/pb1550_defconfig @@ -1192,7 +1192,7 @@ CONFIG_ENABLE_MUST_CHECK=y # CONFIG_DEBUG_KERNEL is not set CONFIG_LOG_BUF_SHIFT=14 CONFIG_CROSSCOMPILE=y -CONFIG_CMDLINE="" +# CONFIG_CMDLINE_BOOL is not set # # Security options diff --git a/arch/mips/configs/pnx8335-stb225_defconfig b/arch/mips/configs/pnx8335-stb225_defconfig index 77a75f0..848344d5 100644 --- a/arch/mips/configs/pnx8335-stb225_defconfig +++ b/arch/mips/configs/pnx8335-stb225_defconfig @@ -1033,7 +1033,7 @@ CONFIG_FRAME_WARN=1024 # CONFIG_DEBUG_KERNEL is not set # CONFIG_SAMPLES is not set # CONFIG_KERNEL_TESTS is not set -CONFIG_CMDLINE="" +# CONFIG_CMDLINE_BOOL is not set # # Security options diff --git a/arch/mips/configs/pnx8550-jbs_defconfig b/arch/mips/configs/pnx8550-jbs_defconfig index 945b27e..9d721fd 100644 --- a/arch/mips/configs/pnx8550-jbs_defconfig +++ b/arch/mips/configs/pnx8550-jbs_defconfig @@ -1214,7 +1214,9 @@ CONFIG_DEBUG_MUTEXES=y CONFIG_FORCED_INLINING=y # CONFIG_RCU_TORTURE_TEST is not set CONFIG_CROSSCOMPILE=y +CONFIG_CMDLINE_BOOL=y CONFIG_CMDLINE="console=ttyS1,38400n8 root=/dev/nfs ip=bootp" +# CONFIG_CMDLINE_OVERRIDE is not set # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_RUNTIME_DEBUG is not set diff --git a/arch/mips/configs/pnx8550-stb810_defconfig b/arch/mips/configs/pnx8550-stb810_defconfig index ff0fc0b..ab07ec0 100644 --- a/arch/mips/configs/pnx8550-stb810_defconfig +++ b/arch/mips/configs/pnx8550-stb810_defconfig @@ -1204,7 +1204,9 @@ CONFIG_DEBUG_SLAB=y CONFIG_FORCED_INLINING=y # CONFIG_RCU_TORTURE_TEST is not set CONFIG_CROSSCOMPILE=y +CONFIG_CMDLINE_BOOL=y CONFIG_CMDLINE="console=ttyS1,38400n8 root=/dev/nfs ip=bootp" +# CONFIG_CMDLINE_OVERRIDE is not set # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_RUNTIME_DEBUG is not set diff --git a/arch/mips/configs/powertv_defconfig b/arch/mips/configs/powertv_defconfig index 86c8007..7291633 100644 --- a/arch/mips/configs/powertv_defconfig +++ b/arch/mips/configs/powertv_defconfig @@ -1418,7 +1418,9 @@ CONFIG_BRANCH_PROFILE_NONE=y CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set # CONFIG_KMEMCHECK is not set +CONFIG_CMDLINE_BOOL=y CONFIG_CMDLINE="rw dhash_entries=1024 ihash_entries=1024 ip=10.0.1.3:10.0.1.1:10.0.1.1:255.255.255.0:zeus:eth0: root=/dev/nfs nfsroot=/nfsroot/cramfs,wsize=512,rsize=512,tcp nokgdb console=ttyUSB0,115200 memsize=252M" +# CONFIG_CMDLINE_OVERRIDE is not set # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_RUNTIME_DEBUG is not set diff --git a/arch/mips/configs/rb532_defconfig b/arch/mips/configs/rb532_defconfig index a9408db..57a5048 100644 --- a/arch/mips/configs/rb532_defconfig +++ b/arch/mips/configs/rb532_defconfig @@ -1203,7 +1203,7 @@ CONFIG_FRAME_WARN=1024 # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set # CONFIG_SAMPLES is not set -CONFIG_CMDLINE="" +# CONFIG_CMDLINE_BOOL is not set # # Security options diff --git a/arch/mips/configs/rbtx49xx_defconfig b/arch/mips/configs/rbtx49xx_defconfig index 1c9a542..21c2022 100644 --- a/arch/mips/configs/rbtx49xx_defconfig +++ b/arch/mips/configs/rbtx49xx_defconfig @@ -1061,7 +1061,7 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_DYNAMIC_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y -CONFIG_CMDLINE="" +# CONFIG_CMDLINE_BOOL is not set # # Security options diff --git a/arch/mips/configs/rm200_defconfig b/arch/mips/configs/rm200_defconfig index 5873fc5..7903628 100644 --- a/arch/mips/configs/rm200_defconfig +++ b/arch/mips/configs/rm200_defconfig @@ -1693,7 +1693,7 @@ CONFIG_ENABLE_MUST_CHECK=y # CONFIG_DEBUG_KERNEL is not set CONFIG_LOG_BUF_SHIFT=14 CONFIG_CROSSCOMPILE=y -CONFIG_CMDLINE="" +# CONFIG_CMDLINE_BOOL is not set # # Security options diff --git a/arch/mips/configs/sb1250-swarm_defconfig b/arch/mips/configs/sb1250-swarm_defconfig index 5244716..7f07bf0 100644 --- a/arch/mips/configs/sb1250-swarm_defconfig +++ b/arch/mips/configs/sb1250-swarm_defconfig @@ -960,7 +960,7 @@ CONFIG_ENABLE_MUST_CHECK=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set # CONFIG_SAMPLES is not set -CONFIG_CMDLINE="" +# CONFIG_CMDLINE_BOOL is not set # CONFIG_SB1XXX_CORELIS is not set # diff --git a/arch/mips/configs/tb0219_defconfig b/arch/mips/configs/tb0219_defconfig index 937b47c..c54d112 100644 --- a/arch/mips/configs/tb0219_defconfig +++ b/arch/mips/configs/tb0219_defconfig @@ -891,7 +891,9 @@ CONFIG_FRAME_WARN=1024 # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set # CONFIG_SAMPLES is not set +CONFIG_CMDLINE_BOOL=y CONFIG_CMDLINE="cca=3 mem=64M console=ttyVR0,115200 ip=any root=/dev/nfs" +# CONFIG_CMDLINE_OVERRIDE is not set # # Security options diff --git a/arch/mips/configs/tb0226_defconfig b/arch/mips/configs/tb0226_defconfig index da73584..e7c5cd3 100644 --- a/arch/mips/configs/tb0226_defconfig +++ b/arch/mips/configs/tb0226_defconfig @@ -894,7 +894,9 @@ CONFIG_FRAME_WARN=1024 # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set # CONFIG_SAMPLES is not set +CONFIG_CMDLINE_BOOL=y CONFIG_CMDLINE="cca=3 mem=32M console=ttyVR0,115200" +# CONFIG_CMDLINE_OVERRIDE is not set # # Security options diff --git a/arch/mips/configs/tb0287_defconfig b/arch/mips/configs/tb0287_defconfig index 99a0d21..b50032b 100644 --- a/arch/mips/configs/tb0287_defconfig +++ b/arch/mips/configs/tb0287_defconfig @@ -1076,7 +1076,9 @@ CONFIG_FRAME_WARN=1024 # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set # CONFIG_SAMPLES is not set +CONFIG_CMDLINE_BOOL=y CONFIG_CMDLINE="cca=3 mem=64M console=ttyVR0,115200 ip=any root=/dev/nfs" +# CONFIG_CMDLINE_OVERRIDE is not set # # Security options diff --git a/arch/mips/configs/workpad_defconfig b/arch/mips/configs/workpad_defconfig index d3646ea..c02ba08 100644 --- a/arch/mips/configs/workpad_defconfig +++ b/arch/mips/configs/workpad_defconfig @@ -754,7 +754,9 @@ CONFIG_ENABLE_MUST_CHECK=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set CONFIG_CROSSCOMPILE=y +CONFIG_CMDLINE_BOOL=y CONFIG_CMDLINE="console=ttyVR0,19200 ide0=0x170,0x376,49 mem=16M" +# CONFIG_CMDLINE_OVERRIDE is not set # # Security options diff --git a/arch/mips/configs/wrppmc_defconfig b/arch/mips/configs/wrppmc_defconfig index c137831..a35bc41 100644 --- a/arch/mips/configs/wrppmc_defconfig +++ b/arch/mips/configs/wrppmc_defconfig @@ -886,7 +886,9 @@ CONFIG_ENABLE_MUST_CHECK=y # CONFIG_DEBUG_KERNEL is not set CONFIG_LOG_BUF_SHIFT=14 CONFIG_CROSSCOMPILE=y +CONFIG_CMDLINE_BOOL=y CONFIG_CMDLINE="console=ttyS0,115200n8" +# CONFIG_CMDLINE_OVERRIDE is not set # # Security options diff --git a/arch/mips/configs/yosemite_defconfig b/arch/mips/configs/yosemite_defconfig index 4a04f0c..e3d68d6 100644 --- a/arch/mips/configs/yosemite_defconfig +++ b/arch/mips/configs/yosemite_defconfig @@ -823,7 +823,7 @@ CONFIG_DEBUG_MUTEXES=y CONFIG_FORCED_INLINING=y # CONFIG_RCU_TORTURE_TEST is not set CONFIG_CROSSCOMPILE=y -CONFIG_CMDLINE="" +# CONFIG_CMDLINE_BOOL is not set # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_RUNTIME_DEBUG is not set diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index bd55f71..f9513f9 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -58,8 +58,12 @@ EXPORT_SYMBOL(mips_machtype); struct boot_mem_map boot_mem_map; -static char command_line[COMMAND_LINE_SIZE]; - char arcs_cmdline[COMMAND_LINE_SIZE] = CONFIG_CMDLINE; +static char __initdata command_line[COMMAND_LINE_SIZE]; +char __initdata arcs_cmdline[COMMAND_LINE_SIZE]; + +#ifdef CONFIG_CMDLINE_BOOL +static char __initdata builtin_cmdline[COMMAND_LINE_SIZE] = CONFIG_CMDLINE; +#endif /* * mips_io_port_base is the begin of the address space to which x86 style @@ -458,8 +462,20 @@ static void __init arch_mem_init(char **cmdline_p) pr_info("Determined physical RAM map:\n"); print_memory_map(); - strlcpy(command_line, arcs_cmdline, sizeof(command_line)); - strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); +#ifdef CONFIG_CMDLINE_BOOL +#ifdef CONFIG_CMDLINE_OVERRIDE + strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE); +#else + if (builtin_cmdline[0]) { + strlcat(arcs_cmdline, " ", COMMAND_LINE_SIZE); + strlcat(arcs_cmdline, builtin_cmdline, COMMAND_LINE_SIZE); + } + strlcpy(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE); +#endif +#else + strlcpy(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE); +#endif + strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); *cmdline_p = command_line; -- cgit v0.10.2 From a4609780c9acd291becfc5e81b08485f92803886 Mon Sep 17 00:00:00 2001 From: Martin Michlmayr Date: Thu, 19 Nov 2009 16:46:32 +0000 Subject: MIPS: No longer hardwire CONFIG_EMBEDDED to y There's no reason for MIPS to select EMBEDDED. In fact, EMBEDDED makes MIPS more awkward to deal with because it makes it different to the majority of architectures for no good reason. [Ralf: Historically disabling EMBEDDED had hid essential options for many MIPS platforms such as serial console and forced crap like VGA support or power managment enabled for platforms where those don't make any sense. The name of the option is also _very_ missleading so many users don't select it even where is was required for a functioning kernel.] Signed-off-by: Martin Michlmayr Cc: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/663/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index f374cca..9541171 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -10,8 +10,6 @@ config MIPS select HAVE_DYNAMIC_FTRACE select HAVE_FTRACE_MCOUNT_RECORD select HAVE_FUNCTION_GRAPH_TRACER - # Horrible source of confusion. Die, die, die ... - select EMBEDDED select RTC_LIB if !MACH_LOONGSON mainmenu "Linux/MIPS Kernel Configuration" -- cgit v0.10.2 From cf72e9470dc071c395f7895b5cb9418dca27d07d Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 17 Dec 2009 01:57:36 +0000 Subject: MIPS: Cleanup random differences beween lmo and Linus' kernel. Signed-off-by: Ralf Baechle diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index 8dda214..9326af5 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -2,8 +2,6 @@ # Makefile for the Linux/MIPS kernel. # -CPPFLAGS_vmlinux.lds := $(KBUILD_CFLAGS) - extra-y := head.o init_task.o vmlinux.lds obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \ @@ -103,3 +101,5 @@ obj-$(CONFIG_HAVE_STD_PC_SERIAL_PORT) += 8250-platform.o obj-$(CONFIG_MIPS_CPUFREQ) += cpufreq/ EXTRA_CFLAGS += -Werror + +CPPFLAGS_vmlinux.lds := $(KBUILD_CFLAGS) -- cgit v0.10.2 From 95abd0dfaf5d2741dc9ebe733c9d609629a92b77 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Thu, 5 Nov 2009 09:21:54 +0800 Subject: RTC: rtc-cmos.c: Fix warning on MIPS This patch fixes the following warning with RTC_LIB on MIPS: drivers/rtc/rtc-cmos.c:697:2: warning: #warning Assuming 128 bytes of RTC+NVRAM address space, not 64 bytes. Signed-off-by: Wu Zhangjin Cc: Arnaud Patard Cc: linux-mips@linux-mips.org Cc: rtc-linux@googlegroups.com Cc: Paul Gortmaker Cc: Alessandro Zummo Patchwork: http://patchwork.linux-mips.org/patch/570/ Acked-by: Alessandro Zummo Signed-off-by: Ralf Baechle diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index eb154dc..c8c1232 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -686,7 +686,8 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) */ #if defined(CONFIG_ATARI) address_space = 64; -#elif defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__sparc__) +#elif defined(__i386__) || defined(__x86_64__) || defined(__arm__) \ + || defined(__sparc__) || defined(__mips__) address_space = 128; #else #warning Assuming 128 bytes of RTC+NVRAM address space, not 64 bytes. -- cgit v0.10.2 From 606d62fa02cf1da43c6e21521650fff07a2e56d1 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 17 Dec 2009 01:57:37 +0000 Subject: MIPS: Lasat: Fix botched changes to sysctl code. Commit 163931922220e4cb5effd5af1e105038c2f0ab7a "sysctl mips/lasat: Remove dead binary sysctl support" obviously wasn't test built ... Signed-off-by: Ralf Baechle diff --git a/arch/mips/lasat/sysctl.c b/arch/mips/lasat/sysctl.c index 14b9a28..d87ffd0 100644 --- a/arch/mips/lasat/sysctl.c +++ b/arch/mips/lasat/sysctl.c @@ -204,7 +204,7 @@ static ctl_table lasat_table[] = { .maxlen = sizeof(int), .mode = 0644, .proc_handler = proc_lasat_prid, -. }, + }, #ifdef CONFIG_INET { .procname = "ipaddr", -- cgit v0.10.2 From 2d1c861871d767153538a77c498752b36d4bb4b8 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Wed, 9 Dec 2009 17:52:13 +1100 Subject: PCI/cardbus: Add a fixup hook and fix powerpc The cardbus code creates PCI devices without ever going through the necessary fixup bits and pieces that normal PCI devices go through. There's in fact a commented out call to pcibios_fixup_bus() in there, it's commented because ... it doesn't work. I could make pcibios_fixup_bus() do the right thing on powerpc easily but I felt it cleaner instead to provide a specific hook pci_fixup_cardbus for which a weak empty implementation is provided by the PCI core. This fixes cardbus on powerbooks and probably all other PowerPC platforms which was broken completely for ever on some platforms and since 2.6.31 on others such as PowerBooks when we made the DMA ops mandatory (since those are setup by the fixups). Acked-by: Dominik Brodowski Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Jesse Barnes diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index e8dfdbd..cadbed6 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -1107,6 +1107,12 @@ void __devinit pcibios_setup_bus_devices(struct pci_bus *bus) list_for_each_entry(dev, &bus->devices, bus_list) { struct dev_archdata *sd = &dev->dev.archdata; + /* Cardbus can call us to add new devices to a bus, so ignore + * those who are already fully discovered + */ + if (dev->is_added) + continue; + /* Setup OF node pointer in archdata */ sd->of_node = pci_device_to_OF_node(dev); @@ -1147,6 +1153,13 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus) } EXPORT_SYMBOL(pcibios_fixup_bus); +void __devinit pci_fixup_cardbus(struct pci_bus *bus) +{ + /* Now fixup devices on that bus */ + pcibios_setup_bus_devices(bus); +} + + static int skip_isa_ioresource_align(struct pci_dev *dev) { if ((ppc_pci_flags & PPC_PCI_CAN_SKIP_ISA_ALIGN) && diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index d50522b..864e703 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -2798,6 +2798,11 @@ int __attribute__ ((weak)) pci_ext_cfg_avail(struct pci_dev *dev) return 1; } +void __weak pci_fixup_cardbus(struct pci_bus *bus) +{ +} +EXPORT_SYMBOL(pci_fixup_cardbus); + static int __init pci_setup(char *str) { while (str) { diff --git a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c index cdf50f3..d99f846 100644 --- a/drivers/pcmcia/cardbus.c +++ b/drivers/pcmcia/cardbus.c @@ -222,7 +222,7 @@ int __ref cb_alloc(struct pcmcia_socket *s) unsigned int max, pass; s->functions = pci_scan_slot(bus, PCI_DEVFN(0, 0)); -/* pcibios_fixup_bus(bus); */ + pci_fixup_cardbus(bus); max = bus->secondary; for (pass = 0; pass < 2; pass++) diff --git a/include/linux/pci.h b/include/linux/pci.h index bf1e670..5da0690 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -566,6 +566,9 @@ void pcibios_align_resource(void *, struct resource *, resource_size_t, resource_size_t); void pcibios_update_irq(struct pci_dev *, int irq); +/* Weak but can be overriden by arch */ +void pci_fixup_cardbus(struct pci_bus *); + /* Generic PCI functions used internally */ extern struct pci_bus *pci_find_bus(int domain, int busnr); -- cgit v0.10.2 From 4f924ba5b5aaf1477daafeae779495d39549186d Mon Sep 17 00:00:00 2001 From: Mattia Dongili Date: Thu, 17 Dec 2009 00:08:33 +0900 Subject: sony-laptop: add AVMode key mapping Some models are equipped with an "AVMode" function key that sends sony-laptop: Unknown event: 0x100 0xa1 sony-laptop: Unknown event: 0x100 0x21 for press and release respectively. Cc: "Matthew W. S. Bell" Cc: Dmitry Torokhov Signed-off-by: Mattia Dongili Signed-off-by: Len Brown diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index a2a742c..9710f70 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c @@ -232,6 +232,7 @@ static int sony_laptop_input_index[] = { 56, /* 69 SONYPI_EVENT_VOLUME_INC_PRESSED */ 57, /* 70 SONYPI_EVENT_VOLUME_DEC_PRESSED */ -1, /* 71 SONYPI_EVENT_BRIGHTNESS_PRESSED */ + 58, /* 72 SONYPI_EVENT_MEDIA_PRESSED */ }; static int sony_laptop_input_keycode_map[] = { @@ -293,6 +294,7 @@ static int sony_laptop_input_keycode_map[] = { KEY_F15, /* 55 SONYPI_EVENT_SETTINGKEY_PRESSED */ KEY_VOLUMEUP, /* 56 SONYPI_EVENT_VOLUME_INC_PRESSED */ KEY_VOLUMEDOWN, /* 57 SONYPI_EVENT_VOLUME_DEC_PRESSED */ + KEY_MEDIA, /* 58 SONYPI_EVENT_MEDIA_PRESSED */ }; /* release buttons after a short delay if pressed */ @@ -890,6 +892,8 @@ static struct sony_nc_event sony_100_events[] = { { 0x0C, SONYPI_EVENT_FNKEY_RELEASED }, { 0x9f, SONYPI_EVENT_CD_EJECT_PRESSED }, { 0x1f, SONYPI_EVENT_ANYBUTTON_RELEASED }, + { 0xa1, SONYPI_EVENT_MEDIA_PRESSED }, + { 0x21, SONYPI_EVENT_ANYBUTTON_RELEASED }, { 0, 0 }, }; diff --git a/include/linux/sonypi.h b/include/linux/sonypi.h index 34c4475..4f95c1a 100644 --- a/include/linux/sonypi.h +++ b/include/linux/sonypi.h @@ -111,6 +111,7 @@ #define SONYPI_EVENT_VOLUME_INC_PRESSED 69 #define SONYPI_EVENT_VOLUME_DEC_PRESSED 70 #define SONYPI_EVENT_BRIGHTNESS_PRESSED 71 +#define SONYPI_EVENT_MEDIA_PRESSED 72 /* get/set brightness */ #define SONYPI_IOCGBRT _IOR('v', 0, __u8) -- cgit v0.10.2 From 416eb39556a03d1c7e52b0791e9052ccd71db241 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 17 Dec 2009 06:05:49 +0100 Subject: sched: Make warning less noisy Cc: Peter Zijlstra Cc: Mike Galbraith LKML-Reference: <20091216170517.807938893@chello.nl> Signed-off-by: Ingo Molnar diff --git a/kernel/sched.c b/kernel/sched.c index 8a2bfd3..af7dfa7 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -2041,7 +2041,7 @@ void set_task_cpu(struct task_struct *p, unsigned int new_cpu) * We should never call set_task_cpu() on a blocked task, * ttwu() will sort out the placement. */ - WARN_ON(p->state != TASK_RUNNING && p->state != TASK_WAKING); + WARN_ON_ONCE(p->state != TASK_RUNNING && p->state != TASK_WAKING); #endif trace_sched_migrate_task(p, new_cpu); -- cgit v0.10.2 From 39b27f4cc332abed2e37c0554a823312955b8afc Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 17 Dec 2009 14:18:27 +0900 Subject: sh: dmaengine support for sh7724. Add a dmaengine platform device to sh7724, fix DMA channel interrupt numbers. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Nobuhiro Iwamatsu Signed-off-by: Paul Mundt diff --git a/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h b/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h index f0886bc..c4ed660 100644 --- a/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h +++ b/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h @@ -19,10 +19,10 @@ #elif defined(CONFIG_CPU_SUBTYPE_SH7723) || \ defined(CONFIG_CPU_SUBTYPE_SH7724) #define DMTE0_IRQ 48 /* DMAC0A*/ -#define DMTE4_IRQ 40 /* DMAC0B */ -#define DMTE6_IRQ 42 -#define DMTE8_IRQ 76 /* DMAC1A */ -#define DMTE9_IRQ 77 +#define DMTE4_IRQ 76 /* DMAC0B */ +#define DMTE6_IRQ 40 +#define DMTE8_IRQ 42 /* DMAC1A */ +#define DMTE9_IRQ 43 #define DMTE10_IRQ 72 /* DMAC1B */ #define DMTE11_IRQ 73 #define DMAE0_IRQ 78 /* DMA Error IRQ*/ diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c index a52f351..d32f96c 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c @@ -23,9 +23,23 @@ #include #include #include +#include #include #include +/* DMA */ +static struct sh_dmae_pdata dma_platform_data = { + .mode = SHDMA_DMAOR1, +}; + +static struct platform_device dma_device = { + .name = "sh-dma-engine", + .id = -1, + .dev = { + .platform_data = &dma_platform_data, + }, +}; + /* Serial */ static struct plat_sci_port scif0_platform_data = { .mapbase = 0xffe00000, @@ -649,6 +663,7 @@ static struct platform_device *sh7724_devices[] __initdata = { &tmu3_device, &tmu4_device, &tmu5_device, + &dma_device, &rtc_device, &iic0_device, &iic1_device, -- cgit v0.10.2 From 4385af80bd617c6126c7ab8cb1c7d9417b548f2e Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Thu, 17 Dec 2009 12:15:57 +0900 Subject: sh: dmaengine support for SH7785 Add dmaengine platform device to SH7785. Signed-off-by: Nobuhiro Iwamatsu Signed-off-by: Paul Mundt diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c index ef26ebd..f685b9b 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c @@ -14,6 +14,7 @@ #include #include #include +#include #include static struct plat_sci_port scif0_platform_data = { @@ -294,6 +295,18 @@ static struct platform_device tmu5_device = { .num_resources = ARRAY_SIZE(tmu5_resources), }; +static struct sh_dmae_pdata dma_platform_data = { + .mode = (SHDMA_MIX_IRQ | SHDMA_DMAOR1), +}; + +static struct platform_device dma_device = { + .name = "sh-dma-engine", + .id = -1, + .dev = { + .platform_data = &dma_platform_data, + }, +}; + static struct platform_device *sh7785_devices[] __initdata = { &scif0_device, &scif1_device, @@ -307,6 +320,7 @@ static struct platform_device *sh7785_devices[] __initdata = { &tmu3_device, &tmu4_device, &tmu5_device, + &dma_device, }; static int __init sh7785_devices_setup(void) -- cgit v0.10.2 From 2f7bb2dfed3b15b388c88250b66f590aabc438da Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 17 Dec 2009 14:25:10 +0900 Subject: sh: Fix up MAX_DMA_CHANNELS definition when DMA is disabled. MAX_DMA_CHANNELS is tested for the total number of channels in order to populate an IRQ map. Stub this out completely when no DMA support is enabled -- as used to be the default behaviour before this was generalized for use by the dmaengine code. Signed-off-by: Paul Mundt diff --git a/arch/sh/include/asm/dma.h b/arch/sh/include/asm/dma.h index 04ad0e1..07373a0 100644 --- a/arch/sh/include/asm/dma.h +++ b/arch/sh/include/asm/dma.h @@ -19,9 +19,11 @@ #include #ifdef CONFIG_NR_DMA_CHANNELS -# define MAX_DMA_CHANNELS (CONFIG_NR_DMA_CHANNELS) +# define MAX_DMA_CHANNELS (CONFIG_NR_DMA_CHANNELS) +#elif defined(CONFIG_NR_ONCHIP_DMA_CHANNELS) +# define MAX_DMA_CHANNELS (CONFIG_NR_ONCHIP_DMA_CHANNELS) #else -# define MAX_DMA_CHANNELS (CONFIG_NR_ONCHIP_DMA_CHANNELS) +# define MAX_DMA_CHANNELS 0 #endif /* -- cgit v0.10.2 From d7b0c143693bcbf391d2be235e150b97bfd8f9ba Mon Sep 17 00:00:00 2001 From: Saeed Bishara Date: Sun, 6 Dec 2009 18:26:17 +0200 Subject: sata_mv: increase PIO IORDY timeout The old value (0xbc) in cycles of the IORDY timeout is suitable for devices with core clock of 166 MHz, but some SoC controllers have faster core clocks. The new value will make the IORDY timeout large enough also for all SoC devices. Signed-off-by: Saeed Bishara Signed-off-by: Jeff Garzik diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index a8a7be0..bbeaf3a 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -3393,7 +3393,7 @@ static void mv_soc_reset_hc_port(struct mv_host_priv *hpriv, ZERO(0x024); /* respq outp */ ZERO(0x020); /* respq inp */ ZERO(0x02c); /* test control */ - writel(0xbc, port_mmio + EDMA_IORDY_TMOUT); + writel(0x800, port_mmio + EDMA_IORDY_TMOUT); } #undef ZERO -- cgit v0.10.2 From c77a2f4e6b76c9094182dfa653ece4243f6df80c Mon Sep 17 00:00:00 2001 From: Saeed Bishara Date: Sun, 6 Dec 2009 18:26:18 +0200 Subject: sata_mv: support clkdev framework Signed-off-by: Saeed Bishara Signed-off-by: Jeff Garzik diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index bbeaf3a..b625b36 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -59,6 +59,7 @@ #include #include #include +#include #include #include #include @@ -548,6 +549,10 @@ struct mv_host_priv { u32 irq_cause_offset; u32 irq_mask_offset; u32 unmask_all_irqs; + +#if defined(CONFIG_HAVE_CLK) + struct clk *clk; +#endif /* * These consistent DMA memory pools give us guaranteed * alignment for hardware-accessed data structures, @@ -4041,6 +4046,14 @@ static int mv_platform_probe(struct platform_device *pdev) resource_size(res)); hpriv->base -= SATAHC0_REG_BASE; +#if defined(CONFIG_HAVE_CLK) + hpriv->clk = clk_get(&pdev->dev, NULL); + if (IS_ERR(hpriv->clk)) + dev_notice(&pdev->dev, "cannot get clkdev\n"); + else + clk_enable(hpriv->clk); +#endif + /* * (Re-)program MBUS remapping windows if we are asked to. */ @@ -4049,12 +4062,12 @@ static int mv_platform_probe(struct platform_device *pdev) rc = mv_create_dma_pools(hpriv, &pdev->dev); if (rc) - return rc; + goto err; /* initialize adapter */ rc = mv_init_host(host, chip_soc); if (rc) - return rc; + goto err; dev_printk(KERN_INFO, &pdev->dev, "slots %u ports %d\n", (unsigned)MV_MAX_Q_DEPTH, @@ -4062,6 +4075,15 @@ static int mv_platform_probe(struct platform_device *pdev) return ata_host_activate(host, platform_get_irq(pdev, 0), mv_interrupt, IRQF_SHARED, &mv6_sht); +err: +#if defined(CONFIG_HAVE_CLK) + if (!IS_ERR(hpriv->clk)) { + clk_disable(hpriv->clk); + clk_put(hpriv->clk); + } +#endif + + return rc; } /* @@ -4076,8 +4098,17 @@ static int __devexit mv_platform_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct ata_host *host = dev_get_drvdata(dev); - +#if defined(CONFIG_HAVE_CLK) + struct mv_host_priv *hpriv = host->private_data; +#endif ata_host_detach(host); + +#if defined(CONFIG_HAVE_CLK) + if (!IS_ERR(hpriv->clk)) { + clk_disable(hpriv->clk); + clk_put(hpriv->clk); + } +#endif return 0; } -- cgit v0.10.2 From 6481f2b52cd5411ea6342b749daf0e4f3b390d7b Mon Sep 17 00:00:00 2001 From: Saeed Bishara Date: Sun, 6 Dec 2009 18:26:19 +0200 Subject: sata_mv: add power management support for the platform driver Signed-off-by: Saeed Bishara Signed-off-by: Jeff Garzik diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c old mode 100644 new mode 100755 index b625b36..0f7704c --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -4112,9 +4112,52 @@ static int __devexit mv_platform_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_PM +static int mv_platform_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct ata_host *host = dev_get_drvdata(&pdev->dev); + if (host) + return ata_host_suspend(host, state); + else + return 0; +} + +static int mv_platform_resume(struct platform_device *pdev) +{ + struct ata_host *host = dev_get_drvdata(&pdev->dev); + int ret; + + if (host) { + struct mv_host_priv *hpriv = host->private_data; + const struct mv_sata_platform_data *mv_platform_data = \ + pdev->dev.platform_data; + /* + * (Re-)program MBUS remapping windows if we are asked to. + */ + if (mv_platform_data->dram != NULL) + mv_conf_mbus_windows(hpriv, mv_platform_data->dram); + + /* initialize adapter */ + ret = mv_init_host(host, chip_soc); + if (ret) { + printk(KERN_ERR DRV_NAME ": Error during HW init\n"); + return ret; + } + ata_host_resume(host); + } + + return 0; +} +#else +#define mv_platform_suspend NULL +#define mv_platform_resume NULL +#endif + static struct platform_driver mv_platform_driver = { .probe = mv_platform_probe, .remove = __devexit_p(mv_platform_remove), + .suspend = mv_platform_suspend, + .resume = mv_platform_resume, .driver = { .name = DRV_NAME, .owner = THIS_MODULE, -- cgit v0.10.2 From c4bc7d7310a40c8c0b917e88983dc4a8e6b59e38 Mon Sep 17 00:00:00 2001 From: Saeed Bishara Date: Sun, 6 Dec 2009 18:26:20 +0200 Subject: sata_mv: move the PCI bar description initialization code The mv_init_host will be used to initialize the host hw on resume. The PCI bar description need to be initialized only once when the device probed. Signed-off-by: Saeed Bishara Signed-off-by: Jeff Garzik diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 0f7704c..e1b9568 100755 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -3910,14 +3910,6 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx) void __iomem *port_mmio = mv_port_base(mmio, port); mv_port_init(&ap->ioaddr, port_mmio); - -#ifdef CONFIG_PCI - if (!IS_SOC(hpriv)) { - unsigned int offset = port_mmio - mmio; - ata_port_pbar_desc(ap, MV_PRIMARY_BAR, -1, "mmio"); - ata_port_pbar_desc(ap, MV_PRIMARY_BAR, offset, "port"); - } -#endif } for (hc = 0; hc < n_hc; hc++) { @@ -4268,7 +4260,7 @@ static int mv_pci_init_one(struct pci_dev *pdev, const struct ata_port_info *ppi[] = { &mv_port_info[board_idx], NULL }; struct ata_host *host; struct mv_host_priv *hpriv; - int n_ports, rc; + int n_ports, port, rc; if (!printed_version++) dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n"); @@ -4304,6 +4296,15 @@ static int mv_pci_init_one(struct pci_dev *pdev, if (rc) return rc; + for (port = 0; port < host->n_ports; port++) { + struct ata_port *ap = host->ports[port]; + void __iomem *port_mmio = mv_port_base(hpriv->base, port); + unsigned int offset = port_mmio - hpriv->base; + + ata_port_pbar_desc(ap, MV_PRIMARY_BAR, -1, "mmio"); + ata_port_pbar_desc(ap, MV_PRIMARY_BAR, offset, "port"); + } + /* initialize adapter */ rc = mv_init_host(host, board_idx); if (rc) -- cgit v0.10.2 From 0cdd6eb7e08fc39e9c906cc46b6ee9095c3077a9 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 10 Dec 2009 10:36:01 +0100 Subject: libata: use the WRITE_SAME_16 define Now that the scsi tree has hit mainline we can use the newly added WRITE_SAME_16 define. Signed-off-by: Christoph Hellwig Signed-off-by: Jeff Garzik diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 1683ebd..f4ea5a8 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -3022,7 +3022,7 @@ static inline ata_xlat_func_t ata_get_xlat_func(struct ata_device *dev, u8 cmd) case WRITE_16: return ata_scsi_rw_xlat; - case 0x93 /*WRITE_SAME_16*/: + case WRITE_SAME_16: return ata_scsi_write_same_xlat; case SYNCHRONIZE_CACHE: -- cgit v0.10.2 From 4716eaf20f37d10fd01b0fcacb3e41c1abd362c3 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 10 Dec 2009 20:03:10 -0500 Subject: pata_octeon_cf: use resource_size(), to fix resource sizing bug It appears the size for cs1 is calculated using the wrong resource. Use the function resource_size to get the correct value. Signed-off-by: H Hartley Sweeten Signed-off-by: Jeff Garzik diff --git a/drivers/ata/pata_octeon_cf.c b/drivers/ata/pata_octeon_cf.c index d6f6956..37ef416 100644 --- a/drivers/ata/pata_octeon_cf.c +++ b/drivers/ata/pata_octeon_cf.c @@ -853,7 +853,7 @@ static int __devinit octeon_cf_probe(struct platform_device *pdev) return -EINVAL; cs1 = devm_ioremap_nocache(&pdev->dev, res_cs1->start, - res_cs0->end - res_cs1->start + 1); + resource_size(res_cs1)); if (!cs1) return -ENOMEM; -- cgit v0.10.2 From 1bfeff03f8a52eb896e5aad33d52e2451437bb0b Mon Sep 17 00:00:00 2001 From: Saeed Bishara Date: Thu, 17 Dec 2009 01:05:00 -0500 Subject: sata_mv: store the board_idx into the host private data This information will be used in the resume function. Signed-off-by: Saeed Bishara Signed-off-by: Jeff Garzik diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index e1b9568..53a1d97 100755 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -539,6 +539,7 @@ struct mv_port_signal { struct mv_host_priv { u32 hp_flags; + unsigned int board_idx; u32 main_irq_mask; struct mv_port_signal signal[8]; const struct mv_hw_ops *ops; @@ -3859,7 +3860,6 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx) /** * mv_init_host - Perform some early initialization of the host. * @host: ATA host to initialize - * @board_idx: controller index * * If possible, do an early global reset of the host. Then do * our port init and clear/unmask all/relevant host interrupts. @@ -3867,13 +3867,13 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx) * LOCKING: * Inherited from caller. */ -static int mv_init_host(struct ata_host *host, unsigned int board_idx) +static int mv_init_host(struct ata_host *host) { int rc = 0, n_hc, port, hc; struct mv_host_priv *hpriv = host->private_data; void __iomem *mmio = hpriv->base; - rc = mv_chip_id(host, board_idx); + rc = mv_chip_id(host, hpriv->board_idx); if (rc) goto done; @@ -4032,6 +4032,7 @@ static int mv_platform_probe(struct platform_device *pdev) return -ENOMEM; host->private_data = hpriv; hpriv->n_ports = n_ports; + hpriv->board_idx = chip_soc; host->iomap = NULL; hpriv->base = devm_ioremap(&pdev->dev, res->start, @@ -4057,7 +4058,7 @@ static int mv_platform_probe(struct platform_device *pdev) goto err; /* initialize adapter */ - rc = mv_init_host(host, chip_soc); + rc = mv_init_host(host); if (rc) goto err; @@ -4130,7 +4131,7 @@ static int mv_platform_resume(struct platform_device *pdev) mv_conf_mbus_windows(hpriv, mv_platform_data->dram); /* initialize adapter */ - ret = mv_init_host(host, chip_soc); + ret = mv_init_host(host); if (ret) { printk(KERN_ERR DRV_NAME ": Error during HW init\n"); return ret; @@ -4274,6 +4275,7 @@ static int mv_pci_init_one(struct pci_dev *pdev, return -ENOMEM; host->private_data = hpriv; hpriv->n_ports = n_ports; + hpriv->board_idx = board_idx; /* acquire resources */ rc = pcim_enable_device(pdev); @@ -4306,7 +4308,7 @@ static int mv_pci_init_one(struct pci_dev *pdev, } /* initialize adapter */ - rc = mv_init_host(host, board_idx); + rc = mv_init_host(host); if (rc) return rc; -- cgit v0.10.2 From b2dec48ccaad004fc706352f82725d43369d9bd7 Mon Sep 17 00:00:00 2001 From: Saeed Bishara Date: Sun, 6 Dec 2009 18:26:22 +0200 Subject: sata_mv: add power management support for the PCI controllers. Signed-off-by: Saeed Bishara Signed-off-by: Jeff Garzik diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 53a1d97..7376819 100755 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -4161,6 +4161,9 @@ static struct platform_driver mv_platform_driver = { #ifdef CONFIG_PCI static int mv_pci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); +#ifdef CONFIG_PM +static int mv_pci_device_resume(struct pci_dev *pdev); +#endif static struct pci_driver mv_pci_driver = { @@ -4168,6 +4171,11 @@ static struct pci_driver mv_pci_driver = { .id_table = mv_pci_tbl, .probe = mv_pci_init_one, .remove = ata_pci_remove_one, +#ifdef CONFIG_PM + .suspend = ata_pci_device_suspend, + .resume = mv_pci_device_resume, +#endif + }; /* move to PCI layer or libata core? */ @@ -4324,6 +4332,27 @@ static int mv_pci_init_one(struct pci_dev *pdev, return ata_host_activate(host, pdev->irq, mv_interrupt, IRQF_SHARED, IS_GEN_I(hpriv) ? &mv5_sht : &mv6_sht); } + +#ifdef CONFIG_PM +static int mv_pci_device_resume(struct pci_dev *pdev) +{ + struct ata_host *host = dev_get_drvdata(&pdev->dev); + int rc; + + rc = ata_pci_device_do_resume(pdev); + if (rc) + return rc; + + /* initialize adapter */ + rc = mv_init_host(host); + if (rc) + return rc; + + ata_host_resume(host); + + return 0; +} +#endif #endif static int mv_platform_probe(struct platform_device *pdev); -- cgit v0.10.2 From 9a8fd68b15e7b047678a651b7f7e2f3dcd19d20d Mon Sep 17 00:00:00 2001 From: Robert Hancock Date: Tue, 8 Dec 2009 20:48:10 -0600 Subject: libata: fix reporting of drained bytes when clearing DRQ When we drain data from a device to clear DRQ during error recovery, the number of bytes reported as drained is too low by a factor of 2 because the count is actually reporting the number of words drained, not bytes. Fix this. Signed-off-by: Robert Hancock Signed-off-by: Jeff Garzik diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index efa8773..741065c 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -2275,7 +2275,7 @@ void ata_sff_drain_fifo(struct ata_queued_cmd *qc) ap = qc->ap; /* Drain up to 64K of data before we give up this recovery method */ for (count = 0; (ap->ops->sff_check_status(ap) & ATA_DRQ) - && count < 32768; count++) + && count < 65536; count += 2) ioread16(ap->ioaddr.data_addr); /* Can become DEBUG later */ -- cgit v0.10.2 From 256ace9bbd4cdb6d48d5f55d55d42fa20527fad1 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Thu, 17 Dec 2009 01:11:27 -0500 Subject: pata_hpt3x2n: fix clock turnaround The clock turnaround code still doesn't work for several reasons: - 'USE_DPLL' flag in 'ap->host->private_data' is never initialized or updated, so the driver can only set the chip to the DPLL clock mode, not the PCI mode; - the driver doesn't serialize access to the channels depending on the current clock mode like the vendor drivers, so the clock turnaround is only executed "optionally", not always as it should be; - the wrong ports are written to when hpt3x2n_set_clock() is called for the secondary channel; - hpt3x2n_set_clock() can inadvertently enable the disabled channels when resetting the channel state machines. Signed-off-by: Sergei Shtylyov Cc: stable@kernel.org Signed-off-by: Jeff Garzik diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c index 9a09a1b..dd26bc7 100644 --- a/drivers/ata/pata_hpt3x2n.c +++ b/drivers/ata/pata_hpt3x2n.c @@ -8,7 +8,7 @@ * Copyright (C) 1999-2003 Andre Hedrick * Portions Copyright (C) 2001 Sun Microsystems, Inc. * Portions Copyright (C) 2003 Red Hat Inc - * Portions Copyright (C) 2005-2007 MontaVista Software, Inc. + * Portions Copyright (C) 2005-2009 MontaVista Software, Inc. * * * TODO @@ -25,7 +25,7 @@ #include #define DRV_NAME "pata_hpt3x2n" -#define DRV_VERSION "0.3.7" +#define DRV_VERSION "0.3.8" enum { HPT_PCI_FAST = (1 << 31), @@ -264,7 +264,7 @@ static void hpt3x2n_bmdma_stop(struct ata_queued_cmd *qc) static void hpt3x2n_set_clock(struct ata_port *ap, int source) { - void __iomem *bmdma = ap->ioaddr.bmdma_addr; + void __iomem *bmdma = ap->ioaddr.bmdma_addr - ap->port_no * 8; /* Tristate the bus */ iowrite8(0x80, bmdma+0x73); @@ -274,9 +274,9 @@ static void hpt3x2n_set_clock(struct ata_port *ap, int source) iowrite8(source, bmdma+0x7B); iowrite8(0xC0, bmdma+0x79); - /* Reset state machines */ - iowrite8(0x37, bmdma+0x70); - iowrite8(0x37, bmdma+0x74); + /* Reset state machines, avoid enabling the disabled channels */ + iowrite8(ioread8(bmdma+0x70) | 0x32, bmdma+0x70); + iowrite8(ioread8(bmdma+0x74) | 0x32, bmdma+0x74); /* Complete reset */ iowrite8(0x00, bmdma+0x79); @@ -286,21 +286,10 @@ static void hpt3x2n_set_clock(struct ata_port *ap, int source) iowrite8(0x00, bmdma+0x77); } -/* Check if our partner interface is busy */ - -static int hpt3x2n_pair_idle(struct ata_port *ap) -{ - struct ata_host *host = ap->host; - struct ata_port *pair = host->ports[ap->port_no ^ 1]; - - if (pair->hsm_task_state == HSM_ST_IDLE) - return 1; - return 0; -} - static int hpt3x2n_use_dpll(struct ata_port *ap, int writing) { long flags = (long)ap->host->private_data; + /* See if we should use the DPLL */ if (writing) return USE_DPLL; /* Needed for write */ @@ -309,20 +298,35 @@ static int hpt3x2n_use_dpll(struct ata_port *ap, int writing) return 0; } +static int hpt3x2n_qc_defer(struct ata_queued_cmd *qc) +{ + struct ata_port *ap = qc->ap; + struct ata_port *alt = ap->host->ports[ap->port_no ^ 1]; + int rc, flags = (long)ap->host->private_data; + int dpll = hpt3x2n_use_dpll(ap, qc->tf.flags & ATA_TFLAG_WRITE); + + /* First apply the usual rules */ + rc = ata_std_qc_defer(qc); + if (rc != 0) + return rc; + + if ((flags & USE_DPLL) != dpll && alt->qc_active) + return ATA_DEFER_PORT; + return 0; +} + static unsigned int hpt3x2n_qc_issue(struct ata_queued_cmd *qc) { - struct ata_taskfile *tf = &qc->tf; struct ata_port *ap = qc->ap; int flags = (long)ap->host->private_data; + int dpll = hpt3x2n_use_dpll(ap, qc->tf.flags & ATA_TFLAG_WRITE); - if (hpt3x2n_pair_idle(ap)) { - int dpll = hpt3x2n_use_dpll(ap, (tf->flags & ATA_TFLAG_WRITE)); - if ((flags & USE_DPLL) != dpll) { - if (dpll == 1) - hpt3x2n_set_clock(ap, 0x21); - else - hpt3x2n_set_clock(ap, 0x23); - } + if ((flags & USE_DPLL) != dpll) { + flags &= ~USE_DPLL; + flags |= dpll; + ap->host->private_data = (void *)(long)flags; + + hpt3x2n_set_clock(ap, dpll ? 0x21 : 0x23); } return ata_sff_qc_issue(qc); } @@ -339,6 +343,8 @@ static struct ata_port_operations hpt3x2n_port_ops = { .inherits = &ata_bmdma_port_ops, .bmdma_stop = hpt3x2n_bmdma_stop, + + .qc_defer = hpt3x2n_qc_defer, .qc_issue = hpt3x2n_qc_issue, .cable_detect = hpt3x2n_cable_detect, @@ -454,7 +460,7 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) unsigned int f_low, f_high; int adjust; unsigned long iobase = pci_resource_start(dev, 4); - void *hpriv = NULL; + void *hpriv = (void *)USE_DPLL; int rc; rc = pcim_enable_device(dev); @@ -539,7 +545,7 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) /* Set our private data up. We only need a few flags so we use it directly */ if (pci_mhz > 60) { - hpriv = (void *)PCI66; + hpriv = (void *)(PCI66 | USE_DPLL); /* * On HPT371N, if ATA clock is 66 MHz we must set bit 2 in * the MISC. register to stretch the UltraDMA Tss timing. -- cgit v0.10.2 From 0535f2bc170bc0779ac471faff39f633ca19ab59 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Thu, 17 Dec 2009 01:23:16 -0500 Subject: sata_mv: remove pointless NULL test Remove !ap test, where ap is guaranteed not-NULL. Found by way of automated bug report from Alexander Strakh via "Linux Device Drivers Verification Project (Svace Detector)" Signed-off-by: Jeff Garzik diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 7376819..df8ee32 100755 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -2781,7 +2781,7 @@ static void mv_port_intr(struct ata_port *ap, u32 port_cause) struct mv_port_priv *pp; int edma_was_enabled; - if (!ap || (ap->flags & ATA_FLAG_DISABLED)) { + if (ap->flags & ATA_FLAG_DISABLED) { mv_unexpected_intr(ap, 0); return; } -- cgit v0.10.2 From 234da7bcdc7aaa935846534c3b726dbc79a9cdd5 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Wed, 16 Dec 2009 20:21:05 +0100 Subject: sched: Teach might_sleep() about preemptible RCU In practice, it is harmless to voluntarily sleep in a rcu_read_lock() section if we are running under preempt rcu, but it is illegal if we build a kernel running non-preemptable rcu. Currently, might_sleep() doesn't notice sleepable operations under rcu_read_lock() sections if we are running under preemptable rcu because preempt_count() is left untouched after rcu_read_lock() in this case. But we want developers who test their changes under such config to notice the "sleeping while atomic" issues. So we add rcu_read_lock_nesting to prempt_count() in might_sleep() checks. [ v2: Handle rcu-tiny ] Signed-off-by: Frederic Weisbecker Reviewed-by: Paul E. McKenney Cc: Peter Zijlstra LKML-Reference: <1260991265-8451-1-git-send-regression-fweisbec@gmail.com> Signed-off-by: Ingo Molnar diff --git a/include/linux/rcutiny.h b/include/linux/rcutiny.h index c4ba9a7..96cc307 100644 --- a/include/linux/rcutiny.h +++ b/include/linux/rcutiny.h @@ -101,4 +101,9 @@ static inline void exit_rcu(void) { } +static inline int rcu_preempt_depth(void) +{ + return 0; +} + #endif /* __LINUX_RCUTINY_H */ diff --git a/include/linux/rcutree.h b/include/linux/rcutree.h index c93eee5..8044b1b 100644 --- a/include/linux/rcutree.h +++ b/include/linux/rcutree.h @@ -45,6 +45,12 @@ extern void __rcu_read_unlock(void); extern void synchronize_rcu(void); extern void exit_rcu(void); +/* + * Defined as macro as it is a very low level header + * included from areas that don't even know about current + */ +#define rcu_preempt_depth() (current->rcu_read_lock_nesting) + #else /* #ifdef CONFIG_TREE_PREEMPT_RCU */ static inline void __rcu_read_lock(void) @@ -63,6 +69,11 @@ static inline void exit_rcu(void) { } +static inline int rcu_preempt_depth(void) +{ + return 0; +} + #endif /* #else #ifdef CONFIG_TREE_PREEMPT_RCU */ static inline void __rcu_read_lock_bh(void) diff --git a/kernel/sched.c b/kernel/sched.c index af7dfa7..7be88a7 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -9682,7 +9682,7 @@ void __init sched_init(void) #ifdef CONFIG_DEBUG_SPINLOCK_SLEEP static inline int preempt_count_equals(int preempt_offset) { - int nested = preempt_count() & ~PREEMPT_ACTIVE; + int nested = (preempt_count() & ~PREEMPT_ACTIVE) + rcu_preempt_depth(); return (nested == PREEMPT_INATOMIC_BASE + preempt_offset); } -- cgit v0.10.2 From 06777d308f8f9ddb67798d34bf193101a4bdf06c Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 17 Dec 2009 04:52:13 -0500 Subject: dio: fix use-after-free Signed-off-by: Al Viro diff --git a/fs/direct-io.c b/fs/direct-io.c index 4012885..e82adc2 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c @@ -1206,7 +1206,7 @@ __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, * NOTE: filesystems with their own locking have to handle this * on their own. */ - if (dio->flags & DIO_LOCKING) { + if (flags & DIO_LOCKING) { if (unlikely((rw & WRITE) && retval < 0)) { loff_t isize = i_size_read(inode); if (end > isize) -- cgit v0.10.2 From 27f37e4bfed803be338dcc78845d4a67eefb40a0 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Fri, 25 Sep 2009 09:39:26 +0200 Subject: regulator: add driver for MAX8660/8661 Tested with a MX25-based custom board. Signed-off-by: Wolfram Sang Acked-by: Mark Brown Signed-off-by: Liam Girdwood diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 7cfdd65..9e0aa14 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -69,6 +69,13 @@ config REGULATOR_MAX1586 regulator via I2C bus. The provided regulator is suitable for PXA27x chips to control VCC_CORE and VCC_USIM voltages. +config REGULATOR_MAX8660 + tristate "Maxim 8660/8661 voltage regulator" + depends on I2C + help + This driver controls a Maxim 8660/8661 voltage output + regulator via I2C bus. + config REGULATOR_TWL4030 bool "TI TWL4030/TWL5030/TWL6030/TPS695x0 PMIC" depends on TWL4030_CORE diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 9ae3cc4..12285e4 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_REGULATOR_BQ24022) += bq24022.o obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o +obj-$(CONFIG_REGULATOR_MAX8660) += max8660.o obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o obj-$(CONFIG_REGULATOR_WM831X) += wm831x-isink.o obj-$(CONFIG_REGULATOR_WM831X) += wm831x-ldo.o diff --git a/drivers/regulator/max8660.c b/drivers/regulator/max8660.c new file mode 100644 index 0000000..acc2fb7 --- /dev/null +++ b/drivers/regulator/max8660.c @@ -0,0 +1,510 @@ +/* + * max8660.c -- Voltage regulation for the Maxim 8660/8661 + * + * based on max1586.c and wm8400-regulator.c + * + * Copyright (C) 2009 Wolfram Sang, Pengutronix e.K. + * + * 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., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + * + * Some info: + * + * Datasheet: http://datasheets.maxim-ic.com/en/ds/MAX8660-MAX8661.pdf + * + * This chip is a bit nasty because it is a write-only device. Thus, the driver + * uses shadow registers to keep track of its values. The main problem appears + * to be the initialization: When Linux boots up, we cannot know if the chip is + * in the default state or not, so we would have to pass such information in + * platform_data. As this adds a bit of complexity to the driver, this is left + * out for now until it is really needed. + * + * [A|S|M]DTV1 registers are currently not used, but [A|S|M]DTV2. + * + * If the driver is feature complete, it might be worth to check if one set of + * functions for V3-V7 is sufficient. For maximum flexibility during + * development, they are separated for now. + * + */ + +#include +#include +#include +#include +#include +#include + +#define MAX8660_DCDC_MIN_UV 725000 +#define MAX8660_DCDC_MAX_UV 1800000 +#define MAX8660_DCDC_STEP 25000 +#define MAX8660_DCDC_MAX_SEL 0x2b + +#define MAX8660_LDO5_MIN_UV 1700000 +#define MAX8660_LDO5_MAX_UV 2000000 +#define MAX8660_LDO5_STEP 25000 +#define MAX8660_LDO5_MAX_SEL 0x0c + +#define MAX8660_LDO67_MIN_UV 1800000 +#define MAX8660_LDO67_MAX_UV 3300000 +#define MAX8660_LDO67_STEP 100000 +#define MAX8660_LDO67_MAX_SEL 0x0f + +enum { + MAX8660_OVER1, + MAX8660_OVER2, + MAX8660_VCC1, + MAX8660_ADTV1, + MAX8660_ADTV2, + MAX8660_SDTV1, + MAX8660_SDTV2, + MAX8660_MDTV1, + MAX8660_MDTV2, + MAX8660_L12VCR, + MAX8660_FPWM, + MAX8660_N_REGS, /* not a real register */ +}; + +struct max8660 { + struct i2c_client *client; + u8 shadow_regs[MAX8660_N_REGS]; /* as chip is write only */ + struct regulator_dev *rdev[]; +}; + +static int max8660_write(struct max8660 *max8660, u8 reg, u8 mask, u8 val) +{ + static const u8 max8660_addresses[MAX8660_N_REGS] = + { 0x10, 0x12, 0x20, 0x23, 0x24, 0x29, 0x2a, 0x32, 0x33, 0x39, 0x80 }; + + int ret; + u8 reg_val = (max8660->shadow_regs[reg] & mask) | val; + dev_vdbg(&max8660->client->dev, "Writing reg %02x with %02x\n", + max8660_addresses[reg], reg_val); + + ret = i2c_smbus_write_byte_data(max8660->client, + max8660_addresses[reg], reg_val); + if (ret == 0) + max8660->shadow_regs[reg] = reg_val; + + return ret; +} + + +/* + * DCDC functions + */ + +static int max8660_dcdc_is_enabled(struct regulator_dev *rdev) +{ + struct max8660 *max8660 = rdev_get_drvdata(rdev); + u8 val = max8660->shadow_regs[MAX8660_OVER1]; + u8 mask = (rdev_get_id(rdev) == MAX8660_V3) ? 1 : 4; + return !!(val & mask); +} + +static int max8660_dcdc_enable(struct regulator_dev *rdev) +{ + struct max8660 *max8660 = rdev_get_drvdata(rdev); + u8 bit = (rdev_get_id(rdev) == MAX8660_V3) ? 1 : 4; + return max8660_write(max8660, MAX8660_OVER1, 0xff, bit); +} + +static int max8660_dcdc_disable(struct regulator_dev *rdev) +{ + struct max8660 *max8660 = rdev_get_drvdata(rdev); + u8 mask = (rdev_get_id(rdev) == MAX8660_V3) ? ~1 : ~4; + return max8660_write(max8660, MAX8660_OVER1, mask, 0); +} + +static int max8660_dcdc_list(struct regulator_dev *rdev, unsigned selector) +{ + if (selector > MAX8660_DCDC_MAX_SEL) + return -EINVAL; + return MAX8660_DCDC_MIN_UV + selector * MAX8660_DCDC_STEP; +} + +static int max8660_dcdc_get(struct regulator_dev *rdev) +{ + struct max8660 *max8660 = rdev_get_drvdata(rdev); + u8 reg = (rdev_get_id(rdev) == MAX8660_V3) ? MAX8660_ADTV2 : MAX8660_SDTV2; + u8 selector = max8660->shadow_regs[reg]; + return MAX8660_DCDC_MIN_UV + selector * MAX8660_DCDC_STEP; +} + +static int max8660_dcdc_set(struct regulator_dev *rdev, int min_uV, int max_uV) +{ + struct max8660 *max8660 = rdev_get_drvdata(rdev); + u8 reg, selector, bits; + int ret; + + if (min_uV < MAX8660_DCDC_MIN_UV || min_uV > MAX8660_DCDC_MAX_UV) + return -EINVAL; + if (max_uV < MAX8660_DCDC_MIN_UV || max_uV > MAX8660_DCDC_MAX_UV) + return -EINVAL; + + selector = (min_uV - (MAX8660_DCDC_MIN_UV - MAX8660_DCDC_STEP + 1)) + / MAX8660_DCDC_STEP; + + ret = max8660_dcdc_list(rdev, selector); + if (ret < 0 || ret > max_uV) + return -EINVAL; + + reg = (rdev_get_id(rdev) == MAX8660_V3) ? MAX8660_ADTV2 : MAX8660_SDTV2; + ret = max8660_write(max8660, reg, 0, selector); + if (ret) + return ret; + + /* Select target voltage register and activate regulation */ + bits = (rdev_get_id(rdev) == MAX8660_V3) ? 0x03 : 0x30; + return max8660_write(max8660, MAX8660_VCC1, 0xff, bits); +} + +static struct regulator_ops max8660_dcdc_ops = { + .is_enabled = max8660_dcdc_is_enabled, + .list_voltage = max8660_dcdc_list, + .set_voltage = max8660_dcdc_set, + .get_voltage = max8660_dcdc_get, +}; + + +/* + * LDO5 functions + */ + +static int max8660_ldo5_list(struct regulator_dev *rdev, unsigned selector) +{ + if (selector > MAX8660_LDO5_MAX_SEL) + return -EINVAL; + return MAX8660_LDO5_MIN_UV + selector * MAX8660_LDO5_STEP; +} + +static int max8660_ldo5_get(struct regulator_dev *rdev) +{ + struct max8660 *max8660 = rdev_get_drvdata(rdev); + u8 selector = max8660->shadow_regs[MAX8660_MDTV2]; + + return MAX8660_LDO5_MIN_UV + selector * MAX8660_LDO5_STEP; +} + +static int max8660_ldo5_set(struct regulator_dev *rdev, int min_uV, int max_uV) +{ + struct max8660 *max8660 = rdev_get_drvdata(rdev); + u8 selector; + int ret; + + if (min_uV < MAX8660_LDO5_MIN_UV || min_uV > MAX8660_LDO5_MAX_UV) + return -EINVAL; + if (max_uV < MAX8660_LDO5_MIN_UV || max_uV > MAX8660_LDO5_MAX_UV) + return -EINVAL; + + selector = (min_uV - (MAX8660_LDO5_MIN_UV - MAX8660_LDO5_STEP + 1)) + / MAX8660_LDO5_STEP; + ret = max8660_ldo5_list(rdev, selector); + if (ret < 0 || ret > max_uV) + return -EINVAL; + + ret = max8660_write(max8660, MAX8660_MDTV2, 0, selector); + if (ret) + return ret; + + /* Select target voltage register and activate regulation */ + return max8660_write(max8660, MAX8660_VCC1, 0xff, 0xc0); +} + +static struct regulator_ops max8660_ldo5_ops = { + .list_voltage = max8660_ldo5_list, + .set_voltage = max8660_ldo5_set, + .get_voltage = max8660_ldo5_get, +}; + + +/* + * LDO67 functions + */ + +static int max8660_ldo67_is_enabled(struct regulator_dev *rdev) +{ + struct max8660 *max8660 = rdev_get_drvdata(rdev); + u8 val = max8660->shadow_regs[MAX8660_OVER2]; + u8 mask = (rdev_get_id(rdev) == MAX8660_V6) ? 2 : 4; + return !!(val & mask); +} + +static int max8660_ldo67_enable(struct regulator_dev *rdev) +{ + struct max8660 *max8660 = rdev_get_drvdata(rdev); + u8 bit = (rdev_get_id(rdev) == MAX8660_V6) ? 2 : 4; + return max8660_write(max8660, MAX8660_OVER2, 0xff, bit); +} + +static int max8660_ldo67_disable(struct regulator_dev *rdev) +{ + struct max8660 *max8660 = rdev_get_drvdata(rdev); + u8 mask = (rdev_get_id(rdev) == MAX8660_V6) ? ~2 : ~4; + return max8660_write(max8660, MAX8660_OVER2, mask, 0); +} + +static int max8660_ldo67_list(struct regulator_dev *rdev, unsigned selector) +{ + if (selector > MAX8660_LDO67_MAX_SEL) + return -EINVAL; + return MAX8660_LDO67_MIN_UV + selector * MAX8660_LDO67_STEP; +} + +static int max8660_ldo67_get(struct regulator_dev *rdev) +{ + struct max8660 *max8660 = rdev_get_drvdata(rdev); + u8 shift = (rdev_get_id(rdev) == MAX8660_V6) ? 0 : 4; + u8 selector = (max8660->shadow_regs[MAX8660_L12VCR] >> shift) & 0xf; + + return MAX8660_LDO67_MIN_UV + selector * MAX8660_LDO67_STEP; +} + +static int max8660_ldo67_set(struct regulator_dev *rdev, int min_uV, int max_uV) +{ + struct max8660 *max8660 = rdev_get_drvdata(rdev); + u8 selector; + int ret; + + if (min_uV < MAX8660_LDO67_MIN_UV || min_uV > MAX8660_LDO67_MAX_UV) + return -EINVAL; + if (max_uV < MAX8660_LDO67_MIN_UV || max_uV > MAX8660_LDO67_MAX_UV) + return -EINVAL; + + selector = (min_uV - (MAX8660_LDO67_MIN_UV - MAX8660_LDO67_STEP + 1)) + / MAX8660_LDO67_STEP; + + ret = max8660_ldo67_list(rdev, selector); + if (ret < 0 || ret > max_uV) + return -EINVAL; + + if (rdev_get_id(rdev) == MAX8660_V6) + return max8660_write(max8660, MAX8660_L12VCR, 0xf0, selector); + else + return max8660_write(max8660, MAX8660_L12VCR, 0x0f, selector << 4); +} + +static struct regulator_ops max8660_ldo67_ops = { + .is_enabled = max8660_ldo67_is_enabled, + .enable = max8660_ldo67_enable, + .disable = max8660_ldo67_disable, + .list_voltage = max8660_ldo67_list, + .get_voltage = max8660_ldo67_get, + .set_voltage = max8660_ldo67_set, +}; + +static struct regulator_desc max8660_reg[] = { + { + .name = "V3(DCDC)", + .id = MAX8660_V3, + .ops = &max8660_dcdc_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = MAX8660_DCDC_MAX_SEL + 1, + .owner = THIS_MODULE, + }, + { + .name = "V4(DCDC)", + .id = MAX8660_V4, + .ops = &max8660_dcdc_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = MAX8660_DCDC_MAX_SEL + 1, + .owner = THIS_MODULE, + }, + { + .name = "V5(LDO)", + .id = MAX8660_V5, + .ops = &max8660_ldo5_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = MAX8660_LDO5_MAX_SEL + 1, + .owner = THIS_MODULE, + }, + { + .name = "V6(LDO)", + .id = MAX8660_V6, + .ops = &max8660_ldo67_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = MAX8660_LDO67_MAX_SEL + 1, + .owner = THIS_MODULE, + }, + { + .name = "V7(LDO)", + .id = MAX8660_V7, + .ops = &max8660_ldo67_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = MAX8660_LDO67_MAX_SEL + 1, + .owner = THIS_MODULE, + }, +}; + +static int max8660_probe(struct i2c_client *client, + const struct i2c_device_id *i2c_id) +{ + struct regulator_dev **rdev; + struct max8660_platform_data *pdata = client->dev.platform_data; + struct max8660 *max8660; + int boot_on, i, id, ret = -EINVAL; + + if (pdata->num_subdevs > MAX8660_V_END) { + dev_err(&client->dev, "Too much regulators found!\n"); + goto out; + } + + max8660 = kzalloc(sizeof(struct max8660) + + sizeof(struct regulator_dev *) * MAX8660_V_END, + GFP_KERNEL); + if (!max8660) { + ret = -ENOMEM; + goto out; + } + + max8660->client = client; + rdev = max8660->rdev; + + if (pdata->en34_is_high) { + /* Simulate always on */ + max8660->shadow_regs[MAX8660_OVER1] = 5; + } else { + /* Otherwise devices can be toggled via software */ + max8660_dcdc_ops.enable = max8660_dcdc_enable; + max8660_dcdc_ops.disable = max8660_dcdc_disable; + } + + /* + * First, set up shadow registers to prevent glitches. As some + * registers are shared between regulators, everything must be properly + * set up for all regulators in advance. + */ + max8660->shadow_regs[MAX8660_ADTV1] = + max8660->shadow_regs[MAX8660_ADTV2] = + max8660->shadow_regs[MAX8660_SDTV1] = + max8660->shadow_regs[MAX8660_SDTV2] = 0x1b; + max8660->shadow_regs[MAX8660_MDTV1] = + max8660->shadow_regs[MAX8660_MDTV2] = 0x04; + + for (i = 0; i < pdata->num_subdevs; i++) { + + if (!pdata->subdevs[i].platform_data) + goto err_free; + + boot_on = pdata->subdevs[i].platform_data->constraints.boot_on; + + switch (pdata->subdevs[i].id) { + case MAX8660_V3: + if (boot_on) + max8660->shadow_regs[MAX8660_OVER1] |= 1; + break; + + case MAX8660_V4: + if (boot_on) + max8660->shadow_regs[MAX8660_OVER1] |= 4; + break; + + case MAX8660_V5: + break; + + case MAX8660_V6: + if (boot_on) + max8660->shadow_regs[MAX8660_OVER2] |= 2; + break; + + case MAX8660_V7: + if (!strcmp(i2c_id->name, "max8661")) { + dev_err(&client->dev, "Regulator not on this chip!\n"); + goto err_free; + } + + if (boot_on) + max8660->shadow_regs[MAX8660_OVER2] |= 4; + break; + + default: + dev_err(&client->dev, "invalid regulator %s\n", + pdata->subdevs[i].name); + goto err_free; + } + } + + /* Finally register devices */ + for (i = 0; i < pdata->num_subdevs; i++) { + + id = pdata->subdevs[i].id; + + rdev[i] = regulator_register(&max8660_reg[id], &client->dev, + pdata->subdevs[i].platform_data, + max8660); + if (IS_ERR(rdev[i])) { + ret = PTR_ERR(rdev[i]); + dev_err(&client->dev, "failed to register %s\n", + max8660_reg[id].name); + goto err_unregister; + } + } + + i2c_set_clientdata(client, rdev); + dev_info(&client->dev, "Maxim 8660/8661 regulator driver loaded\n"); + return 0; + +err_unregister: + while (--i >= 0) + regulator_unregister(rdev[i]); +err_free: + kfree(max8660); +out: + return ret; +} + +static int max8660_remove(struct i2c_client *client) +{ + struct regulator_dev **rdev = i2c_get_clientdata(client); + int i; + + for (i = 0; i < MAX8660_V_END; i++) + if (rdev[i]) + regulator_unregister(rdev[i]); + kfree(rdev); + i2c_set_clientdata(client, NULL); + + return 0; +} + +static const struct i2c_device_id max8660_id[] = { + { "max8660", 0 }, + { "max8661", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, max8660_id); + +static struct i2c_driver max8660_driver = { + .probe = max8660_probe, + .remove = max8660_remove, + .driver = { + .name = "max8660", + }, + .id_table = max8660_id, +}; + +static int __init max8660_init(void) +{ + return i2c_add_driver(&max8660_driver); +} +subsys_initcall(max8660_init); + +static void __exit max8660_exit(void) +{ + i2c_del_driver(&max8660_driver); +} +module_exit(max8660_exit); + +/* Module information */ +MODULE_DESCRIPTION("MAXIM 8660/8661 voltage regulator driver"); +MODULE_AUTHOR("Wolfram Sang"); +MODULE_LICENSE("GPL v2"); diff --git a/include/linux/regulator/max8660.h b/include/linux/regulator/max8660.h new file mode 100644 index 0000000..9936763 --- /dev/null +++ b/include/linux/regulator/max8660.h @@ -0,0 +1,57 @@ +/* + * max8660.h -- Voltage regulation for the Maxim 8660/8661 + * + * Copyright (C) 2009 Wolfram Sang, Pengutronix e.K. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __LINUX_REGULATOR_MAX8660_H +#define __LINUX_REGULATOR_MAX8660_H + +#include + +enum { + MAX8660_V3, + MAX8660_V4, + MAX8660_V5, + MAX8660_V6, + MAX8660_V7, + MAX8660_V_END, +}; + +/** + * max8660_subdev_data - regulator subdev data + * @id: regulator id + * @name: regulator name + * @platform_data: regulator init data + */ +struct max8660_subdev_data { + int id; + char *name; + struct regulator_init_data *platform_data; +}; + +/** + * max8660_platform_data - platform data for max8660 + * @num_subdevs: number of regulators used + * @subdevs: pointer to regulators used + * @en34_is_high: if EN34 is driven high, regulators cannot be en-/disabled. + */ +struct max8660_platform_data { + int num_subdevs; + struct max8660_subdev_data *subdevs; + unsigned en34_is_high:1; +}; +#endif -- cgit v0.10.2 From e24a04c44cf312e88b50006a91ad7ffc1c0d97a5 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 22 Sep 2009 08:47:11 -0700 Subject: regulator: Implement WM831x BuckWise DC-DC convertor DVS support The BuckWise DC-DC convertors in WM831x devices support switching to a second output voltage using the logic level on one of the device pins. This is intended to allow rapid voltage switching for uses like cpufreq, replacing the I2C or SPI write used to configure the voltage of the regulator with a much faster GPIO status change. This is implemented by keeping the DVS voltage configured as the maximum voltage permitted for the regulator. If a request is made for the maximum voltage then the GPIO is used to switch to the DVS voltage, otherwise the normal ON voltage is updated and used. This follows the idiom used by most cpufreq drivers, which drop the minimum voltage as the core frequency is dropped but use a constant maximum - raising the voltage should normally be fast, but lowering it may be slower. Configuration of the DVS MFP on the device should be done externally, for example via OTP. Support is present in the hardware for monitoring the status of the transition using a second GPIO. This is not currently implemented but platform data is provided for it - the driver currently assumes that the device will be configured to transition immediately - but platform data is provided to reduce merge issues once it is. Signed-off-by: Mark Brown Acked-by: Samuel Ortiz Signed-off-by: Liam Girdwood diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c index 2eefc1a..0a65775 100644 --- a/drivers/regulator/wm831x-dcdc.c +++ b/drivers/regulator/wm831x-dcdc.c @@ -19,6 +19,8 @@ #include #include #include +#include +#include #include #include @@ -39,6 +41,7 @@ #define WM831X_DCDC_CONTROL_2 1 #define WM831X_DCDC_ON_CONFIG 2 #define WM831X_DCDC_SLEEP_CONTROL 3 +#define WM831X_DCDC_DVS_CONTROL 4 /* * Shared @@ -50,6 +53,10 @@ struct wm831x_dcdc { int base; struct wm831x *wm831x; struct regulator_dev *regulator; + int dvs_gpio; + int dvs_gpio_state; + int on_vsel; + int dvs_vsel; }; static int wm831x_dcdc_is_enabled(struct regulator_dev *rdev) @@ -240,11 +247,9 @@ static int wm831x_buckv_list_voltage(struct regulator_dev *rdev, return -EINVAL; } -static int wm831x_buckv_set_voltage_int(struct regulator_dev *rdev, int reg, - int min_uV, int max_uV) +static int wm831x_buckv_select_min_voltage(struct regulator_dev *rdev, + int min_uV, int max_uV) { - struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev); - struct wm831x *wm831x = dcdc->wm831x; u16 vsel; if (min_uV < 600000) @@ -257,39 +262,126 @@ static int wm831x_buckv_set_voltage_int(struct regulator_dev *rdev, int reg, if (wm831x_buckv_list_voltage(rdev, vsel) > max_uV) return -EINVAL; - return wm831x_set_bits(wm831x, reg, WM831X_DC1_ON_VSEL_MASK, vsel); + return vsel; +} + +static int wm831x_buckv_select_max_voltage(struct regulator_dev *rdev, + int min_uV, int max_uV) +{ + u16 vsel; + + if (max_uV < 600000 || max_uV > 1800000) + return -EINVAL; + + vsel = ((max_uV - 600000) / 12500) + 8; + + if (wm831x_buckv_list_voltage(rdev, vsel) < min_uV || + wm831x_buckv_list_voltage(rdev, vsel) < max_uV) + return -EINVAL; + + return vsel; +} + +static int wm831x_buckv_set_dvs(struct regulator_dev *rdev, int state) +{ + struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev); + + if (state == dcdc->dvs_gpio_state) + return 0; + + dcdc->dvs_gpio_state = state; + gpio_set_value(dcdc->dvs_gpio, state); + + /* Should wait for DVS state change to be asserted if we have + * a GPIO for it, for now assume the device is configured + * for the fastest possible transition. + */ + + return 0; } static int wm831x_buckv_set_voltage(struct regulator_dev *rdev, - int min_uV, int max_uV) + int min_uV, int max_uV) { struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev); - u16 reg = dcdc->base + WM831X_DCDC_ON_CONFIG; + struct wm831x *wm831x = dcdc->wm831x; + int on_reg = dcdc->base + WM831X_DCDC_ON_CONFIG; + int dvs_reg = dcdc->base + WM831X_DCDC_DVS_CONTROL; + int vsel, ret; + + vsel = wm831x_buckv_select_min_voltage(rdev, min_uV, max_uV); + if (vsel < 0) + return vsel; + + /* If this value is already set then do a GPIO update if we can */ + if (dcdc->dvs_gpio && dcdc->on_vsel == vsel) + return wm831x_buckv_set_dvs(rdev, 0); + + if (dcdc->dvs_gpio && dcdc->dvs_vsel == vsel) + return wm831x_buckv_set_dvs(rdev, 1); + + /* Always set the ON status to the minimum voltage */ + ret = wm831x_set_bits(wm831x, on_reg, WM831X_DC1_ON_VSEL_MASK, vsel); + if (ret < 0) + return ret; + dcdc->on_vsel = vsel; + + if (!dcdc->dvs_gpio) + return ret; + + /* Kick the voltage transition now */ + ret = wm831x_buckv_set_dvs(rdev, 0); + if (ret < 0) + return ret; + + /* Set the high voltage as the DVS voltage. This is optimised + * for CPUfreq usage, most processors will keep the maximum + * voltage constant and lower the minimum with the frequency. */ + vsel = wm831x_buckv_select_max_voltage(rdev, min_uV, max_uV); + if (vsel < 0) { + /* This should never happen - at worst the same vsel + * should be chosen */ + WARN_ON(vsel < 0); + return 0; + } + + /* Don't bother if it's the same VSEL we're already using */ + if (vsel == dcdc->on_vsel) + return 0; - return wm831x_buckv_set_voltage_int(rdev, reg, min_uV, max_uV); + ret = wm831x_set_bits(wm831x, dvs_reg, WM831X_DC1_DVS_VSEL_MASK, vsel); + if (ret == 0) + dcdc->dvs_vsel = vsel; + else + dev_warn(wm831x->dev, "Failed to set DCDC DVS VSEL: %d\n", + ret); + + return 0; } static int wm831x_buckv_set_suspend_voltage(struct regulator_dev *rdev, - int uV) + int uV) { struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev); + struct wm831x *wm831x = dcdc->wm831x; u16 reg = dcdc->base + WM831X_DCDC_SLEEP_CONTROL; + int vsel; + + vsel = wm831x_buckv_select_min_voltage(rdev, uV, uV); + if (vsel < 0) + return vsel; - return wm831x_buckv_set_voltage_int(rdev, reg, uV, uV); + return wm831x_set_bits(wm831x, reg, WM831X_DC1_SLP_VSEL_MASK, vsel); } static int wm831x_buckv_get_voltage(struct regulator_dev *rdev) { struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev); - struct wm831x *wm831x = dcdc->wm831x; - u16 reg = dcdc->base + WM831X_DCDC_ON_CONFIG; - int val; - val = wm831x_reg_read(wm831x, reg); - if (val < 0) - return val; - - return wm831x_buckv_list_voltage(rdev, val & WM831X_DC1_ON_VSEL_MASK); + if (dcdc->dvs_gpio && dcdc->dvs_gpio_state) + return wm831x_buckv_list_voltage(rdev, dcdc->dvs_vsel); + else + return wm831x_buckv_list_voltage(rdev, dcdc->on_vsel); } /* Current limit options */ @@ -346,6 +438,64 @@ static struct regulator_ops wm831x_buckv_ops = { .set_suspend_mode = wm831x_dcdc_set_suspend_mode, }; +/* + * Set up DVS control. We just log errors since we can still run + * (with reduced performance) if we fail. + */ +static __devinit void wm831x_buckv_dvs_init(struct wm831x_dcdc *dcdc, + struct wm831x_buckv_pdata *pdata) +{ + struct wm831x *wm831x = dcdc->wm831x; + int ret; + u16 ctrl; + + if (!pdata || !pdata->dvs_gpio) + return; + + switch (pdata->dvs_control_src) { + case 1: + ctrl = 2 << WM831X_DC1_DVS_SRC_SHIFT; + break; + case 2: + ctrl = 3 << WM831X_DC1_DVS_SRC_SHIFT; + break; + default: + dev_err(wm831x->dev, "Invalid DVS control source %d for %s\n", + pdata->dvs_control_src, dcdc->name); + return; + } + + ret = wm831x_set_bits(wm831x, dcdc->base + WM831X_DCDC_DVS_CONTROL, + WM831X_DC1_DVS_SRC_MASK, ctrl); + if (ret < 0) { + dev_err(wm831x->dev, "Failed to set %s DVS source: %d\n", + dcdc->name, ret); + return; + } + + ret = gpio_request(pdata->dvs_gpio, "DCDC DVS"); + if (ret < 0) { + dev_err(wm831x->dev, "Failed to get %s DVS GPIO: %d\n", + dcdc->name, ret); + return; + } + + /* gpiolib won't let us read the GPIO status so pick the higher + * of the two existing voltages so we take it as platform data. + */ + dcdc->dvs_gpio_state = pdata->dvs_init_state; + + ret = gpio_direction_output(pdata->dvs_gpio, dcdc->dvs_gpio_state); + if (ret < 0) { + dev_err(wm831x->dev, "Failed to enable %s DVS GPIO: %d\n", + dcdc->name, ret); + gpio_free(pdata->dvs_gpio); + return; + } + + dcdc->dvs_gpio = pdata->dvs_gpio; +} + static __devinit int wm831x_buckv_probe(struct platform_device *pdev) { struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); @@ -384,6 +534,23 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev) dcdc->desc.ops = &wm831x_buckv_ops; dcdc->desc.owner = THIS_MODULE; + ret = wm831x_reg_read(wm831x, dcdc->base + WM831X_DCDC_ON_CONFIG); + if (ret < 0) { + dev_err(wm831x->dev, "Failed to read ON VSEL: %d\n", ret); + goto err; + } + dcdc->on_vsel = ret & WM831X_DC1_ON_VSEL_MASK; + + ret = wm831x_reg_read(wm831x, dcdc->base + WM831X_DCDC_ON_CONFIG); + if (ret < 0) { + dev_err(wm831x->dev, "Failed to read DVS VSEL: %d\n", ret); + goto err; + } + dcdc->dvs_vsel = ret & WM831X_DC1_DVS_VSEL_MASK; + + if (pdata->dcdc[id]) + wm831x_buckv_dvs_init(dcdc, pdata->dcdc[id]->driver_data); + dcdc->regulator = regulator_register(&dcdc->desc, &pdev->dev, pdata->dcdc[id], dcdc); if (IS_ERR(dcdc->regulator)) { @@ -422,6 +589,8 @@ err_uv: err_regulator: regulator_unregister(dcdc->regulator); err: + if (dcdc->dvs_gpio) + gpio_free(dcdc->dvs_gpio); kfree(dcdc); return ret; } @@ -434,6 +603,8 @@ static __devexit int wm831x_buckv_remove(struct platform_device *pdev) wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "HC"), dcdc); wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "UV"), dcdc); regulator_unregister(dcdc->regulator); + if (dcdc->dvs_gpio) + gpio_free(dcdc->dvs_gpio); kfree(dcdc); return 0; diff --git a/include/linux/mfd/wm831x/pdata.h b/include/linux/mfd/wm831x/pdata.h index 415c228..fd322ac 100644 --- a/include/linux/mfd/wm831x/pdata.h +++ b/include/linux/mfd/wm831x/pdata.h @@ -41,6 +41,23 @@ struct wm831x_battery_pdata { int timeout; /** Charge cycle timeout, in minutes */ }; +/** + * Configuration for the WM831x DC-DC BuckWise convertors. This + * should be passed as driver_data in the regulator_init_data. + * + * Currently all the configuration is for the fast DVS switching + * support of the devices. This allows MFPs on the device to be + * configured as an input to switch between two output voltages, + * allowing voltage transitions without the expense of an access over + * I2C or SPI buses. + */ +struct wm831x_buckv_pdata { + int dvs_gpio; /** CPU GPIO to use for DVS switching */ + int dvs_control_src; /** Hardware DVS source to use (1 or 2) */ + int dvs_init_state; /** DVS state to expect on startup */ + int dvs_state_gpio; /** CPU GPIO to use for monitoring status */ +}; + /* Sources for status LED configuration. Values are register values * plus 1 to allow for a zero default for preserve. */ -- cgit v0.10.2 From be0e2d3e802908e2a3ca620ba8f49ecab87982b2 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Thu, 8 Oct 2009 02:03:57 -0400 Subject: regulator: add 88PM8607 PMIC driver Hi Liam, Since Samuel merged a new version of mfd 88pm8607 driver, I format a new patch on regulator 88pm8607. I paste the new patch in mail. Please help to review again. And I also attach the mfd driver in mail. From: Haojian Zhuang Date: Thu, 8 Oct 2009 09:36:53 -0400 Subject: [PATCH] regulator: Add 88PM8607 PMIC driver This patch adds regulator drivers for Marvell 88PM8607 PMIC. This controller contains 3 DVC and 14 LDO regulators. This controller uses I2C interface. Signed-off-by: Haojian Zhuang Signed-off-by: Liam Girdwood diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c new file mode 100644 index 0000000..e1aabda --- /dev/null +++ b/drivers/regulator/88pm8607.c @@ -0,0 +1,684 @@ +/* + * Regulators driver for Marvell 88PM8607 + * + * Copyright (C) 2009 Marvell International Ltd. + * Haojian Zhuang + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include +#include +#include + +struct pm8607_regulator_info { + struct regulator_desc desc; + struct pm8607_chip *chip; + struct regulator_dev *regulator; + + int min_uV; + int max_uV; + int step_uV; + int vol_reg; + int vol_shift; + int vol_nbits; + int update_reg; + int update_bit; + int enable_reg; + int enable_bit; + int slope_double; +}; + +static inline int check_range(struct pm8607_regulator_info *info, + int min_uV, int max_uV) +{ + if (max_uV < info->min_uV || min_uV > info->max_uV || min_uV > max_uV) + return -EINVAL; + + return 0; +} + +static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index) +{ + struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); + uint8_t chip_id = info->chip->chip_id; + int ret = -EINVAL; + + switch (info->desc.id) { + case PM8607_ID_BUCK1: + ret = (index < 0x1d) ? (index * 25000 + 800000) : + ((index < 0x20) ? 1500000 : + ((index < 0x40) ? ((index - 0x20) * 25000) : + -EINVAL)); + break; + case PM8607_ID_BUCK3: + ret = (index < 0x3d) ? (index * 25000) : + ((index < 0x40) ? 1500000 : -EINVAL); + if (ret < 0) + break; + if (info->slope_double) + ret <<= 1; + break; + case PM8607_ID_LDO1: + ret = (index == 0) ? 1800000 : + ((index == 1) ? 1200000 : + ((index == 2) ? 2800000 : -EINVAL)); + break; + case PM8607_ID_LDO5: + ret = (index == 0) ? 2900000 : + ((index == 1) ? 3000000 : + ((index == 2) ? 3100000 : 3300000)); + break; + case PM8607_ID_LDO7: + case PM8607_ID_LDO8: + ret = (index < 3) ? (index * 50000 + 1800000) : + ((index < 8) ? (index * 50000 + 2550000) : + -EINVAL); + break; + case PM8607_ID_LDO12: + ret = (index < 2) ? (index * 100000 + 1800000) : + ((index < 7) ? (index * 100000 + 2500000) : + ((index == 7) ? 3300000 : 1200000)); + break; + case PM8607_ID_LDO2: + case PM8607_ID_LDO3: + case PM8607_ID_LDO9: + switch (chip_id) { + case PM8607_CHIP_A0: + case PM8607_CHIP_A1: + ret = (index < 3) ? (index * 50000 + 1800000) : + ((index < 8) ? (index * 50000 + 2550000) : + -EINVAL); + break; + case PM8607_CHIP_B0: + ret = (index < 3) ? (index * 50000 + 1800000) : + ((index < 7) ? (index * 50000 + 2550000) : + 3300000); + break; + } + break; + case PM8607_ID_LDO4: + switch (chip_id) { + case PM8607_CHIP_A0: + case PM8607_CHIP_A1: + ret = (index < 3) ? (index * 50000 + 1800000) : + ((index < 8) ? (index * 50000 + 2550000) : + -EINVAL); + break; + case PM8607_CHIP_B0: + ret = (index < 3) ? (index * 50000 + 1800000) : + ((index < 6) ? (index * 50000 + 2550000) : + ((index == 6) ? 2900000 : 3300000)); + break; + } + break; + case PM8607_ID_LDO6: + switch (chip_id) { + case PM8607_CHIP_A0: + case PM8607_CHIP_A1: + ret = (index < 3) ? (index * 50000 + 1800000) : + ((index < 8) ? (index * 50000 + 2450000) : + -EINVAL); + break; + case PM8607_CHIP_B0: + ret = (index < 2) ? (index * 50000 + 1800000) : + ((index < 7) ? (index * 50000 + 2500000) : + 3300000); + break; + } + break; + case PM8607_ID_LDO10: + switch (chip_id) { + case PM8607_CHIP_A0: + case PM8607_CHIP_A1: + ret = (index < 3) ? (index * 50000 + 1800000) : + ((index < 8) ? (index * 50000 + 2550000) : + 1200000); + break; + case PM8607_CHIP_B0: + ret = (index < 3) ? (index * 50000 + 1800000) : + ((index < 7) ? (index * 50000 + 2550000) : + ((index == 7) ? 3300000 : 1200000)); + break; + } + break; + case PM8607_ID_LDO14: + switch (chip_id) { + case PM8607_CHIP_A0: + case PM8607_CHIP_A1: + ret = (index < 3) ? (index * 50000 + 1800000) : + ((index < 8) ? (index * 50000 + 2550000) : + -EINVAL); + break; + case PM8607_CHIP_B0: + ret = (index < 2) ? (index * 50000 + 1800000) : + ((index < 7) ? (index * 50000 + 2600000) : + 3300000); + break; + } + break; + } + return ret; +} + +static int choose_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) +{ + struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); + uint8_t chip_id = info->chip->chip_id; + int val, ret; + + switch (info->desc.id) { + case PM8607_ID_BUCK1: + if (min_uV >= 800000) /* 800mV ~ 1500mV / 25mV */ + val = (min_uV - 775001) / 25000; + else { /* 25mV ~ 775mV / 25mV */ + val = (min_uV + 249999) / 25000; + val += 32; + } + break; + case PM8607_ID_BUCK3: + if (info->slope_double) + min_uV = min_uV >> 1; + val = (min_uV + 249999) / 25000; /* 0mV ~ 1500mV / 25mV */ + + break; + case PM8607_ID_LDO1: + if (min_uV > 1800000) + val = 2; + else if (min_uV > 1200000) + val = 0; + else + val = 1; + break; + case PM8607_ID_LDO5: + if (min_uV > 3100000) + val = 3; + else /* 2900mV ~ 3100mV / 100mV */ + val = (min_uV - 2800001) / 100000; + break; + case PM8607_ID_LDO7: + case PM8607_ID_LDO8: + if (min_uV < 2700000) { /* 1800mV ~ 1900mV / 50mV */ + if (min_uV <= 1800000) + val = 0; /* 1800mv */ + else if (min_uV <= 1900000) + val = (min_uV - 1750001) / 50000; + else + val = 3; /* 2700mV */ + } else { /* 2700mV ~ 2900mV / 50mV */ + if (min_uV <= 2900000) { + val = (min_uV - 2650001) / 50000; + val += 3; + } else + val = -EINVAL; + } + break; + case PM8607_ID_LDO10: + if (min_uV > 2850000) + val = 7; + else if (min_uV <= 1200000) + val = 8; + else if (min_uV < 2700000) /* 1800mV ~ 1900mV / 50mV */ + val = (min_uV - 1750001) / 50000; + else { /* 2700mV ~ 2850mV / 50mV */ + val = (min_uV - 2650001) / 50000; + val += 3; + } + break; + case PM8607_ID_LDO12: + if (min_uV < 2700000) { /* 1800mV ~ 1900mV / 100mV */ + if (min_uV <= 1200000) + val = 8; /* 1200mV */ + else if (min_uV <= 1800000) + val = 0; /* 1800mV */ + else if (min_uV <= 1900000) + val = (min_uV - 1700001) / 100000; + else + val = 2; /* 2700mV */ + } else { /* 2700mV ~ 3100mV / 100mV */ + if (min_uV <= 3100000) { + val = (min_uV - 2600001) / 100000; + val += 2; + } else if (min_uV <= 3300000) + val = 7; + else + val = -EINVAL; + } + break; + case PM8607_ID_LDO2: + case PM8607_ID_LDO3: + case PM8607_ID_LDO9: + switch (chip_id) { + case PM8607_CHIP_A0: + case PM8607_CHIP_A1: + if (min_uV < 2700000) /* 1800mV ~ 1900mV / 50mV */ + if (min_uV <= 1800000) + val = 0; + else if (min_uV <= 1900000) + val = (min_uV - 1750001) / 50000; + else + val = 3; /* 2700mV */ + else { /* 2700mV ~ 2900mV / 50mV */ + if (min_uV <= 2900000) { + val = (min_uV - 2650001) / 50000; + val += 3; + } else + val = -EINVAL; + } + break; + case PM8607_CHIP_B0: + if (min_uV < 2700000) { /* 1800mV ~ 1900mV / 50mV */ + if (min_uV <= 1800000) + val = 0; + else if (min_uV <= 1900000) + val = (min_uV - 1750001) / 50000; + else + val = 3; /* 2700mV */ + } else { /* 2700mV ~ 2850mV / 50mV */ + if (min_uV <= 2850000) { + val = (min_uV - 2650001) / 50000; + val += 3; + } else if (min_uV <= 3300000) + val = 7; + else + val = -EINVAL; + } + break; + } + break; + case PM8607_ID_LDO4: + switch (chip_id) { + case PM8607_CHIP_A0: + case PM8607_CHIP_A1: + if (min_uV < 2700000) /* 1800mV ~ 1900mV / 50mV */ + if (min_uV <= 1800000) + val = 0; + else if (min_uV <= 1900000) + val = (min_uV - 1750001) / 50000; + else + val = 3; /* 2700mV */ + else { /* 2700mV ~ 2900mV / 50mV */ + if (min_uV <= 2900000) { + val = (min_uV - 2650001) / 50000; + val += 3; + } else + val = -EINVAL; + } + break; + case PM8607_CHIP_B0: + if (min_uV < 2700000) { /* 1800mV ~ 1900mV / 50mV */ + if (min_uV <= 1800000) + val = 0; + else if (min_uV <= 1900000) + val = (min_uV - 1750001) / 50000; + else + val = 3; /* 2700mV */ + } else { /* 2700mV ~ 2800mV / 50mV */ + if (min_uV <= 2850000) { + val = (min_uV - 2650001) / 50000; + val += 3; + } else if (min_uV <= 2900000) + val = 6; + else if (min_uV <= 3300000) + val = 7; + else + val = -EINVAL; + } + break; + } + break; + case PM8607_ID_LDO6: + switch (chip_id) { + case PM8607_CHIP_A0: + case PM8607_CHIP_A1: + if (min_uV < 2600000) { /* 1800mV ~ 1900mV / 50mV */ + if (min_uV <= 1800000) + val = 0; + else if (min_uV <= 1900000) + val = (min_uV - 1750001) / 50000; + else + val = 3; /* 2600mV */ + } else { /* 2600mV ~ 2800mV / 50mV */ + if (min_uV <= 2800000) { + val = (min_uV - 2550001) / 50000; + val += 3; + } else + val = -EINVAL; + } + break; + case PM8607_CHIP_B0: + if (min_uV < 2600000) { /* 1800mV ~ 1850mV / 50mV */ + if (min_uV <= 1800000) + val = 0; + else if (min_uV <= 1850000) + val = (min_uV - 1750001) / 50000; + else + val = 2; /* 2600mV */ + } else { /* 2600mV ~ 2800mV / 50mV */ + if (min_uV <= 2800000) { + val = (min_uV - 2550001) / 50000; + val += 2; + } else if (min_uV <= 3300000) + val = 7; + else + val = -EINVAL; + } + break; + } + break; + case PM8607_ID_LDO14: + switch (chip_id) { + case PM8607_CHIP_A0: + case PM8607_CHIP_A1: + if (min_uV < 2700000) { /* 1800mV ~ 1900mV / 50mV */ + if (min_uV <= 1800000) + val = 0; + else if (min_uV <= 1900000) + val = (min_uV - 1750001) / 50000; + else + val = 3; /* 2700mV */ + } else { /* 2700mV ~ 2900mV / 50mV */ + if (min_uV <= 2900000) { + val = (min_uV - 2650001) / 50000; + val += 3; + } else + val = -EINVAL; + } + break; + case PM8607_CHIP_B0: + if (min_uV < 2700000) { /* 1800mV ~ 1850mV / 50mV */ + if (min_uV <= 1800000) + val = 0; + else if (min_uV <= 1850000) + val = (min_uV - 1750001) / 50000; + else + val = 2; /* 2700mV */ + } else { /* 2700mV ~ 2900mV / 50mV */ + if (min_uV <= 2900000) { + val = (min_uV - 2650001) / 50000; + val += 2; + } else if (min_uV <= 3300000) + val = 7; + else + val = -EINVAL; + } + break; + } + break; + } + if (val >= 0) { + ret = pm8607_list_voltage(rdev, val); + if (ret > max_uV) { + pr_err("exceed voltage range (%d %d) uV", + min_uV, max_uV); + return -EINVAL; + } + } else + pr_err("invalid voltage range (%d %d) uV", min_uV, max_uV); + return val; +} + +static int pm8607_set_voltage(struct regulator_dev *rdev, + int min_uV, int max_uV) +{ + struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); + struct pm8607_chip *chip = info->chip; + uint8_t val, mask; + int ret; + + if (check_range(info, min_uV, max_uV)) { + pr_err("invalid voltage range (%d, %d) uV\n", min_uV, max_uV); + return -EINVAL; + } + + ret = choose_voltage(rdev, min_uV, max_uV); + if (ret < 0) + return -EINVAL; + val = (uint8_t)(ret << info->vol_shift); + mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; + + ret = pm8607_set_bits(chip, info->vol_reg, mask, val); + if (ret) + return ret; + switch (info->desc.id) { + case PM8607_ID_BUCK1: + case PM8607_ID_BUCK3: + ret = pm8607_set_bits(chip, info->update_reg, + 1 << info->update_bit, + 1 << info->update_bit); + break; + } + return ret; +} + +static int pm8607_get_voltage(struct regulator_dev *rdev) +{ + struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); + struct pm8607_chip *chip = info->chip; + uint8_t val, mask; + int ret; + + ret = pm8607_reg_read(chip, info->vol_reg); + if (ret < 0) + return ret; + + mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; + val = ((unsigned char)ret & mask) >> info->vol_shift; + + return pm8607_list_voltage(rdev, val); +} + +static int pm8607_enable(struct regulator_dev *rdev) +{ + struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); + struct pm8607_chip *chip = info->chip; + + return pm8607_set_bits(chip, info->enable_reg, + 1 << info->enable_bit, + 1 << info->enable_bit); +} + +static int pm8607_disable(struct regulator_dev *rdev) +{ + struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); + struct pm8607_chip *chip = info->chip; + + return pm8607_set_bits(chip, info->enable_reg, + 1 << info->enable_bit, 0); +} + +static int pm8607_is_enabled(struct regulator_dev *rdev) +{ + struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); + struct pm8607_chip *chip = info->chip; + int ret; + + ret = pm8607_reg_read(chip, info->enable_reg); + if (ret < 0) + return ret; + + return !!((unsigned char)ret & (1 << info->enable_bit)); +} + +static struct regulator_ops pm8607_regulator_ops = { + .set_voltage = pm8607_set_voltage, + .get_voltage = pm8607_get_voltage, + .enable = pm8607_enable, + .disable = pm8607_disable, + .is_enabled = pm8607_is_enabled, +}; + +#define PM8607_DVC(_id, min, max, step, vreg, nbits, ureg, ubit, ereg, ebit) \ +{ \ + .desc = { \ + .name = "BUCK" #_id, \ + .ops = &pm8607_regulator_ops, \ + .type = REGULATOR_VOLTAGE, \ + .id = PM8607_ID_BUCK##_id, \ + .owner = THIS_MODULE, \ + }, \ + .min_uV = (min) * 1000, \ + .max_uV = (max) * 1000, \ + .step_uV = (step) * 1000, \ + .vol_reg = PM8607_##vreg, \ + .vol_shift = (0), \ + .vol_nbits = (nbits), \ + .update_reg = PM8607_##ureg, \ + .update_bit = (ubit), \ + .enable_reg = PM8607_##ereg, \ + .enable_bit = (ebit), \ + .slope_double = (0), \ +} + +#define PM8607_LDO(_id, min, max, step, vreg, shift, nbits, ereg, ebit) \ +{ \ + .desc = { \ + .name = "LDO" #_id, \ + .ops = &pm8607_regulator_ops, \ + .type = REGULATOR_VOLTAGE, \ + .id = PM8607_ID_LDO##_id, \ + .owner = THIS_MODULE, \ + }, \ + .min_uV = (min) * 1000, \ + .max_uV = (max) * 1000, \ + .step_uV = (step) * 1000, \ + .vol_reg = PM8607_##vreg, \ + .vol_shift = (shift), \ + .vol_nbits = (nbits), \ + .enable_reg = PM8607_##ereg, \ + .enable_bit = (ebit), \ + .slope_double = (0), \ +} + +static struct pm8607_regulator_info pm8607_regulator_info[] = { + PM8607_DVC(1, 0, 1500, 25, BUCK1, 6, GO, 0, SUPPLIES_EN11, 0), + PM8607_DVC(3, 0, 1500, 25, BUCK3, 6, GO, 2, SUPPLIES_EN11, 2), + + PM8607_LDO(1 , 1200, 2800, 0, LDO1 , 0, 2, SUPPLIES_EN11, 3), + PM8607_LDO(2 , 1800, 3300, 0, LDO2 , 0, 3, SUPPLIES_EN11, 4), + PM8607_LDO(3 , 1800, 3300, 0, LDO3 , 0, 3, SUPPLIES_EN11, 5), + PM8607_LDO(4 , 1800, 3300, 0, LDO4 , 0, 3, SUPPLIES_EN11, 6), + PM8607_LDO(5 , 2900, 3300, 0, LDO5 , 0, 2, SUPPLIES_EN11, 7), + PM8607_LDO(6 , 1800, 3300, 0, LDO6 , 0, 3, SUPPLIES_EN12, 0), + PM8607_LDO(7 , 1800, 2900, 0, LDO7 , 0, 3, SUPPLIES_EN12, 1), + PM8607_LDO(8 , 1800, 2900, 0, LDO8 , 0, 3, SUPPLIES_EN12, 2), + PM8607_LDO(9 , 1800, 3300, 0, LDO9 , 0, 3, SUPPLIES_EN12, 3), + PM8607_LDO(10, 1200, 3300, 0, LDO10, 0, 4, SUPPLIES_EN11, 4), + PM8607_LDO(12, 1200, 3300, 0, LDO12, 0, 4, SUPPLIES_EN11, 5), + PM8607_LDO(14, 1800, 3300, 0, LDO14, 0, 3, SUPPLIES_EN11, 6), +}; + +static inline struct pm8607_regulator_info *find_regulator_info(int id) +{ + struct pm8607_regulator_info *info; + int i; + + for (i = 0; i < ARRAY_SIZE(pm8607_regulator_info); i++) { + info = &pm8607_regulator_info[i]; + if (info->desc.id == id) + return info; + } + return NULL; +} + +static int __devinit pm8607_regulator_probe(struct platform_device *pdev) +{ + struct pm8607_chip *chip = dev_get_drvdata(pdev->dev.parent); + struct pm8607_platform_data *pdata = chip->dev->platform_data; + struct pm8607_regulator_info *info = NULL; + + info = find_regulator_info(pdev->id); + if (info == NULL) { + dev_err(&pdev->dev, "invalid regulator ID specified\n"); + return -EINVAL; + } + + info->chip = chip; + + info->regulator = regulator_register(&info->desc, &pdev->dev, + pdata->regulator[pdev->id], info); + if (IS_ERR(info->regulator)) { + dev_err(&pdev->dev, "failed to register regulator %s\n", + info->desc.name); + return PTR_ERR(info->regulator); + } + + /* check DVC ramp slope double */ + if (info->desc.id == PM8607_ID_BUCK3) + if (info->chip->buck3_double) + info->slope_double = 1; + + platform_set_drvdata(pdev, info); + return 0; +} + +static int __devexit pm8607_regulator_remove(struct platform_device *pdev) +{ + struct pm8607_regulator_info *info = platform_get_drvdata(pdev); + + regulator_unregister(info->regulator); + return 0; +} + +#define PM8607_REGULATOR_DRIVER(_name) \ +{ \ + .driver = { \ + .name = "88pm8607-" #_name, \ + .owner = THIS_MODULE, \ + }, \ + .probe = pm8607_regulator_probe, \ + .remove = __devexit_p(pm8607_regulator_remove), \ +} + +static struct platform_driver pm8607_regulator_driver[] = { + PM8607_REGULATOR_DRIVER(buck1), + PM8607_REGULATOR_DRIVER(buck2), + PM8607_REGULATOR_DRIVER(buck3), + PM8607_REGULATOR_DRIVER(ldo1), + PM8607_REGULATOR_DRIVER(ldo2), + PM8607_REGULATOR_DRIVER(ldo3), + PM8607_REGULATOR_DRIVER(ldo4), + PM8607_REGULATOR_DRIVER(ldo5), + PM8607_REGULATOR_DRIVER(ldo6), + PM8607_REGULATOR_DRIVER(ldo7), + PM8607_REGULATOR_DRIVER(ldo8), + PM8607_REGULATOR_DRIVER(ldo9), + PM8607_REGULATOR_DRIVER(ldo10), + PM8607_REGULATOR_DRIVER(ldo12), + PM8607_REGULATOR_DRIVER(ldo14), +}; + +static int __init pm8607_regulator_init(void) +{ + int i, count, ret; + + count = ARRAY_SIZE(pm8607_regulator_driver); + for (i = 0; i < count; i++) { + ret = platform_driver_register(&pm8607_regulator_driver[i]); + if (ret != 0) + pr_err("Failed to register regulator driver: %d\n", + ret); + } + return 0; +} +subsys_initcall(pm8607_regulator_init); + +static void __exit pm8607_regulator_exit(void) +{ + int i, count; + + count = ARRAY_SIZE(pm8607_regulator_driver); + for (i = 0; i < count; i++) + platform_driver_unregister(&pm8607_regulator_driver[i]); +} +module_exit(pm8607_regulator_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Haojian Zhuang "); +MODULE_DESCRIPTION("Regulator Driver for Marvell 88PM8607 PMIC"); +MODULE_ALIAS("platform:88pm8607-regulator"); diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 9e0aa14..262f62e 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -164,5 +164,11 @@ config REGULATOR_TPS6507X three step-down converters and two general-purpose LDO voltage regulators. It supports TI's software based Class-2 SmartReflex implementation. +config REGULATOR_88PM8607 + bool "Marvell 88PM8607 Power regulators" + depends on MFD_88PM8607=y + help + This driver supports 88PM8607 voltage regulator chips. + endif diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 12285e4..499ed07 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -26,5 +26,6 @@ obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o +obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG -- cgit v0.10.2 From 5b307627738f1f6cbc31fad9e28a299b5fe55602 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 13 Oct 2009 13:06:49 +0100 Subject: regulator: Report error codes for bulk operations If we're going to log an error we may as well log what the error code that we're failing on is. Signed-off-by: Mark Brown Signed-off-by: Liam Girdwood diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index efe568d..9b43dab 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1885,9 +1885,9 @@ int regulator_bulk_get(struct device *dev, int num_consumers, consumers[i].consumer = regulator_get(dev, consumers[i].supply); if (IS_ERR(consumers[i].consumer)) { - dev_err(dev, "Failed to get supply '%s'\n", - consumers[i].supply); ret = PTR_ERR(consumers[i].consumer); + dev_err(dev, "Failed to get supply '%s': %d\n", + consumers[i].supply, ret); consumers[i].consumer = NULL; goto err; } @@ -1930,7 +1930,7 @@ int regulator_bulk_enable(int num_consumers, return 0; err: - printk(KERN_ERR "Failed to enable %s\n", consumers[i].supply); + printk(KERN_ERR "Failed to enable %s: %d\n", consumers[i].supply, ret); for (i = 0; i < num_consumers; i++) regulator_disable(consumers[i].consumer); @@ -1965,7 +1965,8 @@ int regulator_bulk_disable(int num_consumers, return 0; err: - printk(KERN_ERR "Failed to disable %s\n", consumers[i].supply); + printk(KERN_ERR "Failed to disable %s: %d\n", consumers[i].supply, + ret); for (i = 0; i < num_consumers; i++) regulator_enable(consumers[i].consumer); -- cgit v0.10.2 From e79055d62ea6ca3c36962209f4c819614972c95a Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 19 Oct 2009 15:53:50 +0100 Subject: regulator: Factor out voltage constraint setup This allows constraints to take effect on regulators that support voltage setting but for which the board does not specify a voltage range (for example, because it is fixed correctly at system startup). Signed-off-by: Mark Brown Signed-off-by: Liam Girdwood diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 9b43dab..c1a4991 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -672,31 +672,11 @@ static void print_constraints(struct regulator_dev *rdev) printk(KERN_INFO "regulator: %s: %s\n", rdev->desc->name, buf); } -/** - * set_machine_constraints - sets regulator constraints - * @rdev: regulator source - * @constraints: constraints to apply - * - * Allows platform initialisation code to define and constrain - * regulator circuits e.g. valid voltage/current ranges, etc. NOTE: - * Constraints *must* be set by platform code in order for some - * regulator operations to proceed i.e. set_voltage, set_current_limit, - * set_mode. - */ -static int set_machine_constraints(struct regulator_dev *rdev, - struct regulation_constraints *constraints) +static int machine_constraints_voltage(struct regulator_dev *rdev, + const char *name, struct regulation_constraints *constraints) { - int ret = 0; - const char *name; struct regulator_ops *ops = rdev->desc->ops; - if (constraints->name) - name = constraints->name; - else if (rdev->desc->name) - name = rdev->desc->name; - else - name = "regulator"; - /* constrain machine-level voltage specs to fit * the actual range supported by this regulator. */ @@ -719,14 +699,13 @@ static int set_machine_constraints(struct regulator_dev *rdev, /* voltage constraints are optional */ if ((cmin == 0) && (cmax == 0)) - goto out; + return 0; /* else require explicit machine-level constraints */ if (cmin <= 0 || cmax <= 0 || cmax < cmin) { pr_err("%s: %s '%s' voltage constraints\n", __func__, "invalid", name); - ret = -EINVAL; - goto out; + return -EINVAL; } /* initial: [cmin..cmax] valid, [min_uV..max_uV] not */ @@ -748,8 +727,7 @@ static int set_machine_constraints(struct regulator_dev *rdev, if (max_uV < min_uV) { pr_err("%s: %s '%s' voltage constraints\n", __func__, "unsupportable", name); - ret = -EINVAL; - goto out; + return -EINVAL; } /* use regulator's subset of machine constraints */ @@ -767,6 +745,38 @@ static int set_machine_constraints(struct regulator_dev *rdev, } } + return 0; +} + +/** + * set_machine_constraints - sets regulator constraints + * @rdev: regulator source + * @constraints: constraints to apply + * + * Allows platform initialisation code to define and constrain + * regulator circuits e.g. valid voltage/current ranges, etc. NOTE: + * Constraints *must* be set by platform code in order for some + * regulator operations to proceed i.e. set_voltage, set_current_limit, + * set_mode. + */ +static int set_machine_constraints(struct regulator_dev *rdev, + struct regulation_constraints *constraints) +{ + int ret = 0; + const char *name; + struct regulator_ops *ops = rdev->desc->ops; + + if (constraints->name) + name = constraints->name; + else if (rdev->desc->name) + name = rdev->desc->name; + else + name = "regulator"; + + ret = machine_constraints_voltage(rdev, name, constraints); + if (ret != 0) + goto out; + rdev->constraints = constraints; /* do we need to apply the constraint voltage */ -- cgit v0.10.2 From af5866c9cdc9e43ef775a14765fd8eab95c7fd20 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 22 Oct 2009 16:31:30 +0100 Subject: regulator: Also lift apply_uV into machine_constraints_voltage() It makes sense to do all the voltage configuration in the one split out function. Signed-off-by: Mark Brown Signed-off-by: Liam Girdwood diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index c1a4991..1848a3f 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -676,6 +676,22 @@ static int machine_constraints_voltage(struct regulator_dev *rdev, const char *name, struct regulation_constraints *constraints) { struct regulator_ops *ops = rdev->desc->ops; + int ret; + + /* do we need to apply the constraint voltage */ + if (rdev->constraints->apply_uV && + rdev->constraints->min_uV == rdev->constraints->max_uV && + ops->set_voltage) { + ret = ops->set_voltage(rdev, + rdev->constraints->min_uV, rdev->constraints->max_uV); + if (ret < 0) { + printk(KERN_ERR "%s: failed to apply %duV constraint to %s\n", + __func__, + rdev->constraints->min_uV, name); + rdev->constraints = NULL; + return ret; + } + } /* constrain machine-level voltage specs to fit * the actual range supported by this regulator. @@ -773,27 +789,12 @@ static int set_machine_constraints(struct regulator_dev *rdev, else name = "regulator"; + rdev->constraints = constraints; + ret = machine_constraints_voltage(rdev, name, constraints); if (ret != 0) goto out; - rdev->constraints = constraints; - - /* do we need to apply the constraint voltage */ - if (rdev->constraints->apply_uV && - rdev->constraints->min_uV == rdev->constraints->max_uV && - ops->set_voltage) { - ret = ops->set_voltage(rdev, - rdev->constraints->min_uV, rdev->constraints->max_uV); - if (ret < 0) { - printk(KERN_ERR "%s: failed to apply %duV constraint to %s\n", - __func__, - rdev->constraints->min_uV, name); - rdev->constraints = NULL; - goto out; - } - } - /* do we need to setup our suspend state */ if (constraints->initial_state) { ret = suspend_prepare(rdev, constraints->initial_state); -- cgit v0.10.2 From 8f031b48cd2eab5fc3e4dffa06706372e90d63fe Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 22 Oct 2009 16:31:31 +0100 Subject: regulator: Display actual settings with constraints When voltage or current constraints are either missing or specify a range display the actual setting along with the constraints if we can. This can aid debugging of configuration problems. Signed-off-by: Mark Brown Signed-off-by: Liam Girdwood diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 1848a3f..d3be67e 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -641,25 +641,43 @@ static void print_constraints(struct regulator_dev *rdev) { struct regulation_constraints *constraints = rdev->constraints; char buf[80]; - int count; + int count = 0; + int ret; - if (rdev->desc->type == REGULATOR_VOLTAGE) { + if (constraints->min_uV && constraints->max_uV) { if (constraints->min_uV == constraints->max_uV) - count = sprintf(buf, "%d mV ", - constraints->min_uV / 1000); + count += sprintf(buf + count, "%d mV ", + constraints->min_uV / 1000); else - count = sprintf(buf, "%d <--> %d mV ", - constraints->min_uV / 1000, - constraints->max_uV / 1000); - } else { + count += sprintf(buf + count, "%d <--> %d mV ", + constraints->min_uV / 1000, + constraints->max_uV / 1000); + } + + if (!constraints->min_uV || + constraints->min_uV != constraints->max_uV) { + ret = _regulator_get_voltage(rdev); + if (ret > 0) + count += sprintf(buf + count, "at %d mV ", ret / 1000); + } + + if (constraints->min_uA && constraints->max_uA) { if (constraints->min_uA == constraints->max_uA) - count = sprintf(buf, "%d mA ", - constraints->min_uA / 1000); + count += sprintf(buf + count, "%d mA ", + constraints->min_uA / 1000); else - count = sprintf(buf, "%d <--> %d mA ", - constraints->min_uA / 1000, - constraints->max_uA / 1000); + count += sprintf(buf + count, "%d <--> %d mA ", + constraints->min_uA / 1000, + constraints->max_uA / 1000); } + + if (!constraints->min_uA || + constraints->min_uA != constraints->max_uA) { + ret = _regulator_get_current_limit(rdev); + if (ret > 0) + count += sprintf(buf + count, "at %d uA ", ret / 1000); + } + if (constraints->valid_modes_mask & REGULATOR_MODE_FAST) count += sprintf(buf + count, "fast "); if (constraints->valid_modes_mask & REGULATOR_MODE_NORMAL) -- cgit v0.10.2 From 1083c39346d482b9001944d05c09191027892226 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 22 Oct 2009 16:31:32 +0100 Subject: regulator: Factor out regulator name pretty printing Some of the regulator API functions have code to allow the machine constraints to override the device supplied name for the regulator in the constraints in order to help tie logging to supplies on the board and disambiguate when there is more than one regulator chip in the system. Factor this code out into a new rdev_get_name() function and use it throughout the regulator API so that we always use the same name. Signed-off-by: Mark Brown Signed-off-by: Liam Girdwood diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index d3be67e..7d0c0d7 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -66,6 +66,16 @@ static unsigned int _regulator_get_mode(struct regulator_dev *rdev); static void _notifier_call_chain(struct regulator_dev *rdev, unsigned long event, void *data); +static const char *rdev_get_name(struct regulator_dev *rdev) +{ + if (rdev->constraints && rdev->constraints->name) + return rdev->constraints->name; + else if (rdev->desc->name) + return rdev->desc->name; + else + return ""; +} + /* gets the regulator for a given consumer device */ static struct regulator *get_device_regulator(struct device *dev) { @@ -96,12 +106,12 @@ static int regulator_check_voltage(struct regulator_dev *rdev, if (!rdev->constraints) { printk(KERN_ERR "%s: no constraints for %s\n", __func__, - rdev->desc->name); + rdev_get_name(rdev)); return -ENODEV; } if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) { printk(KERN_ERR "%s: operation not allowed for %s\n", - __func__, rdev->desc->name); + __func__, rdev_get_name(rdev)); return -EPERM; } @@ -124,12 +134,12 @@ static int regulator_check_current_limit(struct regulator_dev *rdev, if (!rdev->constraints) { printk(KERN_ERR "%s: no constraints for %s\n", __func__, - rdev->desc->name); + rdev_get_name(rdev)); return -ENODEV; } if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_CURRENT)) { printk(KERN_ERR "%s: operation not allowed for %s\n", - __func__, rdev->desc->name); + __func__, rdev_get_name(rdev)); return -EPERM; } @@ -159,17 +169,17 @@ static int regulator_check_mode(struct regulator_dev *rdev, int mode) if (!rdev->constraints) { printk(KERN_ERR "%s: no constraints for %s\n", __func__, - rdev->desc->name); + rdev_get_name(rdev)); return -ENODEV; } if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_MODE)) { printk(KERN_ERR "%s: operation not allowed for %s\n", - __func__, rdev->desc->name); + __func__, rdev_get_name(rdev)); return -EPERM; } if (!(rdev->constraints->valid_modes_mask & mode)) { printk(KERN_ERR "%s: invalid mode %x for %s\n", - __func__, mode, rdev->desc->name); + __func__, mode, rdev_get_name(rdev)); return -EINVAL; } return 0; @@ -180,12 +190,12 @@ static int regulator_check_drms(struct regulator_dev *rdev) { if (!rdev->constraints) { printk(KERN_ERR "%s: no constraints for %s\n", __func__, - rdev->desc->name); + rdev_get_name(rdev)); return -ENODEV; } if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_DRMS)) { printk(KERN_ERR "%s: operation not allowed for %s\n", - __func__, rdev->desc->name); + __func__, rdev_get_name(rdev)); return -EPERM; } return 0; @@ -230,16 +240,8 @@ static ssize_t regulator_name_show(struct device *dev, struct device_attribute *attr, char *buf) { struct regulator_dev *rdev = dev_get_drvdata(dev); - const char *name; - if (rdev->constraints && rdev->constraints->name) - name = rdev->constraints->name; - else if (rdev->desc->name) - name = rdev->desc->name; - else - name = ""; - - return sprintf(buf, "%s\n", name); + return sprintf(buf, "%s\n", rdev_get_name(rdev)); } static ssize_t regulator_print_opmode(char *buf, int mode) @@ -687,13 +689,14 @@ static void print_constraints(struct regulator_dev *rdev) if (constraints->valid_modes_mask & REGULATOR_MODE_STANDBY) count += sprintf(buf + count, "standby"); - printk(KERN_INFO "regulator: %s: %s\n", rdev->desc->name, buf); + printk(KERN_INFO "regulator: %s: %s\n", rdev_get_name(rdev), buf); } static int machine_constraints_voltage(struct regulator_dev *rdev, - const char *name, struct regulation_constraints *constraints) + struct regulation_constraints *constraints) { struct regulator_ops *ops = rdev->desc->ops; + const char *name = rdev_get_name(rdev); int ret; /* do we need to apply the constraint voltage */ @@ -800,16 +803,11 @@ static int set_machine_constraints(struct regulator_dev *rdev, const char *name; struct regulator_ops *ops = rdev->desc->ops; - if (constraints->name) - name = constraints->name; - else if (rdev->desc->name) - name = rdev->desc->name; - else - name = "regulator"; - rdev->constraints = constraints; - ret = machine_constraints_voltage(rdev, name, constraints); + name = rdev_get_name(rdev); + + ret = machine_constraints_voltage(rdev, constraints); if (ret != 0) goto out; @@ -932,7 +930,7 @@ static int set_consumer_device_supply(struct regulator_dev *rdev, dev_name(&node->regulator->dev), node->regulator->desc->name, supply, - dev_name(&rdev->dev), rdev->desc->name); + dev_name(&rdev->dev), rdev_get_name(rdev)); return -EBUSY; } @@ -1241,7 +1239,7 @@ static int _regulator_enable(struct regulator_dev *rdev) ret = _regulator_enable(rdev->supply); if (ret < 0) { printk(KERN_ERR "%s: failed to enable %s: %d\n", - __func__, rdev->desc->name, ret); + __func__, rdev_get_name(rdev), ret); return ret; } } @@ -1267,7 +1265,7 @@ static int _regulator_enable(struct regulator_dev *rdev) } } else if (ret < 0) { printk(KERN_ERR "%s: is_enabled() failed for %s: %d\n", - __func__, rdev->desc->name, ret); + __func__, rdev_get_name(rdev), ret); return ret; } /* Fallthrough on positive return values - already enabled */ @@ -1308,7 +1306,7 @@ static int _regulator_disable(struct regulator_dev *rdev) if (WARN(rdev->use_count <= 0, "unbalanced disables for %s\n", - rdev->desc->name)) + rdev_get_name(rdev))) return -EIO; /* are we the last user and permitted to disable ? */ @@ -1321,7 +1319,7 @@ static int _regulator_disable(struct regulator_dev *rdev) ret = rdev->desc->ops->disable(rdev); if (ret < 0) { printk(KERN_ERR "%s: failed to disable %s\n", - __func__, rdev->desc->name); + __func__, rdev_get_name(rdev)); return ret; } } @@ -1378,7 +1376,7 @@ static int _regulator_force_disable(struct regulator_dev *rdev) ret = rdev->desc->ops->disable(rdev); if (ret < 0) { printk(KERN_ERR "%s: failed to force disable %s\n", - __func__, rdev->desc->name); + __func__, rdev_get_name(rdev)); return ret; } /* notify other consumers that power has been forced off */ @@ -1795,7 +1793,7 @@ int regulator_set_optimum_mode(struct regulator *regulator, int uA_load) output_uV = rdev->desc->ops->get_voltage(rdev); if (output_uV <= 0) { printk(KERN_ERR "%s: invalid output voltage found for %s\n", - __func__, rdev->desc->name); + __func__, rdev_get_name(rdev)); goto out; } @@ -1806,7 +1804,7 @@ int regulator_set_optimum_mode(struct regulator *regulator, int uA_load) input_uV = rdev->constraints->input_uV; if (input_uV <= 0) { printk(KERN_ERR "%s: invalid input voltage found for %s\n", - __func__, rdev->desc->name); + __func__, rdev_get_name(rdev)); goto out; } @@ -1820,7 +1818,7 @@ int regulator_set_optimum_mode(struct regulator *regulator, int uA_load) ret = regulator_check_mode(rdev, mode); if (ret < 0) { printk(KERN_ERR "%s: failed to get optimum mode for %s @" - " %d uA %d -> %d uV\n", __func__, rdev->desc->name, + " %d uA %d -> %d uV\n", __func__, rdev_get_name(rdev), total_uA_load, input_uV, output_uV); goto out; } @@ -1828,7 +1826,7 @@ int regulator_set_optimum_mode(struct regulator *regulator, int uA_load) ret = rdev->desc->ops->set_mode(rdev, mode); if (ret < 0) { printk(KERN_ERR "%s: failed to set optimum mode %x for %s\n", - __func__, mode, rdev->desc->name); + __func__, mode, rdev_get_name(rdev)); goto out; } ret = mode; @@ -2346,7 +2344,7 @@ int regulator_suspend_prepare(suspend_state_t state) if (ret < 0) { printk(KERN_ERR "%s: failed to prepare %s\n", - __func__, rdev->desc->name); + __func__, rdev_get_name(rdev)); goto out; } } @@ -2459,12 +2457,7 @@ static int __init regulator_init_complete(void) ops = rdev->desc->ops; c = rdev->constraints; - if (c && c->name) - name = c->name; - else if (rdev->desc->name) - name = rdev->desc->name; - else - name = "regulator"; + name = rdev_get_name(rdev); if (!ops->disable || (c && c->always_on)) continue; -- cgit v0.10.2 From 638f85c54f4fed0f8f1fbc23745a8f334112e892 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 22 Oct 2009 16:31:33 +0100 Subject: regulator: Handle regulators without suspend mode configuration Since some regulators in the system may not support suspend mode configuration we need to allow some regulators to have a missing suspend mode configuration. Do this by requiring that disabled regulators are explicitly flagged and then skip over regulators that have no state specified. Try to avoid surprises by warning the if we could set the state but no configuration is provided. This also ensures that an all zeros configuration generates a warning rather than silently disabling the regulator. Reported-by: Joonyoung Shim Signed-off-by: Mark Brown Signed-off-by: Liam Girdwood diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 7d0c0d7..2dab0d9 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -581,10 +581,29 @@ static int suspend_set_state(struct regulator_dev *rdev, struct regulator_state *rstate) { int ret = 0; + bool can_set_state; - /* enable & disable are mandatory for suspend control */ - if (!rdev->desc->ops->set_suspend_enable || - !rdev->desc->ops->set_suspend_disable) { + can_set_state = rdev->desc->ops->set_suspend_enable && + rdev->desc->ops->set_suspend_disable; + + /* If we have no suspend mode configration don't set anything; + * only warn if the driver actually makes the suspend mode + * configurable. + */ + if (!rstate->enabled && !rstate->disabled) { + if (can_set_state) + printk(KERN_WARNING "%s: No configuration for %s\n", + __func__, rdev_get_name(rdev)); + return 0; + } + + if (rstate->enabled && rstate->disabled) { + printk(KERN_ERR "%s: invalid configuration for %s\n", + __func__, rdev_get_name(rdev)); + return -EINVAL; + } + + if (!can_set_state) { printk(KERN_ERR "%s: no way to set suspend state\n", __func__); return -EINVAL; diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h index 87f5f17..234a847 100644 --- a/include/linux/regulator/machine.h +++ b/include/linux/regulator/machine.h @@ -43,16 +43,20 @@ struct regulator; /** * struct regulator_state - regulator state during low power system states * - * This describes a regulators state during a system wide low power state. + * This describes a regulators state during a system wide low power + * state. One of enabled or disabled must be set for the + * configuration to be applied. * * @uV: Operating voltage during suspend. * @mode: Operating mode during suspend. * @enabled: Enabled during suspend. + * @disabled: Disabled during suspend. */ struct regulator_state { int uV; /* suspend voltage */ unsigned int mode; /* suspend regulator operating mode */ int enabled; /* is regulator enabled in this suspend state */ + int disabled; /* is the regulator disbled in this suspend state */ }; /** -- cgit v0.10.2 From 9992ef40ff2e16559e49ff1ae63d133cb9849e8f Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 22 Oct 2009 16:31:34 +0100 Subject: regulator: Remove duplicate consts from ab3100 'static const int const' means the same thing as 'static const int' and sparse complains about this. Signed-off-by: Mark Brown Signed-off-by: Liam Girdwood diff --git a/drivers/regulator/ab3100.c b/drivers/regulator/ab3100.c index 49aeee8..5da127b 100644 --- a/drivers/regulator/ab3100.c +++ b/drivers/regulator/ab3100.c @@ -81,7 +81,7 @@ static const u8 ab3100_reg_init_order[AB3100_NUM_REGULATORS+2] = { #define LDO_C_VOLTAGE 2650000 #define LDO_D_VOLTAGE 2650000 -static const int const ldo_e_buck_typ_voltages[] = { +static const int ldo_e_buck_typ_voltages[] = { 1800000, 1400000, 1300000, @@ -91,7 +91,7 @@ static const int const ldo_e_buck_typ_voltages[] = { 900000, }; -static const int const ldo_f_typ_voltages[] = { +static const int ldo_f_typ_voltages[] = { 1800000, 1400000, 1300000, @@ -102,21 +102,21 @@ static const int const ldo_f_typ_voltages[] = { 2650000, }; -static const int const ldo_g_typ_voltages[] = { +static const int ldo_g_typ_voltages[] = { 2850000, 2750000, 1800000, 1500000, }; -static const int const ldo_h_typ_voltages[] = { +static const int ldo_h_typ_voltages[] = { 2750000, 1800000, 1500000, 1200000, }; -static const int const ldo_k_typ_voltages[] = { +static const int ldo_k_typ_voltages[] = { 2750000, 1800000, }; -- cgit v0.10.2 From ddec68107ab101d9ff934811d5598f5c613027f2 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 22 Oct 2009 16:31:35 +0100 Subject: regulator: Ensure val is initialised in 88pm8607 choose_voltage() If we fall through it means that we hit an unknown regulator/chip combination so set -ENOENT as an explicit flag (the return code is only used internally). Signed-off-by: Mark Brown Signed-off-by: Liam Girdwood diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c index e1aabda..0471955 100644 --- a/drivers/regulator/88pm8607.c +++ b/drivers/regulator/88pm8607.c @@ -170,7 +170,8 @@ static int choose_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) { struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); uint8_t chip_id = info->chip->chip_id; - int val, ret; + int val = -ENOENT; + int ret; switch (info->desc.id) { case PM8607_ID_BUCK1: -- cgit v0.10.2 From 495353a3f7fbb11e5100c9258365ff65a4834b37 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Mon, 26 Oct 2009 12:37:11 +0100 Subject: regulator: keep index within bounds in da9034_get_ldo12_voltage() If selector equals ARRAY_SIZE(da9034_ldo12_data), that is one too large already. Signed-off-by: Roel Kluin Acked-by: Mark Brown Signed-off-by: Liam Girdwood diff --git a/drivers/regulator/da903x.c b/drivers/regulator/da903x.c index aa224d9..f8c4661 100644 --- a/drivers/regulator/da903x.c +++ b/drivers/regulator/da903x.c @@ -331,7 +331,7 @@ static int da9034_get_ldo12_voltage(struct regulator_dev *rdev) static int da9034_list_ldo12_voltage(struct regulator_dev *rdev, unsigned selector) { - if (selector > ARRAY_SIZE(da9034_ldo12_data)) + if (selector >= ARRAY_SIZE(da9034_ldo12_data)) return -EINVAL; return da9034_ldo12_data[selector] * 1000; } -- cgit v0.10.2 From 176f45b9c9b7e451ac46becb92110f5e2de02d8c Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 28 Oct 2009 17:30:15 +0100 Subject: Fix some AB3100 regulator issues This patch will remove surplus register writes on shut down of LDO D (this magic was not needed), remove an unnecessary (!) error check and really unregister the regulators when the module is unloaded. Signed-off-by: Linus Walleij Signed-off-by: Liam Girdwood diff --git a/drivers/regulator/ab3100.c b/drivers/regulator/ab3100.c index 5da127b..b349db4 100644 --- a/drivers/regulator/ab3100.c +++ b/drivers/regulator/ab3100.c @@ -241,24 +241,12 @@ static int ab3100_disable_regulator(struct regulator_dev *reg) * LDO D is a special regulator. When it is disabled, the entire * system is shut down. So this is handled specially. */ + pr_info("Called ab3100_disable_regulator\n"); if (abreg->regreg == AB3100_LDO_D) { - int i; - dev_info(®->dev, "disabling LDO D - shut down system\n"); - /* - * Set regulators to default values, ignore any errors, - * we're going DOWN - */ - for (i = 0; i < ARRAY_SIZE(ab3100_reg_init_order); i++) { - (void) ab3100_set_register_interruptible(abreg->ab3100, - ab3100_reg_init_order[i], - abreg->plfdata->reg_initvals[i]); - } - /* Setting LDO D to 0x00 cuts the power to the SoC */ return ab3100_set_register_interruptible(abreg->ab3100, AB3100_LDO_D, 0x00U); - } /* @@ -607,13 +595,6 @@ static int __init ab3100_regulators_probe(struct platform_device *pdev) } } - if (err) { - dev_err(&pdev->dev, - "LDO D regulator initialization failed with error %d\n", - err); - return err; - } - /* Register the regulators */ for (i = 0; i < AB3100_NUM_REGULATORS; i++) { struct ab3100_regulator *reg = &ab3100_regulators[i]; @@ -688,7 +669,7 @@ static __init int ab3100_regulators_init(void) static __exit void ab3100_regulators_exit(void) { - platform_driver_register(&ab3100_regulators_driver); + platform_driver_unregister(&ab3100_regulators_driver); } subsys_initcall(ab3100_regulators_init); -- cgit v0.10.2 From b4b90c659d88d09dcb4e34dce5123458cb1b5071 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 10 Nov 2009 09:18:06 +0100 Subject: regulator/mc13783: rename source file to match other drivers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit One annoying thing about the old name was that the module was just called mc13783 which caused wrong expectations (at least for me). Signed-off-by: Uwe Kleine-König Cc: Sascha Hauer Cc: Liam Girdwood Cc: Mark Brown Cc: Samuel Ortiz Acked-by: Mark Brown Signed-off-by: Liam Girdwood diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 499ed07..b3c806c 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -21,7 +21,7 @@ obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o obj-$(CONFIG_REGULATOR_DA903X) += da903x.o obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o -obj-$(CONFIG_REGULATOR_MC13783) += mc13783.o +obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o diff --git a/drivers/regulator/mc13783-regulator.c b/drivers/regulator/mc13783-regulator.c new file mode 100644 index 0000000..710211f --- /dev/null +++ b/drivers/regulator/mc13783-regulator.c @@ -0,0 +1,410 @@ +/* + * Regulator Driver for Freescale MC13783 PMIC + * + * Copyright (C) 2008 Sascha Hauer, Pengutronix + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +struct mc13783_regulator { + struct regulator_desc desc; + int reg; + int enable_bit; +}; + +static struct regulator_ops mc13783_regulator_ops; + +static struct mc13783_regulator mc13783_regulators[] = { + [MC13783_SW_SW3] = { + .desc = { + .name = "SW_SW3", + .ops = &mc13783_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = MC13783_SW_SW3, + .owner = THIS_MODULE, + }, + .reg = MC13783_REG_SWITCHERS_5, + .enable_bit = MC13783_SWCTRL_SW3_EN, + }, + [MC13783_SW_PLL] = { + .desc = { + .name = "SW_PLL", + .ops = &mc13783_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = MC13783_SW_PLL, + .owner = THIS_MODULE, + }, + .reg = MC13783_REG_SWITCHERS_4, + .enable_bit = MC13783_SWCTRL_PLL_EN, + }, + [MC13783_REGU_VAUDIO] = { + .desc = { + .name = "REGU_VAUDIO", + .ops = &mc13783_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = MC13783_REGU_VAUDIO, + .owner = THIS_MODULE, + }, + .reg = MC13783_REG_REGULATOR_MODE_0, + .enable_bit = MC13783_REGCTRL_VAUDIO_EN, + }, + [MC13783_REGU_VIOHI] = { + .desc = { + .name = "REGU_VIOHI", + .ops = &mc13783_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = MC13783_REGU_VIOHI, + .owner = THIS_MODULE, + }, + .reg = MC13783_REG_REGULATOR_MODE_0, + .enable_bit = MC13783_REGCTRL_VIOHI_EN, + }, + [MC13783_REGU_VIOLO] = { + .desc = { + .name = "REGU_VIOLO", + .ops = &mc13783_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = MC13783_REGU_VIOLO, + .owner = THIS_MODULE, + }, + .reg = MC13783_REG_REGULATOR_MODE_0, + .enable_bit = MC13783_REGCTRL_VIOLO_EN, + }, + [MC13783_REGU_VDIG] = { + .desc = { + .name = "REGU_VDIG", + .ops = &mc13783_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = MC13783_REGU_VDIG, + .owner = THIS_MODULE, + }, + .reg = MC13783_REG_REGULATOR_MODE_0, + .enable_bit = MC13783_REGCTRL_VDIG_EN, + }, + [MC13783_REGU_VGEN] = { + .desc = { + .name = "REGU_VGEN", + .ops = &mc13783_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = MC13783_REGU_VGEN, + .owner = THIS_MODULE, + }, + .reg = MC13783_REG_REGULATOR_MODE_0, + .enable_bit = MC13783_REGCTRL_VGEN_EN, + }, + [MC13783_REGU_VRFDIG] = { + .desc = { + .name = "REGU_VRFDIG", + .ops = &mc13783_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = MC13783_REGU_VRFDIG, + .owner = THIS_MODULE, + }, + .reg = MC13783_REG_REGULATOR_MODE_0, + .enable_bit = MC13783_REGCTRL_VRFDIG_EN, + }, + [MC13783_REGU_VRFREF] = { + .desc = { + .name = "REGU_VRFREF", + .ops = &mc13783_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = MC13783_REGU_VRFREF, + .owner = THIS_MODULE, + }, + .reg = MC13783_REG_REGULATOR_MODE_0, + .enable_bit = MC13783_REGCTRL_VRFREF_EN, + }, + [MC13783_REGU_VRFCP] = { + .desc = { + .name = "REGU_VRFCP", + .ops = &mc13783_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = MC13783_REGU_VRFCP, + .owner = THIS_MODULE, + }, + .reg = MC13783_REG_REGULATOR_MODE_0, + .enable_bit = MC13783_REGCTRL_VRFCP_EN, + }, + [MC13783_REGU_VSIM] = { + .desc = { + .name = "REGU_VSIM", + .ops = &mc13783_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = MC13783_REGU_VSIM, + .owner = THIS_MODULE, + }, + .reg = MC13783_REG_REGULATOR_MODE_1, + .enable_bit = MC13783_REGCTRL_VSIM_EN, + }, + [MC13783_REGU_VESIM] = { + .desc = { + .name = "REGU_VESIM", + .ops = &mc13783_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = MC13783_REGU_VESIM, + .owner = THIS_MODULE, + }, + .reg = MC13783_REG_REGULATOR_MODE_1, + .enable_bit = MC13783_REGCTRL_VESIM_EN, + }, + [MC13783_REGU_VCAM] = { + .desc = { + .name = "REGU_VCAM", + .ops = &mc13783_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = MC13783_REGU_VCAM, + .owner = THIS_MODULE, + }, + .reg = MC13783_REG_REGULATOR_MODE_1, + .enable_bit = MC13783_REGCTRL_VCAM_EN, + }, + [MC13783_REGU_VRFBG] = { + .desc = { + .name = "REGU_VRFBG", + .ops = &mc13783_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = MC13783_REGU_VRFBG, + .owner = THIS_MODULE, + }, + .reg = MC13783_REG_REGULATOR_MODE_1, + .enable_bit = MC13783_REGCTRL_VRFBG_EN, + }, + [MC13783_REGU_VVIB] = { + .desc = { + .name = "REGU_VVIB", + .ops = &mc13783_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = MC13783_REGU_VVIB, + .owner = THIS_MODULE, + }, + .reg = MC13783_REG_REGULATOR_MODE_1, + .enable_bit = MC13783_REGCTRL_VVIB_EN, + }, + [MC13783_REGU_VRF1] = { + .desc = { + .name = "REGU_VRF1", + .ops = &mc13783_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = MC13783_REGU_VRF1, + .owner = THIS_MODULE, + }, + .reg = MC13783_REG_REGULATOR_MODE_1, + .enable_bit = MC13783_REGCTRL_VRF1_EN, + }, + [MC13783_REGU_VRF2] = { + .desc = { + .name = "REGU_VRF2", + .ops = &mc13783_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = MC13783_REGU_VRF2, + .owner = THIS_MODULE, + }, + .reg = MC13783_REG_REGULATOR_MODE_1, + .enable_bit = MC13783_REGCTRL_VRF2_EN, + }, + [MC13783_REGU_VMMC1] = { + .desc = { + .name = "REGU_VMMC1", + .ops = &mc13783_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = MC13783_REGU_VMMC1, + .owner = THIS_MODULE, + }, + .reg = MC13783_REG_REGULATOR_MODE_1, + .enable_bit = MC13783_REGCTRL_VMMC1_EN, + }, + [MC13783_REGU_VMMC2] = { + .desc = { + .name = "REGU_VMMC2", + .ops = &mc13783_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = MC13783_REGU_VMMC2, + .owner = THIS_MODULE, + }, + .reg = MC13783_REG_REGULATOR_MODE_1, + .enable_bit = MC13783_REGCTRL_VMMC2_EN, + }, + [MC13783_REGU_GPO1] = { + .desc = { + .name = "REGU_GPO1", + .ops = &mc13783_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = MC13783_REGU_GPO1, + .owner = THIS_MODULE, + }, + .reg = MC13783_REG_POWER_MISCELLANEOUS, + .enable_bit = MC13783_REGCTRL_GPO1_EN, + }, + [MC13783_REGU_GPO2] = { + .desc = { + .name = "REGU_GPO2", + .ops = &mc13783_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = MC13783_REGU_GPO2, + .owner = THIS_MODULE, + }, + .reg = MC13783_REG_POWER_MISCELLANEOUS, + .enable_bit = MC13783_REGCTRL_GPO2_EN, + }, + [MC13783_REGU_GPO3] = { + .desc = { + .name = "REGU_GPO3", + .ops = &mc13783_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = MC13783_REGU_GPO3, + .owner = THIS_MODULE, + }, + .reg = MC13783_REG_POWER_MISCELLANEOUS, + .enable_bit = MC13783_REGCTRL_GPO3_EN, + }, + [MC13783_REGU_GPO4] = { + .desc = { + .name = "REGU_GPO4", + .ops = &mc13783_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = MC13783_REGU_GPO4, + .owner = THIS_MODULE, + }, + .reg = MC13783_REG_POWER_MISCELLANEOUS, + .enable_bit = MC13783_REGCTRL_GPO4_EN, + }, +}; + +struct mc13783_priv { + struct regulator_desc desc[ARRAY_SIZE(mc13783_regulators)]; + struct mc13783 *mc13783; + struct regulator_dev *regulators[0]; +}; + +static int mc13783_enable(struct regulator_dev *rdev) +{ + struct mc13783_priv *priv = rdev_get_drvdata(rdev); + int id = rdev_get_id(rdev); + + dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); + + return mc13783_set_bits(priv->mc13783, mc13783_regulators[id].reg, + mc13783_regulators[id].enable_bit, + mc13783_regulators[id].enable_bit); +} + +static int mc13783_disable(struct regulator_dev *rdev) +{ + struct mc13783_priv *priv = rdev_get_drvdata(rdev); + int id = rdev_get_id(rdev); + + dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); + + return mc13783_set_bits(priv->mc13783, mc13783_regulators[id].reg, + mc13783_regulators[id].enable_bit, 0); +} + +static int mc13783_is_enabled(struct regulator_dev *rdev) +{ + struct mc13783_priv *priv = rdev_get_drvdata(rdev); + int ret, id = rdev_get_id(rdev); + unsigned int val; + + ret = mc13783_reg_read(priv->mc13783, mc13783_regulators[id].reg, &val); + if (ret) + return ret; + + return (val & mc13783_regulators[id].enable_bit) != 0; +} + +static struct regulator_ops mc13783_regulator_ops = { + .enable = mc13783_enable, + .disable = mc13783_disable, + .is_enabled = mc13783_is_enabled, +}; + +static int __devinit mc13783_regulator_probe(struct platform_device *pdev) +{ + struct mc13783_priv *priv; + struct mc13783 *mc13783 = dev_get_drvdata(pdev->dev.parent); + struct mc13783_regulator_init_data *init_data; + int i, ret; + + dev_dbg(&pdev->dev, "mc13783_regulator_probe id %d\n", pdev->id); + + priv = kzalloc(sizeof(*priv) + mc13783->num_regulators * sizeof(void *), + GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->mc13783 = mc13783; + + for (i = 0; i < mc13783->num_regulators; i++) { + init_data = &mc13783->regulators[i]; + priv->regulators[i] = regulator_register( + &mc13783_regulators[init_data->id].desc, + &pdev->dev, init_data->init_data, priv); + + if (IS_ERR(priv->regulators[i])) { + dev_err(&pdev->dev, "failed to register regulator %s\n", + mc13783_regulators[i].desc.name); + ret = PTR_ERR(priv->regulators[i]); + goto err; + } + } + + platform_set_drvdata(pdev, priv); + + return 0; +err: + while (--i >= 0) + regulator_unregister(priv->regulators[i]); + + kfree(priv); + + return ret; +} + +static int __devexit mc13783_regulator_remove(struct platform_device *pdev) +{ + struct mc13783_priv *priv = platform_get_drvdata(pdev); + struct mc13783 *mc13783 = priv->mc13783; + int i; + + for (i = 0; i < mc13783->num_regulators; i++) + regulator_unregister(priv->regulators[i]); + + return 0; +} + +static struct platform_driver mc13783_regulator_driver = { + .driver = { + .name = "mc13783-regulator", + .owner = THIS_MODULE, + }, + .remove = __devexit_p(mc13783_regulator_remove), +}; + +static int __init mc13783_regulator_init(void) +{ + return platform_driver_probe(&mc13783_regulator_driver, + mc13783_regulator_probe); +} +subsys_initcall(mc13783_regulator_init); + +static void __exit mc13783_regulator_exit(void) +{ + platform_driver_unregister(&mc13783_regulator_driver); +} +module_exit(mc13783_regulator_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Sascha Hauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -struct mc13783_regulator { - struct regulator_desc desc; - int reg; - int enable_bit; -}; - -static struct regulator_ops mc13783_regulator_ops; - -static struct mc13783_regulator mc13783_regulators[] = { - [MC13783_SW_SW3] = { - .desc = { - .name = "SW_SW3", - .ops = &mc13783_regulator_ops, - .type = REGULATOR_VOLTAGE, - .id = MC13783_SW_SW3, - .owner = THIS_MODULE, - }, - .reg = MC13783_REG_SWITCHERS_5, - .enable_bit = MC13783_SWCTRL_SW3_EN, - }, - [MC13783_SW_PLL] = { - .desc = { - .name = "SW_PLL", - .ops = &mc13783_regulator_ops, - .type = REGULATOR_VOLTAGE, - .id = MC13783_SW_PLL, - .owner = THIS_MODULE, - }, - .reg = MC13783_REG_SWITCHERS_4, - .enable_bit = MC13783_SWCTRL_PLL_EN, - }, - [MC13783_REGU_VAUDIO] = { - .desc = { - .name = "REGU_VAUDIO", - .ops = &mc13783_regulator_ops, - .type = REGULATOR_VOLTAGE, - .id = MC13783_REGU_VAUDIO, - .owner = THIS_MODULE, - }, - .reg = MC13783_REG_REGULATOR_MODE_0, - .enable_bit = MC13783_REGCTRL_VAUDIO_EN, - }, - [MC13783_REGU_VIOHI] = { - .desc = { - .name = "REGU_VIOHI", - .ops = &mc13783_regulator_ops, - .type = REGULATOR_VOLTAGE, - .id = MC13783_REGU_VIOHI, - .owner = THIS_MODULE, - }, - .reg = MC13783_REG_REGULATOR_MODE_0, - .enable_bit = MC13783_REGCTRL_VIOHI_EN, - }, - [MC13783_REGU_VIOLO] = { - .desc = { - .name = "REGU_VIOLO", - .ops = &mc13783_regulator_ops, - .type = REGULATOR_VOLTAGE, - .id = MC13783_REGU_VIOLO, - .owner = THIS_MODULE, - }, - .reg = MC13783_REG_REGULATOR_MODE_0, - .enable_bit = MC13783_REGCTRL_VIOLO_EN, - }, - [MC13783_REGU_VDIG] = { - .desc = { - .name = "REGU_VDIG", - .ops = &mc13783_regulator_ops, - .type = REGULATOR_VOLTAGE, - .id = MC13783_REGU_VDIG, - .owner = THIS_MODULE, - }, - .reg = MC13783_REG_REGULATOR_MODE_0, - .enable_bit = MC13783_REGCTRL_VDIG_EN, - }, - [MC13783_REGU_VGEN] = { - .desc = { - .name = "REGU_VGEN", - .ops = &mc13783_regulator_ops, - .type = REGULATOR_VOLTAGE, - .id = MC13783_REGU_VGEN, - .owner = THIS_MODULE, - }, - .reg = MC13783_REG_REGULATOR_MODE_0, - .enable_bit = MC13783_REGCTRL_VGEN_EN, - }, - [MC13783_REGU_VRFDIG] = { - .desc = { - .name = "REGU_VRFDIG", - .ops = &mc13783_regulator_ops, - .type = REGULATOR_VOLTAGE, - .id = MC13783_REGU_VRFDIG, - .owner = THIS_MODULE, - }, - .reg = MC13783_REG_REGULATOR_MODE_0, - .enable_bit = MC13783_REGCTRL_VRFDIG_EN, - }, - [MC13783_REGU_VRFREF] = { - .desc = { - .name = "REGU_VRFREF", - .ops = &mc13783_regulator_ops, - .type = REGULATOR_VOLTAGE, - .id = MC13783_REGU_VRFREF, - .owner = THIS_MODULE, - }, - .reg = MC13783_REG_REGULATOR_MODE_0, - .enable_bit = MC13783_REGCTRL_VRFREF_EN, - }, - [MC13783_REGU_VRFCP] = { - .desc = { - .name = "REGU_VRFCP", - .ops = &mc13783_regulator_ops, - .type = REGULATOR_VOLTAGE, - .id = MC13783_REGU_VRFCP, - .owner = THIS_MODULE, - }, - .reg = MC13783_REG_REGULATOR_MODE_0, - .enable_bit = MC13783_REGCTRL_VRFCP_EN, - }, - [MC13783_REGU_VSIM] = { - .desc = { - .name = "REGU_VSIM", - .ops = &mc13783_regulator_ops, - .type = REGULATOR_VOLTAGE, - .id = MC13783_REGU_VSIM, - .owner = THIS_MODULE, - }, - .reg = MC13783_REG_REGULATOR_MODE_1, - .enable_bit = MC13783_REGCTRL_VSIM_EN, - }, - [MC13783_REGU_VESIM] = { - .desc = { - .name = "REGU_VESIM", - .ops = &mc13783_regulator_ops, - .type = REGULATOR_VOLTAGE, - .id = MC13783_REGU_VESIM, - .owner = THIS_MODULE, - }, - .reg = MC13783_REG_REGULATOR_MODE_1, - .enable_bit = MC13783_REGCTRL_VESIM_EN, - }, - [MC13783_REGU_VCAM] = { - .desc = { - .name = "REGU_VCAM", - .ops = &mc13783_regulator_ops, - .type = REGULATOR_VOLTAGE, - .id = MC13783_REGU_VCAM, - .owner = THIS_MODULE, - }, - .reg = MC13783_REG_REGULATOR_MODE_1, - .enable_bit = MC13783_REGCTRL_VCAM_EN, - }, - [MC13783_REGU_VRFBG] = { - .desc = { - .name = "REGU_VRFBG", - .ops = &mc13783_regulator_ops, - .type = REGULATOR_VOLTAGE, - .id = MC13783_REGU_VRFBG, - .owner = THIS_MODULE, - }, - .reg = MC13783_REG_REGULATOR_MODE_1, - .enable_bit = MC13783_REGCTRL_VRFBG_EN, - }, - [MC13783_REGU_VVIB] = { - .desc = { - .name = "REGU_VVIB", - .ops = &mc13783_regulator_ops, - .type = REGULATOR_VOLTAGE, - .id = MC13783_REGU_VVIB, - .owner = THIS_MODULE, - }, - .reg = MC13783_REG_REGULATOR_MODE_1, - .enable_bit = MC13783_REGCTRL_VVIB_EN, - }, - [MC13783_REGU_VRF1] = { - .desc = { - .name = "REGU_VRF1", - .ops = &mc13783_regulator_ops, - .type = REGULATOR_VOLTAGE, - .id = MC13783_REGU_VRF1, - .owner = THIS_MODULE, - }, - .reg = MC13783_REG_REGULATOR_MODE_1, - .enable_bit = MC13783_REGCTRL_VRF1_EN, - }, - [MC13783_REGU_VRF2] = { - .desc = { - .name = "REGU_VRF2", - .ops = &mc13783_regulator_ops, - .type = REGULATOR_VOLTAGE, - .id = MC13783_REGU_VRF2, - .owner = THIS_MODULE, - }, - .reg = MC13783_REG_REGULATOR_MODE_1, - .enable_bit = MC13783_REGCTRL_VRF2_EN, - }, - [MC13783_REGU_VMMC1] = { - .desc = { - .name = "REGU_VMMC1", - .ops = &mc13783_regulator_ops, - .type = REGULATOR_VOLTAGE, - .id = MC13783_REGU_VMMC1, - .owner = THIS_MODULE, - }, - .reg = MC13783_REG_REGULATOR_MODE_1, - .enable_bit = MC13783_REGCTRL_VMMC1_EN, - }, - [MC13783_REGU_VMMC2] = { - .desc = { - .name = "REGU_VMMC2", - .ops = &mc13783_regulator_ops, - .type = REGULATOR_VOLTAGE, - .id = MC13783_REGU_VMMC2, - .owner = THIS_MODULE, - }, - .reg = MC13783_REG_REGULATOR_MODE_1, - .enable_bit = MC13783_REGCTRL_VMMC2_EN, - }, - [MC13783_REGU_GPO1] = { - .desc = { - .name = "REGU_GPO1", - .ops = &mc13783_regulator_ops, - .type = REGULATOR_VOLTAGE, - .id = MC13783_REGU_GPO1, - .owner = THIS_MODULE, - }, - .reg = MC13783_REG_POWER_MISCELLANEOUS, - .enable_bit = MC13783_REGCTRL_GPO1_EN, - }, - [MC13783_REGU_GPO2] = { - .desc = { - .name = "REGU_GPO2", - .ops = &mc13783_regulator_ops, - .type = REGULATOR_VOLTAGE, - .id = MC13783_REGU_GPO2, - .owner = THIS_MODULE, - }, - .reg = MC13783_REG_POWER_MISCELLANEOUS, - .enable_bit = MC13783_REGCTRL_GPO2_EN, - }, - [MC13783_REGU_GPO3] = { - .desc = { - .name = "REGU_GPO3", - .ops = &mc13783_regulator_ops, - .type = REGULATOR_VOLTAGE, - .id = MC13783_REGU_GPO3, - .owner = THIS_MODULE, - }, - .reg = MC13783_REG_POWER_MISCELLANEOUS, - .enable_bit = MC13783_REGCTRL_GPO3_EN, - }, - [MC13783_REGU_GPO4] = { - .desc = { - .name = "REGU_GPO4", - .ops = &mc13783_regulator_ops, - .type = REGULATOR_VOLTAGE, - .id = MC13783_REGU_GPO4, - .owner = THIS_MODULE, - }, - .reg = MC13783_REG_POWER_MISCELLANEOUS, - .enable_bit = MC13783_REGCTRL_GPO4_EN, - }, -}; - -struct mc13783_priv { - struct regulator_desc desc[ARRAY_SIZE(mc13783_regulators)]; - struct mc13783 *mc13783; - struct regulator_dev *regulators[0]; -}; - -static int mc13783_enable(struct regulator_dev *rdev) -{ - struct mc13783_priv *priv = rdev_get_drvdata(rdev); - int id = rdev_get_id(rdev); - - dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); - - return mc13783_set_bits(priv->mc13783, mc13783_regulators[id].reg, - mc13783_regulators[id].enable_bit, - mc13783_regulators[id].enable_bit); -} - -static int mc13783_disable(struct regulator_dev *rdev) -{ - struct mc13783_priv *priv = rdev_get_drvdata(rdev); - int id = rdev_get_id(rdev); - - dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); - - return mc13783_set_bits(priv->mc13783, mc13783_regulators[id].reg, - mc13783_regulators[id].enable_bit, 0); -} - -static int mc13783_is_enabled(struct regulator_dev *rdev) -{ - struct mc13783_priv *priv = rdev_get_drvdata(rdev); - int ret, id = rdev_get_id(rdev); - unsigned int val; - - ret = mc13783_reg_read(priv->mc13783, mc13783_regulators[id].reg, &val); - if (ret) - return ret; - - return (val & mc13783_regulators[id].enable_bit) != 0; -} - -static struct regulator_ops mc13783_regulator_ops = { - .enable = mc13783_enable, - .disable = mc13783_disable, - .is_enabled = mc13783_is_enabled, -}; - -static int __devinit mc13783_regulator_probe(struct platform_device *pdev) -{ - struct mc13783_priv *priv; - struct mc13783 *mc13783 = dev_get_drvdata(pdev->dev.parent); - struct mc13783_regulator_init_data *init_data; - int i, ret; - - dev_dbg(&pdev->dev, "mc13783_regulator_probe id %d\n", pdev->id); - - priv = kzalloc(sizeof(*priv) + mc13783->num_regulators * sizeof(void *), - GFP_KERNEL); - if (!priv) - return -ENOMEM; - - priv->mc13783 = mc13783; - - for (i = 0; i < mc13783->num_regulators; i++) { - init_data = &mc13783->regulators[i]; - priv->regulators[i] = regulator_register( - &mc13783_regulators[init_data->id].desc, - &pdev->dev, init_data->init_data, priv); - - if (IS_ERR(priv->regulators[i])) { - dev_err(&pdev->dev, "failed to register regulator %s\n", - mc13783_regulators[i].desc.name); - ret = PTR_ERR(priv->regulators[i]); - goto err; - } - } - - platform_set_drvdata(pdev, priv); - - return 0; -err: - while (--i >= 0) - regulator_unregister(priv->regulators[i]); - - kfree(priv); - - return ret; -} - -static int __devexit mc13783_regulator_remove(struct platform_device *pdev) -{ - struct mc13783_priv *priv = platform_get_drvdata(pdev); - struct mc13783 *mc13783 = priv->mc13783; - int i; - - for (i = 0; i < mc13783->num_regulators; i++) - regulator_unregister(priv->regulators[i]); - - return 0; -} - -static struct platform_driver mc13783_regulator_driver = { - .driver = { - .name = "mc13783-regulator", - .owner = THIS_MODULE, - }, - .remove = __devexit_p(mc13783_regulator_remove), -}; - -static int __init mc13783_regulator_init(void) -{ - return platform_driver_probe(&mc13783_regulator_driver, - mc13783_regulator_probe); -} -subsys_initcall(mc13783_regulator_init); - -static void __exit mc13783_regulator_exit(void) -{ - platform_driver_unregister(&mc13783_regulator_driver); -} -module_exit(mc13783_regulator_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Sascha Hauer Date: Tue, 10 Nov 2009 09:18:07 +0100 Subject: regulator/mc13783: various cleanups MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - define needed registers and bits in the driver - properly namespace functions and structs - fix locking as required by patch "mfd/mc13783: near complete rewrite" - use platform_data as provided by "mfd/mc13783: near complete rewrite" instead of accessing struct mc13783 - struct mc13783_regulator_priv.desc is (and was) unused and so can go away - use cpp magic to initialize mc13783_regulators - bring MODULE_LICENSE in sync with actual copyright - minor style fixes This allows not including mc13783-private.h which I intend to remove soon. Signed-off-by: Uwe Kleine-König Cc: Sascha Hauer Cc: Liam Girdwood Cc: Mark Brown Cc: Samuel Ortiz Acked-by: Mark Brown Signed-off-by: Liam Girdwood diff --git a/drivers/regulator/mc13783-regulator.c b/drivers/regulator/mc13783-regulator.c index 710211f..9f99862 100644 --- a/drivers/regulator/mc13783-regulator.c +++ b/drivers/regulator/mc13783-regulator.c @@ -8,15 +8,47 @@ * published by the Free Software Foundation. */ -#include +#include #include #include #include -#include #include #include #include +#define MC13783_REG_SWITCHERS4 28 +#define MC13783_REG_SWITCHERS4_PLLEN (1 << 18) + +#define MC13783_REG_SWITCHERS5 29 +#define MC13783_REG_SWITCHERS5_SW3EN (1 << 20) + +#define MC13783_REG_REGULATORMODE0 32 +#define MC13783_REG_REGULATORMODE0_VAUDIOEN (1 << 0) +#define MC13783_REG_REGULATORMODE0_VIOHIEN (1 << 3) +#define MC13783_REG_REGULATORMODE0_VIOLOEN (1 << 6) +#define MC13783_REG_REGULATORMODE0_VDIGEN (1 << 9) +#define MC13783_REG_REGULATORMODE0_VGENEN (1 << 12) +#define MC13783_REG_REGULATORMODE0_VRFDIGEN (1 << 15) +#define MC13783_REG_REGULATORMODE0_VRFREFEN (1 << 18) +#define MC13783_REG_REGULATORMODE0_VRFCPEN (1 << 21) + +#define MC13783_REG_REGULATORMODE1 33 +#define MC13783_REG_REGULATORMODE1_VSIMEN (1 << 0) +#define MC13783_REG_REGULATORMODE1_VESIMEN (1 << 3) +#define MC13783_REG_REGULATORMODE1_VCAMEN (1 << 6) +#define MC13783_REG_REGULATORMODE1_VRFBGEN (1 << 9) +#define MC13783_REG_REGULATORMODE1_VVIBEN (1 << 11) +#define MC13783_REG_REGULATORMODE1_VRF1EN (1 << 12) +#define MC13783_REG_REGULATORMODE1_VRF2EN (1 << 15) +#define MC13783_REG_REGULATORMODE1_VMMC1EN (1 << 18) +#define MC13783_REG_REGULATORMODE1_VMMC2EN (1 << 21) + +#define MC13783_REG_POWERMISC 34 +#define MC13783_REG_POWERMISC_GPO1EN (1 << 6) +#define MC13783_REG_POWERMISC_GPO2EN (1 << 8) +#define MC13783_REG_POWERMISC_GPO3EN (1 << 10) +#define MC13783_REG_POWERMISC_GPO4EN (1 << 12) + struct mc13783_regulator { struct regulator_desc desc; int reg; @@ -25,298 +57,97 @@ struct mc13783_regulator { static struct regulator_ops mc13783_regulator_ops; +#define MC13783_DEFINE(prefix, _name, _reg) \ + [MC13783_ ## prefix ## _ ## _name] = { \ + .desc = { \ + .name = #prefix "_" #_name, \ + .ops = &mc13783_regulator_ops, \ + .type = REGULATOR_VOLTAGE, \ + .id = MC13783_ ## prefix ## _ ## _name, \ + .owner = THIS_MODULE, \ + }, \ + .reg = MC13783_REG_ ## _reg, \ + .enable_bit = MC13783_REG_ ## _reg ## _ ## _name ## EN, \ + } + +#define MC13783_DEFINE_SW(_name, _reg) MC13783_DEFINE(SW, _name, _reg) +#define MC13783_DEFINE_REGU(_name, _reg) MC13783_DEFINE(REGU, _name, _reg) + static struct mc13783_regulator mc13783_regulators[] = { - [MC13783_SW_SW3] = { - .desc = { - .name = "SW_SW3", - .ops = &mc13783_regulator_ops, - .type = REGULATOR_VOLTAGE, - .id = MC13783_SW_SW3, - .owner = THIS_MODULE, - }, - .reg = MC13783_REG_SWITCHERS_5, - .enable_bit = MC13783_SWCTRL_SW3_EN, - }, - [MC13783_SW_PLL] = { - .desc = { - .name = "SW_PLL", - .ops = &mc13783_regulator_ops, - .type = REGULATOR_VOLTAGE, - .id = MC13783_SW_PLL, - .owner = THIS_MODULE, - }, - .reg = MC13783_REG_SWITCHERS_4, - .enable_bit = MC13783_SWCTRL_PLL_EN, - }, - [MC13783_REGU_VAUDIO] = { - .desc = { - .name = "REGU_VAUDIO", - .ops = &mc13783_regulator_ops, - .type = REGULATOR_VOLTAGE, - .id = MC13783_REGU_VAUDIO, - .owner = THIS_MODULE, - }, - .reg = MC13783_REG_REGULATOR_MODE_0, - .enable_bit = MC13783_REGCTRL_VAUDIO_EN, - }, - [MC13783_REGU_VIOHI] = { - .desc = { - .name = "REGU_VIOHI", - .ops = &mc13783_regulator_ops, - .type = REGULATOR_VOLTAGE, - .id = MC13783_REGU_VIOHI, - .owner = THIS_MODULE, - }, - .reg = MC13783_REG_REGULATOR_MODE_0, - .enable_bit = MC13783_REGCTRL_VIOHI_EN, - }, - [MC13783_REGU_VIOLO] = { - .desc = { - .name = "REGU_VIOLO", - .ops = &mc13783_regulator_ops, - .type = REGULATOR_VOLTAGE, - .id = MC13783_REGU_VIOLO, - .owner = THIS_MODULE, - }, - .reg = MC13783_REG_REGULATOR_MODE_0, - .enable_bit = MC13783_REGCTRL_VIOLO_EN, - }, - [MC13783_REGU_VDIG] = { - .desc = { - .name = "REGU_VDIG", - .ops = &mc13783_regulator_ops, - .type = REGULATOR_VOLTAGE, - .id = MC13783_REGU_VDIG, - .owner = THIS_MODULE, - }, - .reg = MC13783_REG_REGULATOR_MODE_0, - .enable_bit = MC13783_REGCTRL_VDIG_EN, - }, - [MC13783_REGU_VGEN] = { - .desc = { - .name = "REGU_VGEN", - .ops = &mc13783_regulator_ops, - .type = REGULATOR_VOLTAGE, - .id = MC13783_REGU_VGEN, - .owner = THIS_MODULE, - }, - .reg = MC13783_REG_REGULATOR_MODE_0, - .enable_bit = MC13783_REGCTRL_VGEN_EN, - }, - [MC13783_REGU_VRFDIG] = { - .desc = { - .name = "REGU_VRFDIG", - .ops = &mc13783_regulator_ops, - .type = REGULATOR_VOLTAGE, - .id = MC13783_REGU_VRFDIG, - .owner = THIS_MODULE, - }, - .reg = MC13783_REG_REGULATOR_MODE_0, - .enable_bit = MC13783_REGCTRL_VRFDIG_EN, - }, - [MC13783_REGU_VRFREF] = { - .desc = { - .name = "REGU_VRFREF", - .ops = &mc13783_regulator_ops, - .type = REGULATOR_VOLTAGE, - .id = MC13783_REGU_VRFREF, - .owner = THIS_MODULE, - }, - .reg = MC13783_REG_REGULATOR_MODE_0, - .enable_bit = MC13783_REGCTRL_VRFREF_EN, - }, - [MC13783_REGU_VRFCP] = { - .desc = { - .name = "REGU_VRFCP", - .ops = &mc13783_regulator_ops, - .type = REGULATOR_VOLTAGE, - .id = MC13783_REGU_VRFCP, - .owner = THIS_MODULE, - }, - .reg = MC13783_REG_REGULATOR_MODE_0, - .enable_bit = MC13783_REGCTRL_VRFCP_EN, - }, - [MC13783_REGU_VSIM] = { - .desc = { - .name = "REGU_VSIM", - .ops = &mc13783_regulator_ops, - .type = REGULATOR_VOLTAGE, - .id = MC13783_REGU_VSIM, - .owner = THIS_MODULE, - }, - .reg = MC13783_REG_REGULATOR_MODE_1, - .enable_bit = MC13783_REGCTRL_VSIM_EN, - }, - [MC13783_REGU_VESIM] = { - .desc = { - .name = "REGU_VESIM", - .ops = &mc13783_regulator_ops, - .type = REGULATOR_VOLTAGE, - .id = MC13783_REGU_VESIM, - .owner = THIS_MODULE, - }, - .reg = MC13783_REG_REGULATOR_MODE_1, - .enable_bit = MC13783_REGCTRL_VESIM_EN, - }, - [MC13783_REGU_VCAM] = { - .desc = { - .name = "REGU_VCAM", - .ops = &mc13783_regulator_ops, - .type = REGULATOR_VOLTAGE, - .id = MC13783_REGU_VCAM, - .owner = THIS_MODULE, - }, - .reg = MC13783_REG_REGULATOR_MODE_1, - .enable_bit = MC13783_REGCTRL_VCAM_EN, - }, - [MC13783_REGU_VRFBG] = { - .desc = { - .name = "REGU_VRFBG", - .ops = &mc13783_regulator_ops, - .type = REGULATOR_VOLTAGE, - .id = MC13783_REGU_VRFBG, - .owner = THIS_MODULE, - }, - .reg = MC13783_REG_REGULATOR_MODE_1, - .enable_bit = MC13783_REGCTRL_VRFBG_EN, - }, - [MC13783_REGU_VVIB] = { - .desc = { - .name = "REGU_VVIB", - .ops = &mc13783_regulator_ops, - .type = REGULATOR_VOLTAGE, - .id = MC13783_REGU_VVIB, - .owner = THIS_MODULE, - }, - .reg = MC13783_REG_REGULATOR_MODE_1, - .enable_bit = MC13783_REGCTRL_VVIB_EN, - }, - [MC13783_REGU_VRF1] = { - .desc = { - .name = "REGU_VRF1", - .ops = &mc13783_regulator_ops, - .type = REGULATOR_VOLTAGE, - .id = MC13783_REGU_VRF1, - .owner = THIS_MODULE, - }, - .reg = MC13783_REG_REGULATOR_MODE_1, - .enable_bit = MC13783_REGCTRL_VRF1_EN, - }, - [MC13783_REGU_VRF2] = { - .desc = { - .name = "REGU_VRF2", - .ops = &mc13783_regulator_ops, - .type = REGULATOR_VOLTAGE, - .id = MC13783_REGU_VRF2, - .owner = THIS_MODULE, - }, - .reg = MC13783_REG_REGULATOR_MODE_1, - .enable_bit = MC13783_REGCTRL_VRF2_EN, - }, - [MC13783_REGU_VMMC1] = { - .desc = { - .name = "REGU_VMMC1", - .ops = &mc13783_regulator_ops, - .type = REGULATOR_VOLTAGE, - .id = MC13783_REGU_VMMC1, - .owner = THIS_MODULE, - }, - .reg = MC13783_REG_REGULATOR_MODE_1, - .enable_bit = MC13783_REGCTRL_VMMC1_EN, - }, - [MC13783_REGU_VMMC2] = { - .desc = { - .name = "REGU_VMMC2", - .ops = &mc13783_regulator_ops, - .type = REGULATOR_VOLTAGE, - .id = MC13783_REGU_VMMC2, - .owner = THIS_MODULE, - }, - .reg = MC13783_REG_REGULATOR_MODE_1, - .enable_bit = MC13783_REGCTRL_VMMC2_EN, - }, - [MC13783_REGU_GPO1] = { - .desc = { - .name = "REGU_GPO1", - .ops = &mc13783_regulator_ops, - .type = REGULATOR_VOLTAGE, - .id = MC13783_REGU_GPO1, - .owner = THIS_MODULE, - }, - .reg = MC13783_REG_POWER_MISCELLANEOUS, - .enable_bit = MC13783_REGCTRL_GPO1_EN, - }, - [MC13783_REGU_GPO2] = { - .desc = { - .name = "REGU_GPO2", - .ops = &mc13783_regulator_ops, - .type = REGULATOR_VOLTAGE, - .id = MC13783_REGU_GPO2, - .owner = THIS_MODULE, - }, - .reg = MC13783_REG_POWER_MISCELLANEOUS, - .enable_bit = MC13783_REGCTRL_GPO2_EN, - }, - [MC13783_REGU_GPO3] = { - .desc = { - .name = "REGU_GPO3", - .ops = &mc13783_regulator_ops, - .type = REGULATOR_VOLTAGE, - .id = MC13783_REGU_GPO3, - .owner = THIS_MODULE, - }, - .reg = MC13783_REG_POWER_MISCELLANEOUS, - .enable_bit = MC13783_REGCTRL_GPO3_EN, - }, - [MC13783_REGU_GPO4] = { - .desc = { - .name = "REGU_GPO4", - .ops = &mc13783_regulator_ops, - .type = REGULATOR_VOLTAGE, - .id = MC13783_REGU_GPO4, - .owner = THIS_MODULE, - }, - .reg = MC13783_REG_POWER_MISCELLANEOUS, - .enable_bit = MC13783_REGCTRL_GPO4_EN, - }, + MC13783_DEFINE_SW(SW3, SWITCHERS5), + MC13783_DEFINE_SW(PLL, SWITCHERS4), + + MC13783_DEFINE_REGU(VAUDIO, REGULATORMODE0), + MC13783_DEFINE_REGU(VIOHI, REGULATORMODE0), + MC13783_DEFINE_REGU(VIOLO, REGULATORMODE0), + MC13783_DEFINE_REGU(VDIG, REGULATORMODE0), + MC13783_DEFINE_REGU(VGEN, REGULATORMODE0), + MC13783_DEFINE_REGU(VRFDIG, REGULATORMODE0), + MC13783_DEFINE_REGU(VRFREF, REGULATORMODE0), + MC13783_DEFINE_REGU(VRFCP, REGULATORMODE0), + MC13783_DEFINE_REGU(VSIM, REGULATORMODE1), + MC13783_DEFINE_REGU(VESIM, REGULATORMODE1), + MC13783_DEFINE_REGU(VCAM, REGULATORMODE1), + MC13783_DEFINE_REGU(VRFBG, REGULATORMODE1), + MC13783_DEFINE_REGU(VVIB, REGULATORMODE1), + MC13783_DEFINE_REGU(VRF1, REGULATORMODE1), + MC13783_DEFINE_REGU(VRF2, REGULATORMODE1), + MC13783_DEFINE_REGU(VMMC1, REGULATORMODE1), + MC13783_DEFINE_REGU(VMMC2, REGULATORMODE1), + MC13783_DEFINE_REGU(GPO1, POWERMISC), + MC13783_DEFINE_REGU(GPO2, POWERMISC), + MC13783_DEFINE_REGU(GPO3, POWERMISC), + MC13783_DEFINE_REGU(GPO4, POWERMISC), }; -struct mc13783_priv { - struct regulator_desc desc[ARRAY_SIZE(mc13783_regulators)]; +struct mc13783_regulator_priv { struct mc13783 *mc13783; - struct regulator_dev *regulators[0]; + struct regulator_dev *regulators[]; }; -static int mc13783_enable(struct regulator_dev *rdev) +static int mc13783_regulator_enable(struct regulator_dev *rdev) { - struct mc13783_priv *priv = rdev_get_drvdata(rdev); + struct mc13783_regulator_priv *priv = rdev_get_drvdata(rdev); int id = rdev_get_id(rdev); + int ret; dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); - return mc13783_set_bits(priv->mc13783, mc13783_regulators[id].reg, + mc13783_lock(priv->mc13783); + ret = mc13783_reg_rmw(priv->mc13783, mc13783_regulators[id].reg, mc13783_regulators[id].enable_bit, mc13783_regulators[id].enable_bit); + mc13783_unlock(priv->mc13783); + + return ret; } -static int mc13783_disable(struct regulator_dev *rdev) +static int mc13783_regulator_disable(struct regulator_dev *rdev) { - struct mc13783_priv *priv = rdev_get_drvdata(rdev); + struct mc13783_regulator_priv *priv = rdev_get_drvdata(rdev); int id = rdev_get_id(rdev); + int ret; dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); - return mc13783_set_bits(priv->mc13783, mc13783_regulators[id].reg, + mc13783_lock(priv->mc13783); + ret = mc13783_reg_rmw(priv->mc13783, mc13783_regulators[id].reg, mc13783_regulators[id].enable_bit, 0); + mc13783_unlock(priv->mc13783); + + return ret; } -static int mc13783_is_enabled(struct regulator_dev *rdev) +static int mc13783_regulator_is_enabled(struct regulator_dev *rdev) { - struct mc13783_priv *priv = rdev_get_drvdata(rdev); + struct mc13783_regulator_priv *priv = rdev_get_drvdata(rdev); int ret, id = rdev_get_id(rdev); unsigned int val; + mc13783_lock(priv->mc13783); ret = mc13783_reg_read(priv->mc13783, mc13783_regulators[id].reg, &val); + mc13783_unlock(priv->mc13783); + if (ret) return ret; @@ -324,29 +155,32 @@ static int mc13783_is_enabled(struct regulator_dev *rdev) } static struct regulator_ops mc13783_regulator_ops = { - .enable = mc13783_enable, - .disable = mc13783_disable, - .is_enabled = mc13783_is_enabled, + .enable = mc13783_regulator_enable, + .disable = mc13783_regulator_disable, + .is_enabled = mc13783_regulator_is_enabled, }; static int __devinit mc13783_regulator_probe(struct platform_device *pdev) { - struct mc13783_priv *priv; + struct mc13783_regulator_priv *priv; struct mc13783 *mc13783 = dev_get_drvdata(pdev->dev.parent); + struct mc13783_regulator_platform_data *pdata = + dev_get_platdata(&pdev->dev); struct mc13783_regulator_init_data *init_data; int i, ret; dev_dbg(&pdev->dev, "mc13783_regulator_probe id %d\n", pdev->id); - priv = kzalloc(sizeof(*priv) + mc13783->num_regulators * sizeof(void *), + priv = kzalloc(sizeof(*priv) + + pdata->num_regulators * sizeof(priv->regulators[0]), GFP_KERNEL); if (!priv) return -ENOMEM; priv->mc13783 = mc13783; - for (i = 0; i < mc13783->num_regulators; i++) { - init_data = &mc13783->regulators[i]; + for (i = 0; i < pdata->num_regulators; i++) { + init_data = &pdata->regulators[i]; priv->regulators[i] = regulator_register( &mc13783_regulators[init_data->id].desc, &pdev->dev, init_data->init_data, priv); @@ -373,11 +207,12 @@ err: static int __devexit mc13783_regulator_remove(struct platform_device *pdev) { - struct mc13783_priv *priv = platform_get_drvdata(pdev); - struct mc13783 *mc13783 = priv->mc13783; + struct mc13783_regulator_priv *priv = platform_get_drvdata(pdev); + struct mc13783_regulator_platform_data *pdata = + dev_get_platdata(&pdev->dev); int i; - for (i = 0; i < mc13783->num_regulators; i++) + for (i = 0; i < pdata->num_regulators; i++) regulator_unregister(priv->regulators[i]); return 0; @@ -404,7 +239,7 @@ static void __exit mc13783_regulator_exit(void) } module_exit(mc13783_regulator_exit); -MODULE_LICENSE("GPL"); +MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Sascha Hauer Date: Wed, 11 Nov 2009 14:16:10 +0000 Subject: regulator: consumer.h - fix build when consumer.h is #included first. consumer.h requires device.h for stand alone build. Signed-off-by: Liam Girdwood diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h index 490c5b3..030d922 100644 --- a/include/linux/regulator/consumer.h +++ b/include/linux/regulator/consumer.h @@ -35,6 +35,8 @@ #ifndef __LINUX_REGULATOR_CONSUMER_H_ #define __LINUX_REGULATOR_CONSUMER_H_ +#include + /* * Regulator operating modes. * -- cgit v0.10.2 From d662fc82dc745ee24d518b0fde5a6a19758092ec Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 21 Nov 2009 22:18:44 +0100 Subject: drivers/regulator: use PTR_ERR to get error code IS_ERR returns only 1 or 0. The callsite of setup_regulators expects a negative integer in an error case. Thus, PTR_ERR has to be used to extract it. The semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @@ expression E,E1; @@ *E = IS_ERR(...) ... when != E = E1 *return E; // Signed-off-by: Julia Lawall Acked-by: Signed-off-by: Liam Girdwood diff --git a/drivers/regulator/lp3971.c b/drivers/regulator/lp3971.c index 7803a32..76d08c2 100644 --- a/drivers/regulator/lp3971.c +++ b/drivers/regulator/lp3971.c @@ -446,8 +446,8 @@ static int setup_regulators(struct lp3971 *lp3971, lp3971->rdev[i] = regulator_register(®ulators[id], lp3971->dev, pdata->regulators[i].initdata, lp3971); - err = IS_ERR(lp3971->rdev[i]); - if (err) { + if (IS_ERR(lp3971->rdev[i])) { + err = PTR_ERR(lp3971->rdev[i]); dev_err(lp3971->dev, "regulator init failed: %d\n", err); goto error; -- cgit v0.10.2 From fa2984d4691c96367d6666694ecc6744135174c6 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Fri, 27 Nov 2009 15:56:34 +0100 Subject: regulator: core.c: Small coding style cleanup (indentation fixup) Signed-off-by: Stefan Roese Cc: Liam Girdwood Cc: Mark Brown Acked-by: Mark Brown Signed-off-by: Liam Girdwood diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 2dab0d9..1af8df2 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -390,7 +390,7 @@ static ssize_t regulator_total_uA_show(struct device *dev, mutex_lock(&rdev->mutex); list_for_each_entry(regulator, &rdev->consumer_list, list) - uA += regulator->uA_load; + uA += regulator->uA_load; mutex_unlock(&rdev->mutex); return sprintf(buf, "%d\n", uA); } @@ -565,7 +565,7 @@ static void drms_uA_update(struct regulator_dev *rdev) /* calc total requested load */ list_for_each_entry(sibling, &rdev->consumer_list, list) - current_uA += sibling->uA_load; + current_uA += sibling->uA_load; /* now get the optimum mode for our new total regulator load */ mode = rdev->desc->ops->get_optimum_mode(rdev, input_uV, @@ -1829,7 +1829,7 @@ int regulator_set_optimum_mode(struct regulator *regulator, int uA_load) /* calc total requested load for this regulator */ list_for_each_entry(consumer, &rdev->consumer_list, list) - total_uA_load += consumer->uA_load; + total_uA_load += consumer->uA_load; mode = rdev->desc->ops->get_optimum_mode(rdev, input_uV, output_uV, @@ -1898,9 +1898,9 @@ static void _notifier_call_chain(struct regulator_dev *rdev, /* now notify regulator we supply */ list_for_each_entry(_rdev, &rdev->supply_list, slist) { - mutex_lock(&_rdev->mutex); - _notifier_call_chain(_rdev, event, data); - mutex_unlock(&_rdev->mutex); + mutex_lock(&_rdev->mutex); + _notifier_call_chain(_rdev, event, data); + mutex_unlock(&_rdev->mutex); } } -- cgit v0.10.2 From eb143ac1b9f56ca9c6dc782d795acda1f60c5fd2 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 15 Dec 2009 14:30:01 +0100 Subject: regulator: Fix unbalanced disables/enables in regulator_bulk_{enable,disable} error path Currently it is possible for regulator_bulk_{enable,disable} operations to generate unbalanced regulator_{disable,enable} calls in its error path. In case of an error only those regulators of the bulk operation which actually had been enabled/disabled should get their original state restored. Signed-off-by: Lars-Peter Clausen Acked-by: Mark Brown Signed-off-by: Liam Girdwood diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 1af8df2..686ef27 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1977,7 +1977,7 @@ int regulator_bulk_enable(int num_consumers, err: printk(KERN_ERR "Failed to enable %s: %d\n", consumers[i].supply, ret); - for (i = 0; i < num_consumers; i++) + for (--i; i >= 0; --i) regulator_disable(consumers[i].consumer); return ret; @@ -2013,7 +2013,7 @@ int regulator_bulk_disable(int num_consumers, err: printk(KERN_ERR "Failed to disable %s: %d\n", consumers[i].supply, ret); - for (i = 0; i < num_consumers; i++) + for (--i; i >= 0; --i) regulator_enable(consumers[i].consumer); return ret; -- cgit v0.10.2 From 735eb93ae267f0b5638045b86dbc1e0b7019e3e8 Mon Sep 17 00:00:00 2001 From: Alberto Panizzo Date: Mon, 14 Dec 2009 18:53:35 +0100 Subject: regulator: mc13783-regulator: correct the probing time. When the mc13783-regulator driver is built in kernel, probing it during the regulator subsystem initialisation result in a fault. That is because regulator subsystem is planned to be initialised very early in the boot process, before the mfd subsystem initialisation. The mc12783-regulator probing process need to access to the mc13783-core functionality to read/write mc13783 registers and so must be called after the mc13783-core driver initialisation. The way to do this is to let the kernel probe the mc13783-regulator driver when mc13783-core register his regulator subdevice. Signed-off-by: Alberto Panizzo Acked-by: Mark Brown Signed-off-by: Liam Girdwood diff --git a/drivers/regulator/mc13783-regulator.c b/drivers/regulator/mc13783-regulator.c index 9f99862..39c4953 100644 --- a/drivers/regulator/mc13783-regulator.c +++ b/drivers/regulator/mc13783-regulator.c @@ -224,12 +224,12 @@ static struct platform_driver mc13783_regulator_driver = { .owner = THIS_MODULE, }, .remove = __devexit_p(mc13783_regulator_remove), + .probe = mc13783_regulator_probe, }; static int __init mc13783_regulator_init(void) { - return platform_driver_probe(&mc13783_regulator_driver, - mc13783_regulator_probe); + return platform_driver_register(&mc13783_regulator_driver); } subsys_initcall(mc13783_regulator_init); -- cgit v0.10.2 From 07fc493f03019b5a98de1a498ab1b235afc394db Mon Sep 17 00:00:00 2001 From: Juha Keski-Saari Date: Wed, 16 Dec 2009 15:27:55 +0200 Subject: twl-regulator: Add all twl4030 regulators to twlreg_info Define all twl4030 regulators in the twlreg_info table, along with appropriate VSEL tables for adjustable regulators Signed-off-by: Juha Keski-Saari Acked-by: Mark Brown Signed-off-by: Liam Girdwood diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c index 7ea1c3a..43d7494 100644 --- a/drivers/regulator/twl-regulator.c +++ b/drivers/regulator/twl-regulator.c @@ -294,6 +294,18 @@ static const u16 VSIM_VSEL_table[] = { static const u16 VDAC_VSEL_table[] = { 1200, 1300, 1800, 1800, }; +static const u16 VDD1_VSEL_table[] = { + 800, 1450, +}; +static const u16 VDD2_VSEL_table[] = { + 800, 1450, 1500, +}; +static const u16 VIO_VSEL_table[] = { + 1800, 1850, +}; +static const u16 VINTANA2_VSEL_table[] = { + 2500, 2750, +}; static const u16 VAUX1_6030_VSEL_table[] = { 1000, 1300, 1800, 2500, 2800, 2900, 3000, 3000, @@ -464,20 +476,16 @@ static struct twlreg_info twl_regs[] = { TWL4030_ADJUSTABLE_LDO(VAUX4, 0x23, 4), TWL4030_ADJUSTABLE_LDO(VMMC1, 0x27, 5), TWL4030_ADJUSTABLE_LDO(VMMC2, 0x2b, 6), - /* TWL4030_ADJUSTABLE_LDO(VPLL1, 0x2f, 7), - */ TWL4030_ADJUSTABLE_LDO(VPLL2, 0x33, 8), TWL4030_ADJUSTABLE_LDO(VSIM, 0x37, 9), TWL4030_ADJUSTABLE_LDO(VDAC, 0x3b, 10), - /* - TWL4030_ADJUSTABLE_LDO(VINTANA1, 0x3f, 11), + TWL4030_FIXED_LDO(VINTANA1, 0x3f, 11), TWL4030_ADJUSTABLE_LDO(VINTANA2, 0x43, 12), - TWL4030_ADJUSTABLE_LDO(VINTDIG, 0x47, 13), - TWL4030_SMPS(VIO, 0x4b, 14), - TWL4030_SMPS(VDD1, 0x55, 15), - TWL4030_SMPS(VDD2, 0x63, 16), - */ + TWL4030_FIXED_LDO(VINTDIG, 0x47, 13), + TWL4030_ADJUSTABLE_LDO(VIO, 0x4b, 14), + TWL4030_ADJUSTABLE_LDO(VDD1, 0x55, 15), + TWL4030_ADJUSTABLE_LDO(VDD2, 0x63, 16), TWL4030_FIXED_LDO(VUSB1V5, 0x71, 1500, 17), TWL4030_FIXED_LDO(VUSB1V8, 0x74, 1800, 18), TWL4030_FIXED_LDO(VUSB3V1, 0x77, 3100, 19), -- cgit v0.10.2 From 205e5cd3d933a9ea7b75630355c8f8ec5ef16f6c Mon Sep 17 00:00:00 2001 From: Juha Keski-Saari Date: Wed, 16 Dec 2009 15:27:56 +0200 Subject: twl-regulator: Define critical regulators as always_on Defines VIO, VDD1, VDD2, VPLL1 and VINT* regulators as always_on by default since they are critical to TWL and its master's functionality and should be on in all cases where RegFW is used Signed-off-by: Juha Keski-Saari Acked-by: Mark Brown Signed-off-by: Liam Girdwood diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c index 43d7494..aadf4cf 100644 --- a/drivers/regulator/twl-regulator.c +++ b/drivers/regulator/twl-regulator.c @@ -533,6 +533,19 @@ static int twlreg_probe(struct platform_device *pdev) c->valid_ops_mask &= REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS; + switch (pdev->id) { + case TWL4030_REG_VIO: + case TWL4030_REG_VDD1: + case TWL4030_REG_VDD2: + case TWL4030_REG_VPLL1: + case TWL4030_REG_VINTANA1: + case TWL4030_REG_VINTANA2: + case TWL4030_REG_VINTDIG: + c->always_on = true; + break; + default: + break; + } rdev = regulator_register(&info->desc, &pdev->dev, initdata, info); if (IS_ERR(rdev)) { -- cgit v0.10.2 From 045f972f2c254070652a59958591cac650e8684e Mon Sep 17 00:00:00 2001 From: Juha Keski-Saari Date: Wed, 16 Dec 2009 14:49:52 +0200 Subject: twl-regulator: Add turnon-delay and REMAP config to twlreg_info struct This change includes regulator turnon delay values and the REMAP reset configuration to the twlreg_info struct, since they are basic attributes of every TWL regulator Signed-off-by: Juha Keski-Saari Acked-by: Mark Brown Signed-off-by: Liam Girdwood diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c index aadf4cf..3df0226 100644 --- a/drivers/regulator/twl-regulator.c +++ b/drivers/regulator/twl-regulator.c @@ -40,6 +40,12 @@ struct twlreg_info { u8 table_len; const u16 *table; + /* regulator specific turn-on delay */ + u16 delay; + + /* State REMAP default configuration */ + u8 remap; + /* chip constraints on regulator behavior */ u16 min_mV; @@ -426,20 +432,30 @@ static struct regulator_ops twlfixed_ops = { /*----------------------------------------------------------------------*/ -#define TWL4030_ADJUSTABLE_LDO(label, offset, num) \ - TWL_ADJUSTABLE_LDO(label, offset, num, TWL4030) -#define TWL4030_FIXED_LDO(label, offset, mVolts, num) \ - TWL_FIXED_LDO(label, offset, mVolts, num, TWL4030) -#define TWL6030_ADJUSTABLE_LDO(label, offset, num) \ - TWL_ADJUSTABLE_LDO(label, offset, num, TWL6030) -#define TWL6030_FIXED_LDO(label, offset, mVolts, num) \ - TWL_FIXED_LDO(label, offset, mVolts, num, TWL6030) - -#define TWL_ADJUSTABLE_LDO(label, offset, num, family) { \ +#define TWL4030_ADJUSTABLE_LDO(label, offset, num, turnon_delay, remap_conf) \ + TWL_ADJUSTABLE_LDO(label, offset, num, turnon_delay, \ + remap_conf, TWL4030) +#define TWL4030_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ + remap_conf) \ + TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ + remap_conf, TWL4030) +#define TWL6030_ADJUSTABLE_LDO(label, offset, num, turnon_delay, \ + remap_conf) \ + TWL_ADJUSTABLE_LDO(label, offset, num, turnon_delay, \ + remap_conf, TWL6030) +#define TWL6030_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ + remap_conf) \ + TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ + remap_conf, TWL6030) + +#define TWL_ADJUSTABLE_LDO(label, offset, num, turnon_delay, remap_conf, \ + family) { \ .base = offset, \ .id = num, \ .table_len = ARRAY_SIZE(label##_VSEL_table), \ .table = label##_VSEL_table, \ + .delay = turnon_delay, \ + .remap = remap_conf, \ .desc = { \ .name = #label, \ .id = family##_REG_##label, \ @@ -450,10 +466,13 @@ static struct regulator_ops twlfixed_ops = { }, \ } -#define TWL_FIXED_LDO(label, offset, mVolts, num, family) { \ +#define TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, remap_conf, \ + family) { \ .base = offset, \ .id = num, \ .min_mV = mVolts, \ + .delay = turnon_delay, \ + .remap = remap_conf, \ .desc = { \ .name = #label, \ .id = family##_REG_##label, \ @@ -469,39 +488,41 @@ static struct regulator_ops twlfixed_ops = { * software control over them after boot. */ static struct twlreg_info twl_regs[] = { - TWL4030_ADJUSTABLE_LDO(VAUX1, 0x17, 1), - TWL4030_ADJUSTABLE_LDO(VAUX2_4030, 0x1b, 2), - TWL4030_ADJUSTABLE_LDO(VAUX2, 0x1b, 2), - TWL4030_ADJUSTABLE_LDO(VAUX3, 0x1f, 3), - TWL4030_ADJUSTABLE_LDO(VAUX4, 0x23, 4), - TWL4030_ADJUSTABLE_LDO(VMMC1, 0x27, 5), - TWL4030_ADJUSTABLE_LDO(VMMC2, 0x2b, 6), - TWL4030_ADJUSTABLE_LDO(VPLL1, 0x2f, 7), - TWL4030_ADJUSTABLE_LDO(VPLL2, 0x33, 8), - TWL4030_ADJUSTABLE_LDO(VSIM, 0x37, 9), - TWL4030_ADJUSTABLE_LDO(VDAC, 0x3b, 10), - TWL4030_FIXED_LDO(VINTANA1, 0x3f, 11), - TWL4030_ADJUSTABLE_LDO(VINTANA2, 0x43, 12), - TWL4030_FIXED_LDO(VINTDIG, 0x47, 13), - TWL4030_ADJUSTABLE_LDO(VIO, 0x4b, 14), - TWL4030_ADJUSTABLE_LDO(VDD1, 0x55, 15), - TWL4030_ADJUSTABLE_LDO(VDD2, 0x63, 16), - TWL4030_FIXED_LDO(VUSB1V5, 0x71, 1500, 17), - TWL4030_FIXED_LDO(VUSB1V8, 0x74, 1800, 18), - TWL4030_FIXED_LDO(VUSB3V1, 0x77, 3100, 19), + TWL4030_ADJUSTABLE_LDO(VAUX1, 0x17, 1, 100, 0x08), + TWL4030_ADJUSTABLE_LDO(VAUX2_4030, 0x1b, 2, 100, 0x08), + TWL4030_ADJUSTABLE_LDO(VAUX2, 0x1b, 2, 100, 0x08), + TWL4030_ADJUSTABLE_LDO(VAUX3, 0x1f, 3, 100, 0x08), + TWL4030_ADJUSTABLE_LDO(VAUX4, 0x23, 4, 100, 0x08), + TWL4030_ADJUSTABLE_LDO(VMMC1, 0x27, 5, 100, 0x08), + TWL4030_ADJUSTABLE_LDO(VMMC2, 0x2b, 6, 100, 0x08), + TWL4030_ADJUSTABLE_LDO(VPLL1, 0x2f, 7, 100, 0x00), + TWL4030_ADJUSTABLE_LDO(VPLL2, 0x33, 8, 100, 0x08), + TWL4030_ADJUSTABLE_LDO(VSIM, 0x37, 9, 100, 0x00), + TWL4030_ADJUSTABLE_LDO(VDAC, 0x3b, 10, 100, 0x08), + TWL4030_FIXED_LDO(VINTANA1, 0x3f, 1500, 11, 100, 0x08), + TWL4030_ADJUSTABLE_LDO(VINTANA2, 0x43, 12, 100, 0x08), + TWL4030_FIXED_LDO(VINTDIG, 0x47, 1500, 13, 100, 0x08), + TWL4030_ADJUSTABLE_LDO(VIO, 0x4b, 14, 1000, 0x08), + TWL4030_ADJUSTABLE_LDO(VDD1, 0x55, 15, 1000, 0x08), + TWL4030_ADJUSTABLE_LDO(VDD2, 0x63, 16, 1000, 0x08), + TWL4030_FIXED_LDO(VUSB1V5, 0x71, 1500, 17, 100, 0x08), + TWL4030_FIXED_LDO(VUSB1V8, 0x74, 1800, 18, 100, 0x08), + TWL4030_FIXED_LDO(VUSB3V1, 0x77, 3100, 19, 150, 0x08), /* VUSBCP is managed *only* by the USB subchip */ /* 6030 REG with base as PMC Slave Misc : 0x0030 */ - TWL6030_ADJUSTABLE_LDO(VAUX1_6030, 0x54, 1), - TWL6030_ADJUSTABLE_LDO(VAUX2_6030, 0x58, 2), - TWL6030_ADJUSTABLE_LDO(VAUX3_6030, 0x5c, 3), - TWL6030_ADJUSTABLE_LDO(VMMC, 0x68, 4), - TWL6030_ADJUSTABLE_LDO(VPP, 0x6c, 5), - TWL6030_ADJUSTABLE_LDO(VUSIM, 0x74, 7), - TWL6030_FIXED_LDO(VANA, 0x50, 2100, 15), - TWL6030_FIXED_LDO(VCXIO, 0x60, 1800, 16), - TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 17), - TWL6030_FIXED_LDO(VUSB, 0x70, 3300, 18) + /* Turnon-delay and remap configuration values for 6030 are not + verified since the specification is not public */ + TWL6030_ADJUSTABLE_LDO(VAUX1_6030, 0x54, 1, 0, 0x08), + TWL6030_ADJUSTABLE_LDO(VAUX2_6030, 0x58, 2, 0, 0x08), + TWL6030_ADJUSTABLE_LDO(VAUX3_6030, 0x5c, 3, 0, 0x08), + TWL6030_ADJUSTABLE_LDO(VMMC, 0x68, 4, 0, 0x08), + TWL6030_ADJUSTABLE_LDO(VPP, 0x6c, 5, 0, 0x08), + TWL6030_ADJUSTABLE_LDO(VUSIM, 0x74, 7, 0, 0x08), + TWL6030_FIXED_LDO(VANA, 0x50, 2100, 15, 0, 0x08), + TWL6030_FIXED_LDO(VCXIO, 0x60, 1800, 16, 0, 0x08), + TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 17, 0, 0x08), + TWL6030_FIXED_LDO(VUSB, 0x70, 3300, 18, 0, 0x08) }; static int twlreg_probe(struct platform_device *pdev) -- cgit v0.10.2 From 30010fa52c7bd466b441e3f9020ba4cf6154fa41 Mon Sep 17 00:00:00 2001 From: Juha Keski-Saari Date: Wed, 16 Dec 2009 15:27:58 +0200 Subject: twl-regulator: Restore REMAP configuration in regulator probe This change ensures the regulator REMAP register configuration is in a known state so state transitions will function as intended regardless of possible bootloader effects on it Signed-off-by: Juha Keski-Saari Acked-by: Mark Brown Signed-off-by: Liam Girdwood diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c index 3df0226..6c464b8 100644 --- a/drivers/regulator/twl-regulator.c +++ b/drivers/regulator/twl-regulator.c @@ -576,6 +576,9 @@ static int twlreg_probe(struct platform_device *pdev) } platform_set_drvdata(pdev, rdev); + twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_REMAP, + info->remap); + /* NOTE: many regulators support short-circuit IRQs (presentable * as REGULATOR_OVER_CURRENT notifications?) configured via: * - SC_CONFIG -- cgit v0.10.2 From 53b8a9d92a713fa82316bf418dcc19d6da32ca05 Mon Sep 17 00:00:00 2001 From: Juha Keski-Saari Date: Wed, 16 Dec 2009 14:55:26 +0200 Subject: twl-regulator: Add turnon delay to reg_enable This change implements a basic turnon delay in the regulator enable function to make it less probable that reg_enable returns before the regulator output is at target level Signed-off-by: Juha Keski-Saari Acked-by: Mark Brown Signed-off-by: Liam Girdwood diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c index 6c464b8..9bcea4d 100644 --- a/drivers/regulator/twl-regulator.c +++ b/drivers/regulator/twl-regulator.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -134,6 +135,7 @@ static int twlreg_enable(struct regulator_dev *rdev) { struct twlreg_info *info = rdev_get_drvdata(rdev); int grp; + int ret; grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP); if (grp < 0) @@ -144,7 +146,11 @@ static int twlreg_enable(struct regulator_dev *rdev) else grp |= P1_GRP_6030; - return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp); + ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp); + + udelay(info->delay); + + return ret; } static int twlreg_disable(struct regulator_dev *rdev) -- cgit v0.10.2 From cf9836f4ddd1a08e88fe05e06f21313c609d3d55 Mon Sep 17 00:00:00 2001 From: Juha Keski-Saari Date: Wed, 16 Dec 2009 15:28:00 +0200 Subject: twl-regulator: Fix reg_disable functionality for 4030 and 6030 This change makes sure all regulator group assignments are cleared on disable call Signed-off-by: Juha Keski-Saari Acked-by: Mark Brown Signed-off-by: Liam Girdwood diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c index 9bcea4d..7e67485 100644 --- a/drivers/regulator/twl-regulator.c +++ b/drivers/regulator/twl-regulator.c @@ -163,9 +163,9 @@ static int twlreg_disable(struct regulator_dev *rdev) return grp; if (twl_class_is_4030()) - grp &= ~P1_GRP_4030; + grp &= ~(P1_GRP_4030 | P2_GRP_4030 | P3_GRP_4030); else - grp &= ~P1_GRP_6030; + grp &= ~(P1_GRP_6030 | P2_GRP_6030 | P3_GRP_6030); return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp); } -- cgit v0.10.2 From 6f17c65240e35ae99319c659c74d54100a832f45 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Tue, 15 Dec 2009 20:07:31 +0100 Subject: regulator: wm831x_reg_read() failure unnoticed in wm831x_aldo_get_mode() ret should be signed to notice a failure in wm831x_reg_read(). Signed-off-by: Roel Kluin Acked-by: Mark Brown Signed-off-by: Liam Girdwood diff --git a/drivers/regulator/wm831x-ldo.c b/drivers/regulator/wm831x-ldo.c index 902db56..61e02ac 100644 --- a/drivers/regulator/wm831x-ldo.c +++ b/drivers/regulator/wm831x-ldo.c @@ -470,7 +470,7 @@ static unsigned int wm831x_aldo_get_mode(struct regulator_dev *rdev) struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); struct wm831x *wm831x = ldo->wm831x; int on_reg = ldo->base + WM831X_LDO_ON_CONTROL; - unsigned int ret; + int ret; ret = wm831x_reg_read(wm831x, on_reg); if (ret < 0) -- cgit v0.10.2 From 11ab3f3d3c2474d3ed6912443de74c3972bd6f23 Mon Sep 17 00:00:00 2001 From: Chen Liqin Date: Wed, 18 Nov 2009 13:22:33 +0800 Subject: score: add flush_dcahce_page and PG_dcache_dirty define Signed-off-by: Cui Bixiong Signed-off-by: Chen Liqin modified: arch/score/include/asm/cacheflush.h modified: arch/score/mm/cache.c diff --git a/arch/score/include/asm/cacheflush.h b/arch/score/include/asm/cacheflush.h index caaba24..1d545d0 100644 --- a/arch/score/include/asm/cacheflush.h +++ b/arch/score/include/asm/cacheflush.h @@ -14,10 +14,12 @@ extern void flush_cache_sigtramp(unsigned long addr); extern void flush_icache_all(void); extern void flush_icache_range(unsigned long start, unsigned long end); extern void flush_dcache_range(unsigned long start, unsigned long end); +extern void flush_dcache_page(struct page *page); + +#define PG_dcache_dirty PG_arch_1 #define flush_cache_dup_mm(mm) do {} while (0) #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0 -#define flush_dcache_page(page) do {} while (0) #define flush_dcache_mmap_lock(mapping) do {} while (0) #define flush_dcache_mmap_unlock(mapping) do {} while (0) #define flush_cache_vmap(start, end) do {} while (0) diff --git a/arch/score/mm/cache.c b/arch/score/mm/cache.c index dbac9d9..b25e957 100644 --- a/arch/score/mm/cache.c +++ b/arch/score/mm/cache.c @@ -29,6 +29,7 @@ #include #include #include +#include #include @@ -51,6 +52,27 @@ static void flush_data_cache_page(unsigned long addr) } } +void flush_dcache_page(struct page *page) +{ + struct address_space *mapping = page_mapping(page); + unsigned long addr; + + if (PageHighMem(page)) + return; + if (mapping && !mapping_mapped(mapping)) { + set_bit(PG_dcache_dirty, &(page)->flags); + return; + } + + /* + * We could delay the flush for the !page_mapping case too. But that + * case is for exec env/arg pages and those are %99 certainly going to + * get faulted into the tlb (and thus flushed) anyways. + */ + addr = (unsigned long) page_address(page); + flush_data_cache_page(addr); +} + /* called by update_mmu_cache. */ void __update_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte) @@ -63,11 +85,11 @@ void __update_cache(struct vm_area_struct *vma, unsigned long address, if (unlikely(!pfn_valid(pfn))) return; page = pfn_to_page(pfn); - if (page_mapping(page) && test_bit(PG_arch_1, &page->flags)) { + if (page_mapping(page) && test_bit(PG_dcache_dirty, &(page)->flags)) { addr = (unsigned long) page_address(page); if (exec) flush_data_cache_page(addr); - clear_bit(PG_arch_1, &page->flags); + clear_bit(PG_dcache_dirty, &(page)->flags); } } -- cgit v0.10.2 From 202b864ad5aa34989609a3073acbe7a04795b265 Mon Sep 17 00:00:00 2001 From: Chen Liqin Date: Wed, 18 Nov 2009 13:28:13 +0800 Subject: score: fixed pfn_valid define. Signed-off-by: Cui Bixiong Signed-off-by: Chen Liqin modified: arch/score/include/asm/page.h modified: arch/score/kernel/setup.c modified: arch/score/mm/init.c diff --git a/arch/score/include/asm/page.h b/arch/score/include/asm/page.h index d92a5a2..1e9ade8 100644 --- a/arch/score/include/asm/page.h +++ b/arch/score/include/asm/page.h @@ -74,7 +74,7 @@ extern unsigned long max_pfn; #define page_to_bus(page) (page_to_phys(page)) #define phys_to_page(paddr) (pfn_to_page(phys_to_pfn(paddr))) -#define pfn_valid(pfn) ((pfn) >= min_low_pfn && (pfn) < max_mapnr) +#define pfn_valid(pfn) (((pfn) >= min_low_pfn) && ((pfn) < max_low_pfn)) #define ARCH_PFN_OFFSET (PAGE_OFFSET >> PAGE_SHIFT) diff --git a/arch/score/kernel/setup.c b/arch/score/kernel/setup.c index 6a2503c..6f898c0 100644 --- a/arch/score/kernel/setup.c +++ b/arch/score/kernel/setup.c @@ -49,6 +49,7 @@ static void __init bootmem_init(void) min_low_pfn = PFN_UP(MEMORY_START); max_low_pfn = PFN_UP(MEMORY_START + MEMORY_SIZE); + max_mapnr = max_low_pfn - min_low_pfn; /* Initialize the boot-time allocator with low memory only. */ bootmap_size = init_bootmem_node(NODE_DATA(0), start_pfn, diff --git a/arch/score/mm/init.c b/arch/score/mm/init.c index 4e3dcd0..8c15b2c 100644 --- a/arch/score/mm/init.c +++ b/arch/score/mm/init.c @@ -83,7 +83,6 @@ void __init mem_init(void) unsigned long codesize, reservedpages, datasize, initsize; unsigned long tmp, ram = 0; - max_mapnr = max_low_pfn; high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT); totalram_pages += free_all_bootmem(); totalram_pages -= setup_zero_page(); /* Setup zeroed pages. */ @@ -101,10 +100,6 @@ void __init mem_init(void) datasize = (unsigned long) &_edata - (unsigned long) &_etext; initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin; - kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT); - kclist_add(&kcore_vmalloc, (void *) VMALLOC_START, - VMALLOC_END - VMALLOC_START); - printk(KERN_INFO "Memory: %luk/%luk available (%ldk kernel code, " "%ldk reserved, %ldk data, %ldk init, %ldk highmem)\n", (unsigned long) nr_free_pages() << (PAGE_SHIFT-10), -- cgit v0.10.2 From ef8355c3a3c7a4d7f1d49881937337ea78ed306a Mon Sep 17 00:00:00 2001 From: Chen Liqin Date: Thu, 17 Dec 2009 18:31:23 +0800 Subject: score: include asm-generic/param.h in asm/delay.h. Signed-off-by: Cui Bixiong Signed-off-by: Chen Liqin diff --git a/arch/score/include/asm/delay.h b/arch/score/include/asm/delay.h index 6726ec1..529e494 100644 --- a/arch/score/include/asm/delay.h +++ b/arch/score/include/asm/delay.h @@ -1,6 +1,8 @@ #ifndef _ASM_SCORE_DELAY_H #define _ASM_SCORE_DELAY_H +#include + static inline void __delay(unsigned long loops) { /* 3 cycles per loop. */ -- cgit v0.10.2 From d3aad6399a240300534d83ffdacfc40e6ed4fa73 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 11 Dec 2009 18:13:40 -0500 Subject: leds: leds-cobalt-raq.c - use resource_size() Use resource_size() for ioremap. Signed-off-by: H Hartley Sweeten Signed-off-by: Richard Purdie diff --git a/drivers/leds/leds-cobalt-raq.c b/drivers/leds/leds-cobalt-raq.c index defc212..438d483 100644 --- a/drivers/leds/leds-cobalt-raq.c +++ b/drivers/leds/leds-cobalt-raq.c @@ -84,7 +84,7 @@ static int __devinit cobalt_raq_led_probe(struct platform_device *pdev) if (!res) return -EBUSY; - led_port = ioremap(res->start, res->end - res->start + 1); + led_port = ioremap(res->start, resource_size(res)); if (!led_port) return -ENOMEM; -- cgit v0.10.2 From 3c0f6e1eddeddd95ed04d4a7f0e55ab0aa99adf9 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 11 Dec 2009 16:50:58 -0500 Subject: leds: leds-cobalt-qube.c: use resource_size() Use resource_size() for ioremap. Signed-off-by: H Hartley Sweeten Signed-off-by: Richard Purdie diff --git a/drivers/leds/leds-cobalt-qube.c b/drivers/leds/leds-cobalt-qube.c index 8816806..de197538 100644 --- a/drivers/leds/leds-cobalt-qube.c +++ b/drivers/leds/leds-cobalt-qube.c @@ -43,7 +43,7 @@ static int __devinit cobalt_qube_led_probe(struct platform_device *pdev) if (!res) return -EBUSY; - led_port = ioremap(res->start, res->end - res->start + 1); + led_port = ioremap(res->start, resource_size(res)); if (!led_port) return -ENOMEM; -- cgit v0.10.2 From 5b0582ea427b59bf4e70c892aab0b0ba8fbe2306 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Mon, 7 Dec 2009 14:35:32 +0100 Subject: backlight: PTR_ERR return of wrong pointer in cr_backlight_probe() Return the PTR_ERR of the correct pointer. Signed-off-by: Roel Kluin Signed-off-by: Richard Purdie diff --git a/drivers/video/backlight/cr_bllcd.c b/drivers/video/backlight/cr_bllcd.c index 2914bf1..da86db4 100644 --- a/drivers/video/backlight/cr_bllcd.c +++ b/drivers/video/backlight/cr_bllcd.c @@ -201,7 +201,7 @@ static int cr_backlight_probe(struct platform_device *pdev) if (IS_ERR(ldp)) { backlight_device_unregister(bdp); pci_dev_put(lpc_dev); - return PTR_ERR(bdp); + return PTR_ERR(ldp); } pci_read_config_dword(lpc_dev, CRVML_REG_GPIOBAR, -- cgit v0.10.2 From 2fbe74b90bafebce615466b4c20f96b0465df1ae Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Wed, 16 Dec 2009 16:54:43 +0100 Subject: sound/oss/pss: Fix test of unsigned in pss_reset_dsp() and pss_download_boot() limit and jiffies are unsigned so the test did not work. Signed-off-by: Roel Kluin Signed-off-by: Takashi Iwai diff --git a/sound/oss/pss.c b/sound/oss/pss.c index 83f5ee2..e19dd5d 100644 --- a/sound/oss/pss.c +++ b/sound/oss/pss.c @@ -269,7 +269,7 @@ static int pss_reset_dsp(pss_confdata * devc) unsigned long i, limit = jiffies + HZ/10; outw(0x2000, REG(PSS_CONTROL)); - for (i = 0; i < 32768 && (limit-jiffies >= 0); i++) + for (i = 0; i < 32768 && time_after_eq(limit, jiffies); i++) inw(REG(PSS_CONTROL)); outw(0x0000, REG(PSS_CONTROL)); return 1; @@ -369,11 +369,11 @@ static int pss_download_boot(pss_confdata * devc, unsigned char *block, int size outw(0, REG(PSS_DATA)); limit = jiffies + HZ/10; - for (i = 0; i < 32768 && (limit - jiffies >= 0); i++) + for (i = 0; i < 32768 && time_after_eq(limit, jiffies); i++) val = inw(REG(PSS_STATUS)); limit = jiffies + HZ/10; - for (i = 0; i < 32768 && (limit-jiffies >= 0); i++) + for (i = 0; i < 32768 && time_after_eq(limit, jiffies); i++) { val = inw(REG(PSS_STATUS)); if (val & 0x4000) -- cgit v0.10.2 From f5befbbbf9b7af033c94a1df6acaf79e77a3ceb6 Mon Sep 17 00:00:00 2001 From: Jeff Liu Date: Tue, 15 Dec 2009 14:08:28 +0800 Subject: ocfs2-devel: remove redundant OCFS2_MOUNT_POSIX_ACL check in ocfs2_get_acl_nolock() osb->s_mount_opt has already been checked against OCFS2_MOUNT_POSIX_ACL_CHECK before calling ocfs2_get_acl_nolock() in ocfs2_init_acl() && ocfs2_get_acl(), so remove it. Signed-off-by: Jeff Liu Signed-off-by: Joel Becker diff --git a/fs/ocfs2/acl.c b/fs/ocfs2/acl.c index fbeaec7..200b881 100644 --- a/fs/ocfs2/acl.c +++ b/fs/ocfs2/acl.c @@ -98,15 +98,11 @@ static struct posix_acl *ocfs2_get_acl_nolock(struct inode *inode, int type, struct buffer_head *di_bh) { - struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); int name_index; char *value = NULL; struct posix_acl *acl; int retval; - if (!(osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL)) - return NULL; - switch (type) { case ACL_TYPE_ACCESS: name_index = OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS; -- cgit v0.10.2 From ebb83eeb6469bedda83b4dc6f23ddf93eb32b347 Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Thu, 17 Dec 2009 12:23:00 +0100 Subject: ALSA: hda - More ALC663 fixes and support of compatible chips 1. Add more ASUS NB model. 2. Fixed alc663_m51va_setup M51VA has Digital Mic that NID is 0x12. The record source index is 0x9 for ALC663. So, to modify the alc663_m51va_setup function to index 0x9 and add analog Mic aupport function alc663_mode1_setup. 3. Add ASUS mode7 and mode8 modules for ALC663 Signed-off-by: Kailang Yang Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index c9e8607..287bb60 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -131,8 +131,8 @@ enum { enum { ALC269_BASIC, ALC269_QUANTA_FL1, - ALC269_ASUS_EEEPC_P703, - ALC269_ASUS_EEEPC_P901, + ALC269_ASUS_AMIC, + ALC269_ASUS_DMIC, ALC269_FUJITSU, ALC269_LIFEBOOK, ALC269_AUTO, @@ -188,6 +188,8 @@ enum { ALC663_ASUS_MODE4, ALC663_ASUS_MODE5, ALC663_ASUS_MODE6, + ALC663_ASUS_MODE7, + ALC663_ASUS_MODE8, ALC272_DELL, ALC272_DELL_ZM1, ALC272_SAMSUNG_NC10, @@ -13232,10 +13234,12 @@ static struct hda_verb alc269_eeepc_amic_init_verbs[] = { /* toggle speaker-output according to the hp-jack state */ static void alc269_speaker_automute(struct hda_codec *codec) { + struct alc_spec *spec = codec->spec; + unsigned int nid = spec->autocfg.hp_pins[0]; unsigned int present; unsigned char bits; - present = snd_hda_jack_detect(codec, 0x15); + present = snd_hda_jack_detect(codec, nid); bits = present ? AMP_IN_MUTE(0) : 0; snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, AMP_IN_MUTE(0), bits); @@ -13460,8 +13464,8 @@ static void alc269_auto_init(struct hda_codec *codec) static const char *alc269_models[ALC269_MODEL_LAST] = { [ALC269_BASIC] = "basic", [ALC269_QUANTA_FL1] = "quanta", - [ALC269_ASUS_EEEPC_P703] = "eeepc-p703", - [ALC269_ASUS_EEEPC_P901] = "eeepc-p901", + [ALC269_ASUS_AMIC] = "asus-amic", + [ALC269_ASUS_DMIC] = "asus-dmic", [ALC269_FUJITSU] = "fujitsu", [ALC269_LIFEBOOK] = "lifebook", [ALC269_AUTO] = "auto", @@ -13470,18 +13474,41 @@ static const char *alc269_models[ALC269_MODEL_LAST] = { static struct snd_pci_quirk alc269_cfg_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1), SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", - ALC269_ASUS_EEEPC_P703), - SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_ASUS_EEEPC_P703), - SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_ASUS_EEEPC_P703), - SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_ASUS_EEEPC_P703), - SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_ASUS_EEEPC_P703), - SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_ASUS_EEEPC_P703), - SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_ASUS_EEEPC_P703), + ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80JT", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82Jv", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_ASUS_DMIC), + SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_ASUS_AMIC), SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901", - ALC269_ASUS_EEEPC_P901), + ALC269_ASUS_DMIC), SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101", - ALC269_ASUS_EEEPC_P901), - SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_ASUS_EEEPC_P901), + ALC269_ASUS_DMIC), + SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_ASUS_DMIC), + SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_ASUS_DMIC), SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU), SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK), {} @@ -13511,7 +13538,7 @@ static struct alc_config_preset alc269_presets[] = { .setup = alc269_quanta_fl1_setup, .init_hook = alc269_quanta_fl1_init_hook, }, - [ALC269_ASUS_EEEPC_P703] = { + [ALC269_ASUS_AMIC] = { .mixers = { alc269_eeepc_mixer }, .cap_mixer = alc269_epc_capture_mixer, .init_verbs = { alc269_init_verbs, @@ -13525,7 +13552,7 @@ static struct alc_config_preset alc269_presets[] = { .setup = alc269_eeepc_amic_setup, .init_hook = alc269_eeepc_inithook, }, - [ALC269_ASUS_EEEPC_P901] = { + [ALC269_ASUS_DMIC] = { .mixers = { alc269_eeepc_mixer }, .cap_mixer = alc269_epc_capture_mixer, .init_verbs = { alc269_init_verbs, @@ -16160,6 +16187,52 @@ static struct snd_kcontrol_new alc663_g50v_mixer[] = { { } /* end */ }; +static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = { + .ops = &snd_hda_bind_sw, + .values = { + HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), + HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), + HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT), + HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), + HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), + 0 + }, +}; + +static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = { + .ops = &snd_hda_bind_sw, + .values = { + HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), + HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT), + 0 + }, +}; + +static struct snd_kcontrol_new alc663_mode7_mixer[] = { + HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch), + HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol), + HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch), + HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + { } /* end */ +}; + +static struct snd_kcontrol_new alc663_mode8_mixer[] = { + HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch), + HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol), + HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch), + HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), + { } /* end */ +}; + + static struct snd_kcontrol_new alc662_chmode_mixer[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, @@ -16447,6 +16520,45 @@ static struct hda_verb alc272_dell_init_verbs[] = { {} }; +static struct hda_verb alc663_mode7_init_verbs[] = { + {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, + {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, + {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, + {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, + {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, + {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, + {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, + {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, + {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, + {} +}; + +static struct hda_verb alc663_mode8_init_verbs[] = { + {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, + {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, + {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, + {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, + {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, + {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, + {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, + {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, + {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, + {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, + {} +}; + static struct snd_kcontrol_new alc662_auto_capture_mixer[] = { HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), @@ -16626,6 +16738,54 @@ static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec) } } +static void alc663_two_hp_m7_speaker_automute(struct hda_codec *codec) +{ + unsigned int present1, present2; + + present1 = snd_hda_codec_read(codec, 0x1b, 0, + AC_VERB_GET_PIN_SENSE, 0) + & AC_PINSENSE_PRESENCE; + present2 = snd_hda_codec_read(codec, 0x21, 0, + AC_VERB_GET_PIN_SENSE, 0) + & AC_PINSENSE_PRESENCE; + + if (present1 || present2) { + snd_hda_codec_write_cache(codec, 0x14, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, 0); + snd_hda_codec_write_cache(codec, 0x17, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, 0); + } else { + snd_hda_codec_write_cache(codec, 0x14, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); + snd_hda_codec_write_cache(codec, 0x17, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); + } +} + +static void alc663_two_hp_m8_speaker_automute(struct hda_codec *codec) +{ + unsigned int present1, present2; + + present1 = snd_hda_codec_read(codec, 0x21, 0, + AC_VERB_GET_PIN_SENSE, 0) + & AC_PINSENSE_PRESENCE; + present2 = snd_hda_codec_read(codec, 0x15, 0, + AC_VERB_GET_PIN_SENSE, 0) + & AC_PINSENSE_PRESENCE; + + if (present1 || present2) { + snd_hda_codec_write_cache(codec, 0x14, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, 0); + snd_hda_codec_write_cache(codec, 0x17, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, 0); + } else { + snd_hda_codec_write_cache(codec, 0x14, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); + snd_hda_codec_write_cache(codec, 0x17, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); + } +} + static void alc663_m51va_unsol_event(struct hda_codec *codec, unsigned int res) { @@ -16645,7 +16805,7 @@ static void alc663_m51va_setup(struct hda_codec *codec) spec->ext_mic.pin = 0x18; spec->ext_mic.mux_idx = 0; spec->int_mic.pin = 0x12; - spec->int_mic.mux_idx = 1; + spec->int_mic.mux_idx = 9; spec->auto_mic = 1; } @@ -16657,7 +16817,17 @@ static void alc663_m51va_inithook(struct hda_codec *codec) /* ***************** Mode1 ******************************/ #define alc663_mode1_unsol_event alc663_m51va_unsol_event -#define alc663_mode1_setup alc663_m51va_setup + +static void alc663_mode1_setup(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + spec->ext_mic.pin = 0x18; + spec->ext_mic.mux_idx = 0; + spec->int_mic.pin = 0x19; + spec->int_mic.mux_idx = 1; + spec->auto_mic = 1; +} + #define alc663_mode1_inithook alc663_m51va_inithook /* ***************** Mode2 ******************************/ @@ -16674,7 +16844,7 @@ static void alc662_mode2_unsol_event(struct hda_codec *codec, } } -#define alc662_mode2_setup alc663_m51va_setup +#define alc662_mode2_setup alc663_mode1_setup static void alc662_mode2_inithook(struct hda_codec *codec) { @@ -16695,7 +16865,7 @@ static void alc663_mode3_unsol_event(struct hda_codec *codec, } } -#define alc663_mode3_setup alc663_m51va_setup +#define alc663_mode3_setup alc663_mode1_setup static void alc663_mode3_inithook(struct hda_codec *codec) { @@ -16716,7 +16886,7 @@ static void alc663_mode4_unsol_event(struct hda_codec *codec, } } -#define alc663_mode4_setup alc663_m51va_setup +#define alc663_mode4_setup alc663_mode1_setup static void alc663_mode4_inithook(struct hda_codec *codec) { @@ -16737,7 +16907,7 @@ static void alc663_mode5_unsol_event(struct hda_codec *codec, } } -#define alc663_mode5_setup alc663_m51va_setup +#define alc663_mode5_setup alc663_mode1_setup static void alc663_mode5_inithook(struct hda_codec *codec) { @@ -16758,7 +16928,7 @@ static void alc663_mode6_unsol_event(struct hda_codec *codec, } } -#define alc663_mode6_setup alc663_m51va_setup +#define alc663_mode6_setup alc663_mode1_setup static void alc663_mode6_inithook(struct hda_codec *codec) { @@ -16766,6 +16936,50 @@ static void alc663_mode6_inithook(struct hda_codec *codec) alc_mic_automute(codec); } +/* ***************** Mode7 ******************************/ +static void alc663_mode7_unsol_event(struct hda_codec *codec, + unsigned int res) +{ + switch (res >> 26) { + case ALC880_HP_EVENT: + alc663_two_hp_m7_speaker_automute(codec); + break; + case ALC880_MIC_EVENT: + alc_mic_automute(codec); + break; + } +} + +#define alc663_mode7_setup alc663_mode1_setup + +static void alc663_mode7_inithook(struct hda_codec *codec) +{ + alc663_two_hp_m7_speaker_automute(codec); + alc_mic_automute(codec); +} + +/* ***************** Mode8 ******************************/ +static void alc663_mode8_unsol_event(struct hda_codec *codec, + unsigned int res) +{ + switch (res >> 26) { + case ALC880_HP_EVENT: + alc663_two_hp_m8_speaker_automute(codec); + break; + case ALC880_MIC_EVENT: + alc_mic_automute(codec); + break; + } +} + +#define alc663_mode8_setup alc663_m51va_setup + +static void alc663_mode8_inithook(struct hda_codec *codec) +{ + alc663_two_hp_m8_speaker_automute(codec); + alc_mic_automute(codec); +} + static void alc663_g71v_hp_automute(struct hda_codec *codec) { unsigned int present; @@ -16900,6 +17114,8 @@ static const char *alc662_models[ALC662_MODEL_LAST] = { [ALC663_ASUS_MODE4] = "asus-mode4", [ALC663_ASUS_MODE5] = "asus-mode5", [ALC663_ASUS_MODE6] = "asus-mode6", + [ALC663_ASUS_MODE7] = "asus-mode7", + [ALC663_ASUS_MODE8] = "asus-mode8", [ALC272_DELL] = "dell", [ALC272_DELL_ZM1] = "dell-zm1", [ALC272_SAMSUNG_NC10] = "samsung-nc10", @@ -16916,12 +17132,22 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = { SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1), SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2), SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1), + SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1), + SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1), SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2), + SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7), + SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7), + SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8), + SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3), + SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1), SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2), + SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2), + SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1), SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2), SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6), SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6), SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2), + SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1), SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3), SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA), SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2), @@ -17205,6 +17431,36 @@ static struct alc_config_preset alc662_presets[] = { .setup = alc663_mode6_setup, .init_hook = alc663_mode6_inithook, }, + [ALC663_ASUS_MODE7] = { + .mixers = { alc663_mode7_mixer }, + .cap_mixer = alc662_auto_capture_mixer, + .init_verbs = { alc662_init_verbs, + alc663_mode7_init_verbs }, + .num_dacs = ARRAY_SIZE(alc662_dac_nids), + .hp_nid = 0x03, + .dac_nids = alc662_dac_nids, + .dig_out_nid = ALC662_DIGOUT_NID, + .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), + .channel_mode = alc662_3ST_2ch_modes, + .unsol_event = alc663_mode7_unsol_event, + .setup = alc663_mode7_setup, + .init_hook = alc663_mode7_inithook, + }, + [ALC663_ASUS_MODE8] = { + .mixers = { alc663_mode8_mixer }, + .cap_mixer = alc662_auto_capture_mixer, + .init_verbs = { alc662_init_verbs, + alc663_mode8_init_verbs }, + .num_dacs = ARRAY_SIZE(alc662_dac_nids), + .hp_nid = 0x03, + .dac_nids = alc662_dac_nids, + .dig_out_nid = ALC662_DIGOUT_NID, + .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), + .channel_mode = alc662_3ST_2ch_modes, + .unsol_event = alc663_mode8_unsol_event, + .setup = alc663_mode8_setup, + .init_hook = alc663_mode8_inithook, + }, [ALC272_DELL] = { .mixers = { alc663_m51va_mixer }, .cap_mixer = alc272_auto_capture_mixer, @@ -17688,7 +17944,9 @@ static struct hda_codec_preset snd_hda_preset_realtek[] = { { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 }, { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 }, { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 }, + { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 }, { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 }, + { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 }, { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", .patch = patch_alc861 }, { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, -- cgit v0.10.2 From d4cc6a2eee98faebf2c7d3ebc4b35541c1d47d21 Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Mon, 7 Dec 2009 15:08:13 +0100 Subject: leds: Add LED class driver for regulator driven LEDs. This driver provides an interface for controlling LEDs (or vibrators) connected to PMICs for which there is a regulator framework driver. This driver can be used, for instance, to control vibrator on all Motorola EZX phones using the pcap-regulator driver services. Signed-off-by: Antonio Ospite Reviewed-by: Mark Brown Signed-off-by: Richard Purdie diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index f12a996..8a0e1ec 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -229,6 +229,12 @@ config LEDS_PWM help This option enables support for pwm driven LEDs +config LEDS_REGULATOR + tristate "REGULATOR driven LED support" + depends on LEDS_CLASS && REGULATOR + help + This option enables support for regulator driven LEDs. + config LEDS_BD2802 tristate "LED driver for BD2802 RGB LED" depends on LEDS_CLASS && I2C diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index 176f0c6..9e63869 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile @@ -29,6 +29,7 @@ obj-$(CONFIG_LEDS_DA903X) += leds-da903x.o obj-$(CONFIG_LEDS_WM831X_STATUS) += leds-wm831x-status.o obj-$(CONFIG_LEDS_WM8350) += leds-wm8350.o obj-$(CONFIG_LEDS_PWM) += leds-pwm.o +obj-$(CONFIG_LEDS_REGULATOR) += leds-regulator.o obj-$(CONFIG_LEDS_INTEL_SS4200) += leds-ss4200.o obj-$(CONFIG_LEDS_LT3593) += leds-lt3593.o obj-$(CONFIG_LEDS_ADP5520) += leds-adp5520.o diff --git a/drivers/leds/leds-regulator.c b/drivers/leds/leds-regulator.c new file mode 100644 index 0000000..7f00de3 --- /dev/null +++ b/drivers/leds/leds-regulator.c @@ -0,0 +1,242 @@ +/* + * leds-regulator.c - LED class driver for regulator driven LEDs. + * + * Copyright (C) 2009 Antonio Ospite + * + * Inspired by leds-wm8350 driver. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#define to_regulator_led(led_cdev) \ + container_of(led_cdev, struct regulator_led, cdev) + +struct regulator_led { + struct led_classdev cdev; + enum led_brightness value; + int enabled; + struct mutex mutex; + struct work_struct work; + + struct regulator *vcc; +}; + +static inline int led_regulator_get_max_brightness(struct regulator *supply) +{ + int ret; + int voltage = regulator_list_voltage(supply, 0); + + if (voltage <= 0) + return 1; + + /* even if regulator can't change voltages, + * we still assume it can change status + * and the LED can be turned on and off. + */ + ret = regulator_set_voltage(supply, voltage, voltage); + if (ret < 0) + return 1; + + return regulator_count_voltages(supply); +} + +static int led_regulator_get_voltage(struct regulator *supply, + enum led_brightness brightness) +{ + if (brightness == 0) + return -EINVAL; + + return regulator_list_voltage(supply, brightness - 1); +} + + +static void regulator_led_enable(struct regulator_led *led) +{ + int ret; + + if (led->enabled) + return; + + ret = regulator_enable(led->vcc); + if (ret != 0) { + dev_err(led->cdev.dev, "Failed to enable vcc: %d\n", ret); + return; + } + + led->enabled = 1; +} + +static void regulator_led_disable(struct regulator_led *led) +{ + int ret; + + if (!led->enabled) + return; + + ret = regulator_disable(led->vcc); + if (ret != 0) { + dev_err(led->cdev.dev, "Failed to disable vcc: %d\n", ret); + return; + } + + led->enabled = 0; +} + +static void regulator_led_set_value(struct regulator_led *led) +{ + int voltage; + int ret; + + mutex_lock(&led->mutex); + + if (led->value == LED_OFF) { + regulator_led_disable(led); + goto out; + } + + if (led->cdev.max_brightness > 1) { + voltage = led_regulator_get_voltage(led->vcc, led->value); + dev_dbg(led->cdev.dev, "brightness: %d voltage: %d\n", + led->value, voltage); + + ret = regulator_set_voltage(led->vcc, voltage, voltage); + if (ret != 0) + dev_err(led->cdev.dev, "Failed to set voltage %d: %d\n", + voltage, ret); + } + + regulator_led_enable(led); + +out: + mutex_unlock(&led->mutex); +} + +static void led_work(struct work_struct *work) +{ + struct regulator_led *led; + + led = container_of(work, struct regulator_led, work); + regulator_led_set_value(led); +} + +static void regulator_led_brightness_set(struct led_classdev *led_cdev, + enum led_brightness value) +{ + struct regulator_led *led = to_regulator_led(led_cdev); + + led->value = value; + schedule_work(&led->work); +} + +static int __devinit regulator_led_probe(struct platform_device *pdev) +{ + struct led_regulator_platform_data *pdata = pdev->dev.platform_data; + struct regulator_led *led; + struct regulator *vcc; + int ret = 0; + + if (pdata == NULL) { + dev_err(&pdev->dev, "no platform data\n"); + return -ENODEV; + } + + vcc = regulator_get_exclusive(&pdev->dev, "vled"); + if (IS_ERR(vcc)) { + dev_err(&pdev->dev, "Cannot get vcc for %s\n", pdata->name); + return PTR_ERR(vcc); + } + + led = kzalloc(sizeof(*led), GFP_KERNEL); + if (led == NULL) { + ret = -ENOMEM; + goto err_vcc; + } + + led->cdev.max_brightness = led_regulator_get_max_brightness(vcc); + if (pdata->brightness > led->cdev.max_brightness) { + dev_err(&pdev->dev, "Invalid default brightness %d\n", + pdata->brightness); + ret = -EINVAL; + goto err_led; + } + led->value = pdata->brightness; + + led->cdev.brightness_set = regulator_led_brightness_set; + led->cdev.name = pdata->name; + led->cdev.flags |= LED_CORE_SUSPENDRESUME; + led->vcc = vcc; + + mutex_init(&led->mutex); + INIT_WORK(&led->work, led_work); + + platform_set_drvdata(pdev, led); + + ret = led_classdev_register(&pdev->dev, &led->cdev); + if (ret < 0) { + cancel_work_sync(&led->work); + goto err_led; + } + + /* to expose the default value to userspace */ + led->cdev.brightness = led->value; + + /* Set the default led status */ + regulator_led_set_value(led); + + return 0; + +err_led: + kfree(led); +err_vcc: + regulator_put(vcc); + return ret; +} + +static int __devexit regulator_led_remove(struct platform_device *pdev) +{ + struct regulator_led *led = platform_get_drvdata(pdev); + + led_classdev_unregister(&led->cdev); + cancel_work_sync(&led->work); + regulator_led_disable(led); + regulator_put(led->vcc); + kfree(led); + return 0; +} + +static struct platform_driver regulator_led_driver = { + .driver = { + .name = "leds-regulator", + .owner = THIS_MODULE, + }, + .probe = regulator_led_probe, + .remove = __devexit_p(regulator_led_remove), +}; + +static int __init regulator_led_init(void) +{ + return platform_driver_register(®ulator_led_driver); +} +module_init(regulator_led_init); + +static void __exit regulator_led_exit(void) +{ + platform_driver_unregister(®ulator_led_driver); +} +module_exit(regulator_led_exit); + +MODULE_AUTHOR("Antonio Ospite "); +MODULE_DESCRIPTION("Regulator driven LED driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:leds-regulator"); diff --git a/include/linux/leds-regulator.h b/include/linux/leds-regulator.h new file mode 100644 index 0000000..5a8eb38 --- /dev/null +++ b/include/linux/leds-regulator.h @@ -0,0 +1,46 @@ +/* + * leds-regulator.h - platform data structure for regulator driven LEDs. + * + * Copyright (C) 2009 Antonio Ospite + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#ifndef __LINUX_LEDS_REGULATOR_H +#define __LINUX_LEDS_REGULATOR_H + +/* + * Use "vled" as supply id when declaring the regulator consumer: + * + * static struct regulator_consumer_supply pcap_regulator_VVIB_consumers [] = { + * { .dev_name = "leds-regulator.0", supply = "vled" }, + * }; + * + * If you have several regulator driven LEDs, you can append a numerical id to + * .dev_name as done above, and use the same id when declaring the platform + * device: + * + * static struct led_regulator_platform_data a780_vibrator_data = { + * .name = "a780::vibrator", + * }; + * + * static struct platform_device a780_vibrator = { + * .name = "leds-regulator", + * .id = 0, + * .dev = { + * .platform_data = &a780_vibrator_data, + * }, + * }; + */ + +#include + +struct led_regulator_platform_data { + char *name; /* LED name as expected by LED class */ + enum led_brightness brightness; /* initial brightness value */ +}; + +#endif /* __LINUX_LEDS_REGULATOR_H */ -- cgit v0.10.2 From 254bba6a7e28c77d8b32d9eaeba02d4943ee844e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Einar=20R=C3=BCnkaru?= Date: Wed, 16 Dec 2009 22:16:13 +0200 Subject: ALSA: hda - Fixed internal mic initialization for Dell Vostro 1015 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed initialization of internal mic and added internal mic boost control Renamed analog mic boost control to ext mic boost contol. Name pair analog/digital seems too confusing for a normal user. Signed-off-by: Einar Rünkaru Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index a09c03c..ca9ad9fdd 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -111,6 +111,7 @@ struct conexant_spec { unsigned int dell_automute; unsigned int port_d_mode; unsigned char ext_mic_bias; + unsigned int dell_vostro; }; static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo, @@ -2109,9 +2110,12 @@ static int cxt5066_mic_boost_mux_enum_get(struct snd_kcontrol *kcontrol, { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); int val; + hda_nid_t nid = kcontrol->private_value & 0xff; + int inout = (kcontrol->private_value & 0x100) ? + AC_AMP_GET_INPUT : AC_AMP_GET_OUTPUT; - val = snd_hda_codec_read(codec, 0x17, 0, - AC_VERB_GET_AMP_GAIN_MUTE, AC_AMP_GET_OUTPUT); + val = snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_AMP_GAIN_MUTE, inout); ucontrol->value.enumerated.item[0] = val & AC_AMP_GAIN; return 0; @@ -2123,6 +2127,9 @@ static int cxt5066_mic_boost_mux_enum_put(struct snd_kcontrol *kcontrol, struct hda_codec *codec = snd_kcontrol_chip(kcontrol); const struct hda_input_mux *imux = &cxt5066_analog_mic_boost; unsigned int idx; + hda_nid_t nid = kcontrol->private_value & 0xff; + int inout = (kcontrol->private_value & 0x100) ? + AC_AMP_SET_INPUT : AC_AMP_SET_OUTPUT; if (!imux->num_items) return 0; @@ -2130,9 +2137,9 @@ static int cxt5066_mic_boost_mux_enum_put(struct snd_kcontrol *kcontrol, if (idx >= imux->num_items) idx = imux->num_items - 1; - snd_hda_codec_write_cache(codec, 0x17, 0, + snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, - AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_OUTPUT | + AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | inout | imux->items[idx].index); return 1; @@ -2201,10 +2208,11 @@ static struct snd_kcontrol_new cxt5066_mixers[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Analog Mic Boost Capture Enum", + .name = "Ext Mic Boost Capture Enum", .info = cxt5066_mic_boost_mux_enum_info, .get = cxt5066_mic_boost_mux_enum_get, .put = cxt5066_mic_boost_mux_enum_put, + .private_value = 0x17, }, HDA_BIND_VOL("Capture Volume", &cxt5066_bind_capture_vol_others), @@ -2212,6 +2220,18 @@ static struct snd_kcontrol_new cxt5066_mixers[] = { {} }; +static struct snd_kcontrol_new cxt5066_vostro_mixers[] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Int Mic Boost Capture Enum", + .info = cxt5066_mic_boost_mux_enum_info, + .get = cxt5066_mic_boost_mux_enum_get, + .put = cxt5066_mic_boost_mux_enum_put, + .private_value = 0x23 | 0x100, + }, + {} +}; + static struct hda_verb cxt5066_init_verbs[] = { {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */ {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */ @@ -2397,11 +2417,16 @@ static struct hda_verb cxt5066_init_verbs_portd_lo[] = { /* initialize jack-sensing, too */ static int cxt5066_init(struct hda_codec *codec) { + struct conexant_spec *spec = codec->spec; + snd_printdd("CXT5066: init\n"); conexant_init(codec); if (codec->patch_ops.unsol_event) { cxt5066_hp_automute(codec); - cxt5066_automic(codec); + if (spec->dell_vostro) + cxt5066_vostro_automic(codec); + else + cxt5066_automic(codec); } return 0; } @@ -2500,7 +2525,9 @@ static int patch_cxt5066(struct hda_codec *codec) spec->init_verbs[0] = cxt5066_init_verbs_vostro; spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc; spec->mixers[spec->num_mixers++] = cxt5066_mixers; + spec->mixers[spec->num_mixers++] = cxt5066_vostro_mixers; spec->port_d_mode = 0; + spec->dell_vostro = 1; /* no S/PDIF out */ spec->multiout.dig_out_nid = 0; -- cgit v0.10.2 From c0f8faf0c7cd497ec7c1d61e1e9424f4384c1f68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Einar=20R=C3=BCnkaru?= Date: Wed, 16 Dec 2009 22:41:36 +0200 Subject: ALSA: hda - Make use of beep device found in Dell Vostro 1015n MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Conexant CX20583-10Z has digital beep device with volume control. Making use of them. Signed-off-by: Einar Rünkaru Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index ca9ad9fdd..c578c28 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -29,6 +29,7 @@ #include "hda_codec.h" #include "hda_local.h" +#include "hda_beep.h" #define CXT_PIN_DIR_IN 0x00 #define CXT_PIN_DIR_OUT 0x01 @@ -477,6 +478,7 @@ static void conexant_free(struct hda_codec *codec) snd_array_free(&spec->jacks); } #endif + snd_hda_detach_beep_device(codec); kfree(codec->spec); } @@ -2229,6 +2231,7 @@ static struct snd_kcontrol_new cxt5066_vostro_mixers[] = { .put = cxt5066_mic_boost_mux_enum_put, .private_value = 0x23 | 0x100, }, + HDA_CODEC_VOLUME_MONO("Beep Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT), {} }; @@ -2528,6 +2531,7 @@ static int patch_cxt5066(struct hda_codec *codec) spec->mixers[spec->num_mixers++] = cxt5066_vostro_mixers; spec->port_d_mode = 0; spec->dell_vostro = 1; + snd_hda_attach_beep_device(codec, 0x13); /* no S/PDIF out */ spec->multiout.dig_out_nid = 0; -- cgit v0.10.2 From 9695fff8f84d7ab849139750036e443b85804edd Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Sat, 28 Nov 2009 12:55:51 +0100 Subject: leds: leds-pca9532.h- indent with tabs, not spaces Signed-off-by: Antonio Ospite Signed-off-by: Richard Purdie diff --git a/include/linux/leds-pca9532.h b/include/linux/leds-pca9532.h index 96eea90..f158eb1 100644 --- a/include/linux/leds-pca9532.h +++ b/include/linux/leds-pca9532.h @@ -32,7 +32,7 @@ struct pca9532_led { struct i2c_client *client; char *name; struct led_classdev ldev; - struct work_struct work; + struct work_struct work; enum pca9532_type type; enum pca9532_state state; }; -- cgit v0.10.2 From eedd898f6910b88aa2052461ad0c3f443b45bb00 Mon Sep 17 00:00:00 2001 From: "akpm@linux-foundation.org" Date: Fri, 13 Nov 2009 19:56:37 -0800 Subject: leds: drivers/leds/leds-ss4200.c: fix return statement drivers/leds/leds-ss4200.c: In function 'ich7_lpc_probe': drivers/leds/leds-ss4200.c:353: warning: 'return' with no value, in function returning non-void Signed-off-by: Andrew Morton Signed-off-by: Richard Purdie diff --git a/drivers/leds/leds-ss4200.c b/drivers/leds/leds-ss4200.c index c7f6347..97f0498 100644 --- a/drivers/leds/leds-ss4200.c +++ b/drivers/leds/leds-ss4200.c @@ -350,7 +350,7 @@ static int __devinit ich7_lpc_probe(struct pci_dev *dev, status = pci_enable_device(dev); if (status) { dev_err(&dev->dev, "pci_enable_device failed\n"); - return; + return -EIO; } nas_gpio_pci_dev = dev; -- cgit v0.10.2 From 51de036ba388a1bda08755f7c0d3d1ae27c81e66 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Thu, 26 Nov 2009 19:41:02 +0100 Subject: leds: use default-on trigger for Cobalt Qube This patch changes the default trigger from "ide-disk" to "default-on". Users updating from kernels not having this LED driver will prefer having the same LED behavior as they used to. Signed-off-by: Florian Fainelli Signed-off-by: Richard Purdie diff --git a/drivers/leds/leds-cobalt-qube.c b/drivers/leds/leds-cobalt-qube.c index de197538..da5fb01 100644 --- a/drivers/leds/leds-cobalt-qube.c +++ b/drivers/leds/leds-cobalt-qube.c @@ -31,7 +31,7 @@ static struct led_classdev qube_front_led = { .name = "qube::front", .brightness = LED_FULL, .brightness_set = qube_front_led_set, - .default_trigger = "ide-disk", + .default_trigger = "default-on", }; static int __devinit cobalt_qube_led_probe(struct platform_device *pdev) -- cgit v0.10.2 From 1998111582f5d726ca4dbf9d68935d9e7c994374 Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Sun, 29 Nov 2009 13:12:21 +0100 Subject: leds: leds-lp3944.h - remove unneeded includes These were needed in the first version of the driver because we used to expose workqueue and led class details in the header file, now we don't. Signed-off-by: Antonio Ospite Signed-off-by: Richard Purdie diff --git a/include/linux/leds-lp3944.h b/include/linux/leds-lp3944.h index afc9f9f..2618aa9 100644 --- a/include/linux/leds-lp3944.h +++ b/include/linux/leds-lp3944.h @@ -12,9 +12,6 @@ #ifndef __LINUX_LEDS_LP3944_H #define __LINUX_LEDS_LP3944_H -#include -#include - #define LP3944_LED0 0 #define LP3944_LED1 1 #define LP3944_LED2 2 -- cgit v0.10.2 From e45906203d27296b47e56efc1219f9a200bfc2db Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 27 Nov 2009 06:17:38 +0100 Subject: leds: leds-pwm: Set led_classdev max_brightness Currently the driver leds-pwm doesn't set max_brightness for the led device although it's platform data proides a maximum brightness. Instead it stores its own private driver struct. The max_brightness defaults to 255 for led device if it has not been set. As a result any leds-pwm device with a different maximum brightness will show incorrect behavior, as it is posible to either set a longer then period duty time or not be able to switch the led to full brightness. Signed-off-by: Lars-Peter Clausen Signed-off-by: Richard Purdie diff --git a/drivers/leds/leds-pwm.c b/drivers/leds/leds-pwm.c index cdfdc87..88b1dd0 100644 --- a/drivers/leds/leds-pwm.c +++ b/drivers/leds/leds-pwm.c @@ -27,7 +27,6 @@ struct led_pwm_data { struct pwm_device *pwm; unsigned int active_low; unsigned int period; - unsigned int max_brightness; }; static void led_pwm_set(struct led_classdev *led_cdev, @@ -35,7 +34,7 @@ static void led_pwm_set(struct led_classdev *led_cdev, { struct led_pwm_data *led_dat = container_of(led_cdev, struct led_pwm_data, cdev); - unsigned int max = led_dat->max_brightness; + unsigned int max = led_dat->cdev.max_brightness; unsigned int period = led_dat->period; if (brightness == 0) { @@ -77,10 +76,10 @@ static int led_pwm_probe(struct platform_device *pdev) led_dat->cdev.name = cur_led->name; led_dat->cdev.default_trigger = cur_led->default_trigger; led_dat->active_low = cur_led->active_low; - led_dat->max_brightness = cur_led->max_brightness; led_dat->period = cur_led->pwm_period_ns; led_dat->cdev.brightness_set = led_pwm_set; led_dat->cdev.brightness = LED_OFF; + led_dat->cdev.max_brightness = cur_led->max_brightness; led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME; ret = led_classdev_register(&pdev->dev, &led_dat->cdev); -- cgit v0.10.2 From cfc3899fcd0b3b990b29d3d33f75f4edf715e7d1 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Tue, 10 Nov 2009 17:20:40 +0000 Subject: backlight: Pass device through notify callback in the pwm driver Add the device to the notify callback's arguments in the PWM backlight driver. This brings the notify callback into line with the other callbacks defined by this driver. Signed-off-by: Ben Dooks Signed-off-by: Simtec Linux Team Signed-off-by: Richard Purdie diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c index df9e0b3..9d2ec2a 100644 --- a/drivers/video/backlight/pwm_bl.c +++ b/drivers/video/backlight/pwm_bl.c @@ -22,8 +22,10 @@ struct pwm_bl_data { struct pwm_device *pwm; + struct device *dev; unsigned int period; - int (*notify)(int brightness); + int (*notify)(struct device *, + int brightness); }; static int pwm_backlight_update_status(struct backlight_device *bl) @@ -39,7 +41,7 @@ static int pwm_backlight_update_status(struct backlight_device *bl) brightness = 0; if (pb->notify) - brightness = pb->notify(brightness); + brightness = pb->notify(pb->dev, brightness); if (brightness == 0) { pwm_config(pb->pwm, 0, pb->period); @@ -88,6 +90,7 @@ static int pwm_backlight_probe(struct platform_device *pdev) pb->period = data->pwm_period_ns; pb->notify = data->notify; + pb->dev = &pdev->dev; pb->pwm = pwm_request(data->pwm_id, "backlight"); if (IS_ERR(pb->pwm)) { @@ -146,7 +149,7 @@ static int pwm_backlight_suspend(struct platform_device *pdev, struct pwm_bl_data *pb = dev_get_drvdata(&bl->dev); if (pb->notify) - pb->notify(0); + pb->notify(pb->dev, 0); pwm_config(pb->pwm, 0, pb->period); pwm_disable(pb->pwm); return 0; diff --git a/include/linux/pwm_backlight.h b/include/linux/pwm_backlight.h index 7a9754c..01b3d75 100644 --- a/include/linux/pwm_backlight.h +++ b/include/linux/pwm_backlight.h @@ -10,7 +10,7 @@ struct platform_pwm_backlight_data { unsigned int dft_brightness; unsigned int pwm_period_ns; int (*init)(struct device *dev); - int (*notify)(int brightness); + int (*notify)(struct device *dev, int brightness); void (*exit)(struct device *dev); }; -- cgit v0.10.2 From f7a297af49e5d9d2c577466307e8ef392750c9d9 Mon Sep 17 00:00:00 2001 From: Daniel Ritz Date: Wed, 2 Dec 2009 00:41:31 +0100 Subject: backlight: mbp_nvidia_bl - add two more MacBookPro variants This adds the MacBookPro 5,3 and 5,4 to the DMI tables. Signed-off-by: Daniel Ritz Signed-off-by: Richard Purdie diff --git a/drivers/video/backlight/mbp_nvidia_bl.c b/drivers/video/backlight/mbp_nvidia_bl.c index 5812468..2e78b07 100644 --- a/drivers/video/backlight/mbp_nvidia_bl.c +++ b/drivers/video/backlight/mbp_nvidia_bl.c @@ -220,6 +220,24 @@ static const struct dmi_system_id __initdata mbp_device_table[] = { }, { .callback = mbp_dmi_match, + .ident = "MacBookPro 5,3", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,3"), + }, + .driver_data = (void *)&nvidia_chipset_data, + }, + { + .callback = mbp_dmi_match, + .ident = "MacBookPro 5,4", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,4"), + }, + .driver_data = (void *)&nvidia_chipset_data, + }, + { + .callback = mbp_dmi_match, .ident = "MacBookPro 5,5", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), -- cgit v0.10.2 From 733421516b42c44b9e21f1793c430cc801ef8324 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 17 Dec 2009 13:16:27 +0100 Subject: sched: Move TASK_STATE_TO_CHAR_STR near the TASK_state bits So that we don't keep forgetting about it. Signed-off-by: Peter Zijlstra LKML-Reference: <20091217121829.815779372@chello.nl> Signed-off-by: Ingo Molnar diff --git a/include/linux/sched.h b/include/linux/sched.h index 973b2b8..c28ed1b 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -193,6 +193,8 @@ print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq) #define TASK_WAKEKILL 128 #define TASK_WAKING 256 +#define TASK_STATE_TO_CHAR_STR "RSDTtZX" + /* Convenience macros for the sake of set_task_state */ #define TASK_KILLABLE (TASK_WAKEKILL | TASK_UNINTERRUPTIBLE) #define TASK_STOPPED (TASK_WAKEKILL | __TASK_STOPPED) @@ -2595,8 +2597,6 @@ static inline void mm_init_owner(struct mm_struct *mm, struct task_struct *p) } #endif /* CONFIG_MM_OWNER */ -#define TASK_STATE_TO_CHAR_STR "RSDTtZX" - #endif /* __KERNEL__ */ #endif -- cgit v0.10.2 From 44d90df6b757c59651ddd55f1a84f28132b50d29 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 17 Dec 2009 13:16:28 +0100 Subject: sched: Add missing state chars to TASK_STATE_TO_CHAR_STR We grew 3 new task states since the last time someone touched it. Signed-off-by: Peter Zijlstra LKML-Reference: <20091217121829.892737686@chello.nl> Signed-off-by: Ingo Molnar diff --git a/include/linux/sched.h b/include/linux/sched.h index c28ed1b..94858df38 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -193,7 +193,7 @@ print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq) #define TASK_WAKEKILL 128 #define TASK_WAKING 256 -#define TASK_STATE_TO_CHAR_STR "RSDTtZX" +#define TASK_STATE_TO_CHAR_STR "RSDTtZXxKW" /* Convenience macros for the sake of set_task_state */ #define TASK_KILLABLE (TASK_WAKEKILL | TASK_UNINTERRUPTIBLE) -- cgit v0.10.2 From 464763cf1c6df632dccc8f2f4c7e50163154a2c0 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 17 Dec 2009 13:16:29 +0100 Subject: sched: Update task_state_arraypwith new states Neglected because its hidden... (who reads comments anyway) Signed-off-by: Peter Zijlstra LKML-Reference: <20091217121829.970166036@chello.nl> Signed-off-by: Ingo Molnar diff --git a/fs/proc/array.c b/fs/proc/array.c index 4badde1..96361e8 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c @@ -138,9 +138,12 @@ static const char *task_state_array[] = { "S (sleeping)", /* 1 */ "D (disk sleep)", /* 2 */ "T (stopped)", /* 4 */ - "T (tracing stop)", /* 8 */ + "t (tracing stop)", /* 8 */ "Z (zombie)", /* 16 */ - "X (dead)" /* 32 */ + "X (dead)", /* 32 */ + "x (dead)", /* 64 */ + "K (wakekill)", /* 128 */ + "W (waking)", /* 256 */ }; static inline const char *get_task_state(struct task_struct *tsk) -- cgit v0.10.2 From e1781538cf5c870ab696e9b8f0a5c498d3900f2f Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 17 Dec 2009 13:16:30 +0100 Subject: sched: Assert task state bits at build time Since everybody is lazy and prone to forgetting things, make the compiler help us a bit. Signed-off-by: Peter Zijlstra LKML-Reference: <20091217121830.060186433@chello.nl> Signed-off-by: Ingo Molnar diff --git a/fs/proc/array.c b/fs/proc/array.c index 96361e8..f560325 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c @@ -134,14 +134,14 @@ static inline void task_name(struct seq_file *m, struct task_struct *p) * simple bit tests. */ static const char *task_state_array[] = { - "R (running)", /* 0 */ - "S (sleeping)", /* 1 */ - "D (disk sleep)", /* 2 */ - "T (stopped)", /* 4 */ - "t (tracing stop)", /* 8 */ - "Z (zombie)", /* 16 */ - "X (dead)", /* 32 */ - "x (dead)", /* 64 */ + "R (running)", /* 0 */ + "S (sleeping)", /* 1 */ + "D (disk sleep)", /* 2 */ + "T (stopped)", /* 4 */ + "t (tracing stop)", /* 8 */ + "Z (zombie)", /* 16 */ + "X (dead)", /* 32 */ + "x (dead)", /* 64 */ "K (wakekill)", /* 128 */ "W (waking)", /* 256 */ }; @@ -151,6 +151,8 @@ static inline const char *get_task_state(struct task_struct *tsk) unsigned int state = (tsk->state & TASK_REPORT) | tsk->exit_state; const char **p = &task_state_array[0]; + BUILD_BUG_ON(1 + ilog2(TASK_STATE_MAX) != ARRAY_SIZE(task_state_array)); + while (state) { p++; state >>= 1; diff --git a/include/linux/sched.h b/include/linux/sched.h index 94858df38..3754387 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -192,9 +192,13 @@ print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq) #define TASK_DEAD 64 #define TASK_WAKEKILL 128 #define TASK_WAKING 256 +#define TASK_STATE_MAX 512 #define TASK_STATE_TO_CHAR_STR "RSDTtZXxKW" +extern char ___assert_task_state[1 - 2*!!( + sizeof(TASK_STATE_TO_CHAR_STR)-1 != ilog2(TASK_STATE_MAX)+1)]; + /* Convenience macros for the sake of set_task_state */ #define TASK_KILLABLE (TASK_WAKEKILL | TASK_UNINTERRUPTIBLE) #define TASK_STOPPED (TASK_WAKEKILL | __TASK_STOPPED) -- cgit v0.10.2 From 077614ee1e93245a3b9a4e1213659405dbeb0ba6 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 17 Dec 2009 13:16:31 +0100 Subject: sched: Fix broken assertion There's a preemption race in the set_task_cpu() debug check in that when we get preempted after setting task->state we'd still be on the rq proper, but fail the test. Check for preempted tasks, since those are always on the RQ. Signed-off-by: Peter Zijlstra LKML-Reference: <20091217121830.137155561@chello.nl> Signed-off-by: Ingo Molnar diff --git a/kernel/sched.c b/kernel/sched.c index 7be88a7..720df108 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -2041,7 +2041,8 @@ void set_task_cpu(struct task_struct *p, unsigned int new_cpu) * We should never call set_task_cpu() on a blocked task, * ttwu() will sort out the placement. */ - WARN_ON_ONCE(p->state != TASK_RUNNING && p->state != TASK_WAKING); + WARN_ON_ONCE(p->state != TASK_RUNNING && p->state != TASK_WAKING && + !(task_thread_info(p)->preempt_count & PREEMPT_ACTIVE)); #endif trace_sched_migrate_task(p, new_cpu); -- cgit v0.10.2 From 035eb0cff0671ada49ba9f3e5c9e7b0cb950efea Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 17 Dec 2009 15:00:26 +0100 Subject: ALSA: hda - Fix missing capsrc_nids for ALC88x Some model quirks missed the corresponding capsrc_nids. This resulted in non-working capture source selection. Signed-off-by: Takashi Iwai Cc: diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 287bb60..d9a9f0c 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -9238,6 +9238,8 @@ static struct alc_config_preset alc882_presets[] = { .dac_nids = alc883_dac_nids, .num_adc_nids = ARRAY_SIZE(alc889_adc_nids), .adc_nids = alc889_adc_nids, + .capsrc_nids = alc889_capsrc_nids, + .capsrc_nids = alc889_capsrc_nids, .dig_out_nid = ALC883_DIGOUT_NID, .dig_in_nid = ALC883_DIGIN_NID, .slave_dig_outs = alc883_slave_dig_outs, @@ -9284,6 +9286,7 @@ static struct alc_config_preset alc882_presets[] = { .dac_nids = alc883_dac_nids, .adc_nids = alc883_adc_nids_alt, .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt), + .capsrc_nids = alc883_capsrc_nids, .dig_out_nid = ALC883_DIGOUT_NID, .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), .channel_mode = alc883_3ST_2ch_modes, @@ -9430,6 +9433,7 @@ static struct alc_config_preset alc882_presets[] = { .dac_nids = alc883_dac_nids, .adc_nids = alc883_adc_nids_alt, .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt), + .capsrc_nids = alc883_capsrc_nids, .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), .channel_mode = alc883_sixstack_modes, .input_mux = &alc883_capture_source, @@ -9491,6 +9495,7 @@ static struct alc_config_preset alc882_presets[] = { .dac_nids = alc883_dac_nids, .adc_nids = alc883_adc_nids_alt, .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt), + .capsrc_nids = alc883_capsrc_nids, .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), .channel_mode = alc883_3ST_2ch_modes, .input_mux = &alc883_lenovo_101e_capture_source, @@ -9670,6 +9675,7 @@ static struct alc_config_preset alc882_presets[] = { alc880_gpio1_init_verbs }, .adc_nids = alc883_adc_nids, .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), + .capsrc_nids = alc883_capsrc_nids, .dac_nids = alc883_dac_nids, .num_dacs = ARRAY_SIZE(alc883_dac_nids), .channel_mode = alc889A_mb31_6ch_modes, -- cgit v0.10.2 From c051346b7db27aaf674b8f3b4955240580b2a58a Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Thu, 17 Dec 2009 06:56:11 -0800 Subject: Makefile: set LC_CTYPE, LC_COLLATE, LC_NUMERIC to C There are a number of common Unix constructs like character ranges in grep/sed/awk which don't work as expected with LC_COLLATE set to other than C. Similarly, set LC_CTYPE and LC_NUMERIC to C to avoid other nasty surprises. In order to make sure these actually take effect we also have to clear LC_ALL. Signed-off-by: H. Peter Anvin Acked-by: Michal Marek Acked-by: Masami Hiramatsu Acked-by: Roland Dreier Cc: Sam Ravnborg LKML-Reference: <4B2A1761.4070904@suse.cz> diff --git a/Makefile b/Makefile index 33d4732..6e39af1 100644 --- a/Makefile +++ b/Makefile @@ -16,6 +16,13 @@ NAME = Man-Eating Seals of Antiquity # o print "Entering directory ..."; MAKEFLAGS += -rR --no-print-directory +# Avoid funny character set dependencies +LC_ALL= +LC_CTYPE=C +LC_COLLATE=C +LC_NUMERIC=C +export LC_ALL LC_CTYPE LC_COLLATE LC_NUMERIC + # We are using a recursive build, so we need to do a little thinking # to get the ordering right. # -- cgit v0.10.2 From 4beb3d6d144c41525541cce2b611858b2645c725 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Wed, 16 Dec 2009 17:39:48 -0800 Subject: x86: Don't use POSIX character classes in gen-insn-attr-x86.awk Not all awk implementations (including the default awk in Ubuntu 9.10) support POSIX character classes. Since x86-opcode-map.txt is plain ASCII, we can just use explicit ranges for lower case, alphabetic, and alphanumeric characters instead. Signed-off-by: Roland Dreier Acked-by: Masami Hiramatsu LKML-Reference: Signed-off-by: H. Peter Anvin diff --git a/arch/x86/tools/gen-insn-attr-x86.awk b/arch/x86/tools/gen-insn-attr-x86.awk index 7a68506..eaf11f5 100644 --- a/arch/x86/tools/gen-insn-attr-x86.awk +++ b/arch/x86/tools/gen-insn-attr-x86.awk @@ -6,8 +6,6 @@ # Awk implementation sanity check function check_awk_implement() { - if (!match("abc", "[[:lower:]]+")) - return "Your awk doesn't support charactor-class." if (sprintf("%x", 0) != "0") return "Your awk has a printf-format problem." return "" @@ -44,12 +42,12 @@ BEGIN { delete gtable delete atable - opnd_expr = "^[[:alpha:]/]" + opnd_expr = "^[A-Za-z/]" ext_expr = "^\\(" sep_expr = "^\\|$" - group_expr = "^Grp[[:alnum:]]+" + group_expr = "^Grp[0-9A-Za-z]+" - imm_expr = "^[IJAO][[:lower:]]" + imm_expr = "^[IJAO][a-z]" imm_flag["Ib"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)" imm_flag["Jb"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)" imm_flag["Iw"] = "INAT_MAKE_IMM(INAT_IMM_WORD)" @@ -62,7 +60,7 @@ BEGIN { imm_flag["Ob"] = "INAT_MOFFSET" imm_flag["Ov"] = "INAT_MOFFSET" - modrm_expr = "^([CDEGMNPQRSUVW/][[:lower:]]+|NTA|T[012])" + modrm_expr = "^([CDEGMNPQRSUVW/][a-z]+|NTA|T[012])" force64_expr = "\\([df]64\\)" rex_expr = "^REX(\\.[XRWB]+)*" fpu_expr = "^ESC" # TODO -- cgit v0.10.2 From 04a1e62c2cec820501f93526ad1e46073b802dc4 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 17 Dec 2009 07:04:56 -0800 Subject: x86/ptrace: make genregs[32]_get/set more robust The loop condition is fragile: we compare an unsigned value to zero, and then decrement it by something larger than one in the loop. All the callers should be passing in appropriately aligned buffer lengths, but it's better to just not rely on it, and have some appropriate defensive loop limits. Acked-by: Roland McGrath Signed-off-by: Linus Torvalds diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index 2779321..017d937 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c @@ -509,14 +509,14 @@ static int genregs_get(struct task_struct *target, { if (kbuf) { unsigned long *k = kbuf; - while (count > 0) { + while (count >= sizeof(*k)) { *k++ = getreg(target, pos); count -= sizeof(*k); pos += sizeof(*k); } } else { unsigned long __user *u = ubuf; - while (count > 0) { + while (count >= sizeof(*u)) { if (__put_user(getreg(target, pos), u++)) return -EFAULT; count -= sizeof(*u); @@ -535,14 +535,14 @@ static int genregs_set(struct task_struct *target, int ret = 0; if (kbuf) { const unsigned long *k = kbuf; - while (count > 0 && !ret) { + while (count >= sizeof(*k) && !ret) { ret = putreg(target, pos, *k++); count -= sizeof(*k); pos += sizeof(*k); } } else { const unsigned long __user *u = ubuf; - while (count > 0 && !ret) { + while (count >= sizeof(*u) && !ret) { unsigned long word; ret = __get_user(word, u++); if (ret) @@ -1458,14 +1458,14 @@ static int genregs32_get(struct task_struct *target, { if (kbuf) { compat_ulong_t *k = kbuf; - while (count > 0) { + while (count >= sizeof(*k)) { getreg32(target, pos, k++); count -= sizeof(*k); pos += sizeof(*k); } } else { compat_ulong_t __user *u = ubuf; - while (count > 0) { + while (count >= sizeof(*u)) { compat_ulong_t word; getreg32(target, pos, &word); if (__put_user(word, u++)) @@ -1486,14 +1486,14 @@ static int genregs32_set(struct task_struct *target, int ret = 0; if (kbuf) { const compat_ulong_t *k = kbuf; - while (count > 0 && !ret) { + while (count >= sizeof(*k) && !ret) { ret = putreg32(target, pos, *k++); count -= sizeof(*k); pos += sizeof(*k); } } else { const compat_ulong_t __user *u = ubuf; - while (count > 0 && !ret) { + while (count >= sizeof(*u) && !ret) { compat_ulong_t word; ret = __get_user(word, u++); if (ret) -- cgit v0.10.2 From 331d9d5958277de27e6ce42247e1cbec54fd1c7e Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 17 Dec 2009 14:15:09 +0100 Subject: Revert "fbdev: atafb - add palette register check" This reverts commit 8546e3ce6e37c359979b69862442f94e0ef0e03b, as it's a partial duplicate of commit 2f390380ca69e1617cdddb12d8da94f0a9f4319d ("fbdev: add palette register check to several drivers"). The former went in first through the m68k tree, the latter through Andrew Morton. Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Torvalds diff --git a/drivers/video/atafb.c b/drivers/video/atafb.c index 2051c9d..b7687c5 100644 --- a/drivers/video/atafb.c +++ b/drivers/video/atafb.c @@ -2245,9 +2245,6 @@ static int ext_setcolreg(unsigned int regno, unsigned int red, if (regno > 255) return 1; - if (regno > 255) - return 1; - switch (external_card_type) { case IS_VGA: OUTB(0x3c8, regno); -- cgit v0.10.2 From 8ae1c9248042c5122f9628282f41c363c9610dd7 Mon Sep 17 00:00:00 2001 From: Thadeu Lima de Souza Cascardo Date: Mon, 14 Dec 2009 14:20:23 -0800 Subject: spidev: use DECLARE_BITMAP instead of declaring the array [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Thadeu Lima de Souza Cascardo Cc: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Grant Likely diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index f8279e7..cb7147e 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c @@ -54,7 +54,7 @@ #define SPIDEV_MAJOR 153 /* assigned */ #define N_SPI_MINORS 32 /* ... up to 256 */ -static unsigned long minors[N_SPI_MINORS / BITS_PER_LONG]; +static DECLARE_BITMAP(minors, N_SPI_MINORS); /* Bit masks for spi_device.mode management. Note that incorrect -- cgit v0.10.2 From db389b6143c895d23060179b14928f63d44285a2 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 14 Dec 2009 14:20:22 -0800 Subject: spidev: add proper section markers The driver already uses __devexit_p() in the structure, but looks like actual __dev{init,exit} markings were forgotten. The spidev_spi driver also needs renaming to include a "_driver" suffix to avoid section mismatch warnings. Signed-off-by: Mike Frysinger Cc: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Grant Likely diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index cb7147e..f4a7a28 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c @@ -561,7 +561,7 @@ static struct class *spidev_class; /*-------------------------------------------------------------------------*/ -static int spidev_probe(struct spi_device *spi) +static int __devinit spidev_probe(struct spi_device *spi) { struct spidev_data *spidev; int status; @@ -610,7 +610,7 @@ static int spidev_probe(struct spi_device *spi) return status; } -static int spidev_remove(struct spi_device *spi) +static int __devexit spidev_remove(struct spi_device *spi) { struct spidev_data *spidev = spi_get_drvdata(spi); @@ -632,7 +632,7 @@ static int spidev_remove(struct spi_device *spi) return 0; } -static struct spi_driver spidev_spi = { +static struct spi_driver spidev_spi_driver = { .driver = { .name = "spidev", .owner = THIS_MODULE, @@ -664,14 +664,14 @@ static int __init spidev_init(void) spidev_class = class_create(THIS_MODULE, "spidev"); if (IS_ERR(spidev_class)) { - unregister_chrdev(SPIDEV_MAJOR, spidev_spi.driver.name); + unregister_chrdev(SPIDEV_MAJOR, spidev_spi_driver.driver.name); return PTR_ERR(spidev_class); } - status = spi_register_driver(&spidev_spi); + status = spi_register_driver(&spidev_spi_driver); if (status < 0) { class_destroy(spidev_class); - unregister_chrdev(SPIDEV_MAJOR, spidev_spi.driver.name); + unregister_chrdev(SPIDEV_MAJOR, spidev_spi_driver.driver.name); } return status; } @@ -679,9 +679,9 @@ module_init(spidev_init); static void __exit spidev_exit(void) { - spi_unregister_driver(&spidev_spi); + spi_unregister_driver(&spidev_spi_driver); class_destroy(spidev_class); - unregister_chrdev(SPIDEV_MAJOR, spidev_spi.driver.name); + unregister_chrdev(SPIDEV_MAJOR, spidev_spi_driver.driver.name); } module_exit(spidev_exit); -- cgit v0.10.2 From e24c745272072fd2abe55209f1949b7b7ee602a7 Mon Sep 17 00:00:00 2001 From: Feng Tang Date: Mon, 14 Dec 2009 14:20:22 -0800 Subject: spi: controller driver for Designware SPI core Driver for the Designware SPI core, it supports multipul interfaces like PCI/APB etc. User can use "dw_apb_ssi_db.pdf" from Synopsys as HW datasheet. [randy.dunlap@oracle.com: fix build] [akpm@linux-foundation.org: build fix] Signed-off-by: Feng Tang Cc: David Brownell Signed-off-by: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Grant Likely diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 07e5453..d7c1741 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -292,6 +292,16 @@ config SPI_NUC900 # Add new SPI master controllers in alphabetical order above this line # +config SPI_DESIGNWARE + bool "DesignWare SPI controller core support" + depends on SPI_MASTER + help + general driver for SPI controller core from DesignWare + +config SPI_DW_PCI + tristate "PCI interface driver for DW SPI core" + depends on SPI_DESIGNWARE && PCI + # # There are lots of SPI device types, with sensors and memory # being probably the most widely used ones. diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index ed8c167..a909e39 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -16,6 +16,8 @@ obj-$(CONFIG_SPI_BFIN) += spi_bfin5xx.o obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o obj-$(CONFIG_SPI_AU1550) += au1550_spi.o obj-$(CONFIG_SPI_BUTTERFLY) += spi_butterfly.o +obj-$(CONFIG_SPI_DESIGNWARE) += dw_spi.o +obj-$(CONFIG_SPI_DW_PCI) += dw_spi_pci.o obj-$(CONFIG_SPI_GPIO) += spi_gpio.o obj-$(CONFIG_SPI_IMX) += spi_imx.o obj-$(CONFIG_SPI_LM70_LLP) += spi_lm70llp.o diff --git a/drivers/spi/dw_spi.c b/drivers/spi/dw_spi.c new file mode 100644 index 0000000..31620fa --- /dev/null +++ b/drivers/spi/dw_spi.c @@ -0,0 +1,944 @@ +/* + * dw_spi.c - Designware SPI core controller driver (refer pxa2xx_spi.c) + * + * Copyright (c) 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. + */ + +#include +#include +#include +#include + +#include +#include + +#ifdef CONFIG_DEBUG_FS +#include +#endif + +#define START_STATE ((void *)0) +#define RUNNING_STATE ((void *)1) +#define DONE_STATE ((void *)2) +#define ERROR_STATE ((void *)-1) + +#define QUEUE_RUNNING 0 +#define QUEUE_STOPPED 1 + +#define MRST_SPI_DEASSERT 0 +#define MRST_SPI_ASSERT 1 + +/* Slave spi_dev related */ +struct chip_data { + u16 cr0; + u8 cs; /* chip select pin */ + u8 n_bytes; /* current is a 1/2/4 byte op */ + u8 tmode; /* TR/TO/RO/EEPROM */ + u8 type; /* SPI/SSP/MicroWire */ + + u8 poll_mode; /* 1 means use poll mode */ + + u32 dma_width; + u32 rx_threshold; + u32 tx_threshold; + u8 enable_dma; + u8 bits_per_word; + u16 clk_div; /* baud rate divider */ + u32 speed_hz; /* baud rate */ + int (*write)(struct dw_spi *dws); + int (*read)(struct dw_spi *dws); + void (*cs_control)(u32 command); +}; + +#ifdef CONFIG_DEBUG_FS +static int spi_show_regs_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + +#define SPI_REGS_BUFSIZE 1024 +static ssize_t spi_show_regs(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct dw_spi *dws; + char *buf; + u32 len = 0; + ssize_t ret; + + dws = file->private_data; + + buf = kzalloc(SPI_REGS_BUFSIZE, GFP_KERNEL); + if (!buf) + return 0; + + len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, + "MRST SPI0 registers:\n"); + len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, + "=================================\n"); + len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, + "CTRL0: \t\t0x%08x\n", dw_readl(dws, ctrl0)); + len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, + "CTRL1: \t\t0x%08x\n", dw_readl(dws, ctrl1)); + len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, + "SSIENR: \t0x%08x\n", dw_readl(dws, ssienr)); + len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, + "SER: \t\t0x%08x\n", dw_readl(dws, ser)); + len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, + "BAUDR: \t\t0x%08x\n", dw_readl(dws, baudr)); + len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, + "TXFTLR: \t0x%08x\n", dw_readl(dws, txfltr)); + len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, + "RXFTLR: \t0x%08x\n", dw_readl(dws, rxfltr)); + len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, + "TXFLR: \t\t0x%08x\n", dw_readl(dws, txflr)); + len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, + "RXFLR: \t\t0x%08x\n", dw_readl(dws, rxflr)); + len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, + "SR: \t\t0x%08x\n", dw_readl(dws, sr)); + len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, + "IMR: \t\t0x%08x\n", dw_readl(dws, imr)); + len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, + "ISR: \t\t0x%08x\n", dw_readl(dws, isr)); + len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, + "DMACR: \t\t0x%08x\n", dw_readl(dws, dmacr)); + len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, + "DMATDLR: \t0x%08x\n", dw_readl(dws, dmatdlr)); + len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, + "DMARDLR: \t0x%08x\n", dw_readl(dws, dmardlr)); + len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, + "=================================\n"); + + ret = simple_read_from_buffer(user_buf, count, ppos, buf, len); + kfree(buf); + return ret; +} + +static const struct file_operations mrst_spi_regs_ops = { + .owner = THIS_MODULE, + .open = spi_show_regs_open, + .read = spi_show_regs, +}; + +static int mrst_spi_debugfs_init(struct dw_spi *dws) +{ + dws->debugfs = debugfs_create_dir("mrst_spi", NULL); + if (!dws->debugfs) + return -ENOMEM; + + debugfs_create_file("registers", S_IFREG | S_IRUGO, + dws->debugfs, (void *)dws, &mrst_spi_regs_ops); + return 0; +} + +static void mrst_spi_debugfs_remove(struct dw_spi *dws) +{ + if (dws->debugfs) + debugfs_remove_recursive(dws->debugfs); +} + +#else +static inline int mrst_spi_debugfs_init(struct dw_spi *dws) +{ +} + +static inline void mrst_spi_debugfs_remove(struct dw_spi *dws) +{ +} +#endif /* CONFIG_DEBUG_FS */ + +static void wait_till_not_busy(struct dw_spi *dws) +{ + unsigned long end = jiffies + usecs_to_jiffies(1000); + + while (time_before(jiffies, end)) { + if (!(dw_readw(dws, sr) & SR_BUSY)) + return; + } + dev_err(&dws->master->dev, + "DW SPI: Stutus keeps busy for 1000us after a read/write!\n"); +} + +static void flush(struct dw_spi *dws) +{ + while (dw_readw(dws, sr) & SR_RF_NOT_EMPT) + dw_readw(dws, dr); + + wait_till_not_busy(dws); +} + +static void null_cs_control(u32 command) +{ +} + +static int null_writer(struct dw_spi *dws) +{ + u8 n_bytes = dws->n_bytes; + + if (!(dw_readw(dws, sr) & SR_TF_NOT_FULL) + || (dws->tx == dws->tx_end)) + return 0; + dw_writew(dws, dr, 0); + dws->tx += n_bytes; + + wait_till_not_busy(dws); + return 1; +} + +static int null_reader(struct dw_spi *dws) +{ + u8 n_bytes = dws->n_bytes; + + while ((dw_readw(dws, sr) & SR_RF_NOT_EMPT) + && (dws->rx < dws->rx_end)) { + dw_readw(dws, dr); + dws->rx += n_bytes; + } + wait_till_not_busy(dws); + return dws->rx == dws->rx_end; +} + +static int u8_writer(struct dw_spi *dws) +{ + if (!(dw_readw(dws, sr) & SR_TF_NOT_FULL) + || (dws->tx == dws->tx_end)) + return 0; + + dw_writew(dws, dr, *(u8 *)(dws->tx)); + ++dws->tx; + + wait_till_not_busy(dws); + return 1; +} + +static int u8_reader(struct dw_spi *dws) +{ + while ((dw_readw(dws, sr) & SR_RF_NOT_EMPT) + && (dws->rx < dws->rx_end)) { + *(u8 *)(dws->rx) = dw_readw(dws, dr); + ++dws->rx; + } + + wait_till_not_busy(dws); + return dws->rx == dws->rx_end; +} + +static int u16_writer(struct dw_spi *dws) +{ + if (!(dw_readw(dws, sr) & SR_TF_NOT_FULL) + || (dws->tx == dws->tx_end)) + return 0; + + dw_writew(dws, dr, *(u16 *)(dws->tx)); + dws->tx += 2; + + wait_till_not_busy(dws); + return 1; +} + +static int u16_reader(struct dw_spi *dws) +{ + u16 temp; + + while ((dw_readw(dws, sr) & SR_RF_NOT_EMPT) + && (dws->rx < dws->rx_end)) { + temp = dw_readw(dws, dr); + *(u16 *)(dws->rx) = temp; + dws->rx += 2; + } + + wait_till_not_busy(dws); + return dws->rx == dws->rx_end; +} + +static void *next_transfer(struct dw_spi *dws) +{ + struct spi_message *msg = dws->cur_msg; + struct spi_transfer *trans = dws->cur_transfer; + + /* Move to next transfer */ + if (trans->transfer_list.next != &msg->transfers) { + dws->cur_transfer = + list_entry(trans->transfer_list.next, + struct spi_transfer, + transfer_list); + return RUNNING_STATE; + } else + return DONE_STATE; +} + +/* + * Note: first step is the protocol driver prepares + * a dma-capable memory, and this func just need translate + * the virt addr to physical + */ +static int map_dma_buffers(struct dw_spi *dws) +{ + if (!dws->cur_msg->is_dma_mapped || !dws->dma_inited + || !dws->cur_chip->enable_dma) + return 0; + + if (dws->cur_transfer->tx_dma) + dws->tx_dma = dws->cur_transfer->tx_dma; + + if (dws->cur_transfer->rx_dma) + dws->rx_dma = dws->cur_transfer->rx_dma; + + return 1; +} + +/* Caller already set message->status; dma and pio irqs are blocked */ +static void giveback(struct dw_spi *dws) +{ + struct spi_transfer *last_transfer; + unsigned long flags; + struct spi_message *msg; + + spin_lock_irqsave(&dws->lock, flags); + msg = dws->cur_msg; + dws->cur_msg = NULL; + dws->cur_transfer = NULL; + dws->prev_chip = dws->cur_chip; + dws->cur_chip = NULL; + dws->dma_mapped = 0; + queue_work(dws->workqueue, &dws->pump_messages); + spin_unlock_irqrestore(&dws->lock, flags); + + last_transfer = list_entry(msg->transfers.prev, + struct spi_transfer, + transfer_list); + + if (!last_transfer->cs_change) + dws->cs_control(MRST_SPI_DEASSERT); + + msg->state = NULL; + if (msg->complete) + msg->complete(msg->context); +} + +static void int_error_stop(struct dw_spi *dws, const char *msg) +{ + /* Stop and reset hw */ + flush(dws); + spi_enable_chip(dws, 0); + + dev_err(&dws->master->dev, "%s\n", msg); + dws->cur_msg->state = ERROR_STATE; + tasklet_schedule(&dws->pump_transfers); +} + +static void transfer_complete(struct dw_spi *dws) +{ + /* Update total byte transfered return count actual bytes read */ + dws->cur_msg->actual_length += dws->len; + + /* Move to next transfer */ + dws->cur_msg->state = next_transfer(dws); + + /* Handle end of message */ + if (dws->cur_msg->state == DONE_STATE) { + dws->cur_msg->status = 0; + giveback(dws); + } else + tasklet_schedule(&dws->pump_transfers); +} + +static irqreturn_t interrupt_transfer(struct dw_spi *dws) +{ + u16 irq_status, irq_mask = 0x3f; + + irq_status = dw_readw(dws, isr) & irq_mask; + /* Error handling */ + if (irq_status & (SPI_INT_TXOI | SPI_INT_RXOI | SPI_INT_RXUI)) { + dw_readw(dws, txoicr); + dw_readw(dws, rxoicr); + dw_readw(dws, rxuicr); + int_error_stop(dws, "interrupt_transfer: fifo overrun"); + return IRQ_HANDLED; + } + + /* INT comes from tx */ + if (dws->tx && (irq_status & SPI_INT_TXEI)) { + while (dws->tx < dws->tx_end) + dws->write(dws); + + if (dws->tx == dws->tx_end) { + spi_mask_intr(dws, SPI_INT_TXEI); + transfer_complete(dws); + } + } + + /* INT comes from rx */ + if (dws->rx && (irq_status & SPI_INT_RXFI)) { + if (dws->read(dws)) + transfer_complete(dws); + } + return IRQ_HANDLED; +} + +static irqreturn_t dw_spi_irq(int irq, void *dev_id) +{ + struct dw_spi *dws = dev_id; + + if (!dws->cur_msg) { + spi_mask_intr(dws, SPI_INT_TXEI); + /* Never fail */ + return IRQ_HANDLED; + } + + return dws->transfer_handler(dws); +} + +/* Must be called inside pump_transfers() */ +static void poll_transfer(struct dw_spi *dws) +{ + if (dws->tx) { + while (dws->write(dws)) + dws->read(dws); + } + + dws->read(dws); + transfer_complete(dws); +} + +static void dma_transfer(struct dw_spi *dws, int cs_change) +{ +} + +static void pump_transfers(unsigned long data) +{ + struct dw_spi *dws = (struct dw_spi *)data; + struct spi_message *message = NULL; + struct spi_transfer *transfer = NULL; + struct spi_transfer *previous = NULL; + struct spi_device *spi = NULL; + struct chip_data *chip = NULL; + u8 bits = 0; + u8 imask = 0; + u8 cs_change = 0; + u16 clk_div = 0; + u32 speed = 0; + u32 cr0 = 0; + + /* Get current state information */ + message = dws->cur_msg; + transfer = dws->cur_transfer; + chip = dws->cur_chip; + spi = message->spi; + + if (message->state == ERROR_STATE) { + message->status = -EIO; + goto early_exit; + } + + /* Handle end of message */ + if (message->state == DONE_STATE) { + message->status = 0; + goto early_exit; + } + + /* Delay if requested at end of transfer*/ + if (message->state == RUNNING_STATE) { + previous = list_entry(transfer->transfer_list.prev, + struct spi_transfer, + transfer_list); + if (previous->delay_usecs) + udelay(previous->delay_usecs); + } + + dws->n_bytes = chip->n_bytes; + dws->dma_width = chip->dma_width; + dws->cs_control = chip->cs_control; + + dws->rx_dma = transfer->rx_dma; + dws->tx_dma = transfer->tx_dma; + dws->tx = (void *)transfer->tx_buf; + dws->tx_end = dws->tx + transfer->len; + dws->rx = transfer->rx_buf; + dws->rx_end = dws->rx + transfer->len; + dws->write = dws->tx ? chip->write : null_writer; + dws->read = dws->rx ? chip->read : null_reader; + dws->cs_change = transfer->cs_change; + dws->len = dws->cur_transfer->len; + if (chip != dws->prev_chip) + cs_change = 1; + + cr0 = chip->cr0; + + /* Handle per transfer options for bpw and speed */ + if (transfer->speed_hz) { + speed = chip->speed_hz; + + if (transfer->speed_hz != speed) { + speed = transfer->speed_hz; + if (speed > dws->max_freq) { + printk(KERN_ERR "MRST SPI0: unsupported" + "freq: %dHz\n", speed); + message->status = -EIO; + goto early_exit; + } + + /* clk_div doesn't support odd number */ + clk_div = dws->max_freq / speed; + clk_div = (clk_div >> 1) << 1; + + chip->speed_hz = speed; + chip->clk_div = clk_div; + } + } + if (transfer->bits_per_word) { + bits = transfer->bits_per_word; + + switch (bits) { + case 8: + dws->n_bytes = 1; + dws->dma_width = 1; + dws->read = (dws->read != null_reader) ? + u8_reader : null_reader; + dws->write = (dws->write != null_writer) ? + u8_writer : null_writer; + break; + case 16: + dws->n_bytes = 2; + dws->dma_width = 2; + dws->read = (dws->read != null_reader) ? + u16_reader : null_reader; + dws->write = (dws->write != null_writer) ? + u16_writer : null_writer; + break; + default: + printk(KERN_ERR "MRST SPI0: unsupported bits:" + "%db\n", bits); + message->status = -EIO; + goto early_exit; + } + + cr0 = (bits - 1) + | (chip->type << SPI_FRF_OFFSET) + | (spi->mode << SPI_MODE_OFFSET) + | (chip->tmode << SPI_TMOD_OFFSET); + } + message->state = RUNNING_STATE; + + /* Check if current transfer is a DMA transaction */ + dws->dma_mapped = map_dma_buffers(dws); + + if (!dws->dma_mapped && !chip->poll_mode) { + if (dws->rx) + imask |= SPI_INT_RXFI; + if (dws->tx) + imask |= SPI_INT_TXEI; + dws->transfer_handler = interrupt_transfer; + } + + /* + * Reprogram registers only if + * 1. chip select changes + * 2. clk_div is changed + * 3. control value changes + */ + if (dw_readw(dws, ctrl0) != cr0 || cs_change || clk_div) { + spi_enable_chip(dws, 0); + + if (dw_readw(dws, ctrl0) != cr0) + dw_writew(dws, ctrl0, cr0); + + /* Set the interrupt mask, for poll mode just diable all int */ + spi_mask_intr(dws, 0xff); + if (!chip->poll_mode) + spi_umask_intr(dws, imask); + + spi_set_clk(dws, clk_div ? clk_div : chip->clk_div); + spi_chip_sel(dws, spi->chip_select); + spi_enable_chip(dws, 1); + + if (cs_change) + dws->prev_chip = chip; + } + + if (dws->dma_mapped) + dma_transfer(dws, cs_change); + + if (chip->poll_mode) + poll_transfer(dws); + + return; + +early_exit: + giveback(dws); + return; +} + +static void pump_messages(struct work_struct *work) +{ + struct dw_spi *dws = + container_of(work, struct dw_spi, pump_messages); + unsigned long flags; + + /* Lock queue and check for queue work */ + spin_lock_irqsave(&dws->lock, flags); + if (list_empty(&dws->queue) || dws->run == QUEUE_STOPPED) { + dws->busy = 0; + spin_unlock_irqrestore(&dws->lock, flags); + return; + } + + /* Make sure we are not already running a message */ + if (dws->cur_msg) { + spin_unlock_irqrestore(&dws->lock, flags); + return; + } + + /* Extract head of queue */ + dws->cur_msg = list_entry(dws->queue.next, struct spi_message, queue); + list_del_init(&dws->cur_msg->queue); + + /* Initial message state*/ + dws->cur_msg->state = START_STATE; + dws->cur_transfer = list_entry(dws->cur_msg->transfers.next, + struct spi_transfer, + transfer_list); + dws->cur_chip = spi_get_ctldata(dws->cur_msg->spi); + + /* Mark as busy and launch transfers */ + tasklet_schedule(&dws->pump_transfers); + + dws->busy = 1; + spin_unlock_irqrestore(&dws->lock, flags); +} + +/* spi_device use this to queue in their spi_msg */ +static int dw_spi_transfer(struct spi_device *spi, struct spi_message *msg) +{ + struct dw_spi *dws = spi_master_get_devdata(spi->master); + unsigned long flags; + + spin_lock_irqsave(&dws->lock, flags); + + if (dws->run == QUEUE_STOPPED) { + spin_unlock_irqrestore(&dws->lock, flags); + return -ESHUTDOWN; + } + + msg->actual_length = 0; + msg->status = -EINPROGRESS; + msg->state = START_STATE; + + list_add_tail(&msg->queue, &dws->queue); + + if (dws->run == QUEUE_RUNNING && !dws->busy) { + + if (dws->cur_transfer || dws->cur_msg) + queue_work(dws->workqueue, + &dws->pump_messages); + else { + /* If no other data transaction in air, just go */ + spin_unlock_irqrestore(&dws->lock, flags); + pump_messages(&dws->pump_messages); + return 0; + } + } + + spin_unlock_irqrestore(&dws->lock, flags); + return 0; +} + +/* This may be called twice for each spi dev */ +static int dw_spi_setup(struct spi_device *spi) +{ + struct dw_spi_chip *chip_info = NULL; + struct chip_data *chip; + + if (spi->bits_per_word != 8 && spi->bits_per_word != 16) + return -EINVAL; + + /* Only alloc on first setup */ + chip = spi_get_ctldata(spi); + if (!chip) { + chip = kzalloc(sizeof(struct chip_data), GFP_KERNEL); + if (!chip) + return -ENOMEM; + + chip->cs_control = null_cs_control; + chip->enable_dma = 0; + } + + /* + * Protocol drivers may change the chip settings, so... + * if chip_info exists, use it + */ + chip_info = spi->controller_data; + + /* chip_info doesn't always exist */ + if (chip_info) { + if (chip_info->cs_control) + chip->cs_control = chip_info->cs_control; + + chip->poll_mode = chip_info->poll_mode; + chip->type = chip_info->type; + + chip->rx_threshold = 0; + chip->tx_threshold = 0; + + chip->enable_dma = chip_info->enable_dma; + } + + if (spi->bits_per_word <= 8) { + chip->n_bytes = 1; + chip->dma_width = 1; + chip->read = u8_reader; + chip->write = u8_writer; + } else if (spi->bits_per_word <= 16) { + chip->n_bytes = 2; + chip->dma_width = 2; + chip->read = u16_reader; + chip->write = u16_writer; + } else { + /* Never take >16b case for MRST SPIC */ + dev_err(&spi->dev, "invalid wordsize\n"); + return -EINVAL; + } + chip->bits_per_word = spi->bits_per_word; + + chip->speed_hz = spi->max_speed_hz; + if (chip->speed_hz) + chip->clk_div = 25000000 / chip->speed_hz; + else + chip->clk_div = 8; /* default value */ + + chip->tmode = 0; /* Tx & Rx */ + /* Default SPI mode is SCPOL = 0, SCPH = 0 */ + chip->cr0 = (chip->bits_per_word - 1) + | (chip->type << SPI_FRF_OFFSET) + | (spi->mode << SPI_MODE_OFFSET) + | (chip->tmode << SPI_TMOD_OFFSET); + + spi_set_ctldata(spi, chip); + return 0; +} + +static void dw_spi_cleanup(struct spi_device *spi) +{ + struct chip_data *chip = spi_get_ctldata(spi); + kfree(chip); +} + +static int __init init_queue(struct dw_spi *dws) +{ + INIT_LIST_HEAD(&dws->queue); + spin_lock_init(&dws->lock); + + dws->run = QUEUE_STOPPED; + dws->busy = 0; + + tasklet_init(&dws->pump_transfers, + pump_transfers, (unsigned long)dws); + + INIT_WORK(&dws->pump_messages, pump_messages); + dws->workqueue = create_singlethread_workqueue( + dev_name(dws->master->dev.parent)); + if (dws->workqueue == NULL) + return -EBUSY; + + return 0; +} + +static int start_queue(struct dw_spi *dws) +{ + unsigned long flags; + + spin_lock_irqsave(&dws->lock, flags); + + if (dws->run == QUEUE_RUNNING || dws->busy) { + spin_unlock_irqrestore(&dws->lock, flags); + return -EBUSY; + } + + dws->run = QUEUE_RUNNING; + dws->cur_msg = NULL; + dws->cur_transfer = NULL; + dws->cur_chip = NULL; + dws->prev_chip = NULL; + spin_unlock_irqrestore(&dws->lock, flags); + + queue_work(dws->workqueue, &dws->pump_messages); + + return 0; +} + +static int stop_queue(struct dw_spi *dws) +{ + unsigned long flags; + unsigned limit = 50; + int status = 0; + + spin_lock_irqsave(&dws->lock, flags); + dws->run = QUEUE_STOPPED; + while (!list_empty(&dws->queue) && dws->busy && limit--) { + spin_unlock_irqrestore(&dws->lock, flags); + msleep(10); + spin_lock_irqsave(&dws->lock, flags); + } + + if (!list_empty(&dws->queue) || dws->busy) + status = -EBUSY; + spin_unlock_irqrestore(&dws->lock, flags); + + return status; +} + +static int destroy_queue(struct dw_spi *dws) +{ + int status; + + status = stop_queue(dws); + if (status != 0) + return status; + destroy_workqueue(dws->workqueue); + return 0; +} + +/* Restart the controller, disable all interrupts, clean rx fifo */ +static void spi_hw_init(struct dw_spi *dws) +{ + spi_enable_chip(dws, 0); + spi_mask_intr(dws, 0xff); + spi_enable_chip(dws, 1); + flush(dws); +} + +int __devinit dw_spi_add_host(struct dw_spi *dws) +{ + struct spi_master *master; + int ret; + + BUG_ON(dws == NULL); + + master = spi_alloc_master(dws->parent_dev, 0); + if (!master) { + ret = -ENOMEM; + goto exit; + } + + dws->master = master; + dws->type = SSI_MOTO_SPI; + dws->prev_chip = NULL; + dws->dma_inited = 0; + dws->dma_addr = (dma_addr_t)(dws->paddr + 0x60); + + ret = request_irq(dws->irq, dw_spi_irq, 0, + "dw_spi", dws); + if (ret < 0) { + dev_err(&master->dev, "can not get IRQ\n"); + goto err_free_master; + } + + master->mode_bits = SPI_CPOL | SPI_CPHA; + master->bus_num = dws->bus_num; + master->num_chipselect = dws->num_cs; + master->cleanup = dw_spi_cleanup; + master->setup = dw_spi_setup; + master->transfer = dw_spi_transfer; + + dws->dma_inited = 0; + + /* Basic HW init */ + spi_hw_init(dws); + + /* Initial and start queue */ + ret = init_queue(dws); + if (ret) { + dev_err(&master->dev, "problem initializing queue\n"); + goto err_diable_hw; + } + ret = start_queue(dws); + if (ret) { + dev_err(&master->dev, "problem starting queue\n"); + goto err_diable_hw; + } + + spi_master_set_devdata(master, dws); + ret = spi_register_master(master); + if (ret) { + dev_err(&master->dev, "problem registering spi master\n"); + goto err_queue_alloc; + } + + mrst_spi_debugfs_init(dws); + return 0; + +err_queue_alloc: + destroy_queue(dws); +err_diable_hw: + spi_enable_chip(dws, 0); + free_irq(dws->irq, dws); +err_free_master: + spi_master_put(master); +exit: + return ret; +} +EXPORT_SYMBOL(dw_spi_add_host); + +void __devexit dw_spi_remove_host(struct dw_spi *dws) +{ + int status = 0; + + if (!dws) + return; + mrst_spi_debugfs_remove(dws); + + /* Remove the queue */ + status = destroy_queue(dws); + if (status != 0) + dev_err(&dws->master->dev, "dw_spi_remove: workqueue will not " + "complete, message memory not freed\n"); + + spi_enable_chip(dws, 0); + /* Disable clk */ + spi_set_clk(dws, 0); + free_irq(dws->irq, dws); + + /* Disconnect from the SPI framework */ + spi_unregister_master(dws->master); +} + +int dw_spi_suspend_host(struct dw_spi *dws) +{ + int ret = 0; + + ret = stop_queue(dws); + if (ret) + return ret; + spi_enable_chip(dws, 0); + spi_set_clk(dws, 0); + return ret; +} +EXPORT_SYMBOL(dw_spi_suspend_host); + +int dw_spi_resume_host(struct dw_spi *dws) +{ + int ret; + + spi_hw_init(dws); + ret = start_queue(dws); + if (ret) + dev_err(&dws->master->dev, "fail to start queue (%d)\n", ret); + return ret; +} +EXPORT_SYMBOL(dw_spi_resume_host); + +MODULE_AUTHOR("Feng Tang "); +MODULE_DESCRIPTION("Driver for DesignWare SPI controller core"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/spi/dw_spi_pci.c b/drivers/spi/dw_spi_pci.c new file mode 100644 index 0000000..34ba691 --- /dev/null +++ b/drivers/spi/dw_spi_pci.c @@ -0,0 +1,169 @@ +/* + * mrst_spi_pci.c - PCI interface driver for DW SPI Core + * + * Copyright (c) 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. + */ + +#include +#include +#include +#include + +#define DRIVER_NAME "dw_spi_pci" + +struct dw_spi_pci { + struct pci_dev *pdev; + struct dw_spi dws; +}; + +static int __devinit spi_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + struct dw_spi_pci *dwpci; + struct dw_spi *dws; + int pci_bar = 0; + int ret; + + printk(KERN_INFO "DW: found PCI SPI controller(ID: %04x:%04x)\n", + pdev->vendor, pdev->device); + + ret = pci_enable_device(pdev); + if (ret) + return ret; + + dwpci = kzalloc(sizeof(struct dw_spi_pci), GFP_KERNEL); + if (!dwpci) { + ret = -ENOMEM; + goto err_disable; + } + + dwpci->pdev = pdev; + dws = &dwpci->dws; + + /* Get basic io resource and map it */ + dws->paddr = pci_resource_start(pdev, pci_bar); + dws->iolen = pci_resource_len(pdev, pci_bar); + + ret = pci_request_region(pdev, pci_bar, dev_name(&pdev->dev)); + if (ret) + goto err_kfree; + + dws->regs = ioremap_nocache((unsigned long)dws->paddr, + pci_resource_len(pdev, pci_bar)); + if (!dws->regs) { + ret = -ENOMEM; + goto err_release_reg; + } + + dws->parent_dev = &pdev->dev; + dws->bus_num = 0; + dws->num_cs = 4; + dws->max_freq = 25000000; /* for Moorestwon */ + dws->irq = pdev->irq; + + ret = dw_spi_add_host(dws); + if (ret) + goto err_unmap; + + /* PCI hook and SPI hook use the same drv data */ + pci_set_drvdata(pdev, dwpci); + return 0; + +err_unmap: + iounmap(dws->regs); +err_release_reg: + pci_release_region(pdev, pci_bar); +err_kfree: + kfree(dwpci); +err_disable: + pci_disable_device(pdev); + return ret; +} + +static void __devexit spi_pci_remove(struct pci_dev *pdev) +{ + struct dw_spi_pci *dwpci = pci_get_drvdata(pdev); + + pci_set_drvdata(pdev, NULL); + iounmap(dwpci->dws.regs); + pci_release_region(pdev, 0); + kfree(dwpci); + pci_disable_device(pdev); +} + +#ifdef CONFIG_PM +static int spi_suspend(struct pci_dev *pdev, pm_message_t state) +{ + struct dw_spi_pci *dwpci = pci_get_drvdata(pdev); + int ret; + + ret = dw_spi_suspend_host(&dwpci->dws); + if (ret) + return ret; + pci_save_state(pdev); + pci_disable_device(pdev); + pci_set_power_state(pdev, pci_choose_state(pdev, state)); + return ret; +} + +static int spi_resume(struct pci_dev *pdev) +{ + struct dw_spi_pci *dwpci = pci_get_drvdata(pdev); + int ret; + + pci_set_power_state(pdev, PCI_D0); + pci_restore_state(pdev); + ret = pci_enable_device(pdev); + if (ret) + return ret; + return dw_spi_resume_host(&dwpci->dws); +} +#else +#define spi_suspend NULL +#define spi_resume NULL +#endif + +static const struct pci_device_id pci_ids[] __devinitdata = { + /* Intel Moorestown platform SPI controller 0 */ + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0800) }, + {}, +}; + +static struct pci_driver dw_spi_driver = { + .name = DRIVER_NAME, + .id_table = pci_ids, + .probe = spi_pci_probe, + .remove = __devexit_p(spi_pci_remove), + .suspend = spi_suspend, + .resume = spi_resume, +}; + +static int __init mrst_spi_init(void) +{ + return pci_register_driver(&dw_spi_driver); +} + +static void __exit mrst_spi_exit(void) +{ + pci_unregister_driver(&dw_spi_driver); +} + +module_init(mrst_spi_init); +module_exit(mrst_spi_exit); + +MODULE_AUTHOR("Feng Tang "); +MODULE_DESCRIPTION("PCI interface driver for DW SPI Core"); +MODULE_LICENSE("GPL v2"); diff --git a/include/linux/spi/dw_spi.h b/include/linux/spi/dw_spi.h new file mode 100644 index 0000000..51b3e77 --- /dev/null +++ b/include/linux/spi/dw_spi.h @@ -0,0 +1,212 @@ +#ifndef DW_SPI_HEADER_H +#define DW_SPI_HEADER_H +#include + +/* Bit fields in CTRLR0 */ +#define SPI_DFS_OFFSET 0 + +#define SPI_FRF_OFFSET 4 +#define SPI_FRF_SPI 0x0 +#define SPI_FRF_SSP 0x1 +#define SPI_FRF_MICROWIRE 0x2 +#define SPI_FRF_RESV 0x3 + +#define SPI_MODE_OFFSET 6 +#define SPI_SCPH_OFFSET 6 +#define SPI_SCOL_OFFSET 7 +#define SPI_TMOD_OFFSET 8 +#define SPI_TMOD_TR 0x0 /* xmit & recv */ +#define SPI_TMOD_TO 0x1 /* xmit only */ +#define SPI_TMOD_RO 0x2 /* recv only */ +#define SPI_TMOD_EPROMREAD 0x3 /* eeprom read mode */ + +#define SPI_SLVOE_OFFSET 10 +#define SPI_SRL_OFFSET 11 +#define SPI_CFS_OFFSET 12 + +/* Bit fields in SR, 7 bits */ +#define SR_MASK 0x7f /* cover 7 bits */ +#define SR_BUSY (1 << 0) +#define SR_TF_NOT_FULL (1 << 1) +#define SR_TF_EMPT (1 << 2) +#define SR_RF_NOT_EMPT (1 << 3) +#define SR_RF_FULL (1 << 4) +#define SR_TX_ERR (1 << 5) +#define SR_DCOL (1 << 6) + +/* Bit fields in ISR, IMR, RISR, 7 bits */ +#define SPI_INT_TXEI (1 << 0) +#define SPI_INT_TXOI (1 << 1) +#define SPI_INT_RXUI (1 << 2) +#define SPI_INT_RXOI (1 << 3) +#define SPI_INT_RXFI (1 << 4) +#define SPI_INT_MSTI (1 << 5) + +/* TX RX interrupt level threshhold, max can be 256 */ +#define SPI_INT_THRESHOLD 32 + +enum dw_ssi_type { + SSI_MOTO_SPI = 0, + SSI_TI_SSP, + SSI_NS_MICROWIRE, +}; + +struct dw_spi_reg { + u32 ctrl0; + u32 ctrl1; + u32 ssienr; + u32 mwcr; + u32 ser; + u32 baudr; + u32 txfltr; + u32 rxfltr; + u32 txflr; + u32 rxflr; + u32 sr; + u32 imr; + u32 isr; + u32 risr; + u32 txoicr; + u32 rxoicr; + u32 rxuicr; + u32 msticr; + u32 icr; + u32 dmacr; + u32 dmatdlr; + u32 dmardlr; + u32 idr; + u32 version; + u32 dr; /* Currently oper as 32 bits, + though only low 16 bits matters */ +} __packed; + +struct dw_spi { + struct spi_master *master; + struct spi_device *cur_dev; + struct device *parent_dev; + enum dw_ssi_type type; + + void __iomem *regs; + unsigned long paddr; + u32 iolen; + int irq; + u32 max_freq; /* max bus freq supported */ + + u16 bus_num; + u16 num_cs; /* supported slave numbers */ + + /* Driver message queue */ + struct workqueue_struct *workqueue; + struct work_struct pump_messages; + spinlock_t lock; + struct list_head queue; + int busy; + int run; + + /* Message Transfer pump */ + struct tasklet_struct pump_transfers; + + /* Current message transfer state info */ + struct spi_message *cur_msg; + struct spi_transfer *cur_transfer; + struct chip_data *cur_chip; + struct chip_data *prev_chip; + size_t len; + void *tx; + void *tx_end; + void *rx; + void *rx_end; + int dma_mapped; + dma_addr_t rx_dma; + dma_addr_t tx_dma; + size_t rx_map_len; + size_t tx_map_len; + u8 n_bytes; /* current is a 1/2 bytes op */ + u8 max_bits_per_word; /* maxim is 16b */ + u32 dma_width; + int cs_change; + int (*write)(struct dw_spi *dws); + int (*read)(struct dw_spi *dws); + irqreturn_t (*transfer_handler)(struct dw_spi *dws); + void (*cs_control)(u32 command); + + /* Dma info */ + int dma_inited; + struct dma_chan *txchan; + struct dma_chan *rxchan; + int txdma_done; + int rxdma_done; + u64 tx_param; + u64 rx_param; + struct device *dma_dev; + dma_addr_t dma_addr; + + /* Bus interface info */ + void *priv; +#ifdef CONFIG_DEBUG_FS + struct dentry *debugfs; +#endif +}; + +#define dw_readl(dw, name) \ + __raw_readl(&(((struct dw_spi_reg *)dw->regs)->name)) +#define dw_writel(dw, name, val) \ + __raw_writel((val), &(((struct dw_spi_reg *)dw->regs)->name)) +#define dw_readw(dw, name) \ + __raw_readw(&(((struct dw_spi_reg *)dw->regs)->name)) +#define dw_writew(dw, name, val) \ + __raw_writew((val), &(((struct dw_spi_reg *)dw->regs)->name)) + +static inline void spi_enable_chip(struct dw_spi *dws, int enable) +{ + dw_writel(dws, ssienr, (enable ? 1 : 0)); +} + +static inline void spi_set_clk(struct dw_spi *dws, u16 div) +{ + dw_writel(dws, baudr, div); +} + +static inline void spi_chip_sel(struct dw_spi *dws, u16 cs) +{ + if (cs > dws->num_cs) + return; + dw_writel(dws, ser, 1 << cs); +} + +/* Disable IRQ bits */ +static inline void spi_mask_intr(struct dw_spi *dws, u32 mask) +{ + u32 new_mask; + + new_mask = dw_readl(dws, imr) & ~mask; + dw_writel(dws, imr, new_mask); +} + +/* Enable IRQ bits */ +static inline void spi_umask_intr(struct dw_spi *dws, u32 mask) +{ + u32 new_mask; + + new_mask = dw_readl(dws, imr) | mask; + dw_writel(dws, imr, new_mask); +} + +/* + * Each SPI slave device to work with dw_api controller should + * has such a structure claiming its working mode (PIO/DMA etc), + * which can be save in the "controller_data" member of the + * struct spi_device + */ +struct dw_spi_chip { + u8 poll_mode; /* 0 for contoller polling mode */ + u8 type; /* SPI/SSP/Micrwire */ + u8 enable_dma; + void (*cs_control)(u32 command); +}; + +extern int dw_spi_add_host(struct dw_spi *dws); +extern void dw_spi_remove_host(struct dw_spi *dws); +extern int dw_spi_suspend_host(struct dw_spi *dws); +extern int dw_spi_resume_host(struct dw_spi *dws); +#endif /* DW_SPI_HEADER_H */ -- cgit v0.10.2 From b9aff027b2c1d6019d237382c78fd396f9de2ea5 Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Fri, 20 Nov 2009 14:28:35 -0800 Subject: fs: anon_inodes implement dname Add a d_dname method for anon_inodes filesystem, the same way pipefs and sockfs pseudo filesystems. This allows us to remove the DCACHE_UNHASHED hack from anon_inodes.c (see next patch). [AV: inumber is useless here, dropped from anon_inodefs_dname()] Signed-off-by: Nick Piggin Cc: Miklos Szeredi Cc: Davide Libenzi Cc: "David S. Miller" Cc: Jens Axboe Cc: Christoph Hellwig Cc: Al Viro Signed-off-by: Andrew Morton Signed-off-by: Al Viro diff --git a/fs/anon_inodes.c b/fs/anon_inodes.c index 94f5110..01c529a 100644 --- a/fs/anon_inodes.c +++ b/fs/anon_inodes.c @@ -45,6 +45,15 @@ static int anon_inodefs_delete_dentry(struct dentry *dentry) return 1; } +/* + * anon_inodefs_dname() is called from d_path(). + */ +static char *anon_inodefs_dname(struct dentry *dentry, char *buffer, int buflen) +{ + return dynamic_dname(dentry, buffer, buflen, "anon_inode:%s", + dentry->d_name.name); +} + static struct file_system_type anon_inode_fs_type = { .name = "anon_inodefs", .get_sb = anon_inodefs_get_sb, @@ -52,6 +61,7 @@ static struct file_system_type anon_inode_fs_type = { }; static const struct dentry_operations anon_inodefs_dentry_operations = { .d_delete = anon_inodefs_delete_dentry, + .d_dname = anon_inodefs_dname, }; /* -- cgit v0.10.2 From a3a065e3f13da8a3470ed09c7f38aad256083726 Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Wed, 18 Nov 2009 05:30:19 +0100 Subject: fs: no games with DCACHE_UNHASHED Filesystems outside the regular namespace do not have to clear DCACHE_UNHASHED in order to have a working /proc/$pid/fd/XXX. Nothing in proc prevents the fd link from being used if its dentry is not in the hash. Also, it does not get put into the dcache hash if DCACHE_UNHASHED is clear; that depends on the filesystem calling d_add or d_rehash. So delete the misleading comments and needless code. Acked-by: Miklos Szeredi Signed-off-by: Nick Piggin Signed-off-by: Al Viro diff --git a/fs/anon_inodes.c b/fs/anon_inodes.c index 01c529a..2c99459 100644 --- a/fs/anon_inodes.c +++ b/fs/anon_inodes.c @@ -35,16 +35,6 @@ static int anon_inodefs_get_sb(struct file_system_type *fs_type, int flags, mnt); } -static int anon_inodefs_delete_dentry(struct dentry *dentry) -{ - /* - * We faked vfs to believe the dentry was hashed when we created it. - * Now we restore the flag so that dput() will work correctly. - */ - dentry->d_flags |= DCACHE_UNHASHED; - return 1; -} - /* * anon_inodefs_dname() is called from d_path(). */ @@ -60,7 +50,6 @@ static struct file_system_type anon_inode_fs_type = { .kill_sb = kill_anon_super, }; static const struct dentry_operations anon_inodefs_dentry_operations = { - .d_delete = anon_inodefs_delete_dentry, .d_dname = anon_inodefs_dname, }; @@ -129,8 +118,6 @@ struct file *anon_inode_getfile(const char *name, atomic_inc(&anon_inode_inode->i_count); path.dentry->d_op = &anon_inodefs_dentry_operations; - /* Do not publish this dentry inside the global dentry hash table */ - path.dentry->d_flags &= ~DCACHE_UNHASHED; d_instantiate(path.dentry, anon_inode_inode); error = -ENFILE; diff --git a/fs/pipe.c b/fs/pipe.c index 43d79da..37ba29f 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -906,17 +906,6 @@ void free_pipe_info(struct inode *inode) } static struct vfsmount *pipe_mnt __read_mostly; -static int pipefs_delete_dentry(struct dentry *dentry) -{ - /* - * At creation time, we pretended this dentry was hashed - * (by clearing DCACHE_UNHASHED bit in d_flags) - * At delete time, we restore the truth : not hashed. - * (so that dput() can proceed correctly) - */ - dentry->d_flags |= DCACHE_UNHASHED; - return 0; -} /* * pipefs_dname() is called from d_path(). @@ -928,7 +917,6 @@ static char *pipefs_dname(struct dentry *dentry, char *buffer, int buflen) } static const struct dentry_operations pipefs_dentry_operations = { - .d_delete = pipefs_delete_dentry, .d_dname = pipefs_dname, }; @@ -989,12 +977,6 @@ struct file *create_write_pipe(int flags) path.mnt = mntget(pipe_mnt); path.dentry->d_op = &pipefs_dentry_operations; - /* - * We dont want to publish this dentry into global dentry hash table. - * We pretend dentry is already hashed, by unsetting DCACHE_UNHASHED - * This permits a working /proc/$pid/fd/XXX on pipes - */ - path.dentry->d_flags &= ~DCACHE_UNHASHED; d_instantiate(path.dentry, inode); err = -ENFILE; diff --git a/net/socket.c b/net/socket.c index dbfdfa9..769c386 100644 --- a/net/socket.c +++ b/net/socket.c @@ -312,18 +312,6 @@ static struct file_system_type sock_fs_type = { .kill_sb = kill_anon_super, }; -static int sockfs_delete_dentry(struct dentry *dentry) -{ - /* - * At creation time, we pretended this dentry was hashed - * (by clearing DCACHE_UNHASHED bit in d_flags) - * At delete time, we restore the truth : not hashed. - * (so that dput() can proceed correctly) - */ - dentry->d_flags |= DCACHE_UNHASHED; - return 0; -} - /* * sockfs_dname() is called from d_path(). */ @@ -334,7 +322,6 @@ static char *sockfs_dname(struct dentry *dentry, char *buffer, int buflen) } static const struct dentry_operations sockfs_dentry_operations = { - .d_delete = sockfs_delete_dentry, .d_dname = sockfs_dname, }; @@ -374,12 +361,6 @@ static int sock_alloc_file(struct socket *sock, struct file **f, int flags) path.mnt = mntget(sock_mnt); path.dentry->d_op = &sockfs_dentry_operations; - /* - * We dont want to push this dentry into global dentry hash table. - * We pretend dentry is already hashed, by unsetting DCACHE_UNHASHED - * This permits a working /proc/$pid/fd/XXX on sockets - */ - path.dentry->d_flags &= ~DCACHE_UNHASHED; d_instantiate(path.dentry, SOCK_INODE(sock)); SOCK_INODE(sock)->i_fop = &socket_file_ops; -- cgit v0.10.2 From cb59861f03a626196a23fdef5e20ddbb8cca6466 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Mon, 16 Nov 2009 12:05:20 -0800 Subject: vfs: remove extraneous NULL d_inode check from do_filp_open We can't get to this point unless it's a valid pointer. Signed-off-by: Jeff Layton Cc: Al Viro Cc: Christoph Hellwig Signed-off-by: Andrew Morton Signed-off-by: Al Viro diff --git a/fs/namei.c b/fs/namei.c index d2783c8..dad4b80 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -1764,7 +1764,7 @@ do_last: path_to_nameidata(&path, &nd); error = -EISDIR; - if (path.dentry->d_inode && S_ISDIR(path.dentry->d_inode->i_mode)) + if (S_ISDIR(path.dentry->d_inode->i_mode)) goto exit; ok: /* -- cgit v0.10.2 From bec0806cfec6ded1a7e097bb95279e521a796129 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 14 Dec 2009 22:20:24 -0800 Subject: spi_s3c24xx: add FIQ pseudo-DMA support Add pseudo-DMA by FIQ to the S3C24XX SPI driver. This allows the driver to get DMA-like performance where there are either no free DMA channels or when doing transfers that required both TX and RX data paths. Since this patch requires the addition of an assembly file to hold the FIQ code, we rename the module (instead of adding a rename of the .c file to this patch). We expect most users are loading this via udev and thus there should be no change to the userland configuration. Signed-off-by: Ben Dooks Signed-off-by: Simtec Linux Team Cc: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Grant Likely diff --git a/arch/arm/mach-s3c2410/include/mach/spi.h b/arch/arm/mach-s3c2410/include/mach/spi.h index 193b39d..4d95883 100644 --- a/arch/arm/mach-s3c2410/include/mach/spi.h +++ b/arch/arm/mach-s3c2410/include/mach/spi.h @@ -18,6 +18,8 @@ struct s3c2410_spi_info { unsigned int num_cs; /* total chipselects */ int bus_num; /* bus number to use. */ + unsigned int use_fiq:1; /* use fiq */ + void (*gpio_setup)(struct s3c2410_spi_info *spi, int enable); void (*set_cs)(struct s3c2410_spi_info *spi, int cs, int pol); }; diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index d7c1741..6fa595e 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -219,6 +219,17 @@ config SPI_S3C24XX help SPI driver for Samsung S3C24XX series ARM SoCs +config SPI_S3C24XX_FIQ + bool "S3C24XX driver with FIQ pseudo-DMA" + depends on SPI_S3C24XX + select FIQ + help + Enable FIQ support for the S3C24XX SPI driver to provide pseudo + DMA by using the fast-interrupt request framework, This allows + the driver to get DMA-like performance when there are either + no free DMA channels, or when doing transfers that required both + TX and RX data paths. + config SPI_S3C24XX_GPIO tristate "Samsung S3C24XX series SPI by GPIO" depends on ARCH_S3C2410 && EXPERIMENTAL diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index a909e39..33faa7f 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -32,7 +32,7 @@ obj-$(CONFIG_SPI_MPC52xx) += mpc52xx_spi.o obj-$(CONFIG_SPI_MPC8xxx) += spi_mpc8xxx.o obj-$(CONFIG_SPI_PPC4xx) += spi_ppc4xx.o obj-$(CONFIG_SPI_S3C24XX_GPIO) += spi_s3c24xx_gpio.o -obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx.o +obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx_hw.o obj-$(CONFIG_SPI_TXX9) += spi_txx9.o obj-$(CONFIG_SPI_XILINX) += xilinx_spi.o obj-$(CONFIG_SPI_XILINX_OF) += xilinx_spi_of.o @@ -41,6 +41,11 @@ obj-$(CONFIG_SPI_SH_SCI) += spi_sh_sci.o obj-$(CONFIG_SPI_SH_MSIOF) += spi_sh_msiof.o obj-$(CONFIG_SPI_STMP3XXX) += spi_stmp.o obj-$(CONFIG_SPI_NUC900) += spi_nuc900.o + +# special build for s3c24xx spi driver with fiq support +spi_s3c24xx_hw-y := spi_s3c24xx.o +spi_s3c24xx_hw-$(CONFIG_SPI_S3C24XX_FIQ) += spi_s3c24xx_fiq.o + # ... add above this line ... # SPI protocol drivers (device/link on bus) diff --git a/drivers/spi/spi_s3c24xx.c b/drivers/spi/spi_s3c24xx.c index 33d94f7..4b0d25b 100644 --- a/drivers/spi/spi_s3c24xx.c +++ b/drivers/spi/spi_s3c24xx.c @@ -1,7 +1,7 @@ /* linux/drivers/spi/spi_s3c24xx.c * * Copyright (c) 2006 Ben Dooks - * Copyright (c) 2006 Simtec Electronics + * Copyright 2006-2009 Simtec Electronics * Ben Dooks * * This program is free software; you can redistribute it and/or modify @@ -28,6 +28,11 @@ #include #include +#include +#include + +#include "spi_s3c24xx_fiq.h" + /** * s3c24xx_spi_devstate - per device data * @hz: Last frequency calculated for @sppre field. @@ -42,6 +47,13 @@ struct s3c24xx_spi_devstate { u8 sppre; }; +enum spi_fiq_mode { + FIQ_MODE_NONE = 0, + FIQ_MODE_TX = 1, + FIQ_MODE_RX = 2, + FIQ_MODE_TXRX = 3, +}; + struct s3c24xx_spi { /* bitbang has to be first */ struct spi_bitbang bitbang; @@ -52,6 +64,11 @@ struct s3c24xx_spi { int len; int count; + struct fiq_handler fiq_handler; + enum spi_fiq_mode fiq_mode; + unsigned char fiq_inuse; + unsigned char fiq_claimed; + void (*set_cs)(struct s3c2410_spi_info *spi, int cs, int pol); @@ -67,6 +84,7 @@ struct s3c24xx_spi { struct s3c2410_spi_info *pdata; }; + #define SPCON_DEFAULT (S3C2410_SPCON_MSTR | S3C2410_SPCON_SMOD_INT) #define SPPIN_DEFAULT (S3C2410_SPPIN_KEEP) @@ -127,7 +145,7 @@ static int s3c24xx_spi_update_state(struct spi_device *spi, } if (spi->mode != cs->mode) { - u8 spcon = SPCON_DEFAULT; + u8 spcon = SPCON_DEFAULT | S3C2410_SPCON_ENSCK; if (spi->mode & SPI_CPHA) spcon |= S3C2410_SPCON_CPHA_FMTB; @@ -214,13 +232,196 @@ static inline unsigned int hw_txbyte(struct s3c24xx_spi *hw, int count) return hw->tx ? hw->tx[count] : 0; } +#ifdef CONFIG_SPI_S3C24XX_FIQ +/* Support for FIQ based pseudo-DMA to improve the transfer speed. + * + * This code uses the assembly helper in spi_s3c24xx_spi.S which is + * used by the FIQ core to move data between main memory and the peripheral + * block. Since this is code running on the processor, there is no problem + * with cache coherency of the buffers, so we can use any buffer we like. + */ + +/** + * struct spi_fiq_code - FIQ code and header + * @length: The length of the code fragment, excluding this header. + * @ack_offset: The offset from @data to the word to place the IRQ ACK bit at. + * @data: The code itself to install as a FIQ handler. + */ +struct spi_fiq_code { + u32 length; + u32 ack_offset; + u8 data[0]; +}; + +extern struct spi_fiq_code s3c24xx_spi_fiq_txrx; +extern struct spi_fiq_code s3c24xx_spi_fiq_tx; +extern struct spi_fiq_code s3c24xx_spi_fiq_rx; + +/** + * ack_bit - turn IRQ into IRQ acknowledgement bit + * @irq: The interrupt number + * + * Returns the bit to write to the interrupt acknowledge register. + */ +static inline u32 ack_bit(unsigned int irq) +{ + return 1 << (irq - IRQ_EINT0); +} + +/** + * s3c24xx_spi_tryfiq - attempt to claim and setup FIQ for transfer + * @hw: The hardware state. + * + * Claim the FIQ handler (only one can be active at any one time) and + * then setup the correct transfer code for this transfer. + * + * This call updates all the necessary state information if sucessful, + * so the caller does not need to do anything more than start the transfer + * as normal, since the IRQ will have been re-routed to the FIQ handler. +*/ +void s3c24xx_spi_tryfiq(struct s3c24xx_spi *hw) +{ + struct pt_regs regs; + enum spi_fiq_mode mode; + struct spi_fiq_code *code; + int ret; + + if (!hw->fiq_claimed) { + /* try and claim fiq if we haven't got it, and if not + * then return and simply use another transfer method */ + + ret = claim_fiq(&hw->fiq_handler); + if (ret) + return; + } + + if (hw->tx && !hw->rx) + mode = FIQ_MODE_TX; + else if (hw->rx && !hw->tx) + mode = FIQ_MODE_RX; + else + mode = FIQ_MODE_TXRX; + + regs.uregs[fiq_rspi] = (long)hw->regs; + regs.uregs[fiq_rrx] = (long)hw->rx; + regs.uregs[fiq_rtx] = (long)hw->tx + 1; + regs.uregs[fiq_rcount] = hw->len - 1; + regs.uregs[fiq_rirq] = (long)S3C24XX_VA_IRQ; + + set_fiq_regs(®s); + + if (hw->fiq_mode != mode) { + u32 *ack_ptr; + + hw->fiq_mode = mode; + + switch (mode) { + case FIQ_MODE_TX: + code = &s3c24xx_spi_fiq_tx; + break; + case FIQ_MODE_RX: + code = &s3c24xx_spi_fiq_rx; + break; + case FIQ_MODE_TXRX: + code = &s3c24xx_spi_fiq_txrx; + break; + default: + code = NULL; + } + + BUG_ON(!code); + + ack_ptr = (u32 *)&code->data[code->ack_offset]; + *ack_ptr = ack_bit(hw->irq); + + set_fiq_handler(&code->data, code->length); + } + + s3c24xx_set_fiq(hw->irq, true); + + hw->fiq_mode = mode; + hw->fiq_inuse = 1; +} + +/** + * s3c24xx_spi_fiqop - FIQ core code callback + * @pw: Data registered with the handler + * @release: Whether this is a release or a return. + * + * Called by the FIQ code when another module wants to use the FIQ, so + * return whether we are currently using this or not and then update our + * internal state. + */ +static int s3c24xx_spi_fiqop(void *pw, int release) +{ + struct s3c24xx_spi *hw = pw; + int ret = 0; + + if (release) { + if (hw->fiq_inuse) + ret = -EBUSY; + + /* note, we do not need to unroute the FIQ, as the FIQ + * vector code de-routes it to signal the end of transfer */ + + hw->fiq_mode = FIQ_MODE_NONE; + hw->fiq_claimed = 0; + } else { + hw->fiq_claimed = 1; + } + + return ret; +} + +/** + * s3c24xx_spi_initfiq - setup the information for the FIQ core + * @hw: The hardware state. + * + * Setup the fiq_handler block to pass to the FIQ core. + */ +static inline void s3c24xx_spi_initfiq(struct s3c24xx_spi *hw) +{ + hw->fiq_handler.dev_id = hw; + hw->fiq_handler.name = dev_name(hw->dev); + hw->fiq_handler.fiq_op = s3c24xx_spi_fiqop; +} + +/** + * s3c24xx_spi_usefiq - return if we should be using FIQ. + * @hw: The hardware state. + * + * Return true if the platform data specifies whether this channel is + * allowed to use the FIQ. + */ +static inline bool s3c24xx_spi_usefiq(struct s3c24xx_spi *hw) +{ + return hw->pdata->use_fiq; +} + +/** + * s3c24xx_spi_usingfiq - return if channel is using FIQ + * @spi: The hardware state. + * + * Return whether the channel is currently using the FIQ (separate from + * whether the FIQ is claimed). + */ +static inline bool s3c24xx_spi_usingfiq(struct s3c24xx_spi *spi) +{ + return spi->fiq_inuse; +} +#else + +static inline void s3c24xx_spi_initfiq(struct s3c24xx_spi *s) { } +static inline void s3c24xx_spi_tryfiq(struct s3c24xx_spi *s) { } +static inline bool s3c24xx_spi_usefiq(struct s3c24xx_spi *s) { return false; } +static inline bool s3c24xx_spi_usingfiq(struct s3c24xx_spi *s) { return false; } + +#endif /* CONFIG_SPI_S3C24XX_FIQ */ + static int s3c24xx_spi_txrx(struct spi_device *spi, struct spi_transfer *t) { struct s3c24xx_spi *hw = to_hw(spi); - dev_dbg(&spi->dev, "txrx: tx %p, rx %p, len %d\n", - t->tx_buf, t->rx_buf, t->len); - hw->tx = t->tx_buf; hw->rx = t->rx_buf; hw->len = t->len; @@ -228,11 +429,14 @@ static int s3c24xx_spi_txrx(struct spi_device *spi, struct spi_transfer *t) init_completion(&hw->done); + hw->fiq_inuse = 0; + if (s3c24xx_spi_usefiq(hw) && t->len >= 3) + s3c24xx_spi_tryfiq(hw); + /* send the first byte */ writeb(hw_txbyte(hw, 0), hw->regs + S3C2410_SPTDAT); wait_for_completion(&hw->done); - return hw->count; } @@ -254,17 +458,27 @@ static irqreturn_t s3c24xx_spi_irq(int irq, void *dev) goto irq_done; } - hw->count++; + if (!s3c24xx_spi_usingfiq(hw)) { + hw->count++; - if (hw->rx) - hw->rx[count] = readb(hw->regs + S3C2410_SPRDAT); + if (hw->rx) + hw->rx[count] = readb(hw->regs + S3C2410_SPRDAT); - count++; + count++; + + if (count < hw->len) + writeb(hw_txbyte(hw, count), hw->regs + S3C2410_SPTDAT); + else + complete(&hw->done); + } else { + hw->count = hw->len; + hw->fiq_inuse = 0; + + if (hw->rx) + hw->rx[hw->len-1] = readb(hw->regs + S3C2410_SPRDAT); - if (count < hw->len) - writeb(hw_txbyte(hw, count), hw->regs + S3C2410_SPTDAT); - else complete(&hw->done); + } irq_done: return IRQ_HANDLED; @@ -322,6 +536,10 @@ static int __init s3c24xx_spi_probe(struct platform_device *pdev) platform_set_drvdata(pdev, hw); init_completion(&hw->done); + /* initialise fiq handler */ + + s3c24xx_spi_initfiq(hw); + /* setup the master state. */ /* the spi->mode bits understood by this driver: */ diff --git a/drivers/spi/spi_s3c24xx_fiq.S b/drivers/spi/spi_s3c24xx_fiq.S new file mode 100644 index 0000000..3793cae --- /dev/null +++ b/drivers/spi/spi_s3c24xx_fiq.S @@ -0,0 +1,116 @@ +/* linux/drivers/spi/spi_s3c24xx_fiq.S + * + * Copyright 2009 Simtec Electronics + * Ben Dooks + * + * S3C24XX SPI - FIQ pseudo-DMA transfer code + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include +#include + +#include +#include +#include + +#include "spi_s3c24xx_fiq.h" + + .text + + @ entry to these routines is as follows, with the register names + @ defined in fiq.h so that they can be shared with the C files which + @ setup the calling registers. + @ + @ fiq_rirq The base of the IRQ registers to find S3C2410_SRCPND + @ fiq_rtmp Temporary register to hold tx/rx data + @ fiq_rspi The base of the SPI register block + @ fiq_rtx The tx buffer pointer + @ fiq_rrx The rx buffer pointer + @ fiq_rcount The number of bytes to move + + @ each entry starts with a word entry of how long it is + @ and an offset to the irq acknowledgment word + +ENTRY(s3c24xx_spi_fiq_rx) +s3c24xx_spi_fix_rx: + .word fiq_rx_end - fiq_rx_start + .word fiq_rx_irq_ack - fiq_rx_start +fiq_rx_start: + ldr fiq_rtmp, fiq_rx_irq_ack + str fiq_rtmp, [ fiq_rirq, # S3C2410_SRCPND - S3C24XX_VA_IRQ ] + + ldrb fiq_rtmp, [ fiq_rspi, # S3C2410_SPRDAT ] + strb fiq_rtmp, [ fiq_rrx ], #1 + + mov fiq_rtmp, #0xff + strb fiq_rtmp, [ fiq_rspi, # S3C2410_SPTDAT ] + + subs fiq_rcount, fiq_rcount, #1 + subnes pc, lr, #4 @@ return, still have work to do + + @@ set IRQ controller so that next op will trigger IRQ + mov fiq_rtmp, #0 + str fiq_rtmp, [ fiq_rirq, # S3C2410_INTMOD - S3C24XX_VA_IRQ ] + subs pc, lr, #4 + +fiq_rx_irq_ack: + .word 0 +fiq_rx_end: + +ENTRY(s3c24xx_spi_fiq_txrx) +s3c24xx_spi_fiq_txrx: + .word fiq_txrx_end - fiq_txrx_start + .word fiq_txrx_irq_ack - fiq_txrx_start +fiq_txrx_start: + + ldrb fiq_rtmp, [ fiq_rspi, # S3C2410_SPRDAT ] + strb fiq_rtmp, [ fiq_rrx ], #1 + + ldr fiq_rtmp, fiq_txrx_irq_ack + str fiq_rtmp, [ fiq_rirq, # S3C2410_SRCPND - S3C24XX_VA_IRQ ] + + ldrb fiq_rtmp, [ fiq_rtx ], #1 + strb fiq_rtmp, [ fiq_rspi, # S3C2410_SPTDAT ] + + subs fiq_rcount, fiq_rcount, #1 + subnes pc, lr, #4 @@ return, still have work to do + + mov fiq_rtmp, #0 + str fiq_rtmp, [ fiq_rirq, # S3C2410_INTMOD - S3C24XX_VA_IRQ ] + subs pc, lr, #4 + +fiq_txrx_irq_ack: + .word 0 + +fiq_txrx_end: + +ENTRY(s3c24xx_spi_fiq_tx) +s3c24xx_spi_fix_tx: + .word fiq_tx_end - fiq_tx_start + .word fiq_tx_irq_ack - fiq_tx_start +fiq_tx_start: + ldrb fiq_rtmp, [ fiq_rspi, # S3C2410_SPRDAT ] + + ldr fiq_rtmp, fiq_tx_irq_ack + str fiq_rtmp, [ fiq_rirq, # S3C2410_SRCPND - S3C24XX_VA_IRQ ] + + ldrb fiq_rtmp, [ fiq_rtx ], #1 + strb fiq_rtmp, [ fiq_rspi, # S3C2410_SPTDAT ] + + subs fiq_rcount, fiq_rcount, #1 + subnes pc, lr, #4 @@ return, still have work to do + + mov fiq_rtmp, #0 + str fiq_rtmp, [ fiq_rirq, # S3C2410_INTMOD - S3C24XX_VA_IRQ ] + subs pc, lr, #4 + +fiq_tx_irq_ack: + .word 0 + +fiq_tx_end: + + .end diff --git a/drivers/spi/spi_s3c24xx_fiq.h b/drivers/spi/spi_s3c24xx_fiq.h new file mode 100644 index 0000000..a5950bb --- /dev/null +++ b/drivers/spi/spi_s3c24xx_fiq.h @@ -0,0 +1,26 @@ +/* linux/drivers/spi/spi_s3c24xx_fiq.h + * + * Copyright 2009 Simtec Electronics + * Ben Dooks + * + * S3C24XX SPI - FIQ pseudo-DMA transfer support + * + * 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. +*/ + +/* We have R8 through R13 to play with */ + +#ifdef __ASSEMBLY__ +#define __REG_NR(x) r##x +#else +#define __REG_NR(x) (x) +#endif + +#define fiq_rspi __REG_NR(8) +#define fiq_rtmp __REG_NR(9) +#define fiq_rrx __REG_NR(10) +#define fiq_rtx __REG_NR(11) +#define fiq_rcount __REG_NR(12) +#define fiq_rirq __REG_NR(13) -- cgit v0.10.2 From 6aed4ee9b4610cd1e0315c90855b32e59ee81a15 Mon Sep 17 00:00:00 2001 From: Ben Nizette Date: Mon, 14 Dec 2009 22:20:20 -0800 Subject: atmel_spi: fix dma addr calculation for len > BUFFER_SIZE If len > BUFFER_LEN and !xfer->rx_buf we end up calculating the tx buffer address as *tx_dma = xfer->tx_dma + xfer->len - BUFFER_SIZE; which is constant; i.e. we just send the last BUFFER_SIZE data over again until we've reached the right number of bytes. This patch gets around this by using the /requested/ length when calculating addresses. Note there's no way len != *plen when we calculate the rx buffer address but conceptually we should be using *plen and I don't want someone to come through later, see the calculations for rx and tx are different and "clean up" back to what we had. Signed-off-by: Ben Nizette Cc: Haavard Skinnemoen Cc: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Grant Likely diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c index f5b3fdb..8ce70cb 100644 --- a/drivers/spi/atmel_spi.c +++ b/drivers/spi/atmel_spi.c @@ -189,14 +189,14 @@ static void atmel_spi_next_xfer_data(struct spi_master *master, /* use scratch buffer only when rx or tx data is unspecified */ if (xfer->rx_buf) - *rx_dma = xfer->rx_dma + xfer->len - len; + *rx_dma = xfer->rx_dma + xfer->len - *plen; else { *rx_dma = as->buffer_dma; if (len > BUFFER_SIZE) len = BUFFER_SIZE; } if (xfer->tx_buf) - *tx_dma = xfer->tx_dma + xfer->len - len; + *tx_dma = xfer->tx_dma + xfer->len - *plen; else { *tx_dma = as->buffer_dma; if (len > BUFFER_SIZE) -- cgit v0.10.2 From 9afa2fb6c13501e5b3536d15344fce4e5442c469 Mon Sep 17 00:00:00 2001 From: Erez Zadok Date: Wed, 2 Dec 2009 19:51:54 -0500 Subject: fsstack/ecryptfs: remove unused get_nlinks param to fsstack_copy_attr_all This get_nlinks parameter was never used by the only mainline user, ecryptfs; and it has never been used by unionfs or wrapfs either. Acked-by: Dustin Kirkland Acked-by: Tyler Hicks Signed-off-by: Erez Zadok Signed-off-by: Al Viro diff --git a/fs/ecryptfs/dentry.c b/fs/ecryptfs/dentry.c index 2dda5ad..8f006a0 100644 --- a/fs/ecryptfs/dentry.c +++ b/fs/ecryptfs/dentry.c @@ -62,7 +62,7 @@ static int ecryptfs_d_revalidate(struct dentry *dentry, struct nameidata *nd) struct inode *lower_inode = ecryptfs_inode_to_lower(dentry->d_inode); - fsstack_copy_attr_all(dentry->d_inode, lower_inode, NULL); + fsstack_copy_attr_all(dentry->d_inode, lower_inode); } out: return rc; diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 056fed62..429ca0b 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c @@ -626,9 +626,9 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry, lower_new_dir_dentry->d_inode, lower_new_dentry); if (rc) goto out_lock; - fsstack_copy_attr_all(new_dir, lower_new_dir_dentry->d_inode, NULL); + fsstack_copy_attr_all(new_dir, lower_new_dir_dentry->d_inode); if (new_dir != old_dir) - fsstack_copy_attr_all(old_dir, lower_old_dir_dentry->d_inode, NULL); + fsstack_copy_attr_all(old_dir, lower_old_dir_dentry->d_inode); out_lock: unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry); dput(lower_new_dentry->d_parent); @@ -967,7 +967,7 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia) rc = notify_change(lower_dentry, ia); mutex_unlock(&lower_dentry->d_inode->i_mutex); out: - fsstack_copy_attr_all(inode, lower_inode, NULL); + fsstack_copy_attr_all(inode, lower_inode); return rc; } diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index 101fe4c..567bc4b 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c @@ -189,7 +189,7 @@ int ecryptfs_interpose(struct dentry *lower_dentry, struct dentry *dentry, init_special_inode(inode, lower_inode->i_mode, lower_inode->i_rdev); dentry->d_op = &ecryptfs_dops; - fsstack_copy_attr_all(inode, lower_inode, NULL); + fsstack_copy_attr_all(inode, lower_inode); /* This size will be overwritten for real files w/ headers and * other metadata */ fsstack_copy_inode_size(inode, lower_inode); diff --git a/fs/stack.c b/fs/stack.c index 67716f6..0e20e43 100644 --- a/fs/stack.c +++ b/fs/stack.c @@ -14,11 +14,8 @@ void fsstack_copy_inode_size(struct inode *dst, const struct inode *src) } EXPORT_SYMBOL_GPL(fsstack_copy_inode_size); -/* copy all attributes; get_nlinks is optional way to override the i_nlink - * copying - */ -void fsstack_copy_attr_all(struct inode *dest, const struct inode *src, - int (*get_nlinks)(struct inode *)) +/* copy all attributes */ +void fsstack_copy_attr_all(struct inode *dest, const struct inode *src) { dest->i_mode = src->i_mode; dest->i_uid = src->i_uid; @@ -29,14 +26,6 @@ void fsstack_copy_attr_all(struct inode *dest, const struct inode *src, dest->i_ctime = src->i_ctime; dest->i_blkbits = src->i_blkbits; dest->i_flags = src->i_flags; - - /* - * Update the nlinks AFTER updating the above fields, because the - * get_links callback may depend on them. - */ - if (!get_nlinks) - dest->i_nlink = src->i_nlink; - else - dest->i_nlink = (*get_nlinks)(dest); + dest->i_nlink = src->i_nlink; } EXPORT_SYMBOL_GPL(fsstack_copy_attr_all); diff --git a/include/linux/fs_stack.h b/include/linux/fs_stack.h index bb516ce..aa60311 100644 --- a/include/linux/fs_stack.h +++ b/include/linux/fs_stack.h @@ -8,9 +8,7 @@ #include /* externs for fs/stack.c */ -extern void fsstack_copy_attr_all(struct inode *dest, const struct inode *src, - int (*get_nlinks)(struct inode *)); - +extern void fsstack_copy_attr_all(struct inode *dest, const struct inode *src); extern void fsstack_copy_inode_size(struct inode *dst, const struct inode *src); /* inlines */ -- cgit v0.10.2 From 230d42d422e7b69fc9b270f41c69e63b54572e26 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Mon, 30 Nov 2009 07:39:42 +0000 Subject: spi: Add s3c64xx SPI Controller driver Each SPI controller has exactly one CS line and as such doesn't provide for multi-cs. We implement a workaround to support multi-cs by _not_ configuring the mux'ed CS pin for each SPI controller. The CS mechanism is assumed to be fully machine specific - the driver doesn't even assume some GPIO pin is used to control the CS. The driver selects between DMA and POLLING mode depending upon the xfer size - DMA mode for xfers bigger than FIFO size, POLLING mode otherwise. The driver has been designed to be capable of running SoCs since s3c64xx and till date, for that reason some of the register fields have been passed via, SoC specific, platform data. Signed-off-by: Jassi Brar Signed-off-by: Grant Likely diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 6fa595e..c712f53 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -240,6 +240,13 @@ config SPI_S3C24XX_GPIO the inbuilt hardware cannot provide the transfer mode, or where the board is using non hardware connected pins. +config SPI_S3C64XX + tristate "Samsung S3C64XX series type SPI" + depends on ARCH_S3C64XX && EXPERIMENTAL + select S3C64XX_DMA + help + SPI driver for Samsung S3C64XX and newer SoCs. + config SPI_SH_MSIOF tristate "SuperH MSIOF SPI controller" depends on SUPERH && HAVE_CLK diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 33faa7f..f3d2810 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -33,6 +33,7 @@ obj-$(CONFIG_SPI_MPC8xxx) += spi_mpc8xxx.o obj-$(CONFIG_SPI_PPC4xx) += spi_ppc4xx.o obj-$(CONFIG_SPI_S3C24XX_GPIO) += spi_s3c24xx_gpio.o obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx_hw.o +obj-$(CONFIG_SPI_S3C64XX) += spi_s3c64xx.o obj-$(CONFIG_SPI_TXX9) += spi_txx9.o obj-$(CONFIG_SPI_XILINX) += xilinx_spi.o obj-$(CONFIG_SPI_XILINX_OF) += xilinx_spi_of.o diff --git a/drivers/spi/spi_s3c64xx.c b/drivers/spi/spi_s3c64xx.c new file mode 100644 index 0000000..88a456d --- /dev/null +++ b/drivers/spi/spi_s3c64xx.c @@ -0,0 +1,1196 @@ +/* linux/drivers/spi/spi_s3c64xx.c + * + * Copyright (C) 2009 Samsung Electronics Ltd. + * Jaswinder Singh + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +/* Registers and bit-fields */ + +#define S3C64XX_SPI_CH_CFG 0x00 +#define S3C64XX_SPI_CLK_CFG 0x04 +#define S3C64XX_SPI_MODE_CFG 0x08 +#define S3C64XX_SPI_SLAVE_SEL 0x0C +#define S3C64XX_SPI_INT_EN 0x10 +#define S3C64XX_SPI_STATUS 0x14 +#define S3C64XX_SPI_TX_DATA 0x18 +#define S3C64XX_SPI_RX_DATA 0x1C +#define S3C64XX_SPI_PACKET_CNT 0x20 +#define S3C64XX_SPI_PENDING_CLR 0x24 +#define S3C64XX_SPI_SWAP_CFG 0x28 +#define S3C64XX_SPI_FB_CLK 0x2C + +#define S3C64XX_SPI_CH_HS_EN (1<<6) /* High Speed Enable */ +#define S3C64XX_SPI_CH_SW_RST (1<<5) +#define S3C64XX_SPI_CH_SLAVE (1<<4) +#define S3C64XX_SPI_CPOL_L (1<<3) +#define S3C64XX_SPI_CPHA_B (1<<2) +#define S3C64XX_SPI_CH_RXCH_ON (1<<1) +#define S3C64XX_SPI_CH_TXCH_ON (1<<0) + +#define S3C64XX_SPI_CLKSEL_SRCMSK (3<<9) +#define S3C64XX_SPI_CLKSEL_SRCSHFT 9 +#define S3C64XX_SPI_ENCLK_ENABLE (1<<8) +#define S3C64XX_SPI_PSR_MASK 0xff + +#define S3C64XX_SPI_MODE_CH_TSZ_BYTE (0<<29) +#define S3C64XX_SPI_MODE_CH_TSZ_HALFWORD (1<<29) +#define S3C64XX_SPI_MODE_CH_TSZ_WORD (2<<29) +#define S3C64XX_SPI_MODE_CH_TSZ_MASK (3<<29) +#define S3C64XX_SPI_MODE_BUS_TSZ_BYTE (0<<17) +#define S3C64XX_SPI_MODE_BUS_TSZ_HALFWORD (1<<17) +#define S3C64XX_SPI_MODE_BUS_TSZ_WORD (2<<17) +#define S3C64XX_SPI_MODE_BUS_TSZ_MASK (3<<17) +#define S3C64XX_SPI_MODE_RXDMA_ON (1<<2) +#define S3C64XX_SPI_MODE_TXDMA_ON (1<<1) +#define S3C64XX_SPI_MODE_4BURST (1<<0) + +#define S3C64XX_SPI_SLAVE_AUTO (1<<1) +#define S3C64XX_SPI_SLAVE_SIG_INACT (1<<0) + +#define S3C64XX_SPI_ACT(c) writel(0, (c)->regs + S3C64XX_SPI_SLAVE_SEL) + +#define S3C64XX_SPI_DEACT(c) writel(S3C64XX_SPI_SLAVE_SIG_INACT, \ + (c)->regs + S3C64XX_SPI_SLAVE_SEL) + +#define S3C64XX_SPI_INT_TRAILING_EN (1<<6) +#define S3C64XX_SPI_INT_RX_OVERRUN_EN (1<<5) +#define S3C64XX_SPI_INT_RX_UNDERRUN_EN (1<<4) +#define S3C64XX_SPI_INT_TX_OVERRUN_EN (1<<3) +#define S3C64XX_SPI_INT_TX_UNDERRUN_EN (1<<2) +#define S3C64XX_SPI_INT_RX_FIFORDY_EN (1<<1) +#define S3C64XX_SPI_INT_TX_FIFORDY_EN (1<<0) + +#define S3C64XX_SPI_ST_RX_OVERRUN_ERR (1<<5) +#define S3C64XX_SPI_ST_RX_UNDERRUN_ERR (1<<4) +#define S3C64XX_SPI_ST_TX_OVERRUN_ERR (1<<3) +#define S3C64XX_SPI_ST_TX_UNDERRUN_ERR (1<<2) +#define S3C64XX_SPI_ST_RX_FIFORDY (1<<1) +#define S3C64XX_SPI_ST_TX_FIFORDY (1<<0) + +#define S3C64XX_SPI_PACKET_CNT_EN (1<<16) + +#define S3C64XX_SPI_PND_TX_UNDERRUN_CLR (1<<4) +#define S3C64XX_SPI_PND_TX_OVERRUN_CLR (1<<3) +#define S3C64XX_SPI_PND_RX_UNDERRUN_CLR (1<<2) +#define S3C64XX_SPI_PND_RX_OVERRUN_CLR (1<<1) +#define S3C64XX_SPI_PND_TRAILING_CLR (1<<0) + +#define S3C64XX_SPI_SWAP_RX_HALF_WORD (1<<7) +#define S3C64XX_SPI_SWAP_RX_BYTE (1<<6) +#define S3C64XX_SPI_SWAP_RX_BIT (1<<5) +#define S3C64XX_SPI_SWAP_RX_EN (1<<4) +#define S3C64XX_SPI_SWAP_TX_HALF_WORD (1<<3) +#define S3C64XX_SPI_SWAP_TX_BYTE (1<<2) +#define S3C64XX_SPI_SWAP_TX_BIT (1<<1) +#define S3C64XX_SPI_SWAP_TX_EN (1<<0) + +#define S3C64XX_SPI_FBCLK_MSK (3<<0) + +#define S3C64XX_SPI_ST_TRLCNTZ(v, i) ((((v) >> (i)->rx_lvl_offset) & \ + (((i)->fifo_lvl_mask + 1))) \ + ? 1 : 0) + +#define S3C64XX_SPI_ST_TX_DONE(v, i) ((((v) >> (i)->rx_lvl_offset) & \ + (((i)->fifo_lvl_mask + 1) << 1)) \ + ? 1 : 0) +#define TX_FIFO_LVL(v, i) (((v) >> 6) & (i)->fifo_lvl_mask) +#define RX_FIFO_LVL(v, i) (((v) >> (i)->rx_lvl_offset) & (i)->fifo_lvl_mask) + +#define S3C64XX_SPI_MAX_TRAILCNT 0x3ff +#define S3C64XX_SPI_TRAILCNT_OFF 19 + +#define S3C64XX_SPI_TRAILCNT S3C64XX_SPI_MAX_TRAILCNT + +#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t) + +#define SUSPND (1<<0) +#define SPIBUSY (1<<1) +#define RXBUSY (1<<2) +#define TXBUSY (1<<3) + +/** + * struct s3c64xx_spi_driver_data - Runtime info holder for SPI driver. + * @clk: Pointer to the spi clock. + * @master: Pointer to the SPI Protocol master. + * @workqueue: Work queue for the SPI xfer requests. + * @cntrlr_info: Platform specific data for the controller this driver manages. + * @tgl_spi: Pointer to the last CS left untoggled by the cs_change hint. + * @work: Work + * @queue: To log SPI xfer requests. + * @lock: Controller specific lock. + * @state: Set of FLAGS to indicate status. + * @rx_dmach: Controller's DMA channel for Rx. + * @tx_dmach: Controller's DMA channel for Tx. + * @sfr_start: BUS address of SPI controller regs. + * @regs: Pointer to ioremap'ed controller registers. + * @xfer_completion: To indicate completion of xfer task. + * @cur_mode: Stores the active configuration of the controller. + * @cur_bpw: Stores the active bits per word settings. + * @cur_speed: Stores the active xfer clock speed. + */ +struct s3c64xx_spi_driver_data { + void __iomem *regs; + struct clk *clk; + struct platform_device *pdev; + struct spi_master *master; + struct workqueue_struct *workqueue; + struct s3c64xx_spi_cntrlr_info *cntrlr_info; + struct spi_device *tgl_spi; + struct work_struct work; + struct list_head queue; + spinlock_t lock; + enum dma_ch rx_dmach; + enum dma_ch tx_dmach; + unsigned long sfr_start; + struct completion xfer_completion; + unsigned state; + unsigned cur_mode, cur_bpw; + unsigned cur_speed; +}; + +static struct s3c2410_dma_client s3c64xx_spi_dma_client = { + .name = "samsung-spi-dma", +}; + +static void flush_fifo(struct s3c64xx_spi_driver_data *sdd) +{ + struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info; + void __iomem *regs = sdd->regs; + unsigned long loops; + u32 val; + + writel(0, regs + S3C64XX_SPI_PACKET_CNT); + + val = readl(regs + S3C64XX_SPI_CH_CFG); + val |= S3C64XX_SPI_CH_SW_RST; + val &= ~S3C64XX_SPI_CH_HS_EN; + writel(val, regs + S3C64XX_SPI_CH_CFG); + + /* Flush TxFIFO*/ + loops = msecs_to_loops(1); + do { + val = readl(regs + S3C64XX_SPI_STATUS); + } while (TX_FIFO_LVL(val, sci) && loops--); + + /* Flush RxFIFO*/ + loops = msecs_to_loops(1); + do { + val = readl(regs + S3C64XX_SPI_STATUS); + if (RX_FIFO_LVL(val, sci)) + readl(regs + S3C64XX_SPI_RX_DATA); + else + break; + } while (loops--); + + val = readl(regs + S3C64XX_SPI_CH_CFG); + val &= ~S3C64XX_SPI_CH_SW_RST; + writel(val, regs + S3C64XX_SPI_CH_CFG); + + val = readl(regs + S3C64XX_SPI_MODE_CFG); + val &= ~(S3C64XX_SPI_MODE_TXDMA_ON | S3C64XX_SPI_MODE_RXDMA_ON); + writel(val, regs + S3C64XX_SPI_MODE_CFG); + + val = readl(regs + S3C64XX_SPI_CH_CFG); + val &= ~(S3C64XX_SPI_CH_RXCH_ON | S3C64XX_SPI_CH_TXCH_ON); + writel(val, regs + S3C64XX_SPI_CH_CFG); +} + +static void enable_datapath(struct s3c64xx_spi_driver_data *sdd, + struct spi_device *spi, + struct spi_transfer *xfer, int dma_mode) +{ + struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info; + void __iomem *regs = sdd->regs; + u32 modecfg, chcfg; + + modecfg = readl(regs + S3C64XX_SPI_MODE_CFG); + modecfg &= ~(S3C64XX_SPI_MODE_TXDMA_ON | S3C64XX_SPI_MODE_RXDMA_ON); + + chcfg = readl(regs + S3C64XX_SPI_CH_CFG); + chcfg &= ~S3C64XX_SPI_CH_TXCH_ON; + + if (dma_mode) { + chcfg &= ~S3C64XX_SPI_CH_RXCH_ON; + } else { + /* Always shift in data in FIFO, even if xfer is Tx only, + * this helps setting PCKT_CNT value for generating clocks + * as exactly needed. + */ + chcfg |= S3C64XX_SPI_CH_RXCH_ON; + writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff) + | S3C64XX_SPI_PACKET_CNT_EN, + regs + S3C64XX_SPI_PACKET_CNT); + } + + if (xfer->tx_buf != NULL) { + sdd->state |= TXBUSY; + chcfg |= S3C64XX_SPI_CH_TXCH_ON; + if (dma_mode) { + modecfg |= S3C64XX_SPI_MODE_TXDMA_ON; + s3c2410_dma_config(sdd->tx_dmach, 1); + s3c2410_dma_enqueue(sdd->tx_dmach, (void *)sdd, + xfer->tx_dma, xfer->len); + s3c2410_dma_ctrl(sdd->tx_dmach, S3C2410_DMAOP_START); + } else { + unsigned char *buf = (unsigned char *) xfer->tx_buf; + int i = 0; + while (i < xfer->len) + writeb(buf[i++], regs + S3C64XX_SPI_TX_DATA); + } + } + + if (xfer->rx_buf != NULL) { + sdd->state |= RXBUSY; + + if (sci->high_speed && sdd->cur_speed >= 30000000UL + && !(sdd->cur_mode & SPI_CPHA)) + chcfg |= S3C64XX_SPI_CH_HS_EN; + + if (dma_mode) { + modecfg |= S3C64XX_SPI_MODE_RXDMA_ON; + chcfg |= S3C64XX_SPI_CH_RXCH_ON; + writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff) + | S3C64XX_SPI_PACKET_CNT_EN, + regs + S3C64XX_SPI_PACKET_CNT); + s3c2410_dma_config(sdd->rx_dmach, 1); + s3c2410_dma_enqueue(sdd->rx_dmach, (void *)sdd, + xfer->rx_dma, xfer->len); + s3c2410_dma_ctrl(sdd->rx_dmach, S3C2410_DMAOP_START); + } + } + + writel(modecfg, regs + S3C64XX_SPI_MODE_CFG); + writel(chcfg, regs + S3C64XX_SPI_CH_CFG); +} + +static inline void enable_cs(struct s3c64xx_spi_driver_data *sdd, + struct spi_device *spi) +{ + struct s3c64xx_spi_csinfo *cs; + + if (sdd->tgl_spi != NULL) { /* If last device toggled after mssg */ + if (sdd->tgl_spi != spi) { /* if last mssg on diff device */ + /* Deselect the last toggled device */ + cs = sdd->tgl_spi->controller_data; + cs->set_level(spi->mode & SPI_CS_HIGH ? 0 : 1); + } + sdd->tgl_spi = NULL; + } + + cs = spi->controller_data; + cs->set_level(spi->mode & SPI_CS_HIGH ? 1 : 0); +} + +static int wait_for_xfer(struct s3c64xx_spi_driver_data *sdd, + struct spi_transfer *xfer, int dma_mode) +{ + struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info; + void __iomem *regs = sdd->regs; + unsigned long val; + int ms; + + /* millisecs to xfer 'len' bytes @ 'cur_speed' */ + ms = xfer->len * 8 * 1000 / sdd->cur_speed; + ms += 5; /* some tolerance */ + + if (dma_mode) { + val = msecs_to_jiffies(ms) + 10; + val = wait_for_completion_timeout(&sdd->xfer_completion, val); + } else { + val = msecs_to_loops(ms); + do { + val = readl(regs + S3C64XX_SPI_STATUS); + } while (RX_FIFO_LVL(val, sci) < xfer->len && --val); + } + + if (!val) + return -EIO; + + if (dma_mode) { + u32 status; + + /* + * DmaTx returns after simply writing data in the FIFO, + * w/o waiting for real transmission on the bus to finish. + * DmaRx returns only after Dma read data from FIFO which + * needs bus transmission to finish, so we don't worry if + * Xfer involved Rx(with or without Tx). + */ + if (xfer->rx_buf == NULL) { + val = msecs_to_loops(10); + status = readl(regs + S3C64XX_SPI_STATUS); + while ((TX_FIFO_LVL(status, sci) + || !S3C64XX_SPI_ST_TX_DONE(status, sci)) + && --val) { + cpu_relax(); + status = readl(regs + S3C64XX_SPI_STATUS); + } + + if (!val) + return -EIO; + } + } else { + unsigned char *buf; + int i; + + /* If it was only Tx */ + if (xfer->rx_buf == NULL) { + sdd->state &= ~TXBUSY; + return 0; + } + + i = 0; + buf = xfer->rx_buf; + while (i < xfer->len) + buf[i++] = readb(regs + S3C64XX_SPI_RX_DATA); + + sdd->state &= ~RXBUSY; + } + + return 0; +} + +static inline void disable_cs(struct s3c64xx_spi_driver_data *sdd, + struct spi_device *spi) +{ + struct s3c64xx_spi_csinfo *cs = spi->controller_data; + + if (sdd->tgl_spi == spi) + sdd->tgl_spi = NULL; + + cs->set_level(spi->mode & SPI_CS_HIGH ? 0 : 1); +} + +static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd) +{ + struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info; + void __iomem *regs = sdd->regs; + u32 val; + + /* Disable Clock */ + val = readl(regs + S3C64XX_SPI_CLK_CFG); + val &= ~S3C64XX_SPI_ENCLK_ENABLE; + writel(val, regs + S3C64XX_SPI_CLK_CFG); + + /* Set Polarity and Phase */ + val = readl(regs + S3C64XX_SPI_CH_CFG); + val &= ~(S3C64XX_SPI_CH_SLAVE | + S3C64XX_SPI_CPOL_L | + S3C64XX_SPI_CPHA_B); + + if (sdd->cur_mode & SPI_CPOL) + val |= S3C64XX_SPI_CPOL_L; + + if (sdd->cur_mode & SPI_CPHA) + val |= S3C64XX_SPI_CPHA_B; + + writel(val, regs + S3C64XX_SPI_CH_CFG); + + /* Set Channel & DMA Mode */ + val = readl(regs + S3C64XX_SPI_MODE_CFG); + val &= ~(S3C64XX_SPI_MODE_BUS_TSZ_MASK + | S3C64XX_SPI_MODE_CH_TSZ_MASK); + + switch (sdd->cur_bpw) { + case 32: + val |= S3C64XX_SPI_MODE_BUS_TSZ_WORD; + break; + case 16: + val |= S3C64XX_SPI_MODE_BUS_TSZ_HALFWORD; + break; + default: + val |= S3C64XX_SPI_MODE_BUS_TSZ_BYTE; + break; + } + val |= S3C64XX_SPI_MODE_CH_TSZ_BYTE; /* Always 8bits wide */ + + writel(val, regs + S3C64XX_SPI_MODE_CFG); + + /* Configure Clock */ + val = readl(regs + S3C64XX_SPI_CLK_CFG); + val &= ~S3C64XX_SPI_PSR_MASK; + val |= ((clk_get_rate(sci->src_clk) / sdd->cur_speed / 2 - 1) + & S3C64XX_SPI_PSR_MASK); + writel(val, regs + S3C64XX_SPI_CLK_CFG); + + /* Enable Clock */ + val = readl(regs + S3C64XX_SPI_CLK_CFG); + val |= S3C64XX_SPI_ENCLK_ENABLE; + writel(val, regs + S3C64XX_SPI_CLK_CFG); +} + +void s3c64xx_spi_dma_rxcb(struct s3c2410_dma_chan *chan, void *buf_id, + int size, enum s3c2410_dma_buffresult res) +{ + struct s3c64xx_spi_driver_data *sdd = buf_id; + unsigned long flags; + + spin_lock_irqsave(&sdd->lock, flags); + + if (res == S3C2410_RES_OK) + sdd->state &= ~RXBUSY; + else + dev_err(&sdd->pdev->dev, "DmaAbrtRx-%d\n", size); + + /* If the other done */ + if (!(sdd->state & TXBUSY)) + complete(&sdd->xfer_completion); + + spin_unlock_irqrestore(&sdd->lock, flags); +} + +void s3c64xx_spi_dma_txcb(struct s3c2410_dma_chan *chan, void *buf_id, + int size, enum s3c2410_dma_buffresult res) +{ + struct s3c64xx_spi_driver_data *sdd = buf_id; + unsigned long flags; + + spin_lock_irqsave(&sdd->lock, flags); + + if (res == S3C2410_RES_OK) + sdd->state &= ~TXBUSY; + else + dev_err(&sdd->pdev->dev, "DmaAbrtTx-%d \n", size); + + /* If the other done */ + if (!(sdd->state & RXBUSY)) + complete(&sdd->xfer_completion); + + spin_unlock_irqrestore(&sdd->lock, flags); +} + +#define XFER_DMAADDR_INVALID DMA_BIT_MASK(32) + +static int s3c64xx_spi_map_mssg(struct s3c64xx_spi_driver_data *sdd, + struct spi_message *msg) +{ + struct device *dev = &sdd->pdev->dev; + struct spi_transfer *xfer; + + if (msg->is_dma_mapped) + return 0; + + /* First mark all xfer unmapped */ + list_for_each_entry(xfer, &msg->transfers, transfer_list) { + xfer->rx_dma = XFER_DMAADDR_INVALID; + xfer->tx_dma = XFER_DMAADDR_INVALID; + } + + /* Map until end or first fail */ + list_for_each_entry(xfer, &msg->transfers, transfer_list) { + + if (xfer->tx_buf != NULL) { + xfer->tx_dma = dma_map_single(dev, xfer->tx_buf, + xfer->len, DMA_TO_DEVICE); + if (dma_mapping_error(dev, xfer->tx_dma)) { + dev_err(dev, "dma_map_single Tx failed\n"); + xfer->tx_dma = XFER_DMAADDR_INVALID; + return -ENOMEM; + } + } + + if (xfer->rx_buf != NULL) { + xfer->rx_dma = dma_map_single(dev, xfer->rx_buf, + xfer->len, DMA_FROM_DEVICE); + if (dma_mapping_error(dev, xfer->rx_dma)) { + dev_err(dev, "dma_map_single Rx failed\n"); + dma_unmap_single(dev, xfer->tx_dma, + xfer->len, DMA_TO_DEVICE); + xfer->tx_dma = XFER_DMAADDR_INVALID; + xfer->rx_dma = XFER_DMAADDR_INVALID; + return -ENOMEM; + } + } + } + + return 0; +} + +static void s3c64xx_spi_unmap_mssg(struct s3c64xx_spi_driver_data *sdd, + struct spi_message *msg) +{ + struct device *dev = &sdd->pdev->dev; + struct spi_transfer *xfer; + + if (msg->is_dma_mapped) + return; + + list_for_each_entry(xfer, &msg->transfers, transfer_list) { + + if (xfer->rx_buf != NULL + && xfer->rx_dma != XFER_DMAADDR_INVALID) + dma_unmap_single(dev, xfer->rx_dma, + xfer->len, DMA_FROM_DEVICE); + + if (xfer->tx_buf != NULL + && xfer->tx_dma != XFER_DMAADDR_INVALID) + dma_unmap_single(dev, xfer->tx_dma, + xfer->len, DMA_TO_DEVICE); + } +} + +static void handle_msg(struct s3c64xx_spi_driver_data *sdd, + struct spi_message *msg) +{ + struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info; + struct spi_device *spi = msg->spi; + struct s3c64xx_spi_csinfo *cs = spi->controller_data; + struct spi_transfer *xfer; + int status = 0, cs_toggle = 0; + u32 speed; + u8 bpw; + + /* If Master's(controller) state differs from that needed by Slave */ + if (sdd->cur_speed != spi->max_speed_hz + || sdd->cur_mode != spi->mode + || sdd->cur_bpw != spi->bits_per_word) { + sdd->cur_bpw = spi->bits_per_word; + sdd->cur_speed = spi->max_speed_hz; + sdd->cur_mode = spi->mode; + s3c64xx_spi_config(sdd); + } + + /* Map all the transfers if needed */ + if (s3c64xx_spi_map_mssg(sdd, msg)) { + dev_err(&spi->dev, + "Xfer: Unable to map message buffers!\n"); + status = -ENOMEM; + goto out; + } + + /* Configure feedback delay */ + writel(cs->fb_delay & 0x3, sdd->regs + S3C64XX_SPI_FB_CLK); + + list_for_each_entry(xfer, &msg->transfers, transfer_list) { + + unsigned long flags; + int use_dma; + + INIT_COMPLETION(sdd->xfer_completion); + + /* Only BPW and Speed may change across transfers */ + bpw = xfer->bits_per_word ? : spi->bits_per_word; + speed = xfer->speed_hz ? : spi->max_speed_hz; + + if (bpw != sdd->cur_bpw || speed != sdd->cur_speed) { + sdd->cur_bpw = bpw; + sdd->cur_speed = speed; + s3c64xx_spi_config(sdd); + } + + /* Polling method for xfers not bigger than FIFO capacity */ + if (xfer->len <= ((sci->fifo_lvl_mask >> 1) + 1)) + use_dma = 0; + else + use_dma = 1; + + spin_lock_irqsave(&sdd->lock, flags); + + /* Pending only which is to be done */ + sdd->state &= ~RXBUSY; + sdd->state &= ~TXBUSY; + + enable_datapath(sdd, spi, xfer, use_dma); + + /* Slave Select */ + enable_cs(sdd, spi); + + /* Start the signals */ + S3C64XX_SPI_ACT(sdd); + + spin_unlock_irqrestore(&sdd->lock, flags); + + status = wait_for_xfer(sdd, xfer, use_dma); + + /* Quiese the signals */ + S3C64XX_SPI_DEACT(sdd); + + if (status) { + dev_err(&spi->dev, "I/O Error: \ + rx-%d tx-%d res:rx-%c tx-%c len-%d\n", + xfer->rx_buf ? 1 : 0, xfer->tx_buf ? 1 : 0, + (sdd->state & RXBUSY) ? 'f' : 'p', + (sdd->state & TXBUSY) ? 'f' : 'p', + xfer->len); + + if (use_dma) { + if (xfer->tx_buf != NULL + && (sdd->state & TXBUSY)) + s3c2410_dma_ctrl(sdd->tx_dmach, + S3C2410_DMAOP_FLUSH); + if (xfer->rx_buf != NULL + && (sdd->state & RXBUSY)) + s3c2410_dma_ctrl(sdd->rx_dmach, + S3C2410_DMAOP_FLUSH); + } + + goto out; + } + + if (xfer->delay_usecs) + udelay(xfer->delay_usecs); + + if (xfer->cs_change) { + /* Hint that the next mssg is gonna be + for the same device */ + if (list_is_last(&xfer->transfer_list, + &msg->transfers)) + cs_toggle = 1; + else + disable_cs(sdd, spi); + } + + msg->actual_length += xfer->len; + + flush_fifo(sdd); + } + +out: + if (!cs_toggle || status) + disable_cs(sdd, spi); + else + sdd->tgl_spi = spi; + + s3c64xx_spi_unmap_mssg(sdd, msg); + + msg->status = status; + + if (msg->complete) + msg->complete(msg->context); +} + +static int acquire_dma(struct s3c64xx_spi_driver_data *sdd) +{ + if (s3c2410_dma_request(sdd->rx_dmach, + &s3c64xx_spi_dma_client, NULL) < 0) { + dev_err(&sdd->pdev->dev, "cannot get RxDMA\n"); + return 0; + } + s3c2410_dma_set_buffdone_fn(sdd->rx_dmach, s3c64xx_spi_dma_rxcb); + s3c2410_dma_devconfig(sdd->rx_dmach, S3C2410_DMASRC_HW, + sdd->sfr_start + S3C64XX_SPI_RX_DATA); + + if (s3c2410_dma_request(sdd->tx_dmach, + &s3c64xx_spi_dma_client, NULL) < 0) { + dev_err(&sdd->pdev->dev, "cannot get TxDMA\n"); + s3c2410_dma_free(sdd->rx_dmach, &s3c64xx_spi_dma_client); + return 0; + } + s3c2410_dma_set_buffdone_fn(sdd->tx_dmach, s3c64xx_spi_dma_txcb); + s3c2410_dma_devconfig(sdd->tx_dmach, S3C2410_DMASRC_MEM, + sdd->sfr_start + S3C64XX_SPI_TX_DATA); + + return 1; +} + +static void s3c64xx_spi_work(struct work_struct *work) +{ + struct s3c64xx_spi_driver_data *sdd = container_of(work, + struct s3c64xx_spi_driver_data, work); + unsigned long flags; + + /* Acquire DMA channels */ + while (!acquire_dma(sdd)) + msleep(10); + + spin_lock_irqsave(&sdd->lock, flags); + + while (!list_empty(&sdd->queue) + && !(sdd->state & SUSPND)) { + + struct spi_message *msg; + + msg = container_of(sdd->queue.next, struct spi_message, queue); + + list_del_init(&msg->queue); + + /* Set Xfer busy flag */ + sdd->state |= SPIBUSY; + + spin_unlock_irqrestore(&sdd->lock, flags); + + handle_msg(sdd, msg); + + spin_lock_irqsave(&sdd->lock, flags); + + sdd->state &= ~SPIBUSY; + } + + spin_unlock_irqrestore(&sdd->lock, flags); + + /* Free DMA channels */ + s3c2410_dma_free(sdd->tx_dmach, &s3c64xx_spi_dma_client); + s3c2410_dma_free(sdd->rx_dmach, &s3c64xx_spi_dma_client); +} + +static int s3c64xx_spi_transfer(struct spi_device *spi, + struct spi_message *msg) +{ + struct s3c64xx_spi_driver_data *sdd; + unsigned long flags; + + sdd = spi_master_get_devdata(spi->master); + + spin_lock_irqsave(&sdd->lock, flags); + + if (sdd->state & SUSPND) { + spin_unlock_irqrestore(&sdd->lock, flags); + return -ESHUTDOWN; + } + + msg->status = -EINPROGRESS; + msg->actual_length = 0; + + list_add_tail(&msg->queue, &sdd->queue); + + queue_work(sdd->workqueue, &sdd->work); + + spin_unlock_irqrestore(&sdd->lock, flags); + + return 0; +} + +/* + * Here we only check the validity of requested configuration + * and save the configuration in a local data-structure. + * The controller is actually configured only just before we + * get a message to transfer. + */ +static int s3c64xx_spi_setup(struct spi_device *spi) +{ + struct s3c64xx_spi_csinfo *cs = spi->controller_data; + struct s3c64xx_spi_driver_data *sdd; + struct s3c64xx_spi_cntrlr_info *sci; + struct spi_message *msg; + u32 psr, speed; + unsigned long flags; + int err = 0; + + if (cs == NULL || cs->set_level == NULL) { + dev_err(&spi->dev, "No CS for SPI(%d)\n", spi->chip_select); + return -ENODEV; + } + + sdd = spi_master_get_devdata(spi->master); + sci = sdd->cntrlr_info; + + spin_lock_irqsave(&sdd->lock, flags); + + list_for_each_entry(msg, &sdd->queue, queue) { + /* Is some mssg is already queued for this device */ + if (msg->spi == spi) { + dev_err(&spi->dev, + "setup: attempt while mssg in queue!\n"); + spin_unlock_irqrestore(&sdd->lock, flags); + return -EBUSY; + } + } + + if (sdd->state & SUSPND) { + spin_unlock_irqrestore(&sdd->lock, flags); + dev_err(&spi->dev, + "setup: SPI-%d not active!\n", spi->master->bus_num); + return -ESHUTDOWN; + } + + spin_unlock_irqrestore(&sdd->lock, flags); + + if (spi->bits_per_word != 8 + && spi->bits_per_word != 16 + && spi->bits_per_word != 32) { + dev_err(&spi->dev, "setup: %dbits/wrd not supported!\n", + spi->bits_per_word); + err = -EINVAL; + goto setup_exit; + } + + /* Check if we can provide the requested rate */ + speed = clk_get_rate(sci->src_clk) / 2 / (0 + 1); /* Max possible */ + + if (spi->max_speed_hz > speed) + spi->max_speed_hz = speed; + + psr = clk_get_rate(sci->src_clk) / 2 / spi->max_speed_hz - 1; + psr &= S3C64XX_SPI_PSR_MASK; + if (psr == S3C64XX_SPI_PSR_MASK) + psr--; + + speed = clk_get_rate(sci->src_clk) / 2 / (psr + 1); + if (spi->max_speed_hz < speed) { + if (psr+1 < S3C64XX_SPI_PSR_MASK) { + psr++; + } else { + err = -EINVAL; + goto setup_exit; + } + } + + speed = clk_get_rate(sci->src_clk) / 2 / (psr + 1); + if (spi->max_speed_hz >= speed) + spi->max_speed_hz = speed; + else + err = -EINVAL; + +setup_exit: + + /* setup() returns with device de-selected */ + disable_cs(sdd, spi); + + return err; +} + +static void s3c64xx_spi_hwinit(struct s3c64xx_spi_driver_data *sdd, int channel) +{ + struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info; + void __iomem *regs = sdd->regs; + unsigned int val; + + sdd->cur_speed = 0; + + S3C64XX_SPI_DEACT(sdd); + + /* Disable Interrupts - we use Polling if not DMA mode */ + writel(0, regs + S3C64XX_SPI_INT_EN); + + writel(sci->src_clk_nr << S3C64XX_SPI_CLKSEL_SRCSHFT, + regs + S3C64XX_SPI_CLK_CFG); + writel(0, regs + S3C64XX_SPI_MODE_CFG); + writel(0, regs + S3C64XX_SPI_PACKET_CNT); + + /* Clear any irq pending bits */ + writel(readl(regs + S3C64XX_SPI_PENDING_CLR), + regs + S3C64XX_SPI_PENDING_CLR); + + writel(0, regs + S3C64XX_SPI_SWAP_CFG); + + val = readl(regs + S3C64XX_SPI_MODE_CFG); + val &= ~S3C64XX_SPI_MODE_4BURST; + val &= ~(S3C64XX_SPI_MAX_TRAILCNT << S3C64XX_SPI_TRAILCNT_OFF); + val |= (S3C64XX_SPI_TRAILCNT << S3C64XX_SPI_TRAILCNT_OFF); + writel(val, regs + S3C64XX_SPI_MODE_CFG); + + flush_fifo(sdd); +} + +static int __init s3c64xx_spi_probe(struct platform_device *pdev) +{ + struct resource *mem_res, *dmatx_res, *dmarx_res; + struct s3c64xx_spi_driver_data *sdd; + struct s3c64xx_spi_cntrlr_info *sci; + struct spi_master *master; + int ret; + + if (pdev->id < 0) { + dev_err(&pdev->dev, + "Invalid platform device id-%d\n", pdev->id); + return -ENODEV; + } + + if (pdev->dev.platform_data == NULL) { + dev_err(&pdev->dev, "platform_data missing!\n"); + return -ENODEV; + } + + /* Check for availability of necessary resource */ + + dmatx_res = platform_get_resource(pdev, IORESOURCE_DMA, 0); + if (dmatx_res == NULL) { + dev_err(&pdev->dev, "Unable to get SPI-Tx dma resource\n"); + return -ENXIO; + } + + dmarx_res = platform_get_resource(pdev, IORESOURCE_DMA, 1); + if (dmarx_res == NULL) { + dev_err(&pdev->dev, "Unable to get SPI-Rx dma resource\n"); + return -ENXIO; + } + + mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (mem_res == NULL) { + dev_err(&pdev->dev, "Unable to get SPI MEM resource\n"); + return -ENXIO; + } + + master = spi_alloc_master(&pdev->dev, + sizeof(struct s3c64xx_spi_driver_data)); + if (master == NULL) { + dev_err(&pdev->dev, "Unable to allocate SPI Master\n"); + return -ENOMEM; + } + + sci = pdev->dev.platform_data; + + platform_set_drvdata(pdev, master); + + sdd = spi_master_get_devdata(master); + sdd->master = master; + sdd->cntrlr_info = sci; + sdd->pdev = pdev; + sdd->sfr_start = mem_res->start; + sdd->tx_dmach = dmatx_res->start; + sdd->rx_dmach = dmarx_res->start; + + sdd->cur_bpw = 8; + + master->bus_num = pdev->id; + master->setup = s3c64xx_spi_setup; + master->transfer = s3c64xx_spi_transfer; + master->num_chipselect = sci->num_cs; + master->dma_alignment = 8; + /* the spi->mode bits understood by this driver: */ + master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; + + if (request_mem_region(mem_res->start, + resource_size(mem_res), pdev->name) == NULL) { + dev_err(&pdev->dev, "Req mem region failed\n"); + ret = -ENXIO; + goto err0; + } + + sdd->regs = ioremap(mem_res->start, resource_size(mem_res)); + if (sdd->regs == NULL) { + dev_err(&pdev->dev, "Unable to remap IO\n"); + ret = -ENXIO; + goto err1; + } + + if (sci->cfg_gpio == NULL || sci->cfg_gpio(pdev)) { + dev_err(&pdev->dev, "Unable to config gpio\n"); + ret = -EBUSY; + goto err2; + } + + /* Setup clocks */ + sdd->clk = clk_get(&pdev->dev, "spi"); + if (IS_ERR(sdd->clk)) { + dev_err(&pdev->dev, "Unable to acquire clock 'spi'\n"); + ret = PTR_ERR(sdd->clk); + goto err3; + } + + if (clk_enable(sdd->clk)) { + dev_err(&pdev->dev, "Couldn't enable clock 'spi'\n"); + ret = -EBUSY; + goto err4; + } + + if (sci->src_clk_nr == S3C64XX_SPI_SRCCLK_PCLK) + sci->src_clk = sdd->clk; + else + sci->src_clk = clk_get(&pdev->dev, sci->src_clk_name); + if (IS_ERR(sci->src_clk)) { + dev_err(&pdev->dev, + "Unable to acquire clock '%s'\n", sci->src_clk_name); + ret = PTR_ERR(sci->src_clk); + goto err5; + } + + if (sci->src_clk != sdd->clk && clk_enable(sci->src_clk)) { + dev_err(&pdev->dev, "Couldn't enable clock '%s'\n", + sci->src_clk_name); + ret = -EBUSY; + goto err6; + } + + sdd->workqueue = create_singlethread_workqueue( + dev_name(master->dev.parent)); + if (sdd->workqueue == NULL) { + dev_err(&pdev->dev, "Unable to create workqueue\n"); + ret = -ENOMEM; + goto err7; + } + + /* Setup Deufult Mode */ + s3c64xx_spi_hwinit(sdd, pdev->id); + + spin_lock_init(&sdd->lock); + init_completion(&sdd->xfer_completion); + INIT_WORK(&sdd->work, s3c64xx_spi_work); + INIT_LIST_HEAD(&sdd->queue); + + if (spi_register_master(master)) { + dev_err(&pdev->dev, "cannot register SPI master\n"); + ret = -EBUSY; + goto err8; + } + + dev_dbg(&pdev->dev, "Samsung SoC SPI Driver loaded for Bus SPI-%d \ + with %d Slaves attached\n", + pdev->id, master->num_chipselect); + dev_dbg(&pdev->dev, "\tIOmem=[0x%x-0x%x]\ + \tDMA=[Rx-%d, Tx-%d]\n", + mem_res->end, mem_res->start, + sdd->rx_dmach, sdd->tx_dmach); + + return 0; + +err8: + destroy_workqueue(sdd->workqueue); +err7: + if (sci->src_clk != sdd->clk) + clk_disable(sci->src_clk); +err6: + if (sci->src_clk != sdd->clk) + clk_put(sci->src_clk); +err5: + clk_disable(sdd->clk); +err4: + clk_put(sdd->clk); +err3: +err2: + iounmap((void *) sdd->regs); +err1: + release_mem_region(mem_res->start, resource_size(mem_res)); +err0: + platform_set_drvdata(pdev, NULL); + spi_master_put(master); + + return ret; +} + +static int s3c64xx_spi_remove(struct platform_device *pdev) +{ + struct spi_master *master = spi_master_get(platform_get_drvdata(pdev)); + struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); + struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info; + struct resource *mem_res; + unsigned long flags; + + spin_lock_irqsave(&sdd->lock, flags); + sdd->state |= SUSPND; + spin_unlock_irqrestore(&sdd->lock, flags); + + while (sdd->state & SPIBUSY) + msleep(10); + + spi_unregister_master(master); + + destroy_workqueue(sdd->workqueue); + + if (sci->src_clk != sdd->clk) + clk_disable(sci->src_clk); + + if (sci->src_clk != sdd->clk) + clk_put(sci->src_clk); + + clk_disable(sdd->clk); + clk_put(sdd->clk); + + iounmap((void *) sdd->regs); + + mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + release_mem_region(mem_res->start, resource_size(mem_res)); + + platform_set_drvdata(pdev, NULL); + spi_master_put(master); + + return 0; +} + +#ifdef CONFIG_PM +static int s3c64xx_spi_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct spi_master *master = spi_master_get(platform_get_drvdata(pdev)); + struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); + struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info; + struct s3c64xx_spi_csinfo *cs; + unsigned long flags; + + spin_lock_irqsave(&sdd->lock, flags); + sdd->state |= SUSPND; + spin_unlock_irqrestore(&sdd->lock, flags); + + while (sdd->state & SPIBUSY) + msleep(10); + + /* Disable the clock */ + if (sci->src_clk != sdd->clk) + clk_disable(sci->src_clk); + + clk_disable(sdd->clk); + + sdd->cur_speed = 0; /* Output Clock is stopped */ + + return 0; +} + +static int s3c64xx_spi_resume(struct platform_device *pdev) +{ + struct spi_master *master = spi_master_get(platform_get_drvdata(pdev)); + struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); + struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info; + unsigned long flags; + + sci->cfg_gpio(pdev); + + /* Enable the clock */ + if (sci->src_clk != sdd->clk) + clk_enable(sci->src_clk); + + clk_enable(sdd->clk); + + s3c64xx_spi_hwinit(sdd, pdev->id); + + spin_lock_irqsave(&sdd->lock, flags); + sdd->state &= ~SUSPND; + spin_unlock_irqrestore(&sdd->lock, flags); + + return 0; +} +#else +#define s3c64xx_spi_suspend NULL +#define s3c64xx_spi_resume NULL +#endif /* CONFIG_PM */ + +static struct platform_driver s3c64xx_spi_driver = { + .driver = { + .name = "s3c64xx-spi", + .owner = THIS_MODULE, + }, + .remove = s3c64xx_spi_remove, + .suspend = s3c64xx_spi_suspend, + .resume = s3c64xx_spi_resume, +}; +MODULE_ALIAS("platform:s3c64xx-spi"); + +static int __init s3c64xx_spi_init(void) +{ + return platform_driver_probe(&s3c64xx_spi_driver, s3c64xx_spi_probe); +} +module_init(s3c64xx_spi_init); + +static void __exit s3c64xx_spi_exit(void) +{ + platform_driver_unregister(&s3c64xx_spi_driver); +} +module_exit(s3c64xx_spi_exit); + +MODULE_AUTHOR("Jaswinder Singh "); +MODULE_DESCRIPTION("S3C64XX SPI Controller Driver"); +MODULE_LICENSE("GPL"); -- cgit v0.10.2 From 1b8ab8159ef8f818f870a1d2e3b6953d80eefd3f Mon Sep 17 00:00:00 2001 From: Erez Zadok Date: Thu, 3 Dec 2009 21:56:09 -0500 Subject: VFS/fsstack: handle 32-bit smp + preempt + large files in fsstack_copy_inode_size Copy the inode size and blocks from one inode to another correctly on 32-bit systems with CONFIG_SMP, CONFIG_PREEMPT, or CONFIG_LBDAF. Use proper inode spinlocks only when i_size/i_blocks cannot fit in one 32-bit word. Signed-off-by: Hugh Dickins Signed-off-by: Erez Zadok Signed-off-by: Al Viro diff --git a/fs/stack.c b/fs/stack.c index 0e20e43..4a6f7f4 100644 --- a/fs/stack.c +++ b/fs/stack.c @@ -7,10 +7,58 @@ * This function cannot be inlined since i_size_{read,write} is rather * heavy-weight on 32-bit systems */ -void fsstack_copy_inode_size(struct inode *dst, const struct inode *src) +void fsstack_copy_inode_size(struct inode *dst, struct inode *src) { - i_size_write(dst, i_size_read((struct inode *)src)); - dst->i_blocks = src->i_blocks; + loff_t i_size; + blkcnt_t i_blocks; + + /* + * i_size_read() includes its own seqlocking and protection from + * preemption (see include/linux/fs.h): we need nothing extra for + * that here, and prefer to avoid nesting locks than attempt to keep + * i_size and i_blocks in sync together. + */ + i_size = i_size_read(src); + + /* + * But if CONFIG_LBDAF (on 32-bit), we ought to make an effort to + * keep the two halves of i_blocks in sync despite SMP or PREEMPT - + * though stat's generic_fillattr() doesn't bother, and we won't be + * applying quotas (where i_blocks does become important) at the + * upper level. + * + * We don't actually know what locking is used at the lower level; + * but if it's a filesystem that supports quotas, it will be using + * i_lock as in inode_add_bytes(). tmpfs uses other locking, and + * its 32-bit is (just) able to exceed 2TB i_size with the aid of + * holes; but its i_blocks cannot carry into the upper long without + * almost 2TB swap - let's ignore that case. + */ + if (sizeof(i_blocks) > sizeof(long)) + spin_lock(&src->i_lock); + i_blocks = src->i_blocks; + if (sizeof(i_blocks) > sizeof(long)) + spin_unlock(&src->i_lock); + + /* + * If CONFIG_SMP or CONFIG_PREEMPT on 32-bit, it's vital for + * fsstack_copy_inode_size() to hold some lock around + * i_size_write(), otherwise i_size_read() may spin forever (see + * include/linux/fs.h). We don't necessarily hold i_mutex when this + * is called, so take i_lock for that case. + * + * And if CONFIG_LBADF (on 32-bit), continue our effort to keep the + * two halves of i_blocks in sync despite SMP or PREEMPT: use i_lock + * for that case too, and do both at once by combining the tests. + * + * There is none of this locking overhead in the 64-bit case. + */ + if (sizeof(i_size) > sizeof(long) || sizeof(i_blocks) > sizeof(long)) + spin_lock(&dst->i_lock); + i_size_write(dst, i_size); + dst->i_blocks = i_blocks; + if (sizeof(i_size) > sizeof(long) || sizeof(i_blocks) > sizeof(long)) + spin_unlock(&dst->i_lock); } EXPORT_SYMBOL_GPL(fsstack_copy_inode_size); diff --git a/include/linux/fs_stack.h b/include/linux/fs_stack.h index aa60311..da317c7 100644 --- a/include/linux/fs_stack.h +++ b/include/linux/fs_stack.h @@ -9,7 +9,7 @@ /* externs for fs/stack.c */ extern void fsstack_copy_attr_all(struct inode *dest, const struct inode *src); -extern void fsstack_copy_inode_size(struct inode *dst, const struct inode *src); +extern void fsstack_copy_inode_size(struct inode *dst, struct inode *src); /* inlines */ static inline void fsstack_copy_attr_atime(struct inode *dest, -- cgit v0.10.2 From 905aa0ae91798feb4e12d6237496d269dc2f4962 Mon Sep 17 00:00:00 2001 From: hartleys Date: Mon, 14 Dec 2009 22:22:25 +0000 Subject: spi: atmel_spi.c: use resource_size() Signed-off-by: H Hartley Sweeten Cc: Haavard Skinnemoen Signed-off-by: Grant Likely diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c index 8ce70cb..d21c24e 100644 --- a/drivers/spi/atmel_spi.c +++ b/drivers/spi/atmel_spi.c @@ -788,7 +788,7 @@ static int __init atmel_spi_probe(struct platform_device *pdev) spin_lock_init(&as->lock); INIT_LIST_HEAD(&as->queue); as->pdev = pdev; - as->regs = ioremap(regs->start, (regs->end - regs->start) + 1); + as->regs = ioremap(regs->start, resource_size(regs)); if (!as->regs) goto out_free_buffer; as->irq = irq; -- cgit v0.10.2 From 74947b898220c8af794f3de3f3c73a39799b4c4f Mon Sep 17 00:00:00 2001 From: hartleys Date: Mon, 14 Dec 2009 22:33:43 +0000 Subject: spi: spi_bfin5xx.c: use resource_size() Signed-off-by: H Hartley Sweeten Cc: David Brownell Cc: Bryan Wu Signed-off-by: Grant Likely diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c index 73e24ef..1d41058 100644 --- a/drivers/spi/spi_bfin5xx.c +++ b/drivers/spi/spi_bfin5xx.c @@ -1294,7 +1294,7 @@ static int __init bfin_spi_probe(struct platform_device *pdev) goto out_error_get_res; } - drv_data->regs_base = ioremap(res->start, (res->end - res->start + 1)); + drv_data->regs_base = ioremap(res->start, resource_size(res)); if (drv_data->regs_base == NULL) { dev_err(dev, "Cannot map IO\n"); status = -ENXIO; -- cgit v0.10.2 From 82de76513eeb35b93a591497dcff217f2ec76041 Mon Sep 17 00:00:00 2001 From: hartleys Date: Mon, 14 Dec 2009 22:37:15 +0000 Subject: spi: spi_mpc8xxx.c: use resource_size() Signed-off-by: H Hartley Sweeten Cc: David Brownell Cc: Kumar Gala Signed-off-by: Grant Likely diff --git a/drivers/spi/spi_mpc8xxx.c b/drivers/spi/spi_mpc8xxx.c index 1d98be9..797226c 100644 --- a/drivers/spi/spi_mpc8xxx.c +++ b/drivers/spi/spi_mpc8xxx.c @@ -566,7 +566,7 @@ mpc8xxx_spi_probe(struct device *dev, struct resource *mem, unsigned int irq) init_completion(&mpc8xxx_spi->done); - mpc8xxx_spi->base = ioremap(mem->start, mem->end - mem->start + 1); + mpc8xxx_spi->base = ioremap(mem->start, resource_size(mem)); if (mpc8xxx_spi->base == NULL) { ret = -ENOMEM; goto put_master; -- cgit v0.10.2 From 76b6fdd35a2d796febd5dbe0e25f42e2616bfed3 Mon Sep 17 00:00:00 2001 From: hartleys Date: Mon, 14 Dec 2009 22:40:05 +0000 Subject: spi: spi_sh_sci.c: use resource_size() Signed-off-by: H Hartley Sweeten Cc: David Brownell Signed-off-by: Grant Likely diff --git a/drivers/spi/spi_sh_sci.c b/drivers/spi/spi_sh_sci.c index 7d36720..a65c12f 100644 --- a/drivers/spi/spi_sh_sci.c +++ b/drivers/spi/spi_sh_sci.c @@ -148,7 +148,7 @@ static int sh_sci_spi_probe(struct platform_device *dev) ret = -ENOENT; goto err1; } - sp->membase = ioremap(r->start, r->end - r->start + 1); + sp->membase = ioremap(r->start, resource_size(r)); if (!sp->membase) { ret = -ENXIO; goto err1; -- cgit v0.10.2 From d53342bf9616ecd7e4a03fece167d0f53b195e87 Mon Sep 17 00:00:00 2001 From: hartleys Date: Mon, 14 Dec 2009 22:43:42 +0000 Subject: spi: spi_txx9.c: use resource_size() Signed-off-by: H Hartley Sweeten Cc: David Brownell Cc: Atsushi Nemoto Signed-off-by: Grant Likely diff --git a/drivers/spi/spi_txx9.c b/drivers/spi/spi_txx9.c index 96057de..c166eb5 100644 --- a/drivers/spi/spi_txx9.c +++ b/drivers/spi/spi_txx9.c @@ -376,12 +376,10 @@ static int __init txx9spi_probe(struct platform_device *dev) res = platform_get_resource(dev, IORESOURCE_MEM, 0); if (!res) goto exit_busy; - if (!devm_request_mem_region(&dev->dev, - res->start, res->end - res->start + 1, + if (!devm_request_mem_region(&dev->dev, res->start, resource_size(res), "spi_txx9")) goto exit_busy; - c->membase = devm_ioremap(&dev->dev, - res->start, res->end - res->start + 1); + c->membase = devm_ioremap(&dev->dev, res->start, resource_size(res)); if (!c->membase) goto exit_busy; -- cgit v0.10.2 From 76b7e0058d09f8104387980a690001681c04cc0a Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 17 Dec 2009 14:24:20 +0100 Subject: fix up O_SYNC comments Proper Posix O_SYNC handling only made it into 2.6.33, not 2.6.32. Signed-off-by: Christoph Hellwig Signed-off-by: Al Viro diff --git a/arch/alpha/include/asm/fcntl.h b/arch/alpha/include/asm/fcntl.h index 21b1117..70145cb 100644 --- a/arch/alpha/include/asm/fcntl.h +++ b/arch/alpha/include/asm/fcntl.h @@ -16,7 +16,7 @@ #define O_NOATIME 04000000 #define O_CLOEXEC 010000000 /* set close_on_exec */ /* - * Before Linux 2.6.32 only O_DSYNC semantics were implemented, but using + * Before Linux 2.6.33 only O_DSYNC semantics were implemented, but using * the O_SYNC flag. We continue to use the existing numerical value * for O_DSYNC semantics now, but using the correct symbolic name for it. * This new value is used to request true Posix O_SYNC semantics. It is diff --git a/arch/mips/include/asm/fcntl.h b/arch/mips/include/asm/fcntl.h index 7c6681a..e482fe9 100644 --- a/arch/mips/include/asm/fcntl.h +++ b/arch/mips/include/asm/fcntl.h @@ -19,7 +19,7 @@ #define FASYNC 0x1000 /* fcntl, for BSD compatibility */ #define O_LARGEFILE 0x2000 /* allow large file opens */ /* - * Before Linux 2.6.32 only O_DSYNC semantics were implemented, but using + * Before Linux 2.6.33 only O_DSYNC semantics were implemented, but using * the O_SYNC flag. We continue to use the existing numerical value * for O_DSYNC semantics now, but using the correct symbolic name for it. * This new value is used to request true Posix O_SYNC semantics. It is diff --git a/arch/sparc/include/asm/fcntl.h b/arch/sparc/include/asm/fcntl.h index 3b9cfb3..38f37b33 100644 --- a/arch/sparc/include/asm/fcntl.h +++ b/arch/sparc/include/asm/fcntl.h @@ -19,7 +19,7 @@ #define O_NOATIME 0x200000 #define O_CLOEXEC 0x400000 /* - * Before Linux 2.6.32 only O_DSYNC semantics were implemented, but using + * Before Linux 2.6.33 only O_DSYNC semantics were implemented, but using * the O_SYNC flag. We continue to use the existing numerical value * for O_DSYNC semantics now, but using the correct symbolic name for it. * This new value is used to request true Posix O_SYNC semantics. It is diff --git a/include/asm-generic/fcntl.h b/include/asm-generic/fcntl.h index 681ddf3..fcd268c 100644 --- a/include/asm-generic/fcntl.h +++ b/include/asm-generic/fcntl.h @@ -51,7 +51,7 @@ #endif /* - * Before Linux 2.6.32 only O_DSYNC semantics were implemented, but using + * Before Linux 2.6.33 only O_DSYNC semantics were implemented, but using * the O_SYNC flag. We continue to use the existing numerical value * for O_DSYNC semantics now, but using the correct symbolic name for it. * This new value is used to request true Posix O_SYNC semantics. It is -- cgit v0.10.2 From 7a0ad10c367ab57c899d340372f37880cbe6ab52 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 17 Dec 2009 14:24:40 +0100 Subject: fold do_sync_file_range into sys_sync_file_range We recently go rid of all callers of do_sync_file_range as they're better served with vfs_fsync or the filemap_write_and_wait. Now that do_sync_file_range is down to a single caller fold it into it so that people don't start using it again accidentally. While at it also switch it from using __filemap_fdatawrite_range(..., WB_SYNC_ALL) to the more clear filemap_fdatawrite_range(). Signed-off-by: Christoph Hellwig Signed-off-by: Al Viro diff --git a/fs/sync.c b/fs/sync.c index 36752a6..418727a 100644 --- a/fs/sync.c +++ b/fs/sync.c @@ -355,6 +355,7 @@ SYSCALL_DEFINE(sync_file_range)(int fd, loff_t offset, loff_t nbytes, { int ret; struct file *file; + struct address_space *mapping; loff_t endbyte; /* inclusive */ int fput_needed; umode_t i_mode; @@ -405,7 +406,28 @@ SYSCALL_DEFINE(sync_file_range)(int fd, loff_t offset, loff_t nbytes, !S_ISLNK(i_mode)) goto out_put; - ret = do_sync_mapping_range(file->f_mapping, offset, endbyte, flags); + mapping = file->f_mapping; + if (!mapping) { + ret = -EINVAL; + goto out_put; + } + + ret = 0; + if (flags & SYNC_FILE_RANGE_WAIT_BEFORE) { + ret = filemap_fdatawait_range(mapping, offset, endbyte); + if (ret < 0) + goto out_put; + } + + if (flags & SYNC_FILE_RANGE_WRITE) { + ret = filemap_fdatawrite_range(mapping, offset, endbyte); + if (ret < 0) + goto out_put; + } + + if (flags & SYNC_FILE_RANGE_WAIT_AFTER) + ret = filemap_fdatawait_range(mapping, offset, endbyte); + out_put: fput_light(file, fput_needed); out: @@ -437,38 +459,3 @@ asmlinkage long SyS_sync_file_range2(long fd, long flags, } SYSCALL_ALIAS(sys_sync_file_range2, SyS_sync_file_range2); #endif - -/* - * `endbyte' is inclusive - */ -int do_sync_mapping_range(struct address_space *mapping, loff_t offset, - loff_t endbyte, unsigned int flags) -{ - int ret; - - if (!mapping) { - ret = -EINVAL; - goto out; - } - - ret = 0; - if (flags & SYNC_FILE_RANGE_WAIT_BEFORE) { - ret = filemap_fdatawait_range(mapping, offset, endbyte); - if (ret < 0) - goto out; - } - - if (flags & SYNC_FILE_RANGE_WRITE) { - ret = __filemap_fdatawrite_range(mapping, offset, endbyte, - WB_SYNC_ALL); - if (ret < 0) - goto out; - } - - if (flags & SYNC_FILE_RANGE_WAIT_AFTER) { - ret = filemap_fdatawait_range(mapping, offset, endbyte); - } -out: - return ret; -} -EXPORT_SYMBOL_GPL(do_sync_mapping_range); diff --git a/include/linux/fs.h b/include/linux/fs.h index 66bc0a5..77a9750 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1095,10 +1095,6 @@ struct file_lock { extern void send_sigio(struct fown_struct *fown, int fd, int band); -/* fs/sync.c */ -extern int do_sync_mapping_range(struct address_space *mapping, loff_t offset, - loff_t endbyte, unsigned int flags); - #ifdef CONFIG_FILE_LOCKING extern int fcntl_getlk(struct file *, struct flock __user *); extern int fcntl_setlk(unsigned int, struct file *, unsigned int, -- cgit v0.10.2 From eaff8079d4f1016a12e34ab323737314f24127dd Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 17 Dec 2009 14:25:01 +0100 Subject: kill I_LOCK After I_SYNC was split from I_LOCK the leftover is always used together with I_NEW and thus superflous. Signed-off-by: Christoph Hellwig Signed-off-by: Al Viro diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 3ff32fa..6e220f4 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c @@ -125,7 +125,7 @@ static struct inode *gfs2_iget_skip(struct super_block *sb, * directory entry when gfs2_inode_lookup() is invoked. Part of the code * segment inside gfs2_inode_lookup code needs to get moved around. * - * Clean up I_LOCK and I_NEW as well. + * Clears I_NEW as well. **/ void gfs2_set_iop(struct inode *inode) diff --git a/fs/inode.c b/fs/inode.c index 06c1f02..03dfeb2 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -113,7 +113,7 @@ static void wake_up_inode(struct inode *inode) * Prevent speculative execution through spin_unlock(&inode_lock); */ smp_mb(); - wake_up_bit(&inode->i_state, __I_LOCK); + wake_up_bit(&inode->i_state, __I_NEW); } /** @@ -690,17 +690,17 @@ void unlock_new_inode(struct inode *inode) } #endif /* - * This is special! We do not need the spinlock when clearing I_LOCK, + * This is special! We do not need the spinlock when clearing I_NEW, * because we're guaranteed that nobody else tries to do anything about * the state of the inode when it is locked, as we just created it (so - * there can be no old holders that haven't tested I_LOCK). + * there can be no old holders that haven't tested I_NEW). * However we must emit the memory barrier so that other CPUs reliably - * see the clearing of I_LOCK after the other inode initialisation has + * see the clearing of I_NEW after the other inode initialisation has * completed. */ smp_mb(); - WARN_ON((inode->i_state & (I_LOCK|I_NEW)) != (I_LOCK|I_NEW)); - inode->i_state &= ~(I_LOCK|I_NEW); + WARN_ON(!(inode->i_state & I_NEW)); + inode->i_state &= ~I_NEW; wake_up_inode(inode); } EXPORT_SYMBOL(unlock_new_inode); @@ -731,7 +731,7 @@ static struct inode *get_new_inode(struct super_block *sb, goto set_failed; __inode_add_to_lists(sb, head, inode); - inode->i_state = I_LOCK|I_NEW; + inode->i_state = I_NEW; spin_unlock(&inode_lock); /* Return the locked inode with I_NEW set, the @@ -778,7 +778,7 @@ static struct inode *get_new_inode_fast(struct super_block *sb, if (!old) { inode->i_ino = ino; __inode_add_to_lists(sb, head, inode); - inode->i_state = I_LOCK|I_NEW; + inode->i_state = I_NEW; spin_unlock(&inode_lock); /* Return the locked inode with I_NEW set, the @@ -1083,7 +1083,7 @@ int insert_inode_locked(struct inode *inode) ino_t ino = inode->i_ino; struct hlist_head *head = inode_hashtable + hash(sb, ino); - inode->i_state |= I_LOCK|I_NEW; + inode->i_state |= I_NEW; while (1) { struct hlist_node *node; struct inode *old = NULL; @@ -1120,7 +1120,7 @@ int insert_inode_locked4(struct inode *inode, unsigned long hashval, struct super_block *sb = inode->i_sb; struct hlist_head *head = inode_hashtable + hash(sb, hashval); - inode->i_state |= I_LOCK|I_NEW; + inode->i_state |= I_NEW; while (1) { struct hlist_node *node; @@ -1510,7 +1510,7 @@ EXPORT_SYMBOL(inode_wait); * until the deletion _might_ have completed. Callers are responsible * to recheck inode state. * - * It doesn't matter if I_LOCK is not set initially, a call to + * It doesn't matter if I_NEW is not set initially, a call to * wake_up_inode() after removing from the hash list will DTRT. * * This is called with inode_lock held. @@ -1518,8 +1518,8 @@ EXPORT_SYMBOL(inode_wait); static void __wait_on_freeing_inode(struct inode *inode) { wait_queue_head_t *wq; - DEFINE_WAIT_BIT(wait, &inode->i_state, __I_LOCK); - wq = bit_waitqueue(&inode->i_state, __I_LOCK); + DEFINE_WAIT_BIT(wait, &inode->i_state, __I_NEW); + wq = bit_waitqueue(&inode->i_state, __I_NEW); prepare_to_wait(wq, &wait.wait, TASK_UNINTERRUPTIBLE); spin_unlock(&inode_lock); schedule(); diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c index f26e4d0..d945ea7 100644 --- a/fs/jfs/jfs_txnmgr.c +++ b/fs/jfs/jfs_txnmgr.c @@ -1292,7 +1292,7 @@ int txCommit(tid_t tid, /* transaction identifier */ */ /* * I believe this code is no longer needed. Splitting I_LOCK - * into two bits, I_LOCK and I_SYNC should prevent this + * into two bits, I_NEW and I_SYNC should prevent this * deadlock as well. But since I don't have a JFS testload * to verify this, only a trivial s/I_LOCK/I_SYNC/ was done. * Joern diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c index 9938034..dc2505a 100644 --- a/fs/ntfs/inode.c +++ b/fs/ntfs/inode.c @@ -530,7 +530,7 @@ err_corrupt_attr: * the ntfs inode. * * Q: What locks are held when the function is called? - * A: i_state has I_LOCK set, hence the inode is locked, also + * A: i_state has I_NEW set, hence the inode is locked, also * i_count is set to 1, so it is not going to go away * i_flags is set to 0 and we have no business touching it. Only an ioctl() * is allowed to write to them. We should of course be honouring them but @@ -1207,7 +1207,7 @@ err_out: * necessary fields in @vi as well as initializing the ntfs inode. * * Q: What locks are held when the function is called? - * A: i_state has I_LOCK set, hence the inode is locked, also + * A: i_state has I_NEW set, hence the inode is locked, also * i_count is set to 1, so it is not going to go away * * Return 0 on success and -errno on error. In the error case, the inode will @@ -1474,7 +1474,7 @@ err_out: * normal directory inodes. * * Q: What locks are held when the function is called? - * A: i_state has I_LOCK set, hence the inode is locked, also + * A: i_state has I_NEW set, hence the inode is locked, also * i_count is set to 1, so it is not going to go away * * Return 0 on success and -errno on error. In the error case, the inode will diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c index 39849f8..16a6444 100644 --- a/fs/ubifs/file.c +++ b/fs/ubifs/file.c @@ -45,7 +45,7 @@ * * Similarly, @i_mutex is not always locked in 'ubifs_readpage()', e.g., the * read-ahead path does not lock it ("sys_read -> generic_file_aio_read -> - * ondemand_readahead -> readpage"). In case of readahead, @I_LOCK flag is not + * ondemand_readahead -> readpage"). In case of readahead, @I_SYNC flag is not * set as well. However, UBIFS disables readahead. */ diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index 1d5b298..2259460 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c @@ -794,7 +794,7 @@ xfs_setup_inode( struct inode *inode = &ip->i_vnode; inode->i_ino = ip->i_ino; - inode->i_state = I_NEW|I_LOCK; + inode->i_state = I_NEW; inode_add_to_lists(ip->i_mount->m_super, inode); inode->i_mode = ip->i_d.di_mode; diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index 0de36c2..fa402a6 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.c @@ -91,7 +91,7 @@ xfs_inode_alloc( ip->i_new_size = 0; /* prevent anyone from using this yet */ - VFS_I(ip)->i_state = I_NEW|I_LOCK; + VFS_I(ip)->i_state = I_NEW; return ip; } @@ -217,7 +217,7 @@ xfs_iget_cache_hit( trace_xfs_iget_reclaim(ip); goto out_error; } - inode->i_state = I_LOCK|I_NEW; + inode->i_state = I_NEW; } else { /* If the VFS inode is being torn down, pause and try again. */ if (!igrab(inode)) { diff --git a/include/linux/fs.h b/include/linux/fs.h index 77a9750..cca1919 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1587,7 +1587,7 @@ struct super_operations { * until that flag is cleared. I_WILL_FREE, I_FREEING and I_CLEAR are set at * various stages of removing an inode. * - * Two bits are used for locking and completion notification, I_LOCK and I_SYNC. + * Two bits are used for locking and completion notification, I_NEW and I_SYNC. * * I_DIRTY_SYNC Inode is dirty, but doesn't have to be written on * fdatasync(). i_atime is the usual cause. @@ -1596,8 +1596,14 @@ struct super_operations { * don't have to write inode on fdatasync() when only * mtime has changed in it. * I_DIRTY_PAGES Inode has dirty pages. Inode itself may be clean. - * I_NEW get_new_inode() sets i_state to I_LOCK|I_NEW. Both - * are cleared by unlock_new_inode(), called from iget(). + * I_NEW Serves as both a mutex and completion notification. + * New inodes set I_NEW. If two processes both create + * the same inode, one of them will release its inode and + * wait for I_NEW to be released before returning. + * Inodes in I_WILL_FREE, I_FREEING or I_CLEAR state can + * also cause waiting on I_NEW, without I_NEW actually + * being set. find_inode() uses this to prevent returning + * nearly-dead inodes. * I_WILL_FREE Must be set when calling write_inode_now() if i_count * is zero. I_FREEING must be set when I_WILL_FREE is * cleared. @@ -1611,20 +1617,11 @@ struct super_operations { * prohibited for many purposes. iget() must wait for * the inode to be completely released, then create it * anew. Other functions will just ignore such inodes, - * if appropriate. I_LOCK is used for waiting. + * if appropriate. I_NEW is used for waiting. * - * I_LOCK Serves as both a mutex and completion notification. - * New inodes set I_LOCK. If two processes both create - * the same inode, one of them will release its inode and - * wait for I_LOCK to be released before returning. - * Inodes in I_WILL_FREE, I_FREEING or I_CLEAR state can - * also cause waiting on I_LOCK, without I_LOCK actually - * being set. find_inode() uses this to prevent returning - * nearly-dead inodes. - * I_SYNC Similar to I_LOCK, but limited in scope to writeback - * of inode dirty data. Having a separate lock for this - * purpose reduces latency and prevents some filesystem- - * specific deadlocks. + * I_SYNC Synchonized write of dirty inode data. The bits is + * set during data writeback, and cleared with a wakeup + * on the bit address once it is done. * * Q: What is the difference between I_WILL_FREE and I_FREEING? * Q: igrab() only checks on (I_FREEING|I_WILL_FREE). Should it also check on @@ -1633,13 +1630,12 @@ struct super_operations { #define I_DIRTY_SYNC 1 #define I_DIRTY_DATASYNC 2 #define I_DIRTY_PAGES 4 -#define I_NEW 8 +#define __I_NEW 3 +#define I_NEW (1 << __I_NEW) #define I_WILL_FREE 16 #define I_FREEING 32 #define I_CLEAR 64 -#define __I_LOCK 7 -#define I_LOCK (1 << __I_LOCK) -#define __I_SYNC 8 +#define __I_SYNC 7 #define I_SYNC (1 << __I_SYNC) #define I_DIRTY (I_DIRTY_SYNC | I_DIRTY_DATASYNC | I_DIRTY_PAGES) diff --git a/include/linux/writeback.h b/include/linux/writeback.h index 705f01f..c18c008 100644 --- a/include/linux/writeback.h +++ b/include/linux/writeback.h @@ -79,8 +79,7 @@ void wakeup_flusher_threads(long nr_pages); static inline void wait_on_inode(struct inode *inode) { might_sleep(); - wait_on_bit(&inode->i_state, __I_LOCK, inode_wait, - TASK_UNINTERRUPTIBLE); + wait_on_bit(&inode->i_state, __I_NEW, inode_wait, TASK_UNINTERRUPTIBLE); } static inline void inode_sync_wait(struct inode *inode) { -- cgit v0.10.2 From 3542a113ab2f5880f1b62e5909d754250fb57d6b Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 17 Dec 2009 09:41:39 -0700 Subject: sh: fix DMA driver's descriptor chaining and cookie assignment The SH DMA driver wrongly assigns negative cookies to transfer descriptors, also, its chaining of partial descriptors is broken. The latter problem is usually invisible, because maximum transfer size per chunk is 16M, but if you artificially set this limit lower, the driver fails. Since cookies are also used in chunk management, both these problems are fixed in one patch. As side effects a possible memory leak, when descriptors are prepared, but not submitted, and multiple races have also been fixed. Signed-off-by: Guennadi Liakhovetski Acked-by: Paul Mundt Acked-by: Nobuhiro Iwamatsu Signed-off-by: Dan Williams diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c index 8d9acd7..9546f5f 100644 --- a/drivers/dma/shdma.c +++ b/drivers/dma/shdma.c @@ -23,16 +23,19 @@ #include #include #include -#include #include #include #include #include "shdma.h" /* DMA descriptor control */ -#define DESC_LAST (-1) -#define DESC_COMP (1) -#define DESC_NCOMP (0) +enum sh_dmae_desc_status { + DESC_IDLE, + DESC_PREPARED, + DESC_SUBMITTED, + DESC_COMPLETED, /* completed, have to call callback */ + DESC_WAITING, /* callback called, waiting for ack / re-submit */ +}; #define NR_DESCS_PER_CHANNEL 32 /* @@ -45,6 +48,8 @@ */ #define RS_DEFAULT (RS_DUAL) +static void sh_dmae_chan_ld_cleanup(struct sh_dmae_chan *sh_chan, bool all); + #define SH_DMAC_CHAN_BASE(id) (dma_base_addr[id]) static void sh_dmae_writel(struct sh_dmae_chan *sh_dc, u32 data, u32 reg) { @@ -106,11 +111,11 @@ static inline unsigned int calc_xmit_shift(struct sh_dmae_chan *sh_chan) return ts_shift[(chcr & CHCR_TS_MASK) >> CHCR_TS_SHIFT]; } -static void dmae_set_reg(struct sh_dmae_chan *sh_chan, struct sh_dmae_regs hw) +static void dmae_set_reg(struct sh_dmae_chan *sh_chan, struct sh_dmae_regs *hw) { - sh_dmae_writel(sh_chan, hw.sar, SAR); - sh_dmae_writel(sh_chan, hw.dar, DAR); - sh_dmae_writel(sh_chan, hw.tcr >> calc_xmit_shift(sh_chan), TCR); + sh_dmae_writel(sh_chan, hw->sar, SAR); + sh_dmae_writel(sh_chan, hw->dar, DAR); + sh_dmae_writel(sh_chan, hw->tcr >> calc_xmit_shift(sh_chan), TCR); } static void dmae_start(struct sh_dmae_chan *sh_chan) @@ -184,8 +189,9 @@ static int dmae_set_dmars(struct sh_dmae_chan *sh_chan, u16 val) static dma_cookie_t sh_dmae_tx_submit(struct dma_async_tx_descriptor *tx) { - struct sh_desc *desc = tx_to_sh_desc(tx); + struct sh_desc *desc = tx_to_sh_desc(tx), *chunk, *last = desc, *c; struct sh_dmae_chan *sh_chan = to_sh_chan(tx->chan); + dma_async_tx_callback callback = tx->callback; dma_cookie_t cookie; spin_lock_bh(&sh_chan->desc_lock); @@ -195,45 +201,53 @@ static dma_cookie_t sh_dmae_tx_submit(struct dma_async_tx_descriptor *tx) if (cookie < 0) cookie = 1; - /* If desc only in the case of 1 */ - if (desc->async_tx.cookie != -EBUSY) - desc->async_tx.cookie = cookie; - sh_chan->common.cookie = desc->async_tx.cookie; + sh_chan->common.cookie = cookie; + tx->cookie = cookie; + + /* Mark all chunks of this descriptor as submitted, move to the queue */ + list_for_each_entry_safe(chunk, c, desc->node.prev, node) { + /* + * All chunks are on the global ld_free, so, we have to find + * the end of the chain ourselves + */ + if (chunk != desc && (chunk->mark == DESC_IDLE || + chunk->async_tx.cookie > 0 || + chunk->async_tx.cookie == -EBUSY || + &chunk->node == &sh_chan->ld_free)) + break; + chunk->mark = DESC_SUBMITTED; + /* Callback goes to the last chunk */ + chunk->async_tx.callback = NULL; + chunk->cookie = cookie; + list_move_tail(&chunk->node, &sh_chan->ld_queue); + last = chunk; + } + + last->async_tx.callback = callback; + last->async_tx.callback_param = tx->callback_param; - list_splice_init(&desc->tx_list, sh_chan->ld_queue.prev); + dev_dbg(sh_chan->dev, "submit #%d@%p on %d: %x[%d] -> %x\n", + tx->cookie, &last->async_tx, sh_chan->id, + desc->hw.sar, desc->hw.tcr, desc->hw.dar); spin_unlock_bh(&sh_chan->desc_lock); return cookie; } +/* Called with desc_lock held */ static struct sh_desc *sh_dmae_get_desc(struct sh_dmae_chan *sh_chan) { - struct sh_desc *desc, *_desc, *ret = NULL; + struct sh_desc *desc; - spin_lock_bh(&sh_chan->desc_lock); - list_for_each_entry_safe(desc, _desc, &sh_chan->ld_free, node) { - if (async_tx_test_ack(&desc->async_tx)) { + list_for_each_entry(desc, &sh_chan->ld_free, node) + if (desc->mark != DESC_PREPARED) { + BUG_ON(desc->mark != DESC_IDLE); list_del(&desc->node); - ret = desc; - break; + return desc; } - } - spin_unlock_bh(&sh_chan->desc_lock); - - return ret; -} - -static void sh_dmae_put_desc(struct sh_dmae_chan *sh_chan, struct sh_desc *desc) -{ - if (desc) { - spin_lock_bh(&sh_chan->desc_lock); - - list_splice_init(&desc->tx_list, &sh_chan->ld_free); - list_add(&desc->node, &sh_chan->ld_free); - spin_unlock_bh(&sh_chan->desc_lock); - } + return NULL; } static int sh_dmae_alloc_chan_resources(struct dma_chan *chan) @@ -252,11 +266,10 @@ static int sh_dmae_alloc_chan_resources(struct dma_chan *chan) dma_async_tx_descriptor_init(&desc->async_tx, &sh_chan->common); desc->async_tx.tx_submit = sh_dmae_tx_submit; - desc->async_tx.flags = DMA_CTRL_ACK; - INIT_LIST_HEAD(&desc->tx_list); - sh_dmae_put_desc(sh_chan, desc); + desc->mark = DESC_IDLE; spin_lock_bh(&sh_chan->desc_lock); + list_add(&desc->node, &sh_chan->ld_free); sh_chan->descs_allocated++; } spin_unlock_bh(&sh_chan->desc_lock); @@ -273,7 +286,10 @@ static void sh_dmae_free_chan_resources(struct dma_chan *chan) struct sh_desc *desc, *_desc; LIST_HEAD(list); - BUG_ON(!list_empty(&sh_chan->ld_queue)); + /* Prepared and not submitted descriptors can still be on the queue */ + if (!list_empty(&sh_chan->ld_queue)) + sh_dmae_chan_ld_cleanup(sh_chan, true); + spin_lock_bh(&sh_chan->desc_lock); list_splice_init(&sh_chan->ld_free, &list); @@ -292,6 +308,8 @@ static struct dma_async_tx_descriptor *sh_dmae_prep_memcpy( struct sh_dmae_chan *sh_chan; struct sh_desc *first = NULL, *prev = NULL, *new; size_t copy_size; + LIST_HEAD(tx_list); + int chunks = (len + SH_DMA_TCR_MAX) / (SH_DMA_TCR_MAX + 1); if (!chan) return NULL; @@ -301,108 +319,189 @@ static struct dma_async_tx_descriptor *sh_dmae_prep_memcpy( sh_chan = to_sh_chan(chan); + /* Have to lock the whole loop to protect against concurrent release */ + spin_lock_bh(&sh_chan->desc_lock); + + /* + * Chaining: + * first descriptor is what user is dealing with in all API calls, its + * cookie is at first set to -EBUSY, at tx-submit to a positive + * number + * if more than one chunk is needed further chunks have cookie = -EINVAL + * the last chunk, if not equal to the first, has cookie = -ENOSPC + * all chunks are linked onto the tx_list head with their .node heads + * only during this function, then they are immediately spliced + * back onto the free list in form of a chain + */ do { - /* Allocate the link descriptor from DMA pool */ + /* Allocate the link descriptor from the free list */ new = sh_dmae_get_desc(sh_chan); if (!new) { dev_err(sh_chan->dev, "No free memory for link descriptor\n"); - goto err_get_desc; + list_for_each_entry(new, &tx_list, node) + new->mark = DESC_IDLE; + list_splice(&tx_list, &sh_chan->ld_free); + spin_unlock_bh(&sh_chan->desc_lock); + return NULL; } - copy_size = min(len, (size_t)SH_DMA_TCR_MAX); + copy_size = min(len, (size_t)SH_DMA_TCR_MAX + 1); new->hw.sar = dma_src; new->hw.dar = dma_dest; new->hw.tcr = copy_size; - if (!first) + if (!first) { + /* First desc */ + new->async_tx.cookie = -EBUSY; first = new; + } else { + /* Other desc - invisible to the user */ + new->async_tx.cookie = -EINVAL; + } - new->mark = DESC_NCOMP; - async_tx_ack(&new->async_tx); + dev_dbg(sh_chan->dev, + "chaining %u of %u with %p, dst %x, cookie %d\n", + copy_size, len, &new->async_tx, dma_dest, + new->async_tx.cookie); + + new->mark = DESC_PREPARED; + new->async_tx.flags = flags; + new->chunks = chunks--; prev = new; len -= copy_size; dma_src += copy_size; dma_dest += copy_size; /* Insert the link descriptor to the LD ring */ - list_add_tail(&new->node, &first->tx_list); + list_add_tail(&new->node, &tx_list); } while (len); - new->async_tx.flags = flags; /* client is in control of this ack */ - new->async_tx.cookie = -EBUSY; /* Last desc */ + if (new != first) + new->async_tx.cookie = -ENOSPC; - return &first->async_tx; + /* Put them back on the free list, so, they don't get lost */ + list_splice_tail(&tx_list, &sh_chan->ld_free); -err_get_desc: - sh_dmae_put_desc(sh_chan, first); - return NULL; + spin_unlock_bh(&sh_chan->desc_lock); + return &first->async_tx; } -/* - * sh_chan_ld_cleanup - Clean up link descriptors - * - * This function clean up the ld_queue of DMA channel. - */ -static void sh_dmae_chan_ld_cleanup(struct sh_dmae_chan *sh_chan) +static dma_async_tx_callback __ld_cleanup(struct sh_dmae_chan *sh_chan, bool all) { struct sh_desc *desc, *_desc; + /* Is the "exposed" head of a chain acked? */ + bool head_acked = false; + dma_cookie_t cookie = 0; + dma_async_tx_callback callback = NULL; + void *param = NULL; spin_lock_bh(&sh_chan->desc_lock); list_for_each_entry_safe(desc, _desc, &sh_chan->ld_queue, node) { - dma_async_tx_callback callback; - void *callback_param; - - /* non send data */ - if (desc->mark == DESC_NCOMP) + struct dma_async_tx_descriptor *tx = &desc->async_tx; + + BUG_ON(tx->cookie > 0 && tx->cookie != desc->cookie); + BUG_ON(desc->mark != DESC_SUBMITTED && + desc->mark != DESC_COMPLETED && + desc->mark != DESC_WAITING); + + /* + * queue is ordered, and we use this loop to (1) clean up all + * completed descriptors, and to (2) update descriptor flags of + * any chunks in a (partially) completed chain + */ + if (!all && desc->mark == DESC_SUBMITTED && + desc->cookie != cookie) break; - /* send data sesc */ - callback = desc->async_tx.callback; - callback_param = desc->async_tx.callback_param; + if (tx->cookie > 0) + cookie = tx->cookie; - /* Remove from ld_queue list */ - list_splice_init(&desc->tx_list, &sh_chan->ld_free); + if (desc->mark == DESC_COMPLETED && desc->chunks == 1) { + BUG_ON(sh_chan->completed_cookie != desc->cookie - 1); + sh_chan->completed_cookie = desc->cookie; + } - dev_dbg(sh_chan->dev, "link descriptor %p will be recycle.\n", - desc); + /* Call callback on the last chunk */ + if (desc->mark == DESC_COMPLETED && tx->callback) { + desc->mark = DESC_WAITING; + callback = tx->callback; + param = tx->callback_param; + dev_dbg(sh_chan->dev, "descriptor #%d@%p on %d callback\n", + tx->cookie, tx, sh_chan->id); + BUG_ON(desc->chunks != 1); + break; + } - list_move(&desc->node, &sh_chan->ld_free); - /* Run the link descriptor callback function */ - if (callback) { - spin_unlock_bh(&sh_chan->desc_lock); - dev_dbg(sh_chan->dev, "link descriptor %p callback\n", - desc); - callback(callback_param); - spin_lock_bh(&sh_chan->desc_lock); + if (tx->cookie > 0 || tx->cookie == -EBUSY) { + if (desc->mark == DESC_COMPLETED) { + BUG_ON(tx->cookie < 0); + desc->mark = DESC_WAITING; + } + head_acked = async_tx_test_ack(tx); + } else { + switch (desc->mark) { + case DESC_COMPLETED: + desc->mark = DESC_WAITING; + /* Fall through */ + case DESC_WAITING: + if (head_acked) + async_tx_ack(&desc->async_tx); + } + } + + dev_dbg(sh_chan->dev, "descriptor %p #%d completed.\n", + tx, tx->cookie); + + if (((desc->mark == DESC_COMPLETED || + desc->mark == DESC_WAITING) && + async_tx_test_ack(&desc->async_tx)) || all) { + /* Remove from ld_queue list */ + desc->mark = DESC_IDLE; + list_move(&desc->node, &sh_chan->ld_free); } } spin_unlock_bh(&sh_chan->desc_lock); + + if (callback) + callback(param); + + return callback; +} + +/* + * sh_chan_ld_cleanup - Clean up link descriptors + * + * This function cleans up the ld_queue of DMA channel. + */ +static void sh_dmae_chan_ld_cleanup(struct sh_dmae_chan *sh_chan, bool all) +{ + while (__ld_cleanup(sh_chan, all)) + ; } static void sh_chan_xfer_ld_queue(struct sh_dmae_chan *sh_chan) { - struct list_head *ld_node; - struct sh_dmae_regs hw; + struct sh_desc *sd; + spin_lock_bh(&sh_chan->desc_lock); /* DMA work check */ - if (dmae_is_busy(sh_chan)) + if (dmae_is_busy(sh_chan)) { + spin_unlock_bh(&sh_chan->desc_lock); return; + } /* Find the first un-transfer desciptor */ - for (ld_node = sh_chan->ld_queue.next; - (ld_node != &sh_chan->ld_queue) - && (to_sh_desc(ld_node)->mark == DESC_COMP); - ld_node = ld_node->next) - cpu_relax(); - - if (ld_node != &sh_chan->ld_queue) { - /* Get the ld start address from ld_queue */ - hw = to_sh_desc(ld_node)->hw; - dmae_set_reg(sh_chan, hw); - dmae_start(sh_chan); - } + list_for_each_entry(sd, &sh_chan->ld_queue, node) + if (sd->mark == DESC_SUBMITTED) { + /* Get the ld start address from ld_queue */ + dmae_set_reg(sh_chan, &sd->hw); + dmae_start(sh_chan); + break; + } + + spin_unlock_bh(&sh_chan->desc_lock); } static void sh_dmae_memcpy_issue_pending(struct dma_chan *chan) @@ -420,12 +519,11 @@ static enum dma_status sh_dmae_is_complete(struct dma_chan *chan, dma_cookie_t last_used; dma_cookie_t last_complete; - sh_dmae_chan_ld_cleanup(sh_chan); + sh_dmae_chan_ld_cleanup(sh_chan, false); last_used = chan->cookie; last_complete = sh_chan->completed_cookie; - if (last_complete == -EBUSY) - last_complete = last_used; + BUG_ON(last_complete < 0); if (done) *done = last_complete; @@ -480,11 +578,13 @@ static irqreturn_t sh_dmae_err(int irq, void *data) err = sh_dmae_rst(0); if (err) return err; +#ifdef SH_DMAC_BASE1 if (shdev->pdata.mode & SHDMA_DMAOR1) { err = sh_dmae_rst(1); if (err) return err; } +#endif disable_irq(irq); return IRQ_HANDLED; } @@ -494,35 +594,25 @@ static irqreturn_t sh_dmae_err(int irq, void *data) static void dmae_do_tasklet(unsigned long data) { struct sh_dmae_chan *sh_chan = (struct sh_dmae_chan *)data; - struct sh_desc *desc, *_desc, *cur_desc = NULL; + struct sh_desc *desc; u32 sar_buf = sh_dmae_readl(sh_chan, SAR); - list_for_each_entry_safe(desc, _desc, - &sh_chan->ld_queue, node) { - if ((desc->hw.sar + desc->hw.tcr) == sar_buf) { - cur_desc = desc; + spin_lock(&sh_chan->desc_lock); + list_for_each_entry(desc, &sh_chan->ld_queue, node) { + if ((desc->hw.sar + desc->hw.tcr) == sar_buf && + desc->mark == DESC_SUBMITTED) { + dev_dbg(sh_chan->dev, "done #%d@%p dst %u\n", + desc->async_tx.cookie, &desc->async_tx, + desc->hw.dar); + desc->mark = DESC_COMPLETED; break; } } + spin_unlock(&sh_chan->desc_lock); - if (cur_desc) { - switch (cur_desc->async_tx.cookie) { - case 0: /* other desc data */ - break; - case -EBUSY: /* last desc */ - sh_chan->completed_cookie = - cur_desc->async_tx.cookie; - break; - default: /* first desc ( 0 < )*/ - sh_chan->completed_cookie = - cur_desc->async_tx.cookie - 1; - break; - } - cur_desc->mark = DESC_COMP; - } /* Next desc */ sh_chan_xfer_ld_queue(sh_chan); - sh_dmae_chan_ld_cleanup(sh_chan); + sh_dmae_chan_ld_cleanup(sh_chan, false); } static unsigned int get_dmae_irq(unsigned int id) diff --git a/drivers/dma/shdma.h b/drivers/dma/shdma.h index 60b81e5..108f1cf 100644 --- a/drivers/dma/shdma.h +++ b/drivers/dma/shdma.h @@ -13,9 +13,9 @@ #ifndef __DMA_SHDMA_H #define __DMA_SHDMA_H -#include -#include #include +#include +#include #define SH_DMA_TCR_MAX 0x00FFFFFF /* 16MB */ @@ -26,13 +26,16 @@ struct sh_dmae_regs { }; struct sh_desc { - struct list_head tx_list; struct sh_dmae_regs hw; struct list_head node; struct dma_async_tx_descriptor async_tx; + dma_cookie_t cookie; + int chunks; int mark; }; +struct device; + struct sh_dmae_chan { dma_cookie_t completed_cookie; /* The maximum cookie completed */ spinlock_t desc_lock; /* Descriptor operation lock */ -- cgit v0.10.2 From c216775458a2ee345d9412a2770c2916acfb5d30 Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Thu, 12 Nov 2009 09:34:21 +0000 Subject: Btrfs: Fix disk_i_size update corner case There are some cases file extents are inserted without involving ordered struct. In these cases, we update disk_i_size directly, without checking pending ordered extent and DELALLOC bit. This patch extends btrfs_ordered_update_i_size() to handle these cases. Signed-off-by: Yan Zheng Signed-off-by: Chris Mason diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h index f6783a4..3f1f50d 100644 --- a/fs/btrfs/btrfs_inode.h +++ b/fs/btrfs/btrfs_inode.h @@ -44,9 +44,6 @@ struct btrfs_inode { */ struct extent_io_tree io_failure_tree; - /* held while inesrting or deleting extents from files */ - struct mutex extent_mutex; - /* held while logging the inode in tree-log.c */ struct mutex log_mutex; @@ -166,7 +163,7 @@ static inline struct btrfs_inode *BTRFS_I(struct inode *inode) static inline void btrfs_i_size_write(struct inode *inode, u64 size) { - inode->i_size = size; + i_size_write(inode, size); BTRFS_I(inode)->disk_i_size = size; } diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index ef250be..fa57247 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -188,8 +188,18 @@ static noinline int insert_inline_extent(struct btrfs_trans_handle *trans, btrfs_mark_buffer_dirty(leaf); btrfs_free_path(path); + /* + * we're an inline extent, so nobody can + * extend the file past i_size without locking + * a page we already have locked. + * + * We must do any isize and inode updates + * before we unlock the pages. Otherwise we + * could end up racing with unlink. + */ BTRFS_I(inode)->disk_i_size = inode->i_size; btrfs_update_inode(trans, root, inode); + return 0; fail: btrfs_free_path(path); @@ -415,7 +425,6 @@ again: start, end, total_compressed, pages); } - btrfs_end_transaction(trans, root); if (ret == 0) { /* * inline extent creation worked, we don't need @@ -429,9 +438,11 @@ again: EXTENT_CLEAR_DELALLOC | EXTENT_CLEAR_ACCOUNTING | EXTENT_SET_WRITEBACK | EXTENT_END_WRITEBACK); - ret = 0; + + btrfs_end_transaction(trans, root); goto free_pages_out; } + btrfs_end_transaction(trans, root); } if (will_compress) { @@ -542,7 +553,6 @@ static noinline int submit_compressed_extents(struct inode *inode, if (list_empty(&async_cow->extents)) return 0; - trans = btrfs_join_transaction(root, 1); while (!list_empty(&async_cow->extents)) { async_extent = list_entry(async_cow->extents.next, @@ -589,19 +599,15 @@ retry: lock_extent(io_tree, async_extent->start, async_extent->start + async_extent->ram_size - 1, GFP_NOFS); - /* - * here we're doing allocation and writeback of the - * compressed pages - */ - btrfs_drop_extent_cache(inode, async_extent->start, - async_extent->start + - async_extent->ram_size - 1, 0); + trans = btrfs_join_transaction(root, 1); ret = btrfs_reserve_extent(trans, root, async_extent->compressed_size, async_extent->compressed_size, 0, alloc_hint, (u64)-1, &ins, 1); + btrfs_end_transaction(trans, root); + if (ret) { int i; for (i = 0; i < async_extent->nr_pages; i++) { @@ -617,6 +623,14 @@ retry: goto retry; } + /* + * here we're doing allocation and writeback of the + * compressed pages + */ + btrfs_drop_extent_cache(inode, async_extent->start, + async_extent->start + + async_extent->ram_size - 1, 0); + em = alloc_extent_map(GFP_NOFS); em->start = async_extent->start; em->len = async_extent->ram_size; @@ -648,8 +662,6 @@ retry: BTRFS_ORDERED_COMPRESSED); BUG_ON(ret); - btrfs_end_transaction(trans, root); - /* * clear dirty, set writeback and unlock the pages. */ @@ -671,13 +683,11 @@ retry: async_extent->nr_pages); BUG_ON(ret); - trans = btrfs_join_transaction(root, 1); alloc_hint = ins.objectid + ins.offset; kfree(async_extent); cond_resched(); } - btrfs_end_transaction(trans, root); return 0; } @@ -741,6 +751,7 @@ static noinline int cow_file_range(struct inode *inode, EXTENT_CLEAR_DIRTY | EXTENT_SET_WRITEBACK | EXTENT_END_WRITEBACK); + *nr_written = *nr_written + (end - start + PAGE_CACHE_SIZE) / PAGE_CACHE_SIZE; *page_started = 1; @@ -1727,18 +1738,27 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) } } - trans = btrfs_join_transaction(root, 1); - if (!ordered_extent) ordered_extent = btrfs_lookup_ordered_extent(inode, start); BUG_ON(!ordered_extent); - if (test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags)) - goto nocow; + if (test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags)) { + BUG_ON(!list_empty(&ordered_extent->list)); + ret = btrfs_ordered_update_i_size(inode, 0, ordered_extent); + if (!ret) { + trans = btrfs_join_transaction(root, 1); + ret = btrfs_update_inode(trans, root, inode); + BUG_ON(ret); + btrfs_end_transaction(trans, root); + } + goto out; + } lock_extent(io_tree, ordered_extent->file_offset, ordered_extent->file_offset + ordered_extent->len - 1, GFP_NOFS); + trans = btrfs_join_transaction(root, 1); + if (test_bit(BTRFS_ORDERED_COMPRESSED, &ordered_extent->flags)) compressed = 1; if (test_bit(BTRFS_ORDERED_PREALLOC, &ordered_extent->flags)) { @@ -1765,22 +1785,20 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) unlock_extent(io_tree, ordered_extent->file_offset, ordered_extent->file_offset + ordered_extent->len - 1, GFP_NOFS); -nocow: add_pending_csums(trans, inode, ordered_extent->file_offset, &ordered_extent->list); - mutex_lock(&BTRFS_I(inode)->extent_mutex); - btrfs_ordered_update_i_size(inode, ordered_extent); - btrfs_update_inode(trans, root, inode); - btrfs_remove_ordered_extent(inode, ordered_extent); - mutex_unlock(&BTRFS_I(inode)->extent_mutex); - + /* this also removes the ordered extent from the tree */ + btrfs_ordered_update_i_size(inode, 0, ordered_extent); + ret = btrfs_update_inode(trans, root, inode); + BUG_ON(ret); + btrfs_end_transaction(trans, root); +out: /* once for us */ btrfs_put_ordered_extent(ordered_extent); /* once for the tree */ btrfs_put_ordered_extent(ordered_extent); - btrfs_end_transaction(trans, root); return 0; } @@ -3562,7 +3580,6 @@ static noinline void init_btrfs_i(struct inode *inode) INIT_LIST_HEAD(&BTRFS_I(inode)->ordered_operations); RB_CLEAR_NODE(&BTRFS_I(inode)->rb_node); btrfs_ordered_inode_tree_init(&BTRFS_I(inode)->ordered_tree); - mutex_init(&BTRFS_I(inode)->extent_mutex); mutex_init(&BTRFS_I(inode)->log_mutex); } diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c index 5799bc4..9b16073 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c @@ -291,16 +291,16 @@ int btrfs_put_ordered_extent(struct btrfs_ordered_extent *entry) /* * remove an ordered extent from the tree. No references are dropped - * but, anyone waiting on this extent is woken up. + * and you must wake_up entry->wait. You must hold the tree mutex + * while you call this function. */ -int btrfs_remove_ordered_extent(struct inode *inode, +static int __btrfs_remove_ordered_extent(struct inode *inode, struct btrfs_ordered_extent *entry) { struct btrfs_ordered_inode_tree *tree; struct rb_node *node; tree = &BTRFS_I(inode)->ordered_tree; - mutex_lock(&tree->mutex); node = &entry->rb_node; rb_erase(node, &tree->tree); tree->last = NULL; @@ -326,9 +326,26 @@ int btrfs_remove_ordered_extent(struct inode *inode, } spin_unlock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock); + return 0; +} + +/* + * remove an ordered extent from the tree. No references are dropped + * but any waiters are woken. + */ +int btrfs_remove_ordered_extent(struct inode *inode, + struct btrfs_ordered_extent *entry) +{ + struct btrfs_ordered_inode_tree *tree; + int ret; + + tree = &BTRFS_I(inode)->ordered_tree; + mutex_lock(&tree->mutex); + ret = __btrfs_remove_ordered_extent(inode, entry); mutex_unlock(&tree->mutex); wake_up(&entry->wait); - return 0; + + return ret; } /* @@ -589,7 +606,7 @@ out: * After an extent is done, call this to conditionally update the on disk * i_size. i_size is updated to cover any fully written part of the file. */ -int btrfs_ordered_update_i_size(struct inode *inode, +int btrfs_ordered_update_i_size(struct inode *inode, u64 offset, struct btrfs_ordered_extent *ordered) { struct btrfs_ordered_inode_tree *tree = &BTRFS_I(inode)->ordered_tree; @@ -597,18 +614,30 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 disk_i_size; u64 new_i_size; u64 i_size_test; + u64 i_size = i_size_read(inode); struct rb_node *node; + struct rb_node *prev = NULL; struct btrfs_ordered_extent *test; + int ret = 1; + + if (ordered) + offset = entry_end(ordered); mutex_lock(&tree->mutex); disk_i_size = BTRFS_I(inode)->disk_i_size; + /* truncate file */ + if (disk_i_size > i_size) { + BTRFS_I(inode)->disk_i_size = i_size; + ret = 0; + goto out; + } + /* * if the disk i_size is already at the inode->i_size, or * this ordered extent is inside the disk i_size, we're done */ - if (disk_i_size >= inode->i_size || - ordered->file_offset + ordered->len <= disk_i_size) { + if (disk_i_size == i_size || offset <= disk_i_size) { goto out; } @@ -616,8 +645,7 @@ int btrfs_ordered_update_i_size(struct inode *inode, * we can't update the disk_isize if there are delalloc bytes * between disk_i_size and this ordered extent */ - if (test_range_bit(io_tree, disk_i_size, - ordered->file_offset + ordered->len - 1, + if (test_range_bit(io_tree, disk_i_size, offset - 1, EXTENT_DELALLOC, 0, NULL)) { goto out; } @@ -626,20 +654,32 @@ int btrfs_ordered_update_i_size(struct inode *inode, * if we find an ordered extent then we can't update disk i_size * yet */ - node = &ordered->rb_node; - while (1) { - node = rb_prev(node); - if (!node) - break; + if (ordered) { + node = rb_prev(&ordered->rb_node); + } else { + prev = tree_search(tree, offset); + /* + * we insert file extents without involving ordered struct, + * so there should be no ordered struct cover this offset + */ + if (prev) { + test = rb_entry(prev, struct btrfs_ordered_extent, + rb_node); + BUG_ON(offset_in_entry(test, offset)); + } + node = prev; + } + while (node) { test = rb_entry(node, struct btrfs_ordered_extent, rb_node); if (test->file_offset + test->len <= disk_i_size) break; - if (test->file_offset >= inode->i_size) + if (test->file_offset >= i_size) break; if (test->file_offset >= disk_i_size) goto out; + node = rb_prev(node); } - new_i_size = min_t(u64, entry_end(ordered), i_size_read(inode)); + new_i_size = min_t(u64, offset, i_size); /* * at this point, we know we can safely update i_size to at least @@ -647,7 +687,14 @@ int btrfs_ordered_update_i_size(struct inode *inode, * walk forward and see if ios from higher up in the file have * finished. */ - node = rb_next(&ordered->rb_node); + if (ordered) { + node = rb_next(&ordered->rb_node); + } else { + if (prev) + node = rb_next(prev); + else + node = rb_first(&tree->tree); + } i_size_test = 0; if (node) { /* @@ -655,10 +702,10 @@ int btrfs_ordered_update_i_size(struct inode *inode, * between our ordered extent and the next one. */ test = rb_entry(node, struct btrfs_ordered_extent, rb_node); - if (test->file_offset > entry_end(ordered)) + if (test->file_offset > offset) i_size_test = test->file_offset; } else { - i_size_test = i_size_read(inode); + i_size_test = i_size; } /* @@ -667,15 +714,25 @@ int btrfs_ordered_update_i_size(struct inode *inode, * are no delalloc bytes in this area, it is safe to update * disk_i_size to the end of the region. */ - if (i_size_test > entry_end(ordered) && - !test_range_bit(io_tree, entry_end(ordered), i_size_test - 1, - EXTENT_DELALLOC, 0, NULL)) { - new_i_size = min_t(u64, i_size_test, i_size_read(inode)); + if (i_size_test > offset && + !test_range_bit(io_tree, offset, i_size_test - 1, + EXTENT_DELALLOC, 0, NULL)) { + new_i_size = min_t(u64, i_size_test, i_size); } BTRFS_I(inode)->disk_i_size = new_i_size; + ret = 0; out: + /* + * we need to remove the ordered extent with the tree lock held + * so that other people calling this function don't find our fully + * processed ordered entry and skip updating the i_size + */ + if (ordered) + __btrfs_remove_ordered_extent(inode, ordered); mutex_unlock(&tree->mutex); - return 0; + if (ordered) + wake_up(&ordered->wait); + return ret; } /* diff --git a/fs/btrfs/ordered-data.h b/fs/btrfs/ordered-data.h index f82e874..4fa2039 100644 --- a/fs/btrfs/ordered-data.h +++ b/fs/btrfs/ordered-data.h @@ -150,7 +150,7 @@ void btrfs_start_ordered_extent(struct inode *inode, int btrfs_wait_ordered_range(struct inode *inode, u64 start, u64 len); struct btrfs_ordered_extent * btrfs_lookup_first_ordered_extent(struct inode * inode, u64 file_offset); -int btrfs_ordered_update_i_size(struct inode *inode, +int btrfs_ordered_update_i_size(struct inode *inode, u64 offset, struct btrfs_ordered_extent *ordered); int btrfs_find_ordered_sum(struct inode *inode, u64 offset, u64 disk_bytenr, u32 *sum); int btrfs_wait_ordered_extents(struct btrfs_root *root, int nocow_only); -- cgit v0.10.2 From c71bf099abddf3e0fdc27f251ba76fca1461d49a Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Thu, 12 Nov 2009 09:34:40 +0000 Subject: Btrfs: Avoid orphan inodes cleanup while replaying log We do log replay in a single transaction, so it's not good to do unbound operations. This patch cleans up orphan inodes cleanup after replaying the log. It also avoids doing other unbound operations such as truncating a file during replaying log. These unbound operations are postponed to the orphan inode cleanup stage. Signed-off-by: Yan Zheng Signed-off-by: Chris Mason diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index ae5b0aa..fcfbefb 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -859,8 +859,9 @@ struct btrfs_fs_info { struct mutex ordered_operations_mutex; struct rw_semaphore extent_commit_sem; - struct rw_semaphore subvol_sem; + struct rw_semaphore cleanup_work_sem; + struct rw_semaphore subvol_sem; struct srcu_struct subvol_srcu; struct list_head trans_list; @@ -1034,12 +1035,12 @@ struct btrfs_root { int ref_cows; int track_dirty; int in_radix; + int clean_orphans; u64 defrag_trans_start; struct btrfs_key defrag_progress; struct btrfs_key defrag_max; int defrag_running; - int defrag_level; char *name; int in_sysfs; diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 101940f..c1e59e3 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -892,6 +892,8 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize, root->stripesize = stripesize; root->ref_cows = 0; root->track_dirty = 0; + root->in_radix = 0; + root->clean_orphans = 0; root->fs_info = fs_info; root->objectid = objectid; @@ -928,7 +930,6 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize, root->defrag_trans_start = fs_info->generation; init_completion(&root->kobj_unregister); root->defrag_running = 0; - root->defrag_level = 0; root->root_key.objectid = objectid; root->anon_super.s_root = NULL; root->anon_super.s_dev = 0; @@ -1210,8 +1211,10 @@ again: ret = radix_tree_insert(&fs_info->fs_roots_radix, (unsigned long)root->root_key.objectid, root); - if (ret == 0) + if (ret == 0) { root->in_radix = 1; + root->clean_orphans = 1; + } spin_unlock(&fs_info->fs_roots_radix_lock); radix_tree_preload_end(); if (ret) { @@ -1225,10 +1228,6 @@ again: ret = btrfs_find_dead_roots(fs_info->tree_root, root->root_key.objectid); WARN_ON(ret); - - if (!(fs_info->sb->s_flags & MS_RDONLY)) - btrfs_orphan_cleanup(root); - return root; fail: free_fs_root(root); @@ -1689,6 +1688,7 @@ struct btrfs_root *open_ctree(struct super_block *sb, mutex_init(&fs_info->cleaner_mutex); mutex_init(&fs_info->volume_mutex); init_rwsem(&fs_info->extent_commit_sem); + init_rwsem(&fs_info->cleanup_work_sem); init_rwsem(&fs_info->subvol_sem); btrfs_init_free_cluster(&fs_info->meta_alloc_cluster); @@ -2388,6 +2388,11 @@ int btrfs_commit_super(struct btrfs_root *root) mutex_lock(&root->fs_info->cleaner_mutex); btrfs_clean_old_snapshots(root); mutex_unlock(&root->fs_info->cleaner_mutex); + + /* wait until ongoing cleanup work done */ + down_write(&root->fs_info->cleanup_work_sem); + up_write(&root->fs_info->cleanup_work_sem); + trans = btrfs_start_transaction(root, 1); ret = btrfs_commit_transaction(trans, root); BUG_ON(ret); diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index fa57247..eb2db3b 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -2093,16 +2093,17 @@ void btrfs_orphan_cleanup(struct btrfs_root *root) struct inode *inode; int ret = 0, nr_unlink = 0, nr_truncate = 0; - path = btrfs_alloc_path(); - if (!path) + if (!xchg(&root->clean_orphans, 0)) return; + + path = btrfs_alloc_path(); + BUG_ON(!path); path->reada = -1; key.objectid = BTRFS_ORPHAN_OBJECTID; btrfs_set_key_type(&key, BTRFS_ORPHAN_ITEM_KEY); key.offset = (u64)-1; - while (1) { ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); if (ret < 0) { @@ -3298,6 +3299,11 @@ void btrfs_delete_inode(struct inode *inode) } btrfs_wait_ordered_range(inode, 0, (u64)-1); + if (root->fs_info->log_root_recovering) { + BUG_ON(!list_empty(&BTRFS_I(inode)->i_orphan)); + goto no_delete; + } + if (inode->i_nlink > 0) { BUG_ON(btrfs_root_refs(&root->root_item) != 0); goto no_delete; @@ -3705,6 +3711,13 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry) } srcu_read_unlock(&root->fs_info->subvol_srcu, index); + if (root != sub_root) { + down_read(&root->fs_info->cleanup_work_sem); + if (!(inode->i_sb->s_flags & MS_RDONLY)) + btrfs_orphan_cleanup(sub_root); + up_read(&root->fs_info->cleanup_work_sem); + } + return inode; } diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index cfcc93c..975fdd3 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c @@ -3755,6 +3755,7 @@ out: BTRFS_DATA_RELOC_TREE_OBJECTID); if (IS_ERR(fs_root)) err = PTR_ERR(fs_root); + btrfs_orphan_cleanup(fs_root); } return err; } diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 6bbaa10..4a9434b 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -930,6 +930,17 @@ out_nowrite: return 0; } +static int insert_orphan_item(struct btrfs_trans_handle *trans, + struct btrfs_root *root, u64 offset) +{ + int ret; + ret = btrfs_find_orphan_item(root, offset); + if (ret > 0) + ret = btrfs_insert_orphan_item(trans, root, offset); + return ret; +} + + /* * There are a few corners where the link count of the file can't * be properly maintained during replay. So, instead of adding @@ -997,9 +1008,13 @@ static noinline int fixup_inode_link_count(struct btrfs_trans_handle *trans, } BTRFS_I(inode)->index_cnt = (u64)-1; - if (inode->i_nlink == 0 && S_ISDIR(inode->i_mode)) { - ret = replay_dir_deletes(trans, root, NULL, path, - inode->i_ino, 1); + if (inode->i_nlink == 0) { + if (S_ISDIR(inode->i_mode)) { + ret = replay_dir_deletes(trans, root, NULL, path, + inode->i_ino, 1); + BUG_ON(ret); + } + ret = insert_orphan_item(trans, root, inode->i_ino); BUG_ON(ret); } btrfs_free_path(path); @@ -1587,7 +1602,6 @@ static int replay_one_buffer(struct btrfs_root *log, struct extent_buffer *eb, /* inode keys are done during the first stage */ if (key.type == BTRFS_INODE_ITEM_KEY && wc->stage == LOG_WALK_REPLAY_INODES) { - struct inode *inode; struct btrfs_inode_item *inode_item; u32 mode; @@ -1603,31 +1617,16 @@ static int replay_one_buffer(struct btrfs_root *log, struct extent_buffer *eb, eb, i, &key); BUG_ON(ret); - /* for regular files, truncate away - * extents past the new EOF + /* for regular files, make sure corresponding + * orhpan item exist. extents past the new EOF + * will be truncated later by orphan cleanup. */ if (S_ISREG(mode)) { - inode = read_one_inode(root, - key.objectid); - BUG_ON(!inode); - - ret = btrfs_truncate_inode_items(wc->trans, - root, inode, inode->i_size, - BTRFS_EXTENT_DATA_KEY); + ret = insert_orphan_item(wc->trans, root, + key.objectid); BUG_ON(ret); - - /* if the nlink count is zero here, the iput - * will free the inode. We bump it to make - * sure it doesn't get freed until the link - * count fixup is done - */ - if (inode->i_nlink == 0) { - btrfs_inc_nlink(inode); - btrfs_update_inode(wc->trans, - root, inode); - } - iput(inode); } + ret = link_to_fixup_dir(wc->trans, root, path, key.objectid); BUG_ON(ret); -- cgit v0.10.2 From 2e4bfab97055aa6acdd0637913bd705c2d6506d6 Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Thu, 12 Nov 2009 09:37:02 +0000 Subject: Btrfs: Avoid orphan inodes cleanup during committing transaction btrfs_lookup_dentry may trigger orphan cleanup, so it's not good to call it while committing a transaction. Signed-off-by: Yan Zheng Signed-off-by: Chris Mason diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index a1a8db8..3d6b338 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -237,7 +237,6 @@ static noinline int create_subvol(struct btrfs_root *root, u64 objectid; u64 new_dirid = BTRFS_FIRST_FREE_OBJECTID; u64 index = 0; - unsigned long nr = 1; /* * 1 - inode item @@ -342,24 +341,21 @@ static noinline int create_subvol(struct btrfs_root *root, d_instantiate(dentry, btrfs_lookup_dentry(dir, dentry)); fail: - nr = trans->blocks_used; err = btrfs_commit_transaction(trans, root); if (err && !ret) ret = err; btrfs_unreserve_metadata_space(root, 6); - btrfs_btree_balance_dirty(root, nr); return ret; } static int create_snapshot(struct btrfs_root *root, struct dentry *dentry, char *name, int namelen) { + struct inode *inode; struct btrfs_pending_snapshot *pending_snapshot; struct btrfs_trans_handle *trans; - int ret = 0; - int err; - unsigned long nr = 0; + int ret; if (!root->ref_cows) return -EINVAL; @@ -372,20 +368,20 @@ static int create_snapshot(struct btrfs_root *root, struct dentry *dentry, */ ret = btrfs_reserve_metadata_space(root, 6); if (ret) - goto fail_unlock; + goto fail; pending_snapshot = kzalloc(sizeof(*pending_snapshot), GFP_NOFS); if (!pending_snapshot) { ret = -ENOMEM; btrfs_unreserve_metadata_space(root, 6); - goto fail_unlock; + goto fail; } pending_snapshot->name = kmalloc(namelen + 1, GFP_NOFS); if (!pending_snapshot->name) { ret = -ENOMEM; kfree(pending_snapshot); btrfs_unreserve_metadata_space(root, 6); - goto fail_unlock; + goto fail; } memcpy(pending_snapshot->name, name, namelen); pending_snapshot->name[namelen] = '\0'; @@ -395,10 +391,19 @@ static int create_snapshot(struct btrfs_root *root, struct dentry *dentry, pending_snapshot->root = root; list_add(&pending_snapshot->list, &trans->transaction->pending_snapshots); - err = btrfs_commit_transaction(trans, root); + ret = btrfs_commit_transaction(trans, root); + BUG_ON(ret); + btrfs_unreserve_metadata_space(root, 6); -fail_unlock: - btrfs_btree_balance_dirty(root, nr); + inode = btrfs_lookup_dentry(dentry->d_parent->d_inode, dentry); + if (IS_ERR(inode)) { + ret = PTR_ERR(inode); + goto fail; + } + BUG_ON(!inode); + d_instantiate(dentry, inode); + ret = 0; +fail: return ret; } diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index b7b22c3..728e8fe 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c @@ -796,7 +796,6 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, memcpy(&pending->root_key, &key, sizeof(key)); fail: kfree(new_root_item); - btrfs_unreserve_metadata_space(root, 6); return ret; } @@ -808,7 +807,6 @@ static noinline int finish_pending_snapshot(struct btrfs_fs_info *fs_info, u64 index = 0; struct btrfs_trans_handle *trans; struct inode *parent_inode; - struct inode *inode; struct btrfs_root *parent_root; parent_inode = pending->dentry->d_parent->d_inode; @@ -840,8 +838,6 @@ static noinline int finish_pending_snapshot(struct btrfs_fs_info *fs_info, BUG_ON(ret); - inode = btrfs_lookup_dentry(parent_inode, pending->dentry); - d_instantiate(pending->dentry, inode); fail: btrfs_end_transaction(trans, fs_info->fs_root); return ret; -- cgit v0.10.2 From 5a303d5d4b8055d2e5a03e92d04745bfc5881a22 Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Thu, 12 Nov 2009 09:34:52 +0000 Subject: Btrfs: Make fallocate(2) more ENOSPC friendly fallocate(2) may allocate large number of file extents, so it's not good to do it in a single transaction. This patch make fallocate(2) start a new transaction for each file extents it allocates. Signed-off-by: Yan Zheng Signed-off-by: Chris Mason diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index eb2db3b..8d8baaa 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -5664,10 +5664,10 @@ out_fail: return err; } -static int prealloc_file_range(struct btrfs_trans_handle *trans, - struct inode *inode, u64 start, u64 end, +static int prealloc_file_range(struct inode *inode, u64 start, u64 end, u64 alloc_hint, int mode) { + struct btrfs_trans_handle *trans; struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_key ins; u64 alloc_size; @@ -5678,17 +5678,23 @@ static int prealloc_file_range(struct btrfs_trans_handle *trans, while (num_bytes > 0) { alloc_size = min(num_bytes, root->fs_info->max_extent); - ret = btrfs_reserve_metadata_space(root, 1); - if (ret) - goto out; - ret = btrfs_reserve_extent(trans, root, alloc_size, root->sectorsize, 0, alloc_hint, (u64)-1, &ins, 1); if (ret) { WARN_ON(1); - goto out; + break; + } + + ret = btrfs_reserve_metadata_space(root, 3); + if (ret) { + btrfs_free_reserved_extent(root, ins.objectid, + ins.offset); + break; } + + trans = btrfs_start_transaction(root, 1); + ret = insert_reserved_file_extent(trans, inode, cur_offset, ins.objectid, ins.offset, ins.offset, @@ -5697,22 +5703,25 @@ static int prealloc_file_range(struct btrfs_trans_handle *trans, BUG_ON(ret); btrfs_drop_extent_cache(inode, cur_offset, cur_offset + ins.offset -1, 0); + num_bytes -= ins.offset; cur_offset += ins.offset; alloc_hint = ins.objectid + ins.offset; - btrfs_unreserve_metadata_space(root, 1); - } -out: - if (cur_offset > start) { + inode->i_ctime = CURRENT_TIME; BTRFS_I(inode)->flags |= BTRFS_INODE_PREALLOC; if (!(mode & FALLOC_FL_KEEP_SIZE) && - cur_offset > i_size_read(inode)) - btrfs_i_size_write(inode, cur_offset); + cur_offset > inode->i_size) { + i_size_write(inode, cur_offset); + btrfs_ordered_update_i_size(inode, cur_offset, NULL); + } + ret = btrfs_update_inode(trans, root, inode); BUG_ON(ret); - } + btrfs_end_transaction(trans, root); + btrfs_unreserve_metadata_space(root, 3); + } return ret; } @@ -5727,8 +5736,6 @@ static long btrfs_fallocate(struct inode *inode, int mode, u64 locked_end; u64 mask = BTRFS_I(inode)->root->sectorsize - 1; struct extent_map *em; - struct btrfs_trans_handle *trans; - struct btrfs_root *root; int ret; alloc_start = offset & ~mask; @@ -5747,9 +5754,7 @@ static long btrfs_fallocate(struct inode *inode, int mode, goto out; } - root = BTRFS_I(inode)->root; - - ret = btrfs_check_data_free_space(root, inode, + ret = btrfs_check_data_free_space(BTRFS_I(inode)->root, inode, alloc_end - alloc_start); if (ret) goto out; @@ -5758,12 +5763,6 @@ static long btrfs_fallocate(struct inode *inode, int mode, while (1) { struct btrfs_ordered_extent *ordered; - trans = btrfs_start_transaction(BTRFS_I(inode)->root, 1); - if (!trans) { - ret = -EIO; - goto out_free; - } - /* the extent lock is ordered inside the running * transaction */ @@ -5777,8 +5776,6 @@ static long btrfs_fallocate(struct inode *inode, int mode, btrfs_put_ordered_extent(ordered); unlock_extent(&BTRFS_I(inode)->io_tree, alloc_start, locked_end, GFP_NOFS); - btrfs_end_transaction(trans, BTRFS_I(inode)->root); - /* * we can't wait on the range with the transaction * running or with the extent lock held @@ -5799,9 +5796,12 @@ static long btrfs_fallocate(struct inode *inode, int mode, BUG_ON(IS_ERR(em) || !em); last_byte = min(extent_map_end(em), alloc_end); last_byte = (last_byte + mask) & ~mask; - if (em->block_start == EXTENT_MAP_HOLE) { - ret = prealloc_file_range(trans, inode, cur_offset, - last_byte, alloc_hint, mode); + if (em->block_start == EXTENT_MAP_HOLE || + (cur_offset >= inode->i_size && + !test_bit(EXTENT_FLAG_PREALLOC, &em->flags))) { + ret = prealloc_file_range(inode, + cur_offset, last_byte, + alloc_hint, mode); if (ret < 0) { free_extent_map(em); break; @@ -5820,9 +5820,8 @@ static long btrfs_fallocate(struct inode *inode, int mode, unlock_extent(&BTRFS_I(inode)->io_tree, alloc_start, locked_end, GFP_NOFS); - btrfs_end_transaction(trans, BTRFS_I(inode)->root); -out_free: - btrfs_free_reserved_data_space(root, inode, alloc_end - alloc_start); + btrfs_free_reserved_data_space(BTRFS_I(inode)->root, inode, + alloc_end - alloc_start); out: mutex_unlock(&inode->i_mutex); return ret; -- cgit v0.10.2 From 8082510e7124cc50d728f1b875639cb4e22312cc Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Thu, 12 Nov 2009 09:35:36 +0000 Subject: Btrfs: Make truncate(2) more ENOSPC friendly truncating and deleting regular files are unbound operations, so it's not good to do them in a single transaction. This patch makes btrfs_truncate and btrfs_delete_inode start a new transaction after all items in a tree leaf are deleted. Signed-off-by: Yan Zheng Signed-off-by: Chris Mason diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 8d8baaa..dcec42e 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -2848,37 +2848,40 @@ out: * min_type is the minimum key type to truncate down to. If set to 0, this * will kill all the items on this inode, including the INODE_ITEM_KEY. */ -noinline int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - struct inode *inode, - u64 new_size, u32 min_type) +int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct inode *inode, + u64 new_size, u32 min_type) { - int ret; struct btrfs_path *path; - struct btrfs_key key; - struct btrfs_key found_key; - u32 found_type = (u8)-1; struct extent_buffer *leaf; struct btrfs_file_extent_item *fi; + struct btrfs_key key; + struct btrfs_key found_key; u64 extent_start = 0; u64 extent_num_bytes = 0; u64 extent_offset = 0; u64 item_end = 0; + u64 mask = root->sectorsize - 1; + u32 found_type = (u8)-1; int found_extent; int del_item; int pending_del_nr = 0; int pending_del_slot = 0; int extent_type = -1; int encoding; - u64 mask = root->sectorsize - 1; + int ret; + int err = 0; + + BUG_ON(new_size > 0 && min_type != BTRFS_EXTENT_DATA_KEY); if (root->ref_cows) btrfs_drop_extent_cache(inode, new_size & (~mask), (u64)-1, 0); + path = btrfs_alloc_path(); BUG_ON(!path); path->reada = -1; - /* FIXME, add redo link to tree so we don't leak on crash */ key.objectid = inode->i_ino; key.offset = (u64)-1; key.type = (u8)-1; @@ -2886,17 +2889,17 @@ noinline int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, search_again: path->leave_spinning = 1; ret = btrfs_search_slot(trans, root, &key, path, -1, 1); - if (ret < 0) - goto error; + if (ret < 0) { + err = ret; + goto out; + } if (ret > 0) { /* there are no items in the tree for us to truncate, we're * done */ - if (path->slots[0] == 0) { - ret = 0; - goto error; - } + if (path->slots[0] == 0) + goto out; path->slots[0]--; } @@ -2931,28 +2934,17 @@ search_again: } item_end--; } - if (item_end < new_size) { - if (found_type == BTRFS_DIR_ITEM_KEY) - found_type = BTRFS_INODE_ITEM_KEY; - else if (found_type == BTRFS_EXTENT_ITEM_KEY) - found_type = BTRFS_EXTENT_DATA_KEY; - else if (found_type == BTRFS_EXTENT_DATA_KEY) - found_type = BTRFS_XATTR_ITEM_KEY; - else if (found_type == BTRFS_XATTR_ITEM_KEY) - found_type = BTRFS_INODE_REF_KEY; - else if (found_type) - found_type--; - else + if (found_type > min_type) { + del_item = 1; + } else { + if (item_end < new_size) break; - btrfs_set_key_type(&key, found_type); - goto next; + if (found_key.offset >= new_size) + del_item = 1; + else + del_item = 0; } - if (found_key.offset >= new_size) - del_item = 1; - else - del_item = 0; found_extent = 0; - /* FIXME, shrink the extent if the ref count is only 1 */ if (found_type != BTRFS_EXTENT_DATA_KEY) goto delete; @@ -3039,42 +3031,36 @@ delete: inode->i_ino, extent_offset); BUG_ON(ret); } -next: - if (path->slots[0] == 0) { - if (pending_del_nr) - goto del_pending; - btrfs_release_path(root, path); - if (found_type == BTRFS_INODE_ITEM_KEY) - break; - goto search_again; - } - path->slots[0]--; - if (pending_del_nr && - path->slots[0] + 1 != pending_del_slot) { - struct btrfs_key debug; -del_pending: - btrfs_item_key_to_cpu(path->nodes[0], &debug, - pending_del_slot); - ret = btrfs_del_items(trans, root, path, - pending_del_slot, - pending_del_nr); - BUG_ON(ret); - pending_del_nr = 0; + if (found_type == BTRFS_INODE_ITEM_KEY) + break; + + if (path->slots[0] == 0 || + path->slots[0] != pending_del_slot) { + if (root->ref_cows) { + err = -EAGAIN; + goto out; + } + if (pending_del_nr) { + ret = btrfs_del_items(trans, root, path, + pending_del_slot, + pending_del_nr); + BUG_ON(ret); + pending_del_nr = 0; + } btrfs_release_path(root, path); - if (found_type == BTRFS_INODE_ITEM_KEY) - break; goto search_again; + } else { + path->slots[0]--; } } - ret = 0; -error: +out: if (pending_del_nr) { ret = btrfs_del_items(trans, root, path, pending_del_slot, pending_del_nr); } btrfs_free_path(path); - return ret; + return err; } /* @@ -3194,10 +3180,6 @@ int btrfs_cont_expand(struct inode *inode, loff_t size) if (size <= hole_start) return 0; - err = btrfs_truncate_page(inode->i_mapping, inode->i_size); - if (err) - return err; - while (1) { struct btrfs_ordered_extent *ordered; btrfs_wait_ordered_range(inode, hole_start, @@ -3210,9 +3192,6 @@ int btrfs_cont_expand(struct inode *inode, loff_t size) btrfs_put_ordered_extent(ordered); } - trans = btrfs_start_transaction(root, 1); - btrfs_set_trans_block_group(trans, inode); - cur_offset = hole_start; while (1) { em = btrfs_get_extent(inode, NULL, 0, cur_offset, @@ -3220,38 +3199,120 @@ int btrfs_cont_expand(struct inode *inode, loff_t size) BUG_ON(IS_ERR(em) || !em); last_byte = min(extent_map_end(em), block_end); last_byte = (last_byte + mask) & ~mask; - if (test_bit(EXTENT_FLAG_VACANCY, &em->flags)) { + if (!test_bit(EXTENT_FLAG_PREALLOC, &em->flags)) { u64 hint_byte = 0; hole_size = last_byte - cur_offset; - err = btrfs_drop_extents(trans, inode, cur_offset, - cur_offset + hole_size, - &hint_byte, 1); - if (err) - break; - err = btrfs_reserve_metadata_space(root, 1); + err = btrfs_reserve_metadata_space(root, 2); if (err) break; + trans = btrfs_start_transaction(root, 1); + btrfs_set_trans_block_group(trans, inode); + + err = btrfs_drop_extents(trans, inode, cur_offset, + cur_offset + hole_size, + &hint_byte, 1); + BUG_ON(err); + err = btrfs_insert_file_extent(trans, root, inode->i_ino, cur_offset, 0, 0, hole_size, 0, hole_size, 0, 0, 0); + BUG_ON(err); + btrfs_drop_extent_cache(inode, hole_start, last_byte - 1, 0); - btrfs_unreserve_metadata_space(root, 1); + + btrfs_end_transaction(trans, root); + btrfs_unreserve_metadata_space(root, 2); } free_extent_map(em); cur_offset = last_byte; - if (err || cur_offset >= block_end) + if (cur_offset >= block_end) break; } - btrfs_end_transaction(trans, root); unlock_extent(io_tree, hole_start, block_end - 1, GFP_NOFS); return err; } +static int btrfs_setattr_size(struct inode *inode, struct iattr *attr) +{ + struct btrfs_root *root = BTRFS_I(inode)->root; + struct btrfs_trans_handle *trans; + unsigned long nr; + int ret; + + if (attr->ia_size == inode->i_size) + return 0; + + if (attr->ia_size > inode->i_size) { + unsigned long limit; + limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; + if (attr->ia_size > inode->i_sb->s_maxbytes) + return -EFBIG; + if (limit != RLIM_INFINITY && attr->ia_size > limit) { + send_sig(SIGXFSZ, current, 0); + return -EFBIG; + } + } + + ret = btrfs_reserve_metadata_space(root, 1); + if (ret) + return ret; + + trans = btrfs_start_transaction(root, 1); + btrfs_set_trans_block_group(trans, inode); + + ret = btrfs_orphan_add(trans, inode); + BUG_ON(ret); + + nr = trans->blocks_used; + btrfs_end_transaction(trans, root); + btrfs_unreserve_metadata_space(root, 1); + btrfs_btree_balance_dirty(root, nr); + + if (attr->ia_size > inode->i_size) { + ret = btrfs_cont_expand(inode, attr->ia_size); + if (ret) { + btrfs_truncate(inode); + return ret; + } + + i_size_write(inode, attr->ia_size); + btrfs_ordered_update_i_size(inode, inode->i_size, NULL); + + trans = btrfs_start_transaction(root, 1); + btrfs_set_trans_block_group(trans, inode); + + ret = btrfs_update_inode(trans, root, inode); + BUG_ON(ret); + if (inode->i_nlink > 0) { + ret = btrfs_orphan_del(trans, inode); + BUG_ON(ret); + } + nr = trans->blocks_used; + btrfs_end_transaction(trans, root); + btrfs_btree_balance_dirty(root, nr); + return 0; + } + + /* + * We're truncating a file that used to have good data down to + * zero. Make sure it gets into the ordered flush list so that + * any new writes get down to disk quickly. + */ + if (attr->ia_size == 0) + BTRFS_I(inode)->ordered_data_close = 1; + + /* we don't support swapfiles, so vmtruncate shouldn't fail */ + ret = vmtruncate(inode, attr->ia_size); + BUG_ON(ret); + + return 0; +} + static int btrfs_setattr(struct dentry *dentry, struct iattr *attr) { struct inode *inode = dentry->d_inode; @@ -3262,23 +3323,14 @@ static int btrfs_setattr(struct dentry *dentry, struct iattr *attr) return err; if (S_ISREG(inode->i_mode) && (attr->ia_valid & ATTR_SIZE)) { - if (attr->ia_size > inode->i_size) { - err = btrfs_cont_expand(inode, attr->ia_size); - if (err) - return err; - } else if (inode->i_size > 0 && - attr->ia_size == 0) { - - /* we're truncating a file that used to have good - * data down to zero. Make sure it gets into - * the ordered flush list so that any new writes - * get down to disk quickly. - */ - BTRFS_I(inode)->ordered_data_close = 1; - } + err = btrfs_setattr_size(inode, attr); + if (err) + return err; } + attr->ia_valid &= ~ATTR_SIZE; - err = inode_setattr(inode, attr); + if (attr->ia_valid) + err = inode_setattr(inode, attr); if (!err && ((attr->ia_valid & ATTR_MODE))) err = btrfs_acl_chmod(inode); @@ -3310,30 +3362,32 @@ void btrfs_delete_inode(struct inode *inode) } btrfs_i_size_write(inode, 0); - trans = btrfs_join_transaction(root, 1); - btrfs_set_trans_block_group(trans, inode); - ret = btrfs_truncate_inode_items(trans, root, inode, inode->i_size, 0); - if (ret) { - btrfs_orphan_del(NULL, inode); - goto no_delete_lock; - } + while (1) { + trans = btrfs_start_transaction(root, 1); + btrfs_set_trans_block_group(trans, inode); + ret = btrfs_truncate_inode_items(trans, root, inode, 0, 0); - btrfs_orphan_del(trans, inode); + if (ret != -EAGAIN) + break; - nr = trans->blocks_used; - clear_inode(inode); + nr = trans->blocks_used; + btrfs_end_transaction(trans, root); + trans = NULL; + btrfs_btree_balance_dirty(root, nr); + } - btrfs_end_transaction(trans, root); - btrfs_btree_balance_dirty(root, nr); - return; + if (ret == 0) { + ret = btrfs_orphan_del(trans, inode); + BUG_ON(ret); + } -no_delete_lock: nr = trans->blocks_used; btrfs_end_transaction(trans, root); btrfs_btree_balance_dirty(root, nr); no_delete: clear_inode(inode); + return; } /* @@ -5097,17 +5151,20 @@ static void btrfs_truncate(struct inode *inode) unsigned long nr; u64 mask = root->sectorsize - 1; - if (!S_ISREG(inode->i_mode)) - return; - if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) + if (!S_ISREG(inode->i_mode)) { + WARN_ON(1); return; + } ret = btrfs_truncate_page(inode->i_mapping, inode->i_size); if (ret) return; + btrfs_wait_ordered_range(inode, inode->i_size & (~mask), (u64)-1); + btrfs_ordered_update_i_size(inode, inode->i_size, NULL); trans = btrfs_start_transaction(root, 1); + btrfs_set_trans_block_group(trans, inode); /* * setattr is responsible for setting the ordered_data_close flag, @@ -5129,21 +5186,32 @@ static void btrfs_truncate(struct inode *inode) if (inode->i_size == 0 && BTRFS_I(inode)->ordered_data_close) btrfs_add_ordered_operation(trans, root, inode); - btrfs_set_trans_block_group(trans, inode); - btrfs_i_size_write(inode, inode->i_size); + while (1) { + ret = btrfs_truncate_inode_items(trans, root, inode, + inode->i_size, + BTRFS_EXTENT_DATA_KEY); + if (ret != -EAGAIN) + break; - ret = btrfs_orphan_add(trans, inode); - if (ret) - goto out; - /* FIXME, add redo link to tree so we don't leak on crash */ - ret = btrfs_truncate_inode_items(trans, root, inode, inode->i_size, - BTRFS_EXTENT_DATA_KEY); - btrfs_update_inode(trans, root, inode); + ret = btrfs_update_inode(trans, root, inode); + BUG_ON(ret); + + nr = trans->blocks_used; + btrfs_end_transaction(trans, root); + btrfs_btree_balance_dirty(root, nr); + + trans = btrfs_start_transaction(root, 1); + btrfs_set_trans_block_group(trans, inode); + } - ret = btrfs_orphan_del(trans, inode); + if (ret == 0 && inode->i_nlink > 0) { + ret = btrfs_orphan_del(trans, inode); + BUG_ON(ret); + } + + ret = btrfs_update_inode(trans, root, inode); BUG_ON(ret); -out: nr = trans->blocks_used; ret = btrfs_end_transaction_throttle(trans, root); BUG_ON(ret); @@ -5240,9 +5308,9 @@ void btrfs_destroy_inode(struct inode *inode) spin_lock(&root->list_lock); if (!list_empty(&BTRFS_I(inode)->i_orphan)) { - printk(KERN_ERR "BTRFS: inode %lu: inode still on the orphan" - " list\n", inode->i_ino); - dump_stack(); + printk(KERN_INFO "BTRFS: inode %lu still on the orphan list\n", + inode->i_ino); + list_del_init(&BTRFS_I(inode)->i_orphan); } spin_unlock(&root->list_lock); diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index 975fdd3..f2aa53d 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c @@ -1561,6 +1561,20 @@ static int invalidate_extent_cache(struct btrfs_root *root, return 0; } +static void put_inodes(struct list_head *list) +{ + struct inodevec *ivec; + while (!list_empty(list)) { + ivec = list_entry(list->next, struct inodevec, list); + list_del(&ivec->list); + while (ivec->nr > 0) { + ivec->nr--; + iput(ivec->inode[ivec->nr]); + } + kfree(ivec); + } +} + static int find_next_key(struct btrfs_path *path, int level, struct btrfs_key *key) @@ -1723,6 +1737,11 @@ static noinline_for_stack int merge_reloc_root(struct reloc_control *rc, btrfs_btree_balance_dirty(root, nr); + /* + * put inodes outside transaction, otherwise we may deadlock. + */ + put_inodes(&inode_list); + if (replaced && rc->stage == UPDATE_DATA_PTRS) invalidate_extent_cache(root, &key, &next_key); } @@ -1752,19 +1771,7 @@ out: btrfs_btree_balance_dirty(root, nr); - /* - * put inodes while we aren't holding the tree locks - */ - while (!list_empty(&inode_list)) { - struct inodevec *ivec; - ivec = list_entry(inode_list.next, struct inodevec, list); - list_del(&ivec->list); - while (ivec->nr > 0) { - ivec->nr--; - iput(ivec->inode[ivec->nr]); - } - kfree(ivec); - } + put_inodes(&inode_list); if (replaced && rc->stage == UPDATE_DATA_PTRS) invalidate_extent_cache(root, &key, &next_key); -- cgit v0.10.2 From f34f57a3ab4e73304d78c125682f1a53cd3975f2 Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Thu, 12 Nov 2009 09:35:27 +0000 Subject: Btrfs: Pass transaction handle to security and ACL initialization functions Pass transaction handle down to security and ACL initialization functions, so we can avoid starting nested transactions Signed-off-by: Yan Zheng Signed-off-by: Chris Mason diff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c index 3616042..1898f85 100644 --- a/fs/btrfs/acl.c +++ b/fs/btrfs/acl.c @@ -94,7 +94,8 @@ static int btrfs_xattr_get_acl(struct inode *inode, int type, /* * Needs to be called with fs_mutex held */ -static int btrfs_set_acl(struct inode *inode, struct posix_acl *acl, int type) +static int btrfs_set_acl(struct btrfs_trans_handle *trans, + struct inode *inode, struct posix_acl *acl, int type) { int ret, size = 0; const char *name; @@ -140,8 +141,7 @@ static int btrfs_set_acl(struct inode *inode, struct posix_acl *acl, int type) goto out; } - ret = __btrfs_setxattr(inode, name, value, size, 0); - + ret = __btrfs_setxattr(trans, inode, name, value, size, 0); out: kfree(value); @@ -154,7 +154,7 @@ out: static int btrfs_xattr_set_acl(struct inode *inode, int type, const void *value, size_t size) { - int ret = 0; + int ret; struct posix_acl *acl = NULL; if (value) { @@ -167,7 +167,7 @@ static int btrfs_xattr_set_acl(struct inode *inode, int type, } } - ret = btrfs_set_acl(inode, acl, type); + ret = btrfs_set_acl(NULL, inode, acl, type); posix_acl_release(acl); @@ -221,7 +221,8 @@ int btrfs_check_acl(struct inode *inode, int mask) * stuff has been fixed to work with that. If the locking stuff changes, we * need to re-evaluate the acl locking stuff. */ -int btrfs_init_acl(struct inode *inode, struct inode *dir) +int btrfs_init_acl(struct btrfs_trans_handle *trans, + struct inode *inode, struct inode *dir) { struct posix_acl *acl = NULL; int ret = 0; @@ -246,7 +247,8 @@ int btrfs_init_acl(struct inode *inode, struct inode *dir) mode_t mode; if (S_ISDIR(inode->i_mode)) { - ret = btrfs_set_acl(inode, acl, ACL_TYPE_DEFAULT); + ret = btrfs_set_acl(trans, inode, acl, + ACL_TYPE_DEFAULT); if (ret) goto failed; } @@ -261,7 +263,7 @@ int btrfs_init_acl(struct inode *inode, struct inode *dir) inode->i_mode = mode; if (ret > 0) { /* we need an acl */ - ret = btrfs_set_acl(inode, clone, + ret = btrfs_set_acl(trans, inode, clone, ACL_TYPE_ACCESS); } } @@ -294,7 +296,7 @@ int btrfs_acl_chmod(struct inode *inode) ret = posix_acl_chmod_masq(clone, inode->i_mode); if (!ret) - ret = btrfs_set_acl(inode, clone, ACL_TYPE_ACCESS); + ret = btrfs_set_acl(NULL, inode, clone, ACL_TYPE_ACCESS); posix_acl_release(clone); @@ -320,7 +322,8 @@ int btrfs_acl_chmod(struct inode *inode) return 0; } -int btrfs_init_acl(struct inode *inode, struct inode *dir) +int btrfs_init_acl(struct btrfs_trans_handle *trans, + struct inode *inode, struct inode *dir) { return 0; } diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index fcfbefb..a7cac21 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -310,6 +310,9 @@ struct btrfs_header { #define BTRFS_MAX_INLINE_DATA_SIZE(r) (BTRFS_LEAF_DATA_SIZE(r) - \ sizeof(struct btrfs_item) - \ sizeof(struct btrfs_file_extent_item)) +#define BTRFS_MAX_XATTR_SIZE(r) (BTRFS_LEAF_DATA_SIZE(r) - \ + sizeof(struct btrfs_item) -\ + sizeof(struct btrfs_dir_item)) /* @@ -2201,9 +2204,10 @@ int btrfs_delete_one_dir_name(struct btrfs_trans_handle *trans, struct btrfs_path *path, struct btrfs_dir_item *di); int btrfs_insert_xattr_item(struct btrfs_trans_handle *trans, - struct btrfs_root *root, const char *name, - u16 name_len, const void *data, u16 data_len, - u64 dir); + struct btrfs_root *root, + struct btrfs_path *path, u64 objectid, + const char *name, u16 name_len, + const void *data, u16 data_len); struct btrfs_dir_item *btrfs_lookup_xattr(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_path *path, u64 dir, @@ -2382,7 +2386,8 @@ int btrfs_check_acl(struct inode *inode, int mask); #else #define btrfs_check_acl NULL #endif -int btrfs_init_acl(struct inode *inode, struct inode *dir); +int btrfs_init_acl(struct btrfs_trans_handle *trans, + struct inode *inode, struct inode *dir); int btrfs_acl_chmod(struct inode *inode); /* relocation.c */ diff --git a/fs/btrfs/dir-item.c b/fs/btrfs/dir-item.c index f3a6075..e9103b3 100644 --- a/fs/btrfs/dir-item.c +++ b/fs/btrfs/dir-item.c @@ -68,12 +68,12 @@ static struct btrfs_dir_item *insert_with_overflow(struct btrfs_trans_handle * into the tree */ int btrfs_insert_xattr_item(struct btrfs_trans_handle *trans, - struct btrfs_root *root, const char *name, - u16 name_len, const void *data, u16 data_len, - u64 dir) + struct btrfs_root *root, + struct btrfs_path *path, u64 objectid, + const char *name, u16 name_len, + const void *data, u16 data_len) { int ret = 0; - struct btrfs_path *path; struct btrfs_dir_item *dir_item; unsigned long name_ptr, data_ptr; struct btrfs_key key, location; @@ -81,15 +81,11 @@ int btrfs_insert_xattr_item(struct btrfs_trans_handle *trans, struct extent_buffer *leaf; u32 data_size; - key.objectid = dir; + BUG_ON(name_len + data_len > BTRFS_MAX_XATTR_SIZE(root)); + + key.objectid = objectid; btrfs_set_key_type(&key, BTRFS_XATTR_ITEM_KEY); key.offset = btrfs_name_hash(name, name_len); - path = btrfs_alloc_path(); - if (!path) - return -ENOMEM; - if (name_len + data_len + sizeof(struct btrfs_dir_item) > - BTRFS_LEAF_DATA_SIZE(root) - sizeof(struct btrfs_item)) - return -ENOSPC; data_size = sizeof(*dir_item) + name_len + data_len; dir_item = insert_with_overflow(trans, root, path, &key, data_size, @@ -117,7 +113,6 @@ int btrfs_insert_xattr_item(struct btrfs_trans_handle *trans, write_extent_buffer(leaf, data, data_ptr, data_len); btrfs_mark_buffer_dirty(path->nodes[0]); - btrfs_free_path(path); return ret; } diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index dcec42e..82740a3 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -88,13 +88,14 @@ static noinline int cow_file_range(struct inode *inode, u64 start, u64 end, int *page_started, unsigned long *nr_written, int unlock); -static int btrfs_init_inode_security(struct inode *inode, struct inode *dir) +static int btrfs_init_inode_security(struct btrfs_trans_handle *trans, + struct inode *inode, struct inode *dir) { int err; - err = btrfs_init_acl(inode, dir); + err = btrfs_init_acl(trans, inode, dir); if (!err) - err = btrfs_xattr_security_init(inode, dir); + err = btrfs_xattr_security_init(trans, inode, dir); return err; } @@ -4296,7 +4297,7 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry, if (IS_ERR(inode)) goto out_unlock; - err = btrfs_init_inode_security(inode, dir); + err = btrfs_init_inode_security(trans, inode, dir); if (err) { drop_inode = 1; goto out_unlock; @@ -4367,7 +4368,7 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry, if (IS_ERR(inode)) goto out_unlock; - err = btrfs_init_inode_security(inode, dir); + err = btrfs_init_inode_security(trans, inode, dir); if (err) { drop_inode = 1; goto out_unlock; @@ -4500,7 +4501,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) drop_on_err = 1; - err = btrfs_init_inode_security(inode, dir); + err = btrfs_init_inode_security(trans, inode, dir); if (err) goto out_fail; @@ -5660,7 +5661,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry, if (IS_ERR(inode)) goto out_unlock; - err = btrfs_init_inode_security(inode, dir); + err = btrfs_init_inode_security(trans, inode, dir); if (err) { drop_inode = 1; goto out_unlock; diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c index b6dd596..193b58f 100644 --- a/fs/btrfs/xattr.c +++ b/fs/btrfs/xattr.c @@ -85,22 +85,23 @@ out: return ret; } -int __btrfs_setxattr(struct inode *inode, const char *name, - const void *value, size_t size, int flags) +static int do_setxattr(struct btrfs_trans_handle *trans, + struct inode *inode, const char *name, + const void *value, size_t size, int flags) { struct btrfs_dir_item *di; struct btrfs_root *root = BTRFS_I(inode)->root; - struct btrfs_trans_handle *trans; struct btrfs_path *path; - int ret = 0, mod = 0; + size_t name_len = strlen(name); + int ret = 0; + + if (name_len + size > BTRFS_MAX_XATTR_SIZE(root)) + return -ENOSPC; path = btrfs_alloc_path(); if (!path) return -ENOMEM; - trans = btrfs_join_transaction(root, 1); - btrfs_set_trans_block_group(trans, inode); - /* first lets see if we already have this xattr */ di = btrfs_lookup_xattr(trans, root, path, inode->i_ino, name, strlen(name), -1); @@ -118,15 +119,12 @@ int __btrfs_setxattr(struct inode *inode, const char *name, } ret = btrfs_delete_one_dir_name(trans, root, path, di); - if (ret) - goto out; + BUG_ON(ret); btrfs_release_path(root, path); /* if we don't have a value then we are removing the xattr */ - if (!value) { - mod = 1; + if (!value) goto out; - } } else { btrfs_release_path(root, path); @@ -138,20 +136,45 @@ int __btrfs_setxattr(struct inode *inode, const char *name, } /* ok we have to create a completely new xattr */ - ret = btrfs_insert_xattr_item(trans, root, name, strlen(name), - value, size, inode->i_ino); + ret = btrfs_insert_xattr_item(trans, root, path, inode->i_ino, + name, name_len, value, size); + BUG_ON(ret); +out: + btrfs_free_path(path); + return ret; +} + +int __btrfs_setxattr(struct btrfs_trans_handle *trans, + struct inode *inode, const char *name, + const void *value, size_t size, int flags) +{ + struct btrfs_root *root = BTRFS_I(inode)->root; + int ret; + + if (trans) + return do_setxattr(trans, inode, name, value, size, flags); + + ret = btrfs_reserve_metadata_space(root, 2); if (ret) - goto out; - mod = 1; + return ret; -out: - if (mod) { - inode->i_ctime = CURRENT_TIME; - ret = btrfs_update_inode(trans, root, inode); + trans = btrfs_start_transaction(root, 1); + if (!trans) { + ret = -ENOMEM; + goto out; } + btrfs_set_trans_block_group(trans, inode); - btrfs_end_transaction(trans, root); - btrfs_free_path(path); + ret = do_setxattr(trans, inode, name, value, size, flags); + if (ret) + goto out; + + inode->i_ctime = CURRENT_TIME; + ret = btrfs_update_inode(trans, root, inode); + BUG_ON(ret); +out: + btrfs_end_transaction_throttle(trans, root); + btrfs_unreserve_metadata_space(root, 2); return ret; } @@ -314,7 +337,9 @@ int btrfs_setxattr(struct dentry *dentry, const char *name, const void *value, if (size == 0) value = ""; /* empty EA, do not remove */ - return __btrfs_setxattr(dentry->d_inode, name, value, size, flags); + + return __btrfs_setxattr(NULL, dentry->d_inode, name, value, size, + flags); } int btrfs_removexattr(struct dentry *dentry, const char *name) @@ -329,10 +354,13 @@ int btrfs_removexattr(struct dentry *dentry, const char *name) if (!btrfs_is_valid_xattr(name)) return -EOPNOTSUPP; - return __btrfs_setxattr(dentry->d_inode, name, NULL, 0, XATTR_REPLACE); + + return __btrfs_setxattr(NULL, dentry->d_inode, name, NULL, 0, + XATTR_REPLACE); } -int btrfs_xattr_security_init(struct inode *inode, struct inode *dir) +int btrfs_xattr_security_init(struct btrfs_trans_handle *trans, + struct inode *inode, struct inode *dir) { int err; size_t len; @@ -354,7 +382,7 @@ int btrfs_xattr_security_init(struct inode *inode, struct inode *dir) } else { strcpy(name, XATTR_SECURITY_PREFIX); strcpy(name + XATTR_SECURITY_PREFIX_LEN, suffix); - err = __btrfs_setxattr(inode, name, value, len, 0); + err = __btrfs_setxattr(trans, inode, name, value, len, 0); kfree(name); } diff --git a/fs/btrfs/xattr.h b/fs/btrfs/xattr.h index c71e9c3..721efa0 100644 --- a/fs/btrfs/xattr.h +++ b/fs/btrfs/xattr.h @@ -27,15 +27,16 @@ extern struct xattr_handler *btrfs_xattr_handlers[]; extern ssize_t __btrfs_getxattr(struct inode *inode, const char *name, void *buffer, size_t size); -extern int __btrfs_setxattr(struct inode *inode, const char *name, - const void *value, size_t size, int flags); - +extern int __btrfs_setxattr(struct btrfs_trans_handle *trans, + struct inode *inode, const char *name, + const void *value, size_t size, int flags); extern ssize_t btrfs_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t size); extern int btrfs_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags); extern int btrfs_removexattr(struct dentry *dentry, const char *name); -extern int btrfs_xattr_security_init(struct inode *inode, struct inode *dir); +extern int btrfs_xattr_security_init(struct btrfs_trans_handle *trans, + struct inode *inode, struct inode *dir); #endif /* __XATTR__ */ -- cgit v0.10.2 From 24bbcf0442ee04660a5a030efdbb6d03f1c275cb Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Thu, 12 Nov 2009 09:36:34 +0000 Subject: Btrfs: Add delayed iput iput() can trigger new transactions if we are dropping the final reference, so calling it in btrfs_commit_transaction may end up deadlock. This patch adds delayed iput to avoid the issue. Signed-off-by: Yan Zheng Signed-off-by: Chris Mason diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index a7cac21..1983c88 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -872,6 +872,9 @@ struct btrfs_fs_info { struct list_head dead_roots; struct list_head caching_block_groups; + spinlock_t delayed_iput_lock; + struct list_head delayed_iputs; + atomic_t nr_async_submits; atomic_t async_submit_draining; atomic_t nr_async_bios; @@ -2301,7 +2304,7 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, struct inode *inode, u64 new_size, u32 min_type); -int btrfs_start_delalloc_inodes(struct btrfs_root *root); +int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput); int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end); int btrfs_writepages(struct address_space *mapping, struct writeback_control *wbc); @@ -2341,6 +2344,8 @@ int btrfs_orphan_del(struct btrfs_trans_handle *trans, struct inode *inode); void btrfs_orphan_cleanup(struct btrfs_root *root); int btrfs_cont_expand(struct inode *inode, loff_t size); int btrfs_invalidate_inodes(struct btrfs_root *root); +void btrfs_add_delayed_iput(struct inode *inode); +void btrfs_run_delayed_iputs(struct btrfs_root *root); extern const struct dentry_operations btrfs_dentry_operations; /* ioctl.c */ diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index c1e59e3..009e3bd 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -1476,6 +1476,7 @@ static int cleaner_kthread(void *arg) if (!(root->fs_info->sb->s_flags & MS_RDONLY) && mutex_trylock(&root->fs_info->cleaner_mutex)) { + btrfs_run_delayed_iputs(root); btrfs_clean_old_snapshots(root); mutex_unlock(&root->fs_info->cleaner_mutex); } @@ -1605,6 +1606,7 @@ struct btrfs_root *open_ctree(struct super_block *sb, INIT_RADIX_TREE(&fs_info->fs_roots_radix, GFP_ATOMIC); INIT_LIST_HEAD(&fs_info->trans_list); INIT_LIST_HEAD(&fs_info->dead_roots); + INIT_LIST_HEAD(&fs_info->delayed_iputs); INIT_LIST_HEAD(&fs_info->hashers); INIT_LIST_HEAD(&fs_info->delalloc_inodes); INIT_LIST_HEAD(&fs_info->ordered_operations); @@ -1613,6 +1615,7 @@ struct btrfs_root *open_ctree(struct super_block *sb, spin_lock_init(&fs_info->new_trans_lock); spin_lock_init(&fs_info->ref_cache_lock); spin_lock_init(&fs_info->fs_roots_radix_lock); + spin_lock_init(&fs_info->delayed_iput_lock); init_completion(&fs_info->kobj_unregister); fs_info->tree_root = tree_root; @@ -2386,6 +2389,7 @@ int btrfs_commit_super(struct btrfs_root *root) int ret; mutex_lock(&root->fs_info->cleaner_mutex); + btrfs_run_delayed_iputs(root); btrfs_clean_old_snapshots(root); mutex_unlock(&root->fs_info->cleaner_mutex); diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 4a86508..fcdccfa 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -2880,9 +2880,9 @@ static noinline void flush_delalloc_async(struct btrfs_work *work) root = async->root; info = async->info; - btrfs_start_delalloc_inodes(root); + btrfs_start_delalloc_inodes(root, 0); wake_up(&info->flush_wait); - btrfs_wait_ordered_extents(root, 0); + btrfs_wait_ordered_extents(root, 0, 0); spin_lock(&info->lock); info->flushing = 0; @@ -2956,8 +2956,8 @@ static void flush_delalloc(struct btrfs_root *root, return; flush: - btrfs_start_delalloc_inodes(root); - btrfs_wait_ordered_extents(root, 0); + btrfs_start_delalloc_inodes(root, 0); + btrfs_wait_ordered_extents(root, 0, 0); spin_lock(&info->lock); info->flushing = 0; diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 82740a3..168e8c0 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -2022,6 +2022,54 @@ zeroit: return -EIO; } +struct delayed_iput { + struct list_head list; + struct inode *inode; +}; + +void btrfs_add_delayed_iput(struct inode *inode) +{ + struct btrfs_fs_info *fs_info = BTRFS_I(inode)->root->fs_info; + struct delayed_iput *delayed; + + if (atomic_add_unless(&inode->i_count, -1, 1)) + return; + + delayed = kmalloc(sizeof(*delayed), GFP_NOFS | __GFP_NOFAIL); + delayed->inode = inode; + + spin_lock(&fs_info->delayed_iput_lock); + list_add_tail(&delayed->list, &fs_info->delayed_iputs); + spin_unlock(&fs_info->delayed_iput_lock); +} + +void btrfs_run_delayed_iputs(struct btrfs_root *root) +{ + LIST_HEAD(list); + struct btrfs_fs_info *fs_info = root->fs_info; + struct delayed_iput *delayed; + int empty; + + spin_lock(&fs_info->delayed_iput_lock); + empty = list_empty(&fs_info->delayed_iputs); + spin_unlock(&fs_info->delayed_iput_lock); + if (empty) + return; + + down_read(&root->fs_info->cleanup_work_sem); + spin_lock(&fs_info->delayed_iput_lock); + list_splice_init(&fs_info->delayed_iputs, &list); + spin_unlock(&fs_info->delayed_iput_lock); + + while (!list_empty(&list)) { + delayed = list_entry(list.next, struct delayed_iput, list); + list_del(&delayed->list); + iput(delayed->inode); + kfree(delayed); + } + up_read(&root->fs_info->cleanup_work_sem); +} + /* * This creates an orphan entry for the given inode in case something goes * wrong in the middle of an unlink/truncate. @@ -5568,7 +5616,7 @@ out_fail: * some fairly slow code that needs optimization. This walks the list * of all the inodes with pending delalloc and forces them to disk. */ -int btrfs_start_delalloc_inodes(struct btrfs_root *root) +int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput) { struct list_head *head = &root->fs_info->delalloc_inodes; struct btrfs_inode *binode; @@ -5587,7 +5635,10 @@ int btrfs_start_delalloc_inodes(struct btrfs_root *root) spin_unlock(&root->fs_info->delalloc_lock); if (inode) { filemap_flush(inode->i_mapping); - iput(inode); + if (delay_iput) + btrfs_add_delayed_iput(inode); + else + iput(inode); } cond_resched(); spin_lock(&root->fs_info->delalloc_lock); diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c index 9b16073..b10a49d 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c @@ -352,7 +352,8 @@ int btrfs_remove_ordered_extent(struct inode *inode, * wait for all the ordered extents in a root. This is done when balancing * space between drives. */ -int btrfs_wait_ordered_extents(struct btrfs_root *root, int nocow_only) +int btrfs_wait_ordered_extents(struct btrfs_root *root, + int nocow_only, int delay_iput) { struct list_head splice; struct list_head *cur; @@ -389,7 +390,10 @@ int btrfs_wait_ordered_extents(struct btrfs_root *root, int nocow_only) if (inode) { btrfs_start_ordered_extent(inode, ordered, 1); btrfs_put_ordered_extent(ordered); - iput(inode); + if (delay_iput) + btrfs_add_delayed_iput(inode); + else + iput(inode); } else { btrfs_put_ordered_extent(ordered); } @@ -447,7 +451,7 @@ again: btrfs_wait_ordered_range(inode, 0, (u64)-1); else filemap_flush(inode->i_mapping); - iput(inode); + btrfs_add_delayed_iput(inode); } cond_resched(); diff --git a/fs/btrfs/ordered-data.h b/fs/btrfs/ordered-data.h index 4fa2039..1fe1282 100644 --- a/fs/btrfs/ordered-data.h +++ b/fs/btrfs/ordered-data.h @@ -153,9 +153,10 @@ btrfs_lookup_first_ordered_extent(struct inode * inode, u64 file_offset); int btrfs_ordered_update_i_size(struct inode *inode, u64 offset, struct btrfs_ordered_extent *ordered); int btrfs_find_ordered_sum(struct inode *inode, u64 offset, u64 disk_bytenr, u32 *sum); -int btrfs_wait_ordered_extents(struct btrfs_root *root, int nocow_only); int btrfs_run_ordered_operations(struct btrfs_root *root, int wait); int btrfs_add_ordered_operation(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct inode *inode); +int btrfs_wait_ordered_extents(struct btrfs_root *root, + int nocow_only, int delay_iput); #endif diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index f2aa53d..a972868 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c @@ -3541,8 +3541,8 @@ int btrfs_relocate_block_group(struct btrfs_root *extent_root, u64 group_start) (unsigned long long)rc->block_group->key.objectid, (unsigned long long)rc->block_group->flags); - btrfs_start_delalloc_inodes(fs_info->tree_root); - btrfs_wait_ordered_extents(fs_info->tree_root, 0); + btrfs_start_delalloc_inodes(fs_info->tree_root, 0); + btrfs_wait_ordered_extents(fs_info->tree_root, 0, 0); while (1) { rc->extents_found = 0; diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 752a546..270cc96 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -405,8 +405,8 @@ int btrfs_sync_fs(struct super_block *sb, int wait) return 0; } - btrfs_start_delalloc_inodes(root); - btrfs_wait_ordered_extents(root, 0); + btrfs_start_delalloc_inodes(root, 0); + btrfs_wait_ordered_extents(root, 0, 0); trans = btrfs_start_transaction(root, 1); ret = btrfs_commit_transaction(trans, root); diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 728e8fe..75b31ca 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c @@ -333,6 +333,9 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans, memset(trans, 0, sizeof(*trans)); kmem_cache_free(btrfs_trans_handle_cachep, trans); + if (throttle) + btrfs_run_delayed_iputs(root); + return 0; } @@ -991,11 +994,11 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, mutex_unlock(&root->fs_info->trans_mutex); if (flush_on_commit) { - btrfs_start_delalloc_inodes(root); - ret = btrfs_wait_ordered_extents(root, 0); + btrfs_start_delalloc_inodes(root, 1); + ret = btrfs_wait_ordered_extents(root, 0, 1); BUG_ON(ret); } else if (snap_pending) { - ret = btrfs_wait_ordered_extents(root, 1); + ret = btrfs_wait_ordered_extents(root, 0, 1); BUG_ON(ret); } @@ -1113,6 +1116,10 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, current->journal_info = NULL; kmem_cache_free(btrfs_trans_handle_cachep, trans); + + if (current != root->fs_info->transaction_kthread) + btrfs_run_delayed_iputs(root); + return ret; } -- cgit v0.10.2 From 55ef68990029fcd8d04d42fc184aa7fb18cf309e Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Thu, 12 Nov 2009 09:36:44 +0000 Subject: Btrfs: Fix btrfs_drop_extent_cache for skip pinned case The check for skip pinned case is wrong, it may breaks the while loop too soon. Signed-off-by: Yan Zheng Signed-off-by: Chris Mason diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 3d2e45c..3bfe9f0 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -179,18 +179,14 @@ int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end, } flags = em->flags; if (skip_pinned && test_bit(EXTENT_FLAG_PINNED, &em->flags)) { - if (em->start <= start && - (!testend || em->start + em->len >= start + len)) { + if (testend && em->start + em->len >= start + len) { free_extent_map(em); write_unlock(&em_tree->lock); break; } - if (start < em->start) { - len = em->start - start; - } else { + start = em->start + em->len; + if (testend) len = start + len - (em->start + em->len); - start = em->start + em->len; - } free_extent_map(em); write_unlock(&em_tree->lock); continue; -- cgit v0.10.2 From 86b9f2eca5e0984145e3c7698a7cd6dd65c2a93f Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Thu, 12 Nov 2009 09:36:50 +0000 Subject: Btrfs: Fix per root used space accounting The bytes_used field in root item was originally planned to trace the amount of used data and tree blocks. But it never worked right since we can't trace freeing of data accurately. This patch changes it to only trace the amount of tree blocks. Signed-off-by: Yan Zheng Signed-off-by: Chris Mason diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 9d4ba34..c4bc570 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -456,9 +456,8 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, extent_buffer_get(cow); spin_unlock(&root->node_lock); - btrfs_free_extent(trans, root, buf->start, buf->len, - parent_start, root->root_key.objectid, - level, 0); + btrfs_free_tree_block(trans, root, buf->start, buf->len, + parent_start, root->root_key.objectid, level); free_extent_buffer(buf); add_root_to_dirty_list(root); } else { @@ -473,9 +472,8 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, btrfs_set_node_ptr_generation(parent, parent_slot, trans->transid); btrfs_mark_buffer_dirty(parent); - btrfs_free_extent(trans, root, buf->start, buf->len, - parent_start, root->root_key.objectid, - level, 0); + btrfs_free_tree_block(trans, root, buf->start, buf->len, + parent_start, root->root_key.objectid, level); } if (unlock_orig) btrfs_tree_unlock(buf); @@ -1035,8 +1033,8 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, btrfs_tree_unlock(mid); /* once for the path */ free_extent_buffer(mid); - ret = btrfs_free_extent(trans, root, mid->start, mid->len, - 0, root->root_key.objectid, level, 1); + ret = btrfs_free_tree_block(trans, root, mid->start, mid->len, + 0, root->root_key.objectid, level); /* once for the root ptr */ free_extent_buffer(mid); return ret; @@ -1100,10 +1098,10 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, 1); if (wret) ret = wret; - wret = btrfs_free_extent(trans, root, bytenr, - blocksize, 0, - root->root_key.objectid, - level, 0); + wret = btrfs_free_tree_block(trans, root, + bytenr, blocksize, 0, + root->root_key.objectid, + level); if (wret) ret = wret; } else { @@ -1148,9 +1146,8 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, wret = del_ptr(trans, root, path, level + 1, pslot); if (wret) ret = wret; - wret = btrfs_free_extent(trans, root, bytenr, blocksize, - 0, root->root_key.objectid, - level, 0); + wret = btrfs_free_tree_block(trans, root, bytenr, blocksize, + 0, root->root_key.objectid, level); if (wret) ret = wret; } else { @@ -3794,8 +3791,8 @@ static noinline int btrfs_del_leaf(struct btrfs_trans_handle *trans, */ btrfs_unlock_up_safe(path, 0); - ret = btrfs_free_extent(trans, root, leaf->start, leaf->len, - 0, root->root_key.objectid, 0, 0); + ret = btrfs_free_tree_block(trans, root, leaf->start, leaf->len, + 0, root->root_key.objectid, 0); return ret; } /* diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 1983c88..9f806dd 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -1982,6 +1982,10 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, u64 parent, u64 root_objectid, struct btrfs_disk_key *key, int level, u64 hint, u64 empty_size); +int btrfs_free_tree_block(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + u64 bytenr, u32 blocksize, + u64 parent, u64 root_objectid, int level); struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans, struct btrfs_root *root, u64 bytenr, u32 blocksize, diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index fcdccfa..44d7a32 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -3454,14 +3454,6 @@ static int update_block_group(struct btrfs_trans_handle *trans, else old_val -= num_bytes; btrfs_set_super_bytes_used(&info->super_copy, old_val); - - /* block accounting for root item */ - old_val = btrfs_root_used(&root->root_item); - if (alloc) - old_val += num_bytes; - else - old_val -= num_bytes; - btrfs_set_root_used(&root->root_item, old_val); spin_unlock(&info->delalloc_lock); while (total) { @@ -4049,6 +4041,21 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans, return ret; } +int btrfs_free_tree_block(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + u64 bytenr, u32 blocksize, + u64 parent, u64 root_objectid, int level) +{ + u64 used; + spin_lock(&root->node_lock); + used = btrfs_root_used(&root->root_item) - blocksize; + btrfs_set_root_used(&root->root_item, used); + spin_unlock(&root->node_lock); + + return btrfs_free_extent(trans, root, bytenr, blocksize, + parent, root_objectid, level, 0); +} + static u64 stripe_align(struct btrfs_root *root, u64 val) { u64 mask = ((u64)root->stripesize - 1); @@ -4897,6 +4904,14 @@ static int alloc_tree_block(struct btrfs_trans_handle *trans, extent_op); BUG_ON(ret); } + + if (root_objectid == root->root_key.objectid) { + u64 used; + spin_lock(&root->node_lock); + used = btrfs_root_used(&root->root_item) + num_bytes; + btrfs_set_root_used(&root->root_item, used); + spin_unlock(&root->node_lock); + } return ret; } diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 3d6b338..645a179 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -289,7 +289,7 @@ static noinline int create_subvol(struct btrfs_root *root, btrfs_set_root_generation(&root_item, trans->transid); btrfs_set_root_level(&root_item, 0); btrfs_set_root_refs(&root_item, 1); - btrfs_set_root_used(&root_item, 0); + btrfs_set_root_used(&root_item, leaf->len); btrfs_set_root_last_snapshot(&root_item, 0); memset(&root_item.drop_progress, 0, sizeof(root_item.drop_progress)); diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 75b31ca..b2acc79 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c @@ -501,13 +501,16 @@ static int update_cowonly_root(struct btrfs_trans_handle *trans, { int ret; u64 old_root_bytenr; + u64 old_root_used; struct btrfs_root *tree_root = root->fs_info->tree_root; + old_root_used = btrfs_root_used(&root->root_item); btrfs_write_dirty_block_groups(trans, root); while (1) { old_root_bytenr = btrfs_root_bytenr(&root->root_item); - if (old_root_bytenr == root->node->start) + if (old_root_bytenr == root->node->start && + old_root_used == btrfs_root_used(&root->root_item)) break; btrfs_set_root_node(&root->root_item, root->node); @@ -516,6 +519,7 @@ static int update_cowonly_root(struct btrfs_trans_handle *trans, &root->root_item); BUG_ON(ret); + old_root_used = btrfs_root_used(&root->root_item); ret = btrfs_write_dirty_block_groups(trans, root); BUG_ON(ret); } -- cgit v0.10.2 From 06b2331f8333ec6edf41662757ce8882cc1747d5 Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Thu, 26 Nov 2009 09:31:11 +0000 Subject: Btrfs: don't add extent 0 to the free space cache v2 If block group 0 is completely free, btrfs_read_block_groups will add extent [0, BTRFS_SUPER_INFO_OFFSET) to the free space cache. Signed-off-by: Yan Zheng Signed-off-by: Chris Mason diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 44d7a32..39761ca 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -195,6 +195,14 @@ static int exclude_super_stripes(struct btrfs_root *root, int stripe_len; int i, nr, ret; + if (cache->key.objectid < BTRFS_SUPER_INFO_OFFSET) { + stripe_len = BTRFS_SUPER_INFO_OFFSET - cache->key.objectid; + cache->bytes_super += stripe_len; + ret = add_excluded_extent(root, cache->key.objectid, + stripe_len); + BUG_ON(ret); + } + for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) { bytenr = btrfs_sb_offset(i); ret = btrfs_rmap_block(&root->fs_info->mapping_tree, @@ -255,7 +263,7 @@ static u64 add_new_free_space(struct btrfs_block_group_cache *block_group, if (ret) break; - if (extent_start == start) { + if (extent_start <= start) { start = extent_end + 1; } else if (extent_start > start && extent_start < end) { size = extent_start - start; -- cgit v0.10.2 From a7a3f7cadd9bdee569243f7ead9550aa16b60e07 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Sat, 7 Nov 2009 06:19:16 +0000 Subject: Btrfs: fail mount on bad mount options We shouldn't silently ignore unrecognized options. Signed-off-by: Sage Weil Signed-off-by: Chris Mason diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 270cc96..193d920 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -128,6 +128,7 @@ int btrfs_parse_options(struct btrfs_root *root, char *options) substring_t args[MAX_OPT_ARGS]; char *p, *num; int intarg; + int ret = 0; if (!options) return 0; @@ -262,12 +263,18 @@ int btrfs_parse_options(struct btrfs_root *root, char *options) case Opt_discard: btrfs_set_opt(info->mount_opt, DISCARD); break; + case Opt_err: + printk(KERN_INFO "btrfs: unrecognized mount option " + "'%s'\n", p); + ret = -EINVAL; + goto out; default: break; } } +out: kfree(options); - return 0; + return ret; } /* -- cgit v0.10.2 From 4a8be425a8fb8fbb5d881eb55fa6634c3463b9c9 Mon Sep 17 00:00:00 2001 From: TARUISI Hiroaki Date: Thu, 12 Nov 2009 07:14:26 +0000 Subject: Btrfs: deny sys_link across subvolumes. I rebased Christian Parpart's patch to deny hard link across subvolumes. Original patch modifies also btrfs_rename, but I excluded it because we can move across subvolumes now and it make no problem. ----------------- Hard link across subvolumes should not allowed in Btrfs. btrfs_link checks root of 'to' directory is same as root of 'from' file. If not same, btrfs_link returns -EPERM. Signed-off-by: TARUISI Hiroaki Signed-off-by: Chris Mason diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 168e8c0..da76cad 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -4462,6 +4462,10 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, if (inode->i_nlink == 0) return -ENOENT; + /* do not allow sys_link's with other subvols of the same device */ + if (root->objectid != BTRFS_I(inode)->root->objectid) + return -EPERM; + /* * 1 item for inode ref * 2 items for dir items -- cgit v0.10.2 From 20a5239a5d0f340e29827a6a2d28a138001c44b8 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Mon, 14 Dec 2009 22:01:12 +0000 Subject: Btrfs: Show discard option in /proc/mounts Christoph's patch e244a0aeb6a599c19a7c802cda6e2d67c847b154 doesn't display the discard option in /proc/mounts, leading to some confusion for me. Here's the missing bit. Signed-off-by: Matthew Wilcox Signed-off-by: Chris Mason diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 193d920..3f9b457 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -457,6 +457,8 @@ static int btrfs_show_options(struct seq_file *seq, struct vfsmount *vfs) seq_puts(seq, ",notreelog"); if (btrfs_test_opt(root, FLUSHONCOMMIT)) seq_puts(seq, ",flushoncommit"); + if (btrfs_test_opt(root, DISCARD)) + seq_puts(seq, ",discard"); if (!(root->fs_info->sb->s_flags & MS_POSIXACL)) seq_puts(seq, ",noacl"); return 0; -- cgit v0.10.2 From 83d3c9696fed237a3d96fce18299e2fcf112109f Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Mon, 7 Dec 2009 21:45:59 +0000 Subject: Btrfs: make metadata chunks smaller This patch makes us a bit less zealous about making sure we have enough free metadata space by pearing down the size of new metadata chunks to 256mb instead of 1gb. Also, we used to try an allocate metadata chunks when allocating data, but that sort of thing is done elsewhere now so we can just remove it. With my -ENOSPC test I used to have 3gb reserved for metadata out of 75gb, now I have 1.7gb. Thanks, Signed-off-by: Josef Bacik Signed-off-by: Chris Mason diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 39761ca..56e5013 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -4593,7 +4593,6 @@ int btrfs_reserve_extent(struct btrfs_trans_handle *trans, { int ret; u64 search_start = 0; - struct btrfs_fs_info *info = root->fs_info; data = btrfs_get_alloc_profile(root, data); again: @@ -4601,17 +4600,9 @@ again: * the only place that sets empty_size is btrfs_realloc_node, which * is not called recursively on allocations */ - if (empty_size || root->ref_cows) { - if (!(data & BTRFS_BLOCK_GROUP_METADATA)) { - ret = do_chunk_alloc(trans, root->fs_info->extent_root, - 2 * 1024 * 1024, - BTRFS_BLOCK_GROUP_METADATA | - (info->metadata_alloc_profile & - info->avail_metadata_alloc_bits), 0); - } + if (empty_size || root->ref_cows) ret = do_chunk_alloc(trans, root->fs_info->extent_root, num_bytes + 2 * 1024 * 1024, data, 0); - } WARN_ON(num_bytes < root->sectorsize); ret = find_free_extent(trans, root, num_bytes, empty_size, diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 7eda483..198cff2 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -2209,7 +2209,7 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans, max_chunk_size = 10 * calc_size; min_stripe_size = 64 * 1024 * 1024; } else if (type & BTRFS_BLOCK_GROUP_METADATA) { - max_chunk_size = 4 * calc_size; + max_chunk_size = 256 * 1024 * 1024; min_stripe_size = 32 * 1024 * 1024; } else if (type & BTRFS_BLOCK_GROUP_SYSTEM) { calc_size = 8 * 1024 * 1024; -- cgit v0.10.2 From c566ec49159b806db95a90fd8f37448376cd0ad2 Mon Sep 17 00:00:00 2001 From: Zhenyu Wang Date: Thu, 17 Dec 2009 16:12:56 +0800 Subject: drm/i915: Reload hangcheck timer too for Ironlake Make sure hangcheck timer won't beat us unexpectedly on Ironlake. Signed-off-by: Zhenyu Wang Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 1733eea..7cd8110 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -313,6 +313,8 @@ irqreturn_t ironlake_irq_handler(struct drm_device *dev) dev_priv->mm.irq_gem_seqno = seqno; trace_i915_gem_request_complete(dev, seqno); DRM_WAKEUP(&dev_priv->irq_queue); + dev_priv->hangcheck_count = 0; + mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD); } if (de_iir & DE_GSE) -- cgit v0.10.2 From 971beb83aeb2a309175682cf5683d64fd4591841 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Mon, 7 Dec 2009 14:23:21 +0100 Subject: Bluetooth: Fix PTR_ERR return of wrong pointer in hidp_setup_hid() Return the PTR_ERR of the correct pointer. Signed-off-by: Roel Kluin Signed-off-by: Marcel Holtmann diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 5697500..18e7f5a 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c @@ -770,7 +770,7 @@ static int hidp_setup_hid(struct hidp_session *session, hid = hid_allocate_device(); if (IS_ERR(hid)) - return PTR_ERR(session->hid); + return PTR_ERR(hid); session->hid = hid; session->req = req; -- cgit v0.10.2 From 186de9a33803c7ee20d9af75c9049b50e68a3a08 Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Tue, 15 Dec 2009 15:56:34 -0200 Subject: Bluetooth: Fix unset of RemoteBusy flag for L2CAP RemoteBusy flag need to be unset before l2cap_ertm_send(), otherwise l2cap_ertm_send() will return without sending packets because it checks that flag before start sending. Signed-off-by: Gustavo F. Padovan Signed-off-by: Marcel Holtmann diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 5129b88..7db9a1f 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c @@ -3435,8 +3435,8 @@ static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, str (pi->unacked_frames > 0)) __mod_retrans_timer(); - l2cap_ertm_send(sk); pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; + l2cap_ertm_send(sk); } break; -- cgit v0.10.2 From 186ee8cf0130993dea8ab8867ff1af8a148f9ae6 Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Tue, 15 Dec 2009 20:13:27 -0200 Subject: Bluetooth: Ack L2CAP I-frames before retransmit missing packet Moving the Ack to before l2cap_retransmit_frame() we can avoid the case where txWindow is full and the packet can't be retransmited. Signed-off-by: Gustavo F. Padovan Signed-off-by: Marcel Holtmann diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 7db9a1f..fb0f81d 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c @@ -3471,9 +3471,9 @@ static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, str pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; if (rx_control & L2CAP_CTRL_POLL) { - l2cap_retransmit_frame(sk, tx_seq); pi->expected_ack_seq = tx_seq; l2cap_drop_acked_frames(sk); + l2cap_retransmit_frame(sk, tx_seq); l2cap_ertm_send(sk); if (pi->conn_state & L2CAP_CONN_WAIT_F) { pi->srej_save_reqseq = tx_seq; -- cgit v0.10.2 From b13f5860447a98daf0358a51fbff66154ac0663a Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Tue, 15 Dec 2009 11:38:04 +0200 Subject: Bluetooth: Fix L2CAP locking scheme regression When locking was introduced the error path branch was not taken into account. Error was found in sparse code checking. Kudos to Jani Nikula. Signed-off-by: Andrei Emeltchenko Acked-by: Gustavo F. Padovan Signed-off-by: Marcel Holtmann diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index fb0f81d..1120cf1 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c @@ -1212,6 +1212,7 @@ static void l2cap_monitor_timeout(unsigned long arg) bh_lock_sock(sk); if (l2cap_pi(sk)->retry_count >= l2cap_pi(sk)->remote_max_tx) { l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk); + bh_unlock_sock(sk); return; } -- cgit v0.10.2 From 652fd781a52ad6e24b908cd8b83d12699754f253 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Wed, 16 Dec 2009 19:23:43 +0100 Subject: Bluetooth: Prevent ill-timed autosuspend in USB driver The device must be marked busy as it receives data. Signed-off-by: Oliver Neukum Tested-by: Matthew Garrett Signed-off-by: Marcel Holtmann diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 4d29059..a699f09 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -307,6 +307,7 @@ static void btusb_bulk_complete(struct urb *urb) return; usb_anchor_urb(urb, &data->bulk_anchor); + usb_mark_last_busy(data->udev); err = usb_submit_urb(urb, GFP_ATOMIC); if (err < 0) { -- cgit v0.10.2 From 3a1abec9f6880cf406593c392636199ea1c6c917 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Thu, 17 Dec 2009 15:47:17 -0500 Subject: Btrfs: make sure fallocate properly starts a transaction The recent patch to make fallocate enospc friendly would send down a NULL trans handle to the allocator. This moves the transaction start to properly fix things. Signed-off-by: Chris Mason diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index da76cad..5440bab 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -5802,23 +5802,23 @@ static int prealloc_file_range(struct inode *inode, u64 start, u64 end, while (num_bytes > 0) { alloc_size = min(num_bytes, root->fs_info->max_extent); + trans = btrfs_start_transaction(root, 1); + ret = btrfs_reserve_extent(trans, root, alloc_size, root->sectorsize, 0, alloc_hint, (u64)-1, &ins, 1); if (ret) { WARN_ON(1); - break; + goto stop_trans; } ret = btrfs_reserve_metadata_space(root, 3); if (ret) { btrfs_free_reserved_extent(root, ins.objectid, ins.offset); - break; + goto stop_trans; } - trans = btrfs_start_transaction(root, 1); - ret = insert_reserved_file_extent(trans, inode, cur_offset, ins.objectid, ins.offset, ins.offset, @@ -5847,6 +5847,11 @@ static int prealloc_file_range(struct inode *inode, u64 start, u64 end, btrfs_unreserve_metadata_space(root, 3); } return ret; + +stop_trans: + btrfs_end_transaction(trans, root); + return ret; + } static long btrfs_fallocate(struct inode *inode, int mode, -- cgit v0.10.2 From a2770d86b33024f71df269fde2de096df89d6a48 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 17 Dec 2009 12:51:05 -0800 Subject: Revert "fix mismerge with Trond's stuff (create_mnt_ns() export is gone now)" This reverts commit e9496ff46a20a8592fdc7bdaaf41b45eb808d310. Quoth Al: "it's dependent on a lot of other stuff not currently in mainline and badly broken with current fs/namespace.c. Sorry, badly out-of-order cherry-pick from old queue. PS: there's a large pending series reworking the refcounting and lifetime rules for vfsmounts that will, among other things, allow to rip a subtree away _without_ dissolving connections in it, to be garbage-collected when all active references are gone. It's considerably saner wrt "is the subtree busy" logics, but it's nowhere near being ready for merge at the moment; this changeset is one of the things becoming possible with that sucker, but it certainly shouldn't have been picked during this cycle. My apologies..." Noticed-by: Eric Paris Requested-by: Al Viro Signed-off-by: Linus Torvalds diff --git a/fs/namespace.c b/fs/namespace.c index faab127..7d70d63 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -2068,7 +2068,7 @@ struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct mnt_namespace *ns, * create_mnt_ns - creates a private namespace and adds a root filesystem * @mnt: pointer to the new root filesystem mountpoint */ -static struct mnt_namespace *create_mnt_ns(struct vfsmount *mnt) +struct mnt_namespace *create_mnt_ns(struct vfsmount *mnt) { struct mnt_namespace *new_ns; @@ -2080,6 +2080,7 @@ static struct mnt_namespace *create_mnt_ns(struct vfsmount *mnt) } return new_ns; } +EXPORT_SYMBOL(create_mnt_ns); SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name, char __user *, type, unsigned long, flags, void __user *, data) diff --git a/fs/nfs/super.c b/fs/nfs/super.c index d5b112b..ce907ef 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -2648,13 +2648,21 @@ out_freepage: static int nfs_follow_remote_path(struct vfsmount *root_mnt, const char *export_path, struct vfsmount *mnt_target) { + struct mnt_namespace *ns_private; struct nameidata nd; struct super_block *s; int ret; + ns_private = create_mnt_ns(root_mnt); + ret = PTR_ERR(ns_private); + if (IS_ERR(ns_private)) + goto out_mntput; + ret = vfs_path_lookup(root_mnt->mnt_root, root_mnt, export_path, LOOKUP_FOLLOW, &nd); + put_mnt_ns(ns_private); + if (ret != 0) goto out_err; diff --git a/include/linux/mnt_namespace.h b/include/linux/mnt_namespace.h index d9ebf10..d74785c 100644 --- a/include/linux/mnt_namespace.h +++ b/include/linux/mnt_namespace.h @@ -23,6 +23,7 @@ struct proc_mounts { struct fs_struct; +extern struct mnt_namespace *create_mnt_ns(struct vfsmount *mnt); extern struct mnt_namespace *copy_mnt_ns(unsigned long, struct mnt_namespace *, struct fs_struct *); extern void put_mnt_ns(struct mnt_namespace *ns); -- cgit v0.10.2 From cd78809f6191485a90ea6c92c2b58900ab5c156f Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 17 Dec 2009 13:52:39 -0700 Subject: ioat3: fix p-disabled q-continuation When continuing a pq calculation the driver needs 3 extra sources. The driver can perform a 3 source calculation with a single descriptor, but needs an extended descriptor to process up to 8 sources in one operation. However, in the p-disabled case only one extra source is needed. When continuing a p-disabled operation there are occasions (i.e. 0 < src_cnt % 8 < 3) where the tail operation does not need an extended descriptor. Properly account for this fact otherwise invalid 'dmacount' values will be written to hardware usually causing the channel to halt with 'invalid descriptor' errors. Cc: Signed-off-by: Dan Williams diff --git a/drivers/dma/ioat/dma_v3.c b/drivers/dma/ioat/dma_v3.c index 42f6f10..e58ecb2 100644 --- a/drivers/dma/ioat/dma_v3.c +++ b/drivers/dma/ioat/dma_v3.c @@ -650,9 +650,11 @@ __ioat3_prep_pq_lock(struct dma_chan *c, enum sum_check_flags *result, num_descs = ioat2_xferlen_to_descs(ioat, len); /* we need 2x the number of descriptors to cover greater than 3 - * sources + * sources (we need 1 extra source in the q-only continuation + * case and 3 extra sources in the p+q continuation case. */ - if (src_cnt > 3 || flags & DMA_PREP_CONTINUE) { + if (src_cnt + dmaf_p_disabled_continue(flags) > 3 || + (dmaf_continue(flags) && !dmaf_p_disabled_continue(flags))) { with_ext = 1; num_descs *= 2; } else -- cgit v0.10.2 From e02a0e47a3f061c1a53fc4376332a988ec047e8a Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 17 Dec 2009 13:55:38 -0700 Subject: async_tx: expand async raid6 test to cover ioatdma corner case Add explicit 11 and 12 disks cases to exercise the 0 < src_cnt % 8 < 3 corner case in the ioatdma driver. Signed-off-by: Dan Williams diff --git a/crypto/async_tx/raid6test.c b/crypto/async_tx/raid6test.c index 3ec27c7..f84f6b4 100644 --- a/crypto/async_tx/raid6test.c +++ b/crypto/async_tx/raid6test.c @@ -214,6 +214,13 @@ static int raid6_test(void) err += test(4, &tests); if (NDISKS > 5) err += test(5, &tests); + /* the 11 and 12 disk cases are special for ioatdma (p-disabled + * q-continuation without extended descriptor) + */ + if (NDISKS > 12) { + err += test(11, &tests); + err += test(12, &tests); + } err += test(NDISKS, &tests); pr("\n"); -- cgit v0.10.2 From b6e3224fb20954f155e41ec5709b2ab70b50ae2d Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 17 Dec 2009 13:23:24 -0800 Subject: Revert "task_struct: make journal_info conditional" This reverts commit e4c570c4cb7a95dbfafa3d016d2739bf3fdfe319, as requested by Alexey: "I think I gave a good enough arguments to not merge it. To iterate: * patch makes impossible to start using ext3 on EXT3_FS=n kernels without reboot. * this is done only for one pointer on task_struct" None of config options which define task_struct are tristate directly or effectively." Requested-by: Alexey Dobriyan Acked-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/fs/Kconfig b/fs/Kconfig index f8fccaa..64d44ef 100644 --- a/fs/Kconfig +++ b/fs/Kconfig @@ -6,10 +6,6 @@ menu "File systems" if BLOCK -config FS_JOURNAL_INFO - bool - default n - source "fs/ext2/Kconfig" source "fs/ext3/Kconfig" source "fs/ext4/Kconfig" diff --git a/fs/btrfs/Kconfig b/fs/btrfs/Kconfig index 402afe0..7bb3c02 100644 --- a/fs/btrfs/Kconfig +++ b/fs/btrfs/Kconfig @@ -4,7 +4,6 @@ config BTRFS_FS select LIBCRC32C select ZLIB_INFLATE select ZLIB_DEFLATE - select FS_JOURNAL_INFO help Btrfs is a new filesystem with extents, writable snapshotting, support for multiple devices and many more features. diff --git a/fs/ext4/Kconfig b/fs/ext4/Kconfig index e5f6774..9acf7e8 100644 --- a/fs/ext4/Kconfig +++ b/fs/ext4/Kconfig @@ -2,7 +2,6 @@ config EXT4_FS tristate "The Extended 4 (ext4) filesystem" select JBD2 select CRC16 - select FS_JOURNAL_INFO help This is the next generation of the ext3 filesystem. diff --git a/fs/gfs2/Kconfig b/fs/gfs2/Kconfig index b192c66..4dcddf8 100644 --- a/fs/gfs2/Kconfig +++ b/fs/gfs2/Kconfig @@ -10,7 +10,6 @@ config GFS2_FS select SLOW_WORK select QUOTA select QUOTACTL - select FS_JOURNAL_INFO help A cluster filesystem. diff --git a/fs/jbd/Kconfig b/fs/jbd/Kconfig index a840898..4e28bee 100644 --- a/fs/jbd/Kconfig +++ b/fs/jbd/Kconfig @@ -1,6 +1,5 @@ config JBD tristate - select FS_JOURNAL_INFO help This is a generic journalling layer for block devices. It is currently used by the ext3 file system, but it could also be diff --git a/fs/jbd2/Kconfig b/fs/jbd2/Kconfig index 0f7d1ce..f32f346 100644 --- a/fs/jbd2/Kconfig +++ b/fs/jbd2/Kconfig @@ -1,7 +1,6 @@ config JBD2 tristate select CRC32 - select FS_JOURNAL_INFO help This is a generic journaling layer for block devices that support both 32-bit and 64-bit block numbers. It is currently used by diff --git a/fs/nilfs2/Kconfig b/fs/nilfs2/Kconfig index 1225af7..251da07 100644 --- a/fs/nilfs2/Kconfig +++ b/fs/nilfs2/Kconfig @@ -2,7 +2,6 @@ config NILFS2_FS tristate "NILFS2 file system support (EXPERIMENTAL)" depends on EXPERIMENTAL select CRC32 - select FS_JOURNAL_INFO help NILFS2 is a log-structured file system (LFS) supporting continuous snapshotting. In addition to versioning capability of the entire diff --git a/fs/reiserfs/Kconfig b/fs/reiserfs/Kconfig index ac7cd75..513f431 100644 --- a/fs/reiserfs/Kconfig +++ b/fs/reiserfs/Kconfig @@ -1,7 +1,6 @@ config REISERFS_FS tristate "Reiserfs support" select CRC32 - select FS_JOURNAL_INFO help Stores not just filenames but the files themselves in a balanced tree. Uses journalling. diff --git a/include/linux/init_task.h b/include/linux/init_task.h index 5ed8b9c..abec69b 100644 --- a/include/linux/init_task.h +++ b/include/linux/init_task.h @@ -111,12 +111,6 @@ extern struct cred init_cred; # define INIT_PERF_EVENTS(tsk) #endif -#ifdef CONFIG_FS_JOURNAL_INFO -#define INIT_JOURNAL_INFO .journal_info = NULL, -#else -#define INIT_JOURNAL_INFO -#endif - /* * INIT_TASK is used to set up the first task table, touch at * your own risk!. Base=0, limit=0x1fffff (=2MB) @@ -168,6 +162,7 @@ extern struct cred init_cred; .signal = {{0}}}, \ .blocked = {{0}}, \ .alloc_lock = __SPIN_LOCK_UNLOCKED(tsk.alloc_lock), \ + .journal_info = NULL, \ .cpu_timers = INIT_CPU_TIMERS(tsk.cpu_timers), \ .fs_excl = ATOMIC_INIT(0), \ .pi_lock = __RAW_SPIN_LOCK_UNLOCKED(tsk.pi_lock), \ @@ -178,7 +173,6 @@ extern struct cred init_cred; [PIDTYPE_SID] = INIT_PID_LINK(PIDTYPE_SID), \ }, \ .dirties = INIT_PROP_LOCAL_SINGLE(dirties), \ - INIT_JOURNAL_INFO \ INIT_IDS \ INIT_PERF_EVENTS(tsk) \ INIT_TRACE_IRQFLAGS \ diff --git a/include/linux/sched.h b/include/linux/sched.h index 244c287..211ed32 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1446,10 +1446,8 @@ struct task_struct { gfp_t lockdep_reclaim_gfp; #endif -#ifdef CONFIG_FS_JOURNAL_INFO /* journalling filesystem info */ void *journal_info; -#endif /* stacked block device info */ struct bio *bio_list, **bio_tail; -- cgit v0.10.2 From 6c56ccecf05fafe100ab4ea94f6fccbf5ff00db7 Mon Sep 17 00:00:00 2001 From: "Pallipadi, Venkatesh" Date: Thu, 17 Dec 2009 12:27:02 -0800 Subject: x86: Reenable TSC sync check at boot, even with NONSTOP_TSC Commit 83ce4009 did the following change If the TSC is constant and non-stop, also set it reliable. But, there seems to be few systems that will end up with TSC warp across sockets, depending on how the cpus come out of reset. Skipping TSC sync test on such systems may result in time inconsistency later. So, reenable TSC sync test even on constant and non-stop TSC systems. Set, sched_clock_stable to 1 by default and reset it in mark_tsc_unstable, if TSC sync fails. This change still gives perf benefit mentioned in 83ce4009 for systems where TSC is reliable. Signed-off-by: Venkatesh Pallipadi Acked-by: Suresh Siddha LKML-Reference: <20091217202702.GA18015@linux-os.sc.intel.com> Signed-off-by: H. Peter Anvin diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index 9c31e8b..879666f 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c @@ -70,7 +70,6 @@ static void __cpuinit early_init_intel(struct cpuinfo_x86 *c) if (c->x86_power & (1 << 8)) { set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC); set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC); - set_cpu_cap(c, X86_FEATURE_TSC_RELIABLE); sched_clock_stable = 1; } diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index cd982f4..597683a 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c @@ -763,6 +763,7 @@ void mark_tsc_unstable(char *reason) { if (!tsc_unstable) { tsc_unstable = 1; + sched_clock_stable = 0; printk(KERN_INFO "Marking TSC unstable due to %s\n", reason); /* Change only the rating, when not registered */ if (clocksource_tsc.mult) -- cgit v0.10.2 From 8c63450718ea62ee3a70bffde170b4d15fc72d3c Mon Sep 17 00:00:00 2001 From: "akpm@linux-foundation.org" Date: Thu, 17 Dec 2009 15:26:36 -0800 Subject: x86: Fix objdump version check in arch/x86/tools/chkobjdump.awk It says Warning: objdump version is older than 2.19 Warning: Skipping posttest. because it used the wrong field from `objdump -v': akpm:/usr/src/25> /opt/crosstool/gcc-4.0.2-glibc-2.3.6/x86_64-unknown-linux-gnu/bin/x86_64-unknown-linux-gnu-objdump -v GNU objdump 2.16.1 Copyright 2005 Free Software Foundation, Inc. This program is free software; you may redistribute it under the terms of the GNU General Public License. This program has absolutely no warranty. Cc: Thomas Gleixner Cc: Ingo Molnar Signed-off-by: Andrew Morton LKML-Reference: <200912172326.nBHNQaQl024796@imap1.linux-foundation.org> Signed-off-by: H. Peter Anvin Cc: Masami Hiramatsu diff --git a/arch/x86/tools/chkobjdump.awk b/arch/x86/tools/chkobjdump.awk index 0d13cd9..5bbb5a3 100644 --- a/arch/x86/tools/chkobjdump.awk +++ b/arch/x86/tools/chkobjdump.awk @@ -9,7 +9,7 @@ BEGIN { } /^GNU/ { - split($4, ver, "."); + split($3, ver, "."); if (ver[1] > od_ver || (ver[1] == od_ver && ver[2] >= od_sver)) { exit 1; -- cgit v0.10.2 From 3e26120cc7c819c97bc07281ca1fb9017cfe9a39 Mon Sep 17 00:00:00 2001 From: WANG Cong Date: Thu, 17 Dec 2009 15:27:05 -0800 Subject: kernel/sysctl.c: fix the incomplete part of sysctl_max_map_count-should-be-non-negative.patch It is a mistake that we used 'proc_dointvec', it should be 'proc_dointvec_minmax', as in the original patch. Signed-off-by: WANG Cong Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 45e4bef..6665761 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -1131,7 +1131,7 @@ static struct ctl_table vm_table[] = { .data = &sysctl_max_map_count, .maxlen = sizeof(sysctl_max_map_count), .mode = 0644, - .proc_handler = proc_dointvec, + .proc_handler = proc_dointvec_minmax, .extra1 = &zero, }, #else -- cgit v0.10.2 From 2bf212b9e48e1c35eaf8f0cc1729d7c4a39b7b5a Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 17 Dec 2009 15:27:05 -0800 Subject: cs5535: CS5535_MFGPT_DEFAULT_IRQ should depend on CS5535_MFGPT It doesn't make much sense to have CS5535_MFGPT_DEFAULT_IRQ show up in configs that cannot have CS5535_MFGPT. Signed-off-by: Geert Uytterhoeven Acked-by: Andres Salomon Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 1a7a9fc..e3551d2 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -203,6 +203,7 @@ config CS5535_MFGPT config CS5535_MFGPT_DEFAULT_IRQ int + depends on CS5535_MFGPT default 7 help MFGPTs on the CS5535 require an interrupt. The selected IRQ -- cgit v0.10.2 From ec8e2f7466ca370f5e09000ca40a71759afc9ac8 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Thu, 17 Dec 2009 15:27:06 -0800 Subject: reiserfs: truncate blocks not used by a write It can happen that write does not use all the blocks allocated in write_begin either because of some filesystem error (like ENOSPC) or because page with data to write has been removed from memory. We truncate these blocks so that we don't have dangling blocks beyond i_size. Cc: Jeff Mahoney Signed-off-by: Jan Kara Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 3a28e77..290ae38 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c @@ -2538,6 +2538,12 @@ static int reiserfs_writepage(struct page *page, struct writeback_control *wbc) return reiserfs_write_full_page(page, wbc); } +static void reiserfs_truncate_failed_write(struct inode *inode) +{ + truncate_inode_pages(inode->i_mapping, inode->i_size); + reiserfs_truncate_file(inode, 0); +} + static int reiserfs_write_begin(struct file *file, struct address_space *mapping, loff_t pos, unsigned len, unsigned flags, @@ -2604,6 +2610,8 @@ static int reiserfs_write_begin(struct file *file, if (ret) { unlock_page(page); page_cache_release(page); + /* Truncate allocated blocks */ + reiserfs_truncate_failed_write(inode); } return ret; } @@ -2701,9 +2709,7 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping, ** transaction tracking stuff when the size changes. So, we have ** to do the i_size updates here. */ - pos += copied; - - if (pos > inode->i_size) { + if (pos + copied > inode->i_size) { struct reiserfs_transaction_handle myth; lock_depth = reiserfs_write_lock_once(inode->i_sb); locked = true; @@ -2721,7 +2727,7 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping, goto journal_error; reiserfs_update_inode_transaction(inode); - inode->i_size = pos; + inode->i_size = pos + copied; /* * this will just nest into our transaction. It's important * to use mark_inode_dirty so the inode gets pushed around on the @@ -2751,6 +2757,10 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping, reiserfs_write_unlock_once(inode->i_sb, lock_depth); unlock_page(page); page_cache_release(page); + + if (pos + len > inode->i_size) + reiserfs_truncate_failed_write(inode); + return ret == 0 ? copied : ret; journal_error: -- cgit v0.10.2 From 312ea07bf067d41b339473e696f9199245d762f3 Mon Sep 17 00:00:00 2001 From: Samu Onkalo Date: Thu, 17 Dec 2009 15:27:07 -0800 Subject: hwmon: I2C bus support for lis3lv02d and variant accelerometer chips MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Samu Onkalo Cc: Éric Piel Cc: Kalhan Trisal Cc: Jean Delvare Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 95ccbe3..bf28945 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -998,6 +998,23 @@ config SENSORS_LIS3_SPI will be called lis3lv02d and a specific module for the SPI transport is called lis3lv02d_spi. +config SENSORS_LIS3_I2C + tristate "STMicroeletronics LIS3LV02Dx three-axis digital accelerometer (I2C)" + depends on I2C && INPUT + select INPUT_POLLDEV + default n + help + This driver provides support for the LIS3LV02Dx accelerometer connected + via I2C. The accelerometer data is readable via + /sys/devices/platform/lis3lv02d. + + This driver also provides an absolute input class device, allowing + the device to act as a pinball machine-esque joystick. + + This driver can also be built as modules. If so, the core module + will be called lis3lv02d and a specific module for the I2C transport + is called lis3lv02d_i2c. + config SENSORS_APPLESMC tristate "Apple SMC (Motion sensor, light sensor, keyboard backlight)" depends on INPUT && X86 diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 33c2ee1..4131e25 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -55,6 +55,7 @@ obj-$(CONFIG_SENSORS_IT87) += it87.o obj-$(CONFIG_SENSORS_K8TEMP) += k8temp.o obj-$(CONFIG_SENSORS_LIS3LV02D) += lis3lv02d.o hp_accel.o obj-$(CONFIG_SENSORS_LIS3_SPI) += lis3lv02d.o lis3lv02d_spi.o +obj-$(CONFIG_SENSORS_LIS3_I2C) += lis3lv02d.o lis3lv02d_i2c.o obj-$(CONFIG_SENSORS_LM63) += lm63.o obj-$(CONFIG_SENSORS_LM70) += lm70.o obj-$(CONFIG_SENSORS_LM73) += lm73.o diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c new file mode 100644 index 0000000..dc1f540 --- /dev/null +++ b/drivers/hwmon/lis3lv02d_i2c.c @@ -0,0 +1,183 @@ +/* + * drivers/hwmon/lis3lv02d_i2c.c + * + * Implements I2C interface for lis3lv02d (STMicroelectronics) accelerometer. + * Driver is based on corresponding SPI driver written by Daniel Mack + * (lis3lv02d_spi.c (C) 2009 Daniel Mack ). + * + * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + * + * Contact: Samu Onkalo + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include "lis3lv02d.h" + +#define DRV_NAME "lis3lv02d_i2c" + +static inline s32 lis3_i2c_write(struct lis3lv02d *lis3, int reg, u8 value) +{ + struct i2c_client *c = lis3->bus_priv; + return i2c_smbus_write_byte_data(c, reg, value); +} + +static inline s32 lis3_i2c_read(struct lis3lv02d *lis3, int reg, u8 *v) +{ + struct i2c_client *c = lis3->bus_priv; + *v = i2c_smbus_read_byte_data(c, reg); + return 0; +} + +static int lis3_i2c_init(struct lis3lv02d *lis3) +{ + u8 reg; + int ret; + + /* power up the device */ + ret = lis3->read(lis3, CTRL_REG1, ®); + if (ret < 0) + return ret; + + reg |= CTRL1_PD0; + return lis3->write(lis3, CTRL_REG1, reg); +} + +/* Default axis mapping but it can be overwritten by platform data */ +static struct axis_conversion lis3lv02d_axis_map = { LIS3_DEV_X, + LIS3_DEV_Y, + LIS3_DEV_Z }; + +static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int ret = 0; + struct lis3lv02d_platform_data *pdata = client->dev.platform_data; + + if (pdata) { + if (pdata->axis_x) + lis3lv02d_axis_map.x = pdata->axis_x; + + if (pdata->axis_y) + lis3lv02d_axis_map.y = pdata->axis_y; + + if (pdata->axis_z) + lis3lv02d_axis_map.z = pdata->axis_z; + + if (pdata->setup_resources) + ret = pdata->setup_resources(); + + if (ret) + goto fail; + } + + lis3_dev.pdata = pdata; + lis3_dev.bus_priv = client; + lis3_dev.init = lis3_i2c_init; + lis3_dev.read = lis3_i2c_read; + lis3_dev.write = lis3_i2c_write; + lis3_dev.irq = client->irq; + lis3_dev.ac = lis3lv02d_axis_map; + + i2c_set_clientdata(client, &lis3_dev); + ret = lis3lv02d_init_device(&lis3_dev); +fail: + return ret; +} + +static int __devexit lis3lv02d_i2c_remove(struct i2c_client *client) +{ + struct lis3lv02d *lis3 = i2c_get_clientdata(client); + struct lis3lv02d_platform_data *pdata = client->dev.platform_data; + + if (pdata && pdata->release_resources) + pdata->release_resources(); + + lis3lv02d_joystick_disable(); + lis3lv02d_poweroff(lis3); + + return lis3lv02d_remove_fs(&lis3_dev); +} + +#ifdef CONFIG_PM +static int lis3lv02d_i2c_suspend(struct i2c_client *client, pm_message_t mesg) +{ + struct lis3lv02d *lis3 = i2c_get_clientdata(client); + + if (!lis3->pdata->wakeup_flags) + lis3lv02d_poweroff(lis3); + return 0; +} + +static int lis3lv02d_i2c_resume(struct i2c_client *client) +{ + struct lis3lv02d *lis3 = i2c_get_clientdata(client); + + if (!lis3->pdata->wakeup_flags) + lis3lv02d_poweron(lis3); + return 0; +} + +static void lis3lv02d_i2c_shutdown(struct i2c_client *client) +{ + lis3lv02d_i2c_suspend(client, PMSG_SUSPEND); +} +#else +#define lis3lv02d_i2c_suspend NULL +#define lis3lv02d_i2c_resume NULL +#define lis3lv02d_i2c_shutdown NULL +#endif + +static const struct i2c_device_id lis3lv02d_id[] = { + {"lis3lv02d", 0 }, + {} +}; + +MODULE_DEVICE_TABLE(i2c, lis3lv02d_id); + +static struct i2c_driver lis3lv02d_i2c_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + }, + .suspend = lis3lv02d_i2c_suspend, + .shutdown = lis3lv02d_i2c_shutdown, + .resume = lis3lv02d_i2c_resume, + .probe = lis3lv02d_i2c_probe, + .remove = __devexit_p(lis3lv02d_i2c_remove), + .id_table = lis3lv02d_id, +}; + +static int __init lis3lv02d_init(void) +{ + return i2c_add_driver(&lis3lv02d_i2c_driver); +} + +static void __exit lis3lv02d_exit(void) +{ + i2c_del_driver(&lis3lv02d_i2c_driver); +} + +MODULE_AUTHOR("Nokia Corporation"); +MODULE_DESCRIPTION("lis3lv02d I2C interface"); +MODULE_LICENSE("GPL"); + +module_init(lis3lv02d_init); +module_exit(lis3lv02d_exit); -- cgit v0.10.2 From 0f05058531330854ff383237e1547044c67e5740 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 17 Dec 2009 15:27:09 -0800 Subject: drivers/video/via/viafbdev.c: correct code taking the size of a pointer sizeof(viafb_gamma_table) is just the size of the pointer. This is changed to the size used when calling kmalloc to initialize the pointer. A simplified version of the semantic patch that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @@ expression *x; expression f; type T; @@ *f(...,(T)x,...) // Signed-off-by: Julia Lawall Acked-by: Florian Tobias Schandinat Cc: Joseph Chan Cc: Scott Fang Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c index 10d8c4b..d8df17a 100644 --- a/drivers/video/via/viafbdev.c +++ b/drivers/video/via/viafbdev.c @@ -680,7 +680,7 @@ static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg) if (!viafb_gamma_table) return -ENOMEM; if (copy_from_user(viafb_gamma_table, argp, - sizeof(viafb_gamma_table))) { + 256 * sizeof(u32))) { kfree(viafb_gamma_table); return -EFAULT; } @@ -694,7 +694,7 @@ static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg) return -ENOMEM; viafb_get_gamma_table(viafb_gamma_table); if (copy_to_user(argp, viafb_gamma_table, - sizeof(viafb_gamma_table))) { + 256 * sizeof(u32))) { kfree(viafb_gamma_table); return -EFAULT; } -- cgit v0.10.2 From 5d0bb2c4238e333ae18c5cd23f75e02a3dac3519 Mon Sep 17 00:00:00 2001 From: Bernhard Walle Date: Thu, 17 Dec 2009 15:27:11 -0800 Subject: vt: don't export vt_kmsg_redirect() to userspace Fix following warning in linux-next by guarding the function definition (both the "extern" and the inline) with #ifdef __KERNEL__. usr/include/linux/vt.h:89: userspace cannot call function or variable defined in the kernel Introduced by commit 5ada918b82399eef3afd6a71e3637697d6bd719f ("vt: introduce and use vt_kmsg_redirect() function"). Signed-off-by: Bernhard Walle Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/include/linux/vt.h b/include/linux/vt.h index 3fb9944..d5dd0bc 100644 --- a/include/linux/vt.h +++ b/include/linux/vt.h @@ -84,6 +84,8 @@ struct vt_setactivate { #define VT_SETACTIVATE 0x560F /* Activate and set the mode of a console */ +#ifdef __KERNEL__ + #ifdef CONFIG_VT_CONSOLE extern int vt_kmsg_redirect(int new); @@ -97,6 +99,8 @@ static inline int vt_kmsg_redirect(int new) #endif +#endif /* __KERNEL__ */ + #define vt_get_kmsg_redirect() vt_kmsg_redirect(-1) #endif /* _LINUX_VT_H */ -- cgit v0.10.2 From 8a79503aa83d0f889abc64a2fc0a020411837222 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Thu, 17 Dec 2009 15:27:12 -0800 Subject: lib/vsprintf.c: document more vsnprintf extensions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These were added in 9ac6e44 (lib/vsprintf.c: add %pU to print UUID/GUIDs) c7dabef (vsprintf: use %pR, %pr instead of %pRt, %pRf) 8a27f7c (lib/vsprintf.c: Add "%pI6c" - print pointer as compressed ipv6 address) 4aa9960 (printk: add %I4, %I6, %i4, %i6 format specifiers) dd45c9c (printk: add %pM format specifier for MAC addresses) but only added comments to pointer() not vsnprintf() that is refered to by printk's comments. Signed-off-by: Uwe Kleine-König Cc: Harvey Harrison Cc: David S. Miller Cc: Joe Perches Cc: Jens Rosenboom Cc: David S. Miller Cc: Bjorn Helgaas Cc: Jesse Barnes Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 735343f..d4996cf 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -1179,7 +1179,18 @@ qualifier: * %ps output the name of a text symbol without offset * %pF output the name of a function pointer with its offset * %pf output the name of a function pointer without its offset - * %pR output the address range in a struct resource + * %pR output the address range in a struct resource with decoded flags + * %pr output the address range in a struct resource with raw flags + * %pM output a 6-byte MAC address with colons + * %pm output a 6-byte MAC address without colons + * %pI4 print an IPv4 address without leading zeros + * %pi4 print an IPv4 address with leading zeros + * %pI6 print an IPv6 address with colons + * %pi6 print an IPv6 address without colons + * %pI6c print an IPv6 address as specified by + * http://www.ietf.org/id/draft-kawamura-ipv6-text-representation-03.txt + * %pU[bBlL] print a UUID/GUID in big or little endian using lower or upper + * case. * %n is ignored * * The return value is the number of characters which would -- cgit v0.10.2 From 0f67b0b0392ccca98459bf40b36c0037793b5f71 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Thu, 17 Dec 2009 15:27:14 -0800 Subject: nommu: ramfs: remove unused local var Signed-off-by: Mike Frysinger Cc: David Howells Acked-by: Greg Ungerer Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/fs/ramfs/file-nommu.c b/fs/ramfs/file-nommu.c index 32fae40..2efc571 100644 --- a/fs/ramfs/file-nommu.c +++ b/fs/ramfs/file-nommu.c @@ -60,7 +60,7 @@ const struct inode_operations ramfs_file_inode_operations = { */ int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize) { - unsigned long npages, xpages, loop, limit; + unsigned long npages, xpages, loop; struct page *pages; unsigned order; void *data; -- cgit v0.10.2 From 9cd80bbb07fcd6d4d037fad4297496d3b132ac6b Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Thu, 17 Dec 2009 15:27:15 -0800 Subject: do_wait() optimization: do not place sub-threads on task_struct->children list Thanks to Roland who pointed out de_thread() issues. Currently we add sub-threads to ->real_parent->children list. This buys nothing but slows down do_wait(). With this patch ->children contains only main threads (group leaders). The only complication is that forget_original_parent() should iterate over sub-threads by hand, and de_thread() needs another list_replace() when it changes ->group_leader. Henceforth do_wait_thread() can never see task_detached() && !EXIT_DEAD tasks, we can remove this check (and we can unify do_wait_thread() and ptrace_do_wait()). This change can confuse the optimistic search in mm_update_next_owner(), but this is fixable and minor. Perhaps badness() and oom_kill_process() should be updated, but they should be fixed in any case. Signed-off-by: Oleg Nesterov Cc: Roland McGrath Cc: Ingo Molnar Cc: Ratan Nalumasu Cc: Vitaly Mayatskikh Cc: David Rientjes Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/fs/exec.c b/fs/exec.c index 623a5cc..77db9a9 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -826,7 +826,9 @@ static int de_thread(struct task_struct *tsk) attach_pid(tsk, PIDTYPE_PID, task_pid(leader)); transfer_pid(leader, tsk, PIDTYPE_PGID); transfer_pid(leader, tsk, PIDTYPE_SID); + list_replace_rcu(&leader->tasks, &tsk->tasks); + list_replace_init(&leader->sibling, &tsk->sibling); tsk->group_leader = tsk; leader->group_leader = tsk; diff --git a/kernel/exit.c b/kernel/exit.c index 5962d7c..546774a 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -68,10 +68,10 @@ static void __unhash_process(struct task_struct *p) detach_pid(p, PIDTYPE_SID); list_del_rcu(&p->tasks); + list_del_init(&p->sibling); __get_cpu_var(process_counts)--; } list_del_rcu(&p->thread_group); - list_del_init(&p->sibling); } /* @@ -736,12 +736,9 @@ static struct task_struct *find_new_reaper(struct task_struct *father) /* * Any that need to be release_task'd are put on the @dead list. */ -static void reparent_thread(struct task_struct *father, struct task_struct *p, +static void reparent_leader(struct task_struct *father, struct task_struct *p, struct list_head *dead) { - if (p->pdeath_signal) - group_send_sig_info(p->pdeath_signal, SEND_SIG_NOINFO, p); - list_move_tail(&p->sibling, &p->real_parent->children); if (task_detached(p)) @@ -780,12 +777,18 @@ static void forget_original_parent(struct task_struct *father) reaper = find_new_reaper(father); list_for_each_entry_safe(p, n, &father->children, sibling) { - p->real_parent = reaper; - if (p->parent == father) { - BUG_ON(task_ptrace(p)); - p->parent = p->real_parent; - } - reparent_thread(father, p, &dead_children); + struct task_struct *t = p; + do { + t->real_parent = reaper; + if (t->parent == father) { + BUG_ON(task_ptrace(t)); + t->parent = t->real_parent; + } + if (t->pdeath_signal) + group_send_sig_info(t->pdeath_signal, + SEND_SIG_NOINFO, t); + } while_each_thread(p, t); + reparent_leader(father, p, &dead_children); } write_unlock_irq(&tasklist_lock); @@ -1551,14 +1554,9 @@ static int do_wait_thread(struct wait_opts *wo, struct task_struct *tsk) struct task_struct *p; list_for_each_entry(p, &tsk->children, sibling) { - /* - * Do not consider detached threads. - */ - if (!task_detached(p)) { - int ret = wait_consider_task(wo, 0, p); - if (ret) - return ret; - } + int ret = wait_consider_task(wo, 0, p); + if (ret) + return ret; } return 0; diff --git a/kernel/fork.c b/kernel/fork.c index 202a0ba..5b2959b 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1291,7 +1291,6 @@ static struct task_struct *copy_process(unsigned long clone_flags, } if (likely(p->pid)) { - list_add_tail(&p->sibling, &p->real_parent->children); tracehook_finish_clone(p, clone_flags, trace); if (thread_group_leader(p)) { @@ -1303,6 +1302,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, p->signal->tty = tty_kref_get(current->signal->tty); attach_pid(p, PIDTYPE_PGID, task_pgrp(current)); attach_pid(p, PIDTYPE_SID, task_session(current)); + list_add_tail(&p->sibling, &p->real_parent->children); list_add_tail_rcu(&p->tasks, &init_task.tasks); __get_cpu_var(process_counts)++; } -- cgit v0.10.2 From f6151dfea21496d43dbaba32cfcd9c9f404769bc Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Thu, 17 Dec 2009 15:27:16 -0800 Subject: mm: introduce coredump parameter structure Introduce coredump parameter data structure (struct coredump_params) to simplify binfmt->core_dump() arguments. Signed-off-by: Masami Hiramatsu Suggested-by: Ingo Molnar Cc: Hidehiro Kawai Cc: Oleg Nesterov Cc: Roland McGrath Cc: KOSAKI Motohiro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c index b639dcf..346b694 100644 --- a/fs/binfmt_aout.c +++ b/fs/binfmt_aout.c @@ -32,7 +32,7 @@ static int load_aout_binary(struct linux_binprm *, struct pt_regs * regs); static int load_aout_library(struct file*); -static int aout_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit); +static int aout_core_dump(struct coredump_params *cprm); static struct linux_binfmt aout_format = { .module = THIS_MODULE, @@ -89,8 +89,9 @@ if (file->f_op->llseek) { \ * dumping of the process results in another error.. */ -static int aout_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit) +static int aout_core_dump(struct coredump_params *cprm) { + struct file *file = cprm->file; mm_segment_t fs; int has_dumped = 0; unsigned long dump_start, dump_size; @@ -108,16 +109,16 @@ static int aout_core_dump(long signr, struct pt_regs *regs, struct file *file, u current->flags |= PF_DUMPCORE; strncpy(dump.u_comm, current->comm, sizeof(dump.u_comm)); dump.u_ar0 = offsetof(struct user, regs); - dump.signal = signr; - aout_dump_thread(regs, &dump); + dump.signal = cprm->signr; + aout_dump_thread(cprm->regs, &dump); /* If the size of the dump file exceeds the rlimit, then see what would happen if we wrote the stack, but not the data area. */ - if ((dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE > limit) + if ((dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE > cprm->limit) dump.u_dsize = 0; /* Make sure we have enough room to write the stack and data areas. */ - if ((dump.u_ssize + 1) * PAGE_SIZE > limit) + if ((dump.u_ssize + 1) * PAGE_SIZE > cprm->limit) dump.u_ssize = 0; /* make sure we actually have a data and stack area to dump */ diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 97b6e9e..edd90c4 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -45,7 +45,7 @@ static unsigned long elf_map(struct file *, unsigned long, struct elf_phdr *, * don't even try. */ #ifdef CONFIG_ELF_CORE -static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit); +static int elf_core_dump(struct coredump_params *cprm); #else #define elf_core_dump NULL #endif @@ -1272,8 +1272,9 @@ static int writenote(struct memelfnote *men, struct file *file, } #undef DUMP_WRITE -#define DUMP_WRITE(addr, nr) \ - if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \ +#define DUMP_WRITE(addr, nr) \ + if ((size += (nr)) > cprm->limit || \ + !dump_write(cprm->file, (addr), (nr))) \ goto end_coredump; static void fill_elf_header(struct elfhdr *elf, int segs, @@ -1901,7 +1902,7 @@ static struct vm_area_struct *next_vma(struct vm_area_struct *this_vma, * and then they are actually written out. If we run out of core limit * we just truncate. */ -static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit) +static int elf_core_dump(struct coredump_params *cprm) { int has_dumped = 0; mm_segment_t fs; @@ -1947,7 +1948,7 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file, un * notes. This also sets up the file header. */ if (!fill_note_info(elf, segs + 1, /* including notes section */ - &info, signr, regs)) + &info, cprm->signr, cprm->regs)) goto cleanup; has_dumped = 1; @@ -2009,14 +2010,14 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file, un #endif /* write out the notes section */ - if (!write_note_info(&info, file, &foffset)) + if (!write_note_info(&info, cprm->file, &foffset)) goto end_coredump; - if (elf_coredump_extra_notes_write(file, &foffset)) + if (elf_coredump_extra_notes_write(cprm->file, &foffset)) goto end_coredump; /* Align to page */ - if (!dump_seek(file, dataoff - foffset)) + if (!dump_seek(cprm->file, dataoff - foffset)) goto end_coredump; for (vma = first_vma(current, gate_vma); vma != NULL; @@ -2033,12 +2034,13 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file, un page = get_dump_page(addr); if (page) { void *kaddr = kmap(page); - stop = ((size += PAGE_SIZE) > limit) || - !dump_write(file, kaddr, PAGE_SIZE); + stop = ((size += PAGE_SIZE) > cprm->limit) || + !dump_write(cprm->file, kaddr, + PAGE_SIZE); kunmap(page); page_cache_release(page); } else - stop = !dump_seek(file, PAGE_SIZE); + stop = !dump_seek(cprm->file, PAGE_SIZE); if (stop) goto end_coredump; } diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index 7b05538..c25256a 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c @@ -76,7 +76,7 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *, struct file *, struct mm_struct *); #ifdef CONFIG_ELF_CORE -static int elf_fdpic_core_dump(long, struct pt_regs *, struct file *, unsigned long limit); +static int elf_fdpic_core_dump(struct coredump_params *cprm); #endif static struct linux_binfmt elf_fdpic_format = { @@ -1326,8 +1326,9 @@ static int writenote(struct memelfnote *men, struct file *file) #undef DUMP_WRITE #undef DUMP_SEEK -#define DUMP_WRITE(addr, nr) \ - if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \ +#define DUMP_WRITE(addr, nr) \ + if ((size += (nr)) > cprm->limit || \ + !dump_write(cprm->file, (addr), (nr))) \ goto end_coredump; static inline void fill_elf_fdpic_header(struct elfhdr *elf, int segs) @@ -1582,8 +1583,7 @@ static int elf_fdpic_dump_segments(struct file *file, size_t *size, * and then they are actually written out. If we run out of core limit * we just truncate. */ -static int elf_fdpic_core_dump(long signr, struct pt_regs *regs, - struct file *file, unsigned long limit) +static int elf_fdpic_core_dump(struct coredump_params *cprm) { #define NUM_NOTES 6 int has_dumped = 0; @@ -1642,7 +1642,7 @@ static int elf_fdpic_core_dump(long signr, struct pt_regs *regs, goto cleanup; #endif - if (signr) { + if (cprm->signr) { struct core_thread *ct; struct elf_thread_status *tmp; @@ -1661,14 +1661,14 @@ static int elf_fdpic_core_dump(long signr, struct pt_regs *regs, int sz; tmp = list_entry(t, struct elf_thread_status, list); - sz = elf_dump_thread_status(signr, tmp); + sz = elf_dump_thread_status(cprm->signr, tmp); thread_status_size += sz; } } /* now collect the dump for the current */ - fill_prstatus(prstatus, current, signr); - elf_core_copy_regs(&prstatus->pr_reg, regs); + fill_prstatus(prstatus, current, cprm->signr); + elf_core_copy_regs(&prstatus->pr_reg, cprm->regs); segs = current->mm->map_count; #ifdef ELF_CORE_EXTRA_PHDRS @@ -1703,7 +1703,7 @@ static int elf_fdpic_core_dump(long signr, struct pt_regs *regs, /* Try to dump the FPU. */ if ((prstatus->pr_fpvalid = - elf_core_copy_task_fpregs(current, regs, fpu))) + elf_core_copy_task_fpregs(current, cprm->regs, fpu))) fill_note(notes + numnote++, "CORE", NT_PRFPREG, sizeof(*fpu), fpu); #ifdef ELF_CORE_COPY_XFPREGS @@ -1774,7 +1774,7 @@ static int elf_fdpic_core_dump(long signr, struct pt_regs *regs, /* write out the notes section */ for (i = 0; i < numnote; i++) - if (!writenote(notes + i, file)) + if (!writenote(notes + i, cprm->file)) goto end_coredump; /* write out the thread status notes section */ @@ -1783,14 +1783,15 @@ static int elf_fdpic_core_dump(long signr, struct pt_regs *regs, list_entry(t, struct elf_thread_status, list); for (i = 0; i < tmp->num_notes; i++) - if (!writenote(&tmp->notes[i], file)) + if (!writenote(&tmp->notes[i], cprm->file)) goto end_coredump; } - if (!dump_seek(file, dataoff)) + if (!dump_seek(cprm->file, dataoff)) goto end_coredump; - if (elf_fdpic_dump_segments(file, &size, &limit, mm_flags) < 0) + if (elf_fdpic_dump_segments(cprm->file, &size, &cprm->limit, + mm_flags) < 0) goto end_coredump; #ifdef ELF_CORE_WRITE_EXTRA_DATA diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index a279665..d4a00ea 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c @@ -87,7 +87,7 @@ static int load_flat_shared_library(int id, struct lib_info *p); #endif static int load_flat_binary(struct linux_binprm *, struct pt_regs * regs); -static int flat_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit); +static int flat_core_dump(struct coredump_params *cprm); static struct linux_binfmt flat_format = { .module = THIS_MODULE, @@ -102,10 +102,10 @@ static struct linux_binfmt flat_format = { * Currently only a stub-function. */ -static int flat_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit) +static int flat_core_dump(struct coredump_params *cprm) { printk("Process %s:%d received signr %d and should have core dumped\n", - current->comm, current->pid, (int) signr); + current->comm, current->pid, (int) cprm->signr); return(1); } diff --git a/fs/binfmt_som.c b/fs/binfmt_som.c index eff74b9..2a9b533 100644 --- a/fs/binfmt_som.c +++ b/fs/binfmt_som.c @@ -43,7 +43,7 @@ static int load_som_library(struct file *); * don't even try. */ #if 0 -static int som_core_dump(long signr, struct pt_regs *regs, unsigned long limit); +static int som_core_dump(struct coredump_params *cprm); #else #define som_core_dump NULL #endif diff --git a/fs/exec.c b/fs/exec.c index 77db9a9..632b02e 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1763,17 +1763,20 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) struct mm_struct *mm = current->mm; struct linux_binfmt * binfmt; struct inode * inode; - struct file * file; const struct cred *old_cred; struct cred *cred; int retval = 0; int flag = 0; int ispipe = 0; - unsigned long core_limit = current->signal->rlim[RLIMIT_CORE].rlim_cur; char **helper_argv = NULL; int helper_argc = 0; int dump_count = 0; static atomic_t core_dump_count = ATOMIC_INIT(0); + struct coredump_params cprm = { + .signr = signr, + .regs = regs, + .limit = current->signal->rlim[RLIMIT_CORE].rlim_cur, + }; audit_core_dumps(signr); @@ -1829,15 +1832,15 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) ispipe = format_corename(corename, signr); unlock_kernel(); - if ((!ispipe) && (core_limit < binfmt->min_coredump)) + if ((!ispipe) && (cprm.limit < binfmt->min_coredump)) goto fail_unlock; if (ispipe) { - if (core_limit == 0) { + if (cprm.limit == 0) { /* * Normally core limits are irrelevant to pipes, since * we're not writing to the file system, but we use - * core_limit of 0 here as a speacial value. Any + * cprm.limit of 0 here as a speacial value. Any * non-zero limit gets set to RLIM_INFINITY below, but * a limit of 0 skips the dump. This is a consistent * way to catch recursive crashes. We can still crash @@ -1870,25 +1873,25 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) goto fail_dropcount; } - core_limit = RLIM_INFINITY; + cprm.limit = RLIM_INFINITY; /* SIGPIPE can happen, but it's just never processed */ if (call_usermodehelper_pipe(helper_argv[0], helper_argv, NULL, - &file)) { + &cprm.file)) { printk(KERN_INFO "Core dump to %s pipe failed\n", corename); goto fail_dropcount; } } else - file = filp_open(corename, + cprm.file = filp_open(corename, O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag, 0600); - if (IS_ERR(file)) + if (IS_ERR(cprm.file)) goto fail_dropcount; - inode = file->f_path.dentry->d_inode; + inode = cprm.file->f_path.dentry->d_inode; if (inode->i_nlink > 1) goto close_fail; /* multiple links - don't dump */ - if (!ispipe && d_unhashed(file->f_path.dentry)) + if (!ispipe && d_unhashed(cprm.file->f_path.dentry)) goto close_fail; /* AK: actually i see no reason to not allow this for named pipes etc., @@ -1901,21 +1904,22 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) */ if (inode->i_uid != current_fsuid()) goto close_fail; - if (!file->f_op) + if (!cprm.file->f_op) goto close_fail; - if (!file->f_op->write) + if (!cprm.file->f_op->write) goto close_fail; - if (!ispipe && do_truncate(file->f_path.dentry, 0, 0, file) != 0) + if (!ispipe && + do_truncate(cprm.file->f_path.dentry, 0, 0, cprm.file) != 0) goto close_fail; - retval = binfmt->core_dump(signr, regs, file, core_limit); + retval = binfmt->core_dump(&cprm); if (retval) current->signal->group_exit_code |= 0x80; close_fail: if (ispipe && core_pipe_limit) - wait_for_dump_helpers(file); - filp_close(file, NULL); + wait_for_dump_helpers(cprm.file); + filp_close(cprm.file, NULL); fail_dropcount: if (dump_count) atomic_dec(&core_dump_count); diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h index aece486..cd4349b 100644 --- a/include/linux/binfmts.h +++ b/include/linux/binfmts.h @@ -68,6 +68,14 @@ struct linux_binprm{ #define BINPRM_MAX_RECURSION 4 +/* Function parameter for binfmt->coredump */ +struct coredump_params { + long signr; + struct pt_regs *regs; + struct file *file; + unsigned long limit; +}; + /* * This structure defines the functions that are used to load the binary formats that * linux accepts. @@ -77,7 +85,7 @@ struct linux_binfmt { struct module *module; int (*load_binary)(struct linux_binprm *, struct pt_regs * regs); int (*load_shlib)(struct file *); - int (*core_dump)(long signr, struct pt_regs *regs, struct file *file, unsigned long limit); + int (*core_dump)(struct coredump_params *cprm); unsigned long min_coredump; /* minimal dump size */ int hasvdso; }; -- cgit v0.10.2 From 3d10a1ba0d37c8f5fd5afcdda00613fbb8a90bf5 Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Thu, 17 Dec 2009 15:27:17 -0800 Subject: sdio: fix reference counting in sdio_remove_func() sdio_remove_func() needs to be more careful about reference counting. It can be called in error paths where sdio_add_func() has never been called e.g. mmc_attach_sdio error path --> mmc_sdio_remove --> sdio_remove_func Signed-off-by: Daniel Drake Reviewed-by: Matt Fleming Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c index d37464e..9e060c8 100644 --- a/drivers/mmc/core/sdio_bus.c +++ b/drivers/mmc/core/sdio_bus.c @@ -248,12 +248,15 @@ int sdio_add_func(struct sdio_func *func) /* * Unregister a SDIO function with the driver model, and * (eventually) free it. + * This function can be called through error paths where sdio_add_func() was + * never executed (because a failure occurred at an earlier point). */ void sdio_remove_func(struct sdio_func *func) { - if (sdio_func_present(func)) - device_del(&func->dev); + if (!sdio_func_present(func)) + return; + device_del(&func->dev); put_device(&func->dev); } -- cgit v0.10.2 From e8812793637b4f23f01eb46db86b5dad1fc97f2a Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Thu, 17 Dec 2009 15:27:18 -0800 Subject: sdio: initialise SDIO functions and update card->sdio_funcs in lockstep Daniel Drake noticed a crash in the error path of mmc_attach_sdio(). This bug is discussed at http://dev.laptop.org/ticket/9707. BUG: unable to handle kernel paging request at 6b6b6c57 IP: [] sdio_remove_func+0x9/0x27 Call Trace: [] ? mmc_sdio_remove+0x34/0x65 [] ? mmc_attach_sdio+0x217/0x240 [] ? mmc_rescan+0x1a2/0x20f [] ? worker_thread+0x156/0x1e We need to accurately track how many SDIO functions have been initialised (and keep card->sdio_funcs in sync) so that we don't try to remove more functions than we initialised if we hit the error path in mmc_attach_sdio(). Without this patch if we hit the error path in mmc_attach_sdio() we run the risk of deferencing invalid memory in sdio_remove_func(), leading to a crash. Signed-off-by: Matt Fleming Cc: Daniel Drake Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index cdb845b..06b6408 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -516,7 +516,8 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr) * The number of functions on the card is encoded inside * the ocr. */ - card->sdio_funcs = funcs = (ocr & 0x70000000) >> 28; + funcs = (ocr & 0x70000000) >> 28; + card->sdio_funcs = 0; /* * If needed, disconnect card detection pull-up resistor. @@ -528,7 +529,7 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr) /* * Initialize (but don't add) all present functions. */ - for (i = 0;i < funcs;i++) { + for (i = 0; i < funcs; i++, card->sdio_funcs++) { err = sdio_init_func(host->card, i + 1); if (err) goto remove; -- cgit v0.10.2 From c0bba0d25ee13f4be4598730057a25758014d7f1 Mon Sep 17 00:00:00 2001 From: Albert Herranz Date: Thu, 17 Dec 2009 15:27:19 -0800 Subject: sdhci: protect header file against multi inclusion Signed-off-by: Albert Herranz Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index ce5f1d7..842f46f 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -8,6 +8,8 @@ * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. */ +#ifndef __SDHCI_H +#define __SDHCI_H #include #include @@ -408,3 +410,5 @@ extern void sdhci_remove_host(struct sdhci_host *host, int dead); extern int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state); extern int sdhci_resume_host(struct sdhci_host *host); #endif + +#endif /* __SDHCI_H */ -- cgit v0.10.2 From bc1ad567b16031a82b90e4ef86c1e7541957781f Mon Sep 17 00:00:00 2001 From: Albert Herranz Date: Thu, 17 Dec 2009 15:27:19 -0800 Subject: sdhci-of: rename main driver file prior to reorganization This patch renames sdhci-of.c to sdhci-of-core.c before reorganizing the driver to support additional hardware. The driver is still built as sdhci-of despite the rename of the file. No functional change. Signed-off-by: Albert Herranz Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index ded4d8cd..1efaaa4 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -13,7 +13,6 @@ obj-$(CONFIG_MMC_MXC) += mxcmmc.o obj-$(CONFIG_MMC_SDHCI) += sdhci.o obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o obj-$(CONFIG_MMC_RICOH_MMC) += ricoh_mmc.o -obj-$(CONFIG_MMC_SDHCI_OF) += sdhci-of.o obj-$(CONFIG_MMC_SDHCI_PLTFM) += sdhci-pltfm.o obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o obj-$(CONFIG_MMC_WBSD) += wbsd.o @@ -37,6 +36,9 @@ obj-$(CONFIG_MMC_CB710) += cb710-mmc.o obj-$(CONFIG_MMC_VIA_SDMMC) += via-sdmmc.o obj-$(CONFIG_SDH_BFIN) += bfin_sdh.o +obj-$(CONFIG_MMC_SDHCI_OF) += sdhci-of.o +sdhci-of-y := sdhci-of-core.o + ifeq ($(CONFIG_CB710_DEBUG),y) CFLAGS-cb710-mmc += -DDEBUG endif diff --git a/drivers/mmc/host/sdhci-of-core.c b/drivers/mmc/host/sdhci-of-core.c new file mode 100644 index 0000000..01ab916 --- /dev/null +++ b/drivers/mmc/host/sdhci-of-core.c @@ -0,0 +1,336 @@ +/* + * OpenFirmware bindings for Secure Digital Host Controller Interface. + * + * Copyright (c) 2007 Freescale Semiconductor, Inc. + * Copyright (c) 2009 MontaVista Software, Inc. + * + * Authors: Xiaobo Xie + * Anton Vorontsov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "sdhci.h" + +struct sdhci_of_data { + unsigned int quirks; + struct sdhci_ops ops; +}; + +struct sdhci_of_host { + unsigned int clock; + u16 xfer_mode_shadow; +}; + +/* + * Ops and quirks for the Freescale eSDHC controller. + */ + +#define ESDHC_DMA_SYSCTL 0x40c +#define ESDHC_DMA_SNOOP 0x00000040 + +#define ESDHC_SYSTEM_CONTROL 0x2c +#define ESDHC_CLOCK_MASK 0x0000fff0 +#define ESDHC_PREDIV_SHIFT 8 +#define ESDHC_DIVIDER_SHIFT 4 +#define ESDHC_CLOCK_PEREN 0x00000004 +#define ESDHC_CLOCK_HCKEN 0x00000002 +#define ESDHC_CLOCK_IPGEN 0x00000001 + +#define ESDHC_HOST_CONTROL_RES 0x05 + +static u32 esdhc_readl(struct sdhci_host *host, int reg) +{ + return in_be32(host->ioaddr + reg); +} + +static u16 esdhc_readw(struct sdhci_host *host, int reg) +{ + u16 ret; + + if (unlikely(reg == SDHCI_HOST_VERSION)) + ret = in_be16(host->ioaddr + reg); + else + ret = in_be16(host->ioaddr + (reg ^ 0x2)); + return ret; +} + +static u8 esdhc_readb(struct sdhci_host *host, int reg) +{ + return in_8(host->ioaddr + (reg ^ 0x3)); +} + +static void esdhc_writel(struct sdhci_host *host, u32 val, int reg) +{ + out_be32(host->ioaddr + reg, val); +} + +static void esdhc_writew(struct sdhci_host *host, u16 val, int reg) +{ + struct sdhci_of_host *of_host = sdhci_priv(host); + int base = reg & ~0x3; + int shift = (reg & 0x2) * 8; + + switch (reg) { + case SDHCI_TRANSFER_MODE: + /* + * Postpone this write, we must do it together with a + * command write that is down below. + */ + of_host->xfer_mode_shadow = val; + return; + case SDHCI_COMMAND: + esdhc_writel(host, val << 16 | of_host->xfer_mode_shadow, + SDHCI_TRANSFER_MODE); + return; + case SDHCI_BLOCK_SIZE: + /* + * Two last DMA bits are reserved, and first one is used for + * non-standard blksz of 4096 bytes that we don't support + * yet. So clear the DMA boundary bits. + */ + val &= ~SDHCI_MAKE_BLKSZ(0x7, 0); + /* fall through */ + } + clrsetbits_be32(host->ioaddr + base, 0xffff << shift, val << shift); +} + +static void esdhc_writeb(struct sdhci_host *host, u8 val, int reg) +{ + int base = reg & ~0x3; + int shift = (reg & 0x3) * 8; + + /* Prevent SDHCI core from writing reserved bits (e.g. HISPD). */ + if (reg == SDHCI_HOST_CONTROL) + val &= ~ESDHC_HOST_CONTROL_RES; + + clrsetbits_be32(host->ioaddr + base , 0xff << shift, val << shift); +} + +static void esdhc_set_clock(struct sdhci_host *host, unsigned int clock) +{ + int pre_div = 2; + int div = 1; + + clrbits32(host->ioaddr + ESDHC_SYSTEM_CONTROL, ESDHC_CLOCK_IPGEN | + ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN | ESDHC_CLOCK_MASK); + + if (clock == 0) + goto out; + + while (host->max_clk / pre_div / 16 > clock && pre_div < 256) + pre_div *= 2; + + while (host->max_clk / pre_div / div > clock && div < 16) + div++; + + dev_dbg(mmc_dev(host->mmc), "desired SD clock: %d, actual: %d\n", + clock, host->max_clk / pre_div / div); + + pre_div >>= 1; + div--; + + setbits32(host->ioaddr + ESDHC_SYSTEM_CONTROL, ESDHC_CLOCK_IPGEN | + ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN | + div << ESDHC_DIVIDER_SHIFT | pre_div << ESDHC_PREDIV_SHIFT); + mdelay(100); +out: + host->clock = clock; +} + +static int esdhc_enable_dma(struct sdhci_host *host) +{ + setbits32(host->ioaddr + ESDHC_DMA_SYSCTL, ESDHC_DMA_SNOOP); + return 0; +} + +static unsigned int esdhc_get_max_clock(struct sdhci_host *host) +{ + struct sdhci_of_host *of_host = sdhci_priv(host); + + return of_host->clock; +} + +static unsigned int esdhc_get_min_clock(struct sdhci_host *host) +{ + struct sdhci_of_host *of_host = sdhci_priv(host); + + return of_host->clock / 256 / 16; +} + +static struct sdhci_of_data sdhci_esdhc = { + .quirks = SDHCI_QUIRK_FORCE_BLK_SZ_2048 | + SDHCI_QUIRK_BROKEN_CARD_DETECTION | + SDHCI_QUIRK_NO_BUSY_IRQ | + SDHCI_QUIRK_NONSTANDARD_CLOCK | + SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | + SDHCI_QUIRK_PIO_NEEDS_DELAY | + SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET | + SDHCI_QUIRK_NO_CARD_NO_RESET, + .ops = { + .readl = esdhc_readl, + .readw = esdhc_readw, + .readb = esdhc_readb, + .writel = esdhc_writel, + .writew = esdhc_writew, + .writeb = esdhc_writeb, + .set_clock = esdhc_set_clock, + .enable_dma = esdhc_enable_dma, + .get_max_clock = esdhc_get_max_clock, + .get_min_clock = esdhc_get_min_clock, + }, +}; + +#ifdef CONFIG_PM + +static int sdhci_of_suspend(struct of_device *ofdev, pm_message_t state) +{ + struct sdhci_host *host = dev_get_drvdata(&ofdev->dev); + + return mmc_suspend_host(host->mmc, state); +} + +static int sdhci_of_resume(struct of_device *ofdev) +{ + struct sdhci_host *host = dev_get_drvdata(&ofdev->dev); + + return mmc_resume_host(host->mmc); +} + +#else + +#define sdhci_of_suspend NULL +#define sdhci_of_resume NULL + +#endif + +static bool __devinit sdhci_of_wp_inverted(struct device_node *np) +{ + if (of_get_property(np, "sdhci,wp-inverted", NULL)) + return true; + + /* Old device trees don't have the wp-inverted property. */ + return machine_is(mpc837x_rdb) || machine_is(mpc837x_mds); +} + +static int __devinit sdhci_of_probe(struct of_device *ofdev, + const struct of_device_id *match) +{ + struct device_node *np = ofdev->node; + struct sdhci_of_data *sdhci_of_data = match->data; + struct sdhci_host *host; + struct sdhci_of_host *of_host; + const u32 *clk; + int size; + int ret; + + if (!of_device_is_available(np)) + return -ENODEV; + + host = sdhci_alloc_host(&ofdev->dev, sizeof(*of_host)); + if (IS_ERR(host)) + return -ENOMEM; + + of_host = sdhci_priv(host); + dev_set_drvdata(&ofdev->dev, host); + + host->ioaddr = of_iomap(np, 0); + if (!host->ioaddr) { + ret = -ENOMEM; + goto err_addr_map; + } + + host->irq = irq_of_parse_and_map(np, 0); + if (!host->irq) { + ret = -EINVAL; + goto err_no_irq; + } + + host->hw_name = dev_name(&ofdev->dev); + if (sdhci_of_data) { + host->quirks = sdhci_of_data->quirks; + host->ops = &sdhci_of_data->ops; + } + + if (of_get_property(np, "sdhci,1-bit-only", NULL)) + host->quirks |= SDHCI_QUIRK_FORCE_1_BIT_DATA; + + if (sdhci_of_wp_inverted(np)) + host->quirks |= SDHCI_QUIRK_INVERTED_WRITE_PROTECT; + + clk = of_get_property(np, "clock-frequency", &size); + if (clk && size == sizeof(*clk) && *clk) + of_host->clock = *clk; + + ret = sdhci_add_host(host); + if (ret) + goto err_add_host; + + return 0; + +err_add_host: + irq_dispose_mapping(host->irq); +err_no_irq: + iounmap(host->ioaddr); +err_addr_map: + sdhci_free_host(host); + return ret; +} + +static int __devexit sdhci_of_remove(struct of_device *ofdev) +{ + struct sdhci_host *host = dev_get_drvdata(&ofdev->dev); + + sdhci_remove_host(host, 0); + sdhci_free_host(host); + irq_dispose_mapping(host->irq); + iounmap(host->ioaddr); + return 0; +} + +static const struct of_device_id sdhci_of_match[] = { + { .compatible = "fsl,mpc8379-esdhc", .data = &sdhci_esdhc, }, + { .compatible = "fsl,mpc8536-esdhc", .data = &sdhci_esdhc, }, + { .compatible = "fsl,esdhc", .data = &sdhci_esdhc, }, + { .compatible = "generic-sdhci", }, + {}, +}; +MODULE_DEVICE_TABLE(of, sdhci_of_match); + +static struct of_platform_driver sdhci_of_driver = { + .driver.name = "sdhci-of", + .match_table = sdhci_of_match, + .probe = sdhci_of_probe, + .remove = __devexit_p(sdhci_of_remove), + .suspend = sdhci_of_suspend, + .resume = sdhci_of_resume, +}; + +static int __init sdhci_of_init(void) +{ + return of_register_platform_driver(&sdhci_of_driver); +} +module_init(sdhci_of_init); + +static void __exit sdhci_of_exit(void) +{ + of_unregister_platform_driver(&sdhci_of_driver); +} +module_exit(sdhci_of_exit); + +MODULE_DESCRIPTION("Secure Digital Host Controller Interface OF driver"); +MODULE_AUTHOR("Xiaobo Xie , " + "Anton Vorontsov "); +MODULE_LICENSE("GPL"); diff --git a/drivers/mmc/host/sdhci-of.c b/drivers/mmc/host/sdhci-of.c deleted file mode 100644 index 01ab916..0000000 --- a/drivers/mmc/host/sdhci-of.c +++ /dev/null @@ -1,336 +0,0 @@ -/* - * OpenFirmware bindings for Secure Digital Host Controller Interface. - * - * Copyright (c) 2007 Freescale Semiconductor, Inc. - * Copyright (c) 2009 MontaVista Software, Inc. - * - * Authors: Xiaobo Xie - * Anton Vorontsov - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "sdhci.h" - -struct sdhci_of_data { - unsigned int quirks; - struct sdhci_ops ops; -}; - -struct sdhci_of_host { - unsigned int clock; - u16 xfer_mode_shadow; -}; - -/* - * Ops and quirks for the Freescale eSDHC controller. - */ - -#define ESDHC_DMA_SYSCTL 0x40c -#define ESDHC_DMA_SNOOP 0x00000040 - -#define ESDHC_SYSTEM_CONTROL 0x2c -#define ESDHC_CLOCK_MASK 0x0000fff0 -#define ESDHC_PREDIV_SHIFT 8 -#define ESDHC_DIVIDER_SHIFT 4 -#define ESDHC_CLOCK_PEREN 0x00000004 -#define ESDHC_CLOCK_HCKEN 0x00000002 -#define ESDHC_CLOCK_IPGEN 0x00000001 - -#define ESDHC_HOST_CONTROL_RES 0x05 - -static u32 esdhc_readl(struct sdhci_host *host, int reg) -{ - return in_be32(host->ioaddr + reg); -} - -static u16 esdhc_readw(struct sdhci_host *host, int reg) -{ - u16 ret; - - if (unlikely(reg == SDHCI_HOST_VERSION)) - ret = in_be16(host->ioaddr + reg); - else - ret = in_be16(host->ioaddr + (reg ^ 0x2)); - return ret; -} - -static u8 esdhc_readb(struct sdhci_host *host, int reg) -{ - return in_8(host->ioaddr + (reg ^ 0x3)); -} - -static void esdhc_writel(struct sdhci_host *host, u32 val, int reg) -{ - out_be32(host->ioaddr + reg, val); -} - -static void esdhc_writew(struct sdhci_host *host, u16 val, int reg) -{ - struct sdhci_of_host *of_host = sdhci_priv(host); - int base = reg & ~0x3; - int shift = (reg & 0x2) * 8; - - switch (reg) { - case SDHCI_TRANSFER_MODE: - /* - * Postpone this write, we must do it together with a - * command write that is down below. - */ - of_host->xfer_mode_shadow = val; - return; - case SDHCI_COMMAND: - esdhc_writel(host, val << 16 | of_host->xfer_mode_shadow, - SDHCI_TRANSFER_MODE); - return; - case SDHCI_BLOCK_SIZE: - /* - * Two last DMA bits are reserved, and first one is used for - * non-standard blksz of 4096 bytes that we don't support - * yet. So clear the DMA boundary bits. - */ - val &= ~SDHCI_MAKE_BLKSZ(0x7, 0); - /* fall through */ - } - clrsetbits_be32(host->ioaddr + base, 0xffff << shift, val << shift); -} - -static void esdhc_writeb(struct sdhci_host *host, u8 val, int reg) -{ - int base = reg & ~0x3; - int shift = (reg & 0x3) * 8; - - /* Prevent SDHCI core from writing reserved bits (e.g. HISPD). */ - if (reg == SDHCI_HOST_CONTROL) - val &= ~ESDHC_HOST_CONTROL_RES; - - clrsetbits_be32(host->ioaddr + base , 0xff << shift, val << shift); -} - -static void esdhc_set_clock(struct sdhci_host *host, unsigned int clock) -{ - int pre_div = 2; - int div = 1; - - clrbits32(host->ioaddr + ESDHC_SYSTEM_CONTROL, ESDHC_CLOCK_IPGEN | - ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN | ESDHC_CLOCK_MASK); - - if (clock == 0) - goto out; - - while (host->max_clk / pre_div / 16 > clock && pre_div < 256) - pre_div *= 2; - - while (host->max_clk / pre_div / div > clock && div < 16) - div++; - - dev_dbg(mmc_dev(host->mmc), "desired SD clock: %d, actual: %d\n", - clock, host->max_clk / pre_div / div); - - pre_div >>= 1; - div--; - - setbits32(host->ioaddr + ESDHC_SYSTEM_CONTROL, ESDHC_CLOCK_IPGEN | - ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN | - div << ESDHC_DIVIDER_SHIFT | pre_div << ESDHC_PREDIV_SHIFT); - mdelay(100); -out: - host->clock = clock; -} - -static int esdhc_enable_dma(struct sdhci_host *host) -{ - setbits32(host->ioaddr + ESDHC_DMA_SYSCTL, ESDHC_DMA_SNOOP); - return 0; -} - -static unsigned int esdhc_get_max_clock(struct sdhci_host *host) -{ - struct sdhci_of_host *of_host = sdhci_priv(host); - - return of_host->clock; -} - -static unsigned int esdhc_get_min_clock(struct sdhci_host *host) -{ - struct sdhci_of_host *of_host = sdhci_priv(host); - - return of_host->clock / 256 / 16; -} - -static struct sdhci_of_data sdhci_esdhc = { - .quirks = SDHCI_QUIRK_FORCE_BLK_SZ_2048 | - SDHCI_QUIRK_BROKEN_CARD_DETECTION | - SDHCI_QUIRK_NO_BUSY_IRQ | - SDHCI_QUIRK_NONSTANDARD_CLOCK | - SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | - SDHCI_QUIRK_PIO_NEEDS_DELAY | - SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET | - SDHCI_QUIRK_NO_CARD_NO_RESET, - .ops = { - .readl = esdhc_readl, - .readw = esdhc_readw, - .readb = esdhc_readb, - .writel = esdhc_writel, - .writew = esdhc_writew, - .writeb = esdhc_writeb, - .set_clock = esdhc_set_clock, - .enable_dma = esdhc_enable_dma, - .get_max_clock = esdhc_get_max_clock, - .get_min_clock = esdhc_get_min_clock, - }, -}; - -#ifdef CONFIG_PM - -static int sdhci_of_suspend(struct of_device *ofdev, pm_message_t state) -{ - struct sdhci_host *host = dev_get_drvdata(&ofdev->dev); - - return mmc_suspend_host(host->mmc, state); -} - -static int sdhci_of_resume(struct of_device *ofdev) -{ - struct sdhci_host *host = dev_get_drvdata(&ofdev->dev); - - return mmc_resume_host(host->mmc); -} - -#else - -#define sdhci_of_suspend NULL -#define sdhci_of_resume NULL - -#endif - -static bool __devinit sdhci_of_wp_inverted(struct device_node *np) -{ - if (of_get_property(np, "sdhci,wp-inverted", NULL)) - return true; - - /* Old device trees don't have the wp-inverted property. */ - return machine_is(mpc837x_rdb) || machine_is(mpc837x_mds); -} - -static int __devinit sdhci_of_probe(struct of_device *ofdev, - const struct of_device_id *match) -{ - struct device_node *np = ofdev->node; - struct sdhci_of_data *sdhci_of_data = match->data; - struct sdhci_host *host; - struct sdhci_of_host *of_host; - const u32 *clk; - int size; - int ret; - - if (!of_device_is_available(np)) - return -ENODEV; - - host = sdhci_alloc_host(&ofdev->dev, sizeof(*of_host)); - if (IS_ERR(host)) - return -ENOMEM; - - of_host = sdhci_priv(host); - dev_set_drvdata(&ofdev->dev, host); - - host->ioaddr = of_iomap(np, 0); - if (!host->ioaddr) { - ret = -ENOMEM; - goto err_addr_map; - } - - host->irq = irq_of_parse_and_map(np, 0); - if (!host->irq) { - ret = -EINVAL; - goto err_no_irq; - } - - host->hw_name = dev_name(&ofdev->dev); - if (sdhci_of_data) { - host->quirks = sdhci_of_data->quirks; - host->ops = &sdhci_of_data->ops; - } - - if (of_get_property(np, "sdhci,1-bit-only", NULL)) - host->quirks |= SDHCI_QUIRK_FORCE_1_BIT_DATA; - - if (sdhci_of_wp_inverted(np)) - host->quirks |= SDHCI_QUIRK_INVERTED_WRITE_PROTECT; - - clk = of_get_property(np, "clock-frequency", &size); - if (clk && size == sizeof(*clk) && *clk) - of_host->clock = *clk; - - ret = sdhci_add_host(host); - if (ret) - goto err_add_host; - - return 0; - -err_add_host: - irq_dispose_mapping(host->irq); -err_no_irq: - iounmap(host->ioaddr); -err_addr_map: - sdhci_free_host(host); - return ret; -} - -static int __devexit sdhci_of_remove(struct of_device *ofdev) -{ - struct sdhci_host *host = dev_get_drvdata(&ofdev->dev); - - sdhci_remove_host(host, 0); - sdhci_free_host(host); - irq_dispose_mapping(host->irq); - iounmap(host->ioaddr); - return 0; -} - -static const struct of_device_id sdhci_of_match[] = { - { .compatible = "fsl,mpc8379-esdhc", .data = &sdhci_esdhc, }, - { .compatible = "fsl,mpc8536-esdhc", .data = &sdhci_esdhc, }, - { .compatible = "fsl,esdhc", .data = &sdhci_esdhc, }, - { .compatible = "generic-sdhci", }, - {}, -}; -MODULE_DEVICE_TABLE(of, sdhci_of_match); - -static struct of_platform_driver sdhci_of_driver = { - .driver.name = "sdhci-of", - .match_table = sdhci_of_match, - .probe = sdhci_of_probe, - .remove = __devexit_p(sdhci_of_remove), - .suspend = sdhci_of_suspend, - .resume = sdhci_of_resume, -}; - -static int __init sdhci_of_init(void) -{ - return of_register_platform_driver(&sdhci_of_driver); -} -module_init(sdhci_of_init); - -static void __exit sdhci_of_exit(void) -{ - of_unregister_platform_driver(&sdhci_of_driver); -} -module_exit(sdhci_of_exit); - -MODULE_DESCRIPTION("Secure Digital Host Controller Interface OF driver"); -MODULE_AUTHOR("Xiaobo Xie , " - "Anton Vorontsov "); -MODULE_LICENSE("GPL"); -- cgit v0.10.2 From 7657c3a7d4bd42b832af5d6bb0e0e9bdba82d44d Mon Sep 17 00:00:00 2001 From: Albert Herranz Date: Thu, 17 Dec 2009 15:27:20 -0800 Subject: sdhci-of: reorganize driver to support additional hardware This patch breaks down sdhci-of into a core portion and a eSDHC portion, clearing the path to easily support additional hardware using the same OF driver. Signed-off-by: Albert Herranz Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 9d405b1..d923464 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -44,6 +44,19 @@ config MMC_SDHCI_IO_ACCESSORS This is silent Kconfig symbol that is selected by the drivers that need to overwrite SDHCI IO memory accessors. +config MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER + bool + select MMC_SDHCI_IO_ACCESSORS + help + This option is selected by drivers running on big endian hosts + and performing I/O to a SDHCI controller through a bus that + implements a hardware byte swapper using a 32-bit datum. + This endian mapping mode is called "data invariance" and + has the effect of scrambling the addresses and formats of data + accessed in sizes other than the datum size. + + This is the case for the Freescale eSDHC. + config MMC_SDHCI_PCI tristate "SDHCI support on PCI bus" depends on MMC_SDHCI && PCI @@ -75,11 +88,18 @@ config MMC_RICOH_MMC config MMC_SDHCI_OF tristate "SDHCI support on OpenFirmware platforms" depends on MMC_SDHCI && PPC_OF - select MMC_SDHCI_IO_ACCESSORS help This selects the OF support for Secure Digital Host Controller - Interfaces. So far, only the Freescale eSDHC controller is known - to exist on OF platforms. + Interfaces. + + If unsure, say N. + +config MMC_SDHCI_OF_ESDHC + bool "SDHCI OF support for the Freescale eSDHC controller" + depends on MMC_SDHCI_OF + select MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER + help + This selects the Freescale eSDHC controller support. If unsure, say N. diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index 1efaaa4..cbda9b2 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -38,6 +38,7 @@ obj-$(CONFIG_SDH_BFIN) += bfin_sdh.o obj-$(CONFIG_MMC_SDHCI_OF) += sdhci-of.o sdhci-of-y := sdhci-of-core.o +sdhci-of-$(CONFIG_MMC_SDHCI_OF_ESDHC) += sdhci-of-esdhc.o ifeq ($(CONFIG_CB710_DEBUG),y) CFLAGS-cb710-mmc += -DDEBUG diff --git a/drivers/mmc/host/sdhci-of-core.c b/drivers/mmc/host/sdhci-of-core.c index 01ab916..add2008 100644 --- a/drivers/mmc/host/sdhci-of-core.c +++ b/drivers/mmc/host/sdhci-of-core.c @@ -22,62 +22,37 @@ #include #include #include +#include "sdhci-of.h" #include "sdhci.h" -struct sdhci_of_data { - unsigned int quirks; - struct sdhci_ops ops; -}; - -struct sdhci_of_host { - unsigned int clock; - u16 xfer_mode_shadow; -}; +#ifdef CONFIG_MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER /* - * Ops and quirks for the Freescale eSDHC controller. + * These accessors are designed for big endian hosts doing I/O to + * little endian controllers incorporating a 32-bit hardware byte swapper. */ -#define ESDHC_DMA_SYSCTL 0x40c -#define ESDHC_DMA_SNOOP 0x00000040 - -#define ESDHC_SYSTEM_CONTROL 0x2c -#define ESDHC_CLOCK_MASK 0x0000fff0 -#define ESDHC_PREDIV_SHIFT 8 -#define ESDHC_DIVIDER_SHIFT 4 -#define ESDHC_CLOCK_PEREN 0x00000004 -#define ESDHC_CLOCK_HCKEN 0x00000002 -#define ESDHC_CLOCK_IPGEN 0x00000001 - -#define ESDHC_HOST_CONTROL_RES 0x05 - -static u32 esdhc_readl(struct sdhci_host *host, int reg) +u32 sdhci_be32bs_readl(struct sdhci_host *host, int reg) { return in_be32(host->ioaddr + reg); } -static u16 esdhc_readw(struct sdhci_host *host, int reg) +u16 sdhci_be32bs_readw(struct sdhci_host *host, int reg) { - u16 ret; - - if (unlikely(reg == SDHCI_HOST_VERSION)) - ret = in_be16(host->ioaddr + reg); - else - ret = in_be16(host->ioaddr + (reg ^ 0x2)); - return ret; + return in_be16(host->ioaddr + (reg ^ 0x2)); } -static u8 esdhc_readb(struct sdhci_host *host, int reg) +u8 sdhci_be32bs_readb(struct sdhci_host *host, int reg) { return in_8(host->ioaddr + (reg ^ 0x3)); } -static void esdhc_writel(struct sdhci_host *host, u32 val, int reg) +void sdhci_be32bs_writel(struct sdhci_host *host, u32 val, int reg) { out_be32(host->ioaddr + reg, val); } -static void esdhc_writew(struct sdhci_host *host, u16 val, int reg) +void sdhci_be32bs_writew(struct sdhci_host *host, u16 val, int reg) { struct sdhci_of_host *of_host = sdhci_priv(host); int base = reg & ~0x3; @@ -92,106 +67,21 @@ static void esdhc_writew(struct sdhci_host *host, u16 val, int reg) of_host->xfer_mode_shadow = val; return; case SDHCI_COMMAND: - esdhc_writel(host, val << 16 | of_host->xfer_mode_shadow, - SDHCI_TRANSFER_MODE); + sdhci_be32bs_writel(host, val << 16 | of_host->xfer_mode_shadow, + SDHCI_TRANSFER_MODE); return; - case SDHCI_BLOCK_SIZE: - /* - * Two last DMA bits are reserved, and first one is used for - * non-standard blksz of 4096 bytes that we don't support - * yet. So clear the DMA boundary bits. - */ - val &= ~SDHCI_MAKE_BLKSZ(0x7, 0); - /* fall through */ } clrsetbits_be32(host->ioaddr + base, 0xffff << shift, val << shift); } -static void esdhc_writeb(struct sdhci_host *host, u8 val, int reg) +void sdhci_be32bs_writeb(struct sdhci_host *host, u8 val, int reg) { int base = reg & ~0x3; int shift = (reg & 0x3) * 8; - /* Prevent SDHCI core from writing reserved bits (e.g. HISPD). */ - if (reg == SDHCI_HOST_CONTROL) - val &= ~ESDHC_HOST_CONTROL_RES; - clrsetbits_be32(host->ioaddr + base , 0xff << shift, val << shift); } - -static void esdhc_set_clock(struct sdhci_host *host, unsigned int clock) -{ - int pre_div = 2; - int div = 1; - - clrbits32(host->ioaddr + ESDHC_SYSTEM_CONTROL, ESDHC_CLOCK_IPGEN | - ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN | ESDHC_CLOCK_MASK); - - if (clock == 0) - goto out; - - while (host->max_clk / pre_div / 16 > clock && pre_div < 256) - pre_div *= 2; - - while (host->max_clk / pre_div / div > clock && div < 16) - div++; - - dev_dbg(mmc_dev(host->mmc), "desired SD clock: %d, actual: %d\n", - clock, host->max_clk / pre_div / div); - - pre_div >>= 1; - div--; - - setbits32(host->ioaddr + ESDHC_SYSTEM_CONTROL, ESDHC_CLOCK_IPGEN | - ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN | - div << ESDHC_DIVIDER_SHIFT | pre_div << ESDHC_PREDIV_SHIFT); - mdelay(100); -out: - host->clock = clock; -} - -static int esdhc_enable_dma(struct sdhci_host *host) -{ - setbits32(host->ioaddr + ESDHC_DMA_SYSCTL, ESDHC_DMA_SNOOP); - return 0; -} - -static unsigned int esdhc_get_max_clock(struct sdhci_host *host) -{ - struct sdhci_of_host *of_host = sdhci_priv(host); - - return of_host->clock; -} - -static unsigned int esdhc_get_min_clock(struct sdhci_host *host) -{ - struct sdhci_of_host *of_host = sdhci_priv(host); - - return of_host->clock / 256 / 16; -} - -static struct sdhci_of_data sdhci_esdhc = { - .quirks = SDHCI_QUIRK_FORCE_BLK_SZ_2048 | - SDHCI_QUIRK_BROKEN_CARD_DETECTION | - SDHCI_QUIRK_NO_BUSY_IRQ | - SDHCI_QUIRK_NONSTANDARD_CLOCK | - SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | - SDHCI_QUIRK_PIO_NEEDS_DELAY | - SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET | - SDHCI_QUIRK_NO_CARD_NO_RESET, - .ops = { - .readl = esdhc_readl, - .readw = esdhc_readw, - .readb = esdhc_readb, - .writel = esdhc_writel, - .writew = esdhc_writew, - .writeb = esdhc_writeb, - .set_clock = esdhc_set_clock, - .enable_dma = esdhc_enable_dma, - .get_max_clock = esdhc_get_max_clock, - .get_min_clock = esdhc_get_min_clock, - }, -}; +#endif /* CONFIG_MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER */ #ifdef CONFIG_PM @@ -301,9 +191,11 @@ static int __devexit sdhci_of_remove(struct of_device *ofdev) } static const struct of_device_id sdhci_of_match[] = { +#ifdef CONFIG_MMC_SDHCI_OF_ESDHC { .compatible = "fsl,mpc8379-esdhc", .data = &sdhci_esdhc, }, { .compatible = "fsl,mpc8536-esdhc", .data = &sdhci_esdhc, }, { .compatible = "fsl,esdhc", .data = &sdhci_esdhc, }, +#endif { .compatible = "generic-sdhci", }, {}, }; diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c new file mode 100644 index 0000000..d5b11a1 --- /dev/null +++ b/drivers/mmc/host/sdhci-of-esdhc.c @@ -0,0 +1,143 @@ +/* + * Freescale eSDHC controller driver. + * + * Copyright (c) 2007 Freescale Semiconductor, Inc. + * Copyright (c) 2009 MontaVista Software, Inc. + * + * Authors: Xiaobo Xie + * Anton Vorontsov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + */ + +#include +#include +#include +#include "sdhci-of.h" +#include "sdhci.h" + +/* + * Ops and quirks for the Freescale eSDHC controller. + */ + +#define ESDHC_DMA_SYSCTL 0x40c +#define ESDHC_DMA_SNOOP 0x00000040 + +#define ESDHC_SYSTEM_CONTROL 0x2c +#define ESDHC_CLOCK_MASK 0x0000fff0 +#define ESDHC_PREDIV_SHIFT 8 +#define ESDHC_DIVIDER_SHIFT 4 +#define ESDHC_CLOCK_PEREN 0x00000004 +#define ESDHC_CLOCK_HCKEN 0x00000002 +#define ESDHC_CLOCK_IPGEN 0x00000001 + +#define ESDHC_HOST_CONTROL_RES 0x05 + +static u16 esdhc_readw(struct sdhci_host *host, int reg) +{ + u16 ret; + + if (unlikely(reg == SDHCI_HOST_VERSION)) + ret = in_be16(host->ioaddr + reg); + else + ret = sdhci_be32bs_readw(host, reg); + return ret; +} + +static void esdhc_writew(struct sdhci_host *host, u16 val, int reg) +{ + if (reg == SDHCI_BLOCK_SIZE) { + /* + * Two last DMA bits are reserved, and first one is used for + * non-standard blksz of 4096 bytes that we don't support + * yet. So clear the DMA boundary bits. + */ + val &= ~SDHCI_MAKE_BLKSZ(0x7, 0); + } + sdhci_be32bs_writew(host, val, reg); +} + +static void esdhc_writeb(struct sdhci_host *host, u8 val, int reg) +{ + /* Prevent SDHCI core from writing reserved bits (e.g. HISPD). */ + if (reg == SDHCI_HOST_CONTROL) + val &= ~ESDHC_HOST_CONTROL_RES; + sdhci_be32bs_writeb(host, val, reg); +} + +static void esdhc_set_clock(struct sdhci_host *host, unsigned int clock) +{ + int pre_div = 2; + int div = 1; + + clrbits32(host->ioaddr + ESDHC_SYSTEM_CONTROL, ESDHC_CLOCK_IPGEN | + ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN | ESDHC_CLOCK_MASK); + + if (clock == 0) + goto out; + + while (host->max_clk / pre_div / 16 > clock && pre_div < 256) + pre_div *= 2; + + while (host->max_clk / pre_div / div > clock && div < 16) + div++; + + dev_dbg(mmc_dev(host->mmc), "desired SD clock: %d, actual: %d\n", + clock, host->max_clk / pre_div / div); + + pre_div >>= 1; + div--; + + setbits32(host->ioaddr + ESDHC_SYSTEM_CONTROL, ESDHC_CLOCK_IPGEN | + ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN | + div << ESDHC_DIVIDER_SHIFT | pre_div << ESDHC_PREDIV_SHIFT); + mdelay(100); +out: + host->clock = clock; +} + +static int esdhc_enable_dma(struct sdhci_host *host) +{ + setbits32(host->ioaddr + ESDHC_DMA_SYSCTL, ESDHC_DMA_SNOOP); + return 0; +} + +static unsigned int esdhc_get_max_clock(struct sdhci_host *host) +{ + struct sdhci_of_host *of_host = sdhci_priv(host); + + return of_host->clock; +} + +static unsigned int esdhc_get_min_clock(struct sdhci_host *host) +{ + struct sdhci_of_host *of_host = sdhci_priv(host); + + return of_host->clock / 256 / 16; +} + +struct sdhci_of_data sdhci_esdhc = { + .quirks = SDHCI_QUIRK_FORCE_BLK_SZ_2048 | + SDHCI_QUIRK_BROKEN_CARD_DETECTION | + SDHCI_QUIRK_NO_BUSY_IRQ | + SDHCI_QUIRK_NONSTANDARD_CLOCK | + SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | + SDHCI_QUIRK_PIO_NEEDS_DELAY | + SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET | + SDHCI_QUIRK_NO_CARD_NO_RESET, + .ops = { + .readl = sdhci_be32bs_readl, + .readw = esdhc_readw, + .readb = sdhci_be32bs_readb, + .writel = sdhci_be32bs_writel, + .writew = esdhc_writew, + .writeb = esdhc_writeb, + .set_clock = esdhc_set_clock, + .enable_dma = esdhc_enable_dma, + .get_max_clock = esdhc_get_max_clock, + .get_min_clock = esdhc_get_min_clock, + }, +}; diff --git a/drivers/mmc/host/sdhci-of.h b/drivers/mmc/host/sdhci-of.h new file mode 100644 index 0000000..17e873d --- /dev/null +++ b/drivers/mmc/host/sdhci-of.h @@ -0,0 +1,41 @@ +/* + * OpenFirmware bindings for Secure Digital Host Controller Interface. + * + * Copyright (c) 2007 Freescale Semiconductor, Inc. + * Copyright (c) 2009 MontaVista Software, Inc. + * + * Authors: Xiaobo Xie + * Anton Vorontsov + * + * 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 __SDHCI_OF_H +#define __SDHCI_OF_H + +#include +#include "sdhci.h" + +struct sdhci_of_data { + unsigned int quirks; + struct sdhci_ops ops; +}; + +struct sdhci_of_host { + unsigned int clock; + u16 xfer_mode_shadow; +}; + +extern u32 sdhci_be32bs_readl(struct sdhci_host *host, int reg); +extern u16 sdhci_be32bs_readw(struct sdhci_host *host, int reg); +extern u8 sdhci_be32bs_readb(struct sdhci_host *host, int reg); +extern void sdhci_be32bs_writel(struct sdhci_host *host, u32 val, int reg); +extern void sdhci_be32bs_writew(struct sdhci_host *host, u16 val, int reg); +extern void sdhci_be32bs_writeb(struct sdhci_host *host, u8 val, int reg); + +extern struct sdhci_of_data sdhci_esdhc; + +#endif /* __SDHCI_OF_H */ -- cgit v0.10.2 From 1144ab5d4b2da9f964d126105c6b3ced939eb073 Mon Sep 17 00:00:00 2001 From: Albert Herranz Date: Thu, 17 Dec 2009 15:27:20 -0800 Subject: sdhci-of: add support for the wii sdhci controller Add support for the Secure Digital Host Controller Interface found on the "Hollywood" chipset of the Nintendo Wii video game console. Signed-off-by: Albert Herranz Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index d923464..ce1d288 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -55,7 +55,7 @@ config MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER has the effect of scrambling the addresses and formats of data accessed in sizes other than the datum size. - This is the case for the Freescale eSDHC. + This is the case for the Freescale eSDHC and Nintendo Wii SDHCI. config MMC_SDHCI_PCI tristate "SDHCI support on PCI bus" @@ -103,6 +103,17 @@ config MMC_SDHCI_OF_ESDHC If unsure, say N. +config MMC_SDHCI_OF_HLWD + bool "SDHCI OF support for the Nintendo Wii SDHCI controllers" + depends on MMC_SDHCI_OF + select MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER + help + This selects the Secure Digital Host Controller Interface (SDHCI) + found in the "Hollywood" chipset of the Nintendo Wii video game + console. + + If unsure, say N. + config MMC_SDHCI_PLTFM tristate "SDHCI support on the platform specific bus" depends on MMC_SDHCI diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index cbda9b2..3d253dd 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -39,6 +39,7 @@ obj-$(CONFIG_SDH_BFIN) += bfin_sdh.o obj-$(CONFIG_MMC_SDHCI_OF) += sdhci-of.o sdhci-of-y := sdhci-of-core.o sdhci-of-$(CONFIG_MMC_SDHCI_OF_ESDHC) += sdhci-of-esdhc.o +sdhci-of-$(CONFIG_MMC_SDHCI_OF_HLWD) += sdhci-of-hlwd.o ifeq ($(CONFIG_CB710_DEBUG),y) CFLAGS-cb710-mmc += -DDEBUG diff --git a/drivers/mmc/host/sdhci-of-core.c b/drivers/mmc/host/sdhci-of-core.c index add2008..55e3313 100644 --- a/drivers/mmc/host/sdhci-of-core.c +++ b/drivers/mmc/host/sdhci-of-core.c @@ -196,6 +196,9 @@ static const struct of_device_id sdhci_of_match[] = { { .compatible = "fsl,mpc8536-esdhc", .data = &sdhci_esdhc, }, { .compatible = "fsl,esdhc", .data = &sdhci_esdhc, }, #endif +#ifdef CONFIG_MMC_SDHCI_OF_HLWD + { .compatible = "nintendo,hollywood-sdhci", .data = &sdhci_hlwd, }, +#endif { .compatible = "generic-sdhci", }, {}, }; diff --git a/drivers/mmc/host/sdhci-of-hlwd.c b/drivers/mmc/host/sdhci-of-hlwd.c new file mode 100644 index 0000000..35117f3 --- /dev/null +++ b/drivers/mmc/host/sdhci-of-hlwd.c @@ -0,0 +1,65 @@ +/* + * drivers/mmc/host/sdhci-of-hlwd.c + * + * Nintendo Wii Secure Digital Host Controller Interface. + * Copyright (C) 2009 The GameCube Linux Team + * Copyright (C) 2009 Albert Herranz + * + * Based on sdhci-of-esdhc.c + * + * Copyright (c) 2007 Freescale Semiconductor, Inc. + * Copyright (c) 2009 MontaVista Software, Inc. + * + * Authors: Xiaobo Xie + * Anton Vorontsov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + */ + +#include +#include +#include "sdhci-of.h" +#include "sdhci.h" + +/* + * Ops and quirks for the Nintendo Wii SDHCI controllers. + */ + +/* + * We need a small delay after each write, or things go horribly wrong. + */ +#define SDHCI_HLWD_WRITE_DELAY 5 /* usecs */ + +static void sdhci_hlwd_writel(struct sdhci_host *host, u32 val, int reg) +{ + sdhci_be32bs_writel(host, val, reg); + udelay(SDHCI_HLWD_WRITE_DELAY); +} + +static void sdhci_hlwd_writew(struct sdhci_host *host, u16 val, int reg) +{ + sdhci_be32bs_writew(host, val, reg); + udelay(SDHCI_HLWD_WRITE_DELAY); +} + +static void sdhci_hlwd_writeb(struct sdhci_host *host, u8 val, int reg) +{ + sdhci_be32bs_writeb(host, val, reg); + udelay(SDHCI_HLWD_WRITE_DELAY); +} + +struct sdhci_of_data sdhci_hlwd = { + .quirks = SDHCI_QUIRK_32BIT_DMA_ADDR | + SDHCI_QUIRK_32BIT_DMA_SIZE, + .ops = { + .readl = sdhci_be32bs_readl, + .readw = sdhci_be32bs_readw, + .readb = sdhci_be32bs_readb, + .writel = sdhci_hlwd_writel, + .writew = sdhci_hlwd_writew, + .writeb = sdhci_hlwd_writeb, + }, +}; diff --git a/drivers/mmc/host/sdhci-of.h b/drivers/mmc/host/sdhci-of.h index 17e873d..ad09ad9 100644 --- a/drivers/mmc/host/sdhci-of.h +++ b/drivers/mmc/host/sdhci-of.h @@ -37,5 +37,6 @@ extern void sdhci_be32bs_writew(struct sdhci_host *host, u16 val, int reg); extern void sdhci_be32bs_writeb(struct sdhci_host *host, u8 val, int reg); extern struct sdhci_of_data sdhci_esdhc; +extern struct sdhci_of_data sdhci_hlwd; #endif /* __SDHCI_OF_H */ -- cgit v0.10.2 From 26b3c01f7debc1bbc3117bc9c9e016ca6f2e41d5 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Thu, 17 Dec 2009 15:27:23 -0800 Subject: rtc: set wakeup capability for I2C and SPI RTC drivers RTC core won't allow wakeup alarms to be set if RTC devices' parent (i.e. i2c_client or spi_device) isn't wakeup capable. For I2C devices there is I2C_CLIENT_WAKE flag exists that we can pass via board info, and if set, I2C core will initialize wakeup capability. For SPI devices there is no such flag at all. I believe that it's not platform code responsibility to allow or disallow wakeups, instead, drivers themselves should set the capability if a device can trigger wakeups. That's what drivers/base/power/sysfs.c says: * It is the responsibility of device drivers to enable (or disable) * wakeup signaling as part of changing device power states, respecting * the policy choices provided through the driver model. I2C and SPI RTC devices send wakeup events via interrupt lines, so we should set the wakeup capability if IRQ is routed. Ideally we should also check irq for wakeup capability before setting device's capability, i.e. if (can_irq_wake(irq)) device_set_wakeup_capable(&client->dev, 1); But there is no can_irq_wake() call exist, and it is not that trivial to implement it for all interrupts controllers and complex/cascaded setups. drivers/base/power/sysfs.c also covers these cases: * Devices may not be able to generate wakeup events from all power * states. Also, the events may be ignored in some configurations; * for example, they might need help from other devices that aren't * active So there is no guarantee that wakeup will actually work, and so I think there is no point in being pedantic wrt checking IRQ wakeup capability. Signed-off-by: Anton Vorontsov Cc: David Brownell Cc: Ben Dooks Cc: Jean Delvare Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/rtc/rtc-ds1305.c b/drivers/rtc/rtc-ds1305.c index 259db7f..9630e7d 100644 --- a/drivers/rtc/rtc-ds1305.c +++ b/drivers/rtc/rtc-ds1305.c @@ -778,6 +778,8 @@ static int __devinit ds1305_probe(struct spi_device *spi) spi->irq, status); goto fail1; } + + device_set_wakeup_capable(&spi->dev, 1); } /* export NVRAM */ diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 8a99da6..c4ec5c1 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -881,6 +881,8 @@ read_rtc: "unable to request IRQ!\n"); goto exit_irq; } + + device_set_wakeup_capable(&client->dev, 1); set_bit(HAS_ALARM, &ds1307->flags); dev_dbg(&client->dev, "got IRQ %d\n", client->irq); } diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c index 713f7bf..5317bbc 100644 --- a/drivers/rtc/rtc-ds1374.c +++ b/drivers/rtc/rtc-ds1374.c @@ -383,6 +383,8 @@ static int ds1374_probe(struct i2c_client *client, dev_err(&client->dev, "unable to request IRQ\n"); goto out_free; } + + device_set_wakeup_capable(&client->dev, 1); } ds1374->rtc = rtc_device_register(client->name, &client->dev, -- cgit v0.10.2 From 65a80b4c61f5b5f6eb0f5669c8fb120893bfb388 Mon Sep 17 00:00:00 2001 From: Hisashi Hifumi Date: Thu, 17 Dec 2009 15:27:26 -0800 Subject: readahead: add blk_run_backing_dev I added blk_run_backing_dev on page_cache_async_readahead so readahead I/O is unpluged to improve throughput on especially RAID environment. The normal case is, if page N become uptodate at time T(N), then T(N) <= T(N+1) holds. With RAID (and NFS to some degree), there is no strict ordering, the data arrival time depends on runtime status of individual disks, which breaks that formula. So in do_generic_file_read(), just after submitting the async readahead IO request, the current page may well be uptodate, so the page won't be locked, and the block device won't be implicitly unplugged: if (PageReadahead(page)) page_cache_async_readahead() if (!PageUptodate(page)) goto page_not_up_to_date; //... page_not_up_to_date: lock_page_killable(page); Therefore explicit unplugging can help. Following is the test result with dd. #dd if=testdir/testfile of=/dev/null bs=16384 -2.6.30-rc6 1048576+0 records in 1048576+0 records out 17179869184 bytes (17 GB) copied, 224.182 seconds, 76.6 MB/s -2.6.30-rc6-patched 1048576+0 records in 1048576+0 records out 17179869184 bytes (17 GB) copied, 206.465 seconds, 83.2 MB/s (7Disks RAID-0 Array) -2.6.30-rc6 1054976+0 records in 1054976+0 records out 17284726784 bytes (17 GB) copied, 212.233 seconds, 81.4 MB/s -2.6.30-rc6-patched 1054976+0 records out 17284726784 bytes (17 GB) copied, 198.878 seconds, 86.9 MB/s (7Disks RAID-5 Array) The patch was found to improve performance with the SCST scsi target driver. See http://sourceforge.net/mailarchive/forum.php?thread_name=a0272b440906030714g67eabc5k8f847fb1e538cc62%40mail.gmail.com&forum_name=scst-devel [akpm@linux-foundation.org: unbust comment layout] [akpm@linux-foundation.org: "fix" CONFIG_BLOCK=n] Signed-off-by: Hisashi Hifumi Acked-by: Wu Fengguang Cc: Jens Axboe Cc: KOSAKI Motohiro Tested-by: Ronald Cc: Bart Van Assche Cc: Vladislav Bolkhovitin Cc: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/mm/readahead.c b/mm/readahead.c index aa1aa23..033bc13 100644 --- a/mm/readahead.c +++ b/mm/readahead.c @@ -547,5 +547,17 @@ page_cache_async_readahead(struct address_space *mapping, /* do read-ahead */ ondemand_readahead(mapping, ra, filp, true, offset, req_size); + +#ifdef CONFIG_BLOCK + /* + * Normally the current page is !uptodate and lock_page() will be + * immediately called to implicitly unplug the device. However this + * is not always true for RAID conifgurations, where data arrives + * not strictly in their submission order. In this case we need to + * explicitly kick off the IO. + */ + if (PageUptodate(page)) + blk_run_backing_dev(mapping->backing_dev_info, NULL); +#endif } EXPORT_SYMBOL_GPL(page_cache_async_readahead); -- cgit v0.10.2 From 6485536bcf499839a54dcda8a8d47ea0bd29b375 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 17 Dec 2009 15:27:27 -0800 Subject: printk: fix new kernel-doc warnings Fix kernel-doc warnings in printk.c: Warning(kernel/printk.c:1422): No description found for parameter 'dumper' Warning(kernel/printk.c:1422): Excess function parameter 'dump' description in 'kmsg_dump_register' Warning(kernel/printk.c:1451): No description found for parameter 'dumper' Warning(kernel/printk.c:1451): Excess function parameter 'dump' description in 'kmsg_dump_unregister' Signed-off-by: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/kernel/printk.c b/kernel/printk.c index 1ded8e7..17463ca 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -1412,7 +1412,7 @@ static LIST_HEAD(dump_list); /** * kmsg_dump_register - register a kernel log dumper. - * @dump: pointer to the kmsg_dumper structure + * @dumper: pointer to the kmsg_dumper structure * * Adds a kernel log dumper to the system. The dump callback in the * structure will be called when the kernel oopses or panics and must be @@ -1442,7 +1442,7 @@ EXPORT_SYMBOL_GPL(kmsg_dump_register); /** * kmsg_dump_unregister - unregister a kmsg dumper. - * @dump: pointer to the kmsg_dumper structure + * @dumper: pointer to the kmsg_dumper structure * * Removes a dump device from the system. Returns zero on success and * %-EINVAL otherwise. -- cgit v0.10.2 From 06b5dc646b9479b786d77749936f25910cd82a37 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Thu, 17 Dec 2009 15:51:37 -0800 Subject: Makefile: Unexport LC_ALL instead of clearing it Apparently not all versions of glibc and utilities treat an empty LC_ALL as nonexistent, causing error messages to be garbled. Instead, explicitly unexport it from the environment. Reported-and-tested-by: Masami Hiramatsu Signed-off-by: H. Peter Anvin LKML-Reference: <4B2AC394.4030108@redhat.com> Cc: Michal Marek Cc: Roland Dreier Cc: Sam Ravnborg diff --git a/Makefile b/Makefile index 6e39af1..5e92ca5 100644 --- a/Makefile +++ b/Makefile @@ -17,11 +17,11 @@ NAME = Man-Eating Seals of Antiquity MAKEFLAGS += -rR --no-print-directory # Avoid funny character set dependencies -LC_ALL= +unexport LC_ALL LC_CTYPE=C LC_COLLATE=C LC_NUMERIC=C -export LC_ALL LC_CTYPE LC_COLLATE LC_NUMERIC +export LC_CTYPE LC_COLLATE LC_NUMERIC # We are using a recursive build, so we need to do a little thinking # to get the ordering right. -- cgit v0.10.2 From d54e7929d8073b0fff8af16f8ff6ebbba6fc4154 Mon Sep 17 00:00:00 2001 From: Thomas Champagne Date: Fri, 18 Dec 2009 03:41:41 +0300 Subject: pmu_battery: Fix battery full reporting Prior to this patch, pmu_battery was unable to report battery full status. This patch fixes the issue by adding a proper handling code into pmu_bat_get_property(): if we're on AC and the battery isn't charging, then the battery is considered full. Signed-off-by: Thomas Champagne Acked-By: David Woodhouse Signed-off-by: Anton Vorontsov diff --git a/drivers/power/pmu_battery.c b/drivers/power/pmu_battery.c index 9346a86..9c87ad5 100644 --- a/drivers/power/pmu_battery.c +++ b/drivers/power/pmu_battery.c @@ -89,6 +89,8 @@ static int pmu_bat_get_property(struct power_supply *psy, case POWER_SUPPLY_PROP_STATUS: if (pbi->flags & PMU_BATT_CHARGING) val->intval = POWER_SUPPLY_STATUS_CHARGING; + else if (pmu_power_flags & PMU_PWR_AC_PRESENT) + val->intval = POWER_SUPPLY_STATUS_FULL; else val->intval = POWER_SUPPLY_STATUS_DISCHARGING; break; -- cgit v0.10.2 From 875ab0b74e85d6801a49392447d26e0b28688d86 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 18 Dec 2009 01:57:31 +0100 Subject: PM: Make the initcall_debug style timing for suspend/resume complete Commit f2511774863487e61b56a97da07ebf8dd61d7836 (PM: Add initcall_debug style timing for suspend/resume) introduced basic timing instrumentation, needed for a scritps/bootgraph.pl equivalent or humans, but it missed the fact that bus types and device classes which haven't been switched to using struct dev_pm_ops objects yet need special handling. As a result, the suspend/resume timing information is only available for devices whose bus types or device classes use struct dev_pm_ops objects, so the majority of devices is not covered. Fix this by adding basic suspend/resume timing instrumentation for devices whose bus types and device classes still don't use struct dev_pm_ops objects for power management. To reduce code duplication move the timing code to helper functions. Signed-off-by: Rafael J. Wysocki diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 1a216c1..c448d59 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -161,6 +161,32 @@ void device_pm_move_last(struct device *dev) list_move_tail(&dev->power.entry, &dpm_list); } +static ktime_t initcall_debug_start(struct device *dev) +{ + ktime_t calltime = ktime_set(0, 0); + + if (initcall_debug) { + pr_info("calling %s+ @ %i\n", + dev_name(dev), task_pid_nr(current)); + calltime = ktime_get(); + } + + return calltime; +} + +static void initcall_debug_report(struct device *dev, ktime_t calltime, + int error) +{ + ktime_t delta, rettime; + + if (initcall_debug) { + rettime = ktime_get(); + delta = ktime_sub(rettime, calltime); + pr_info("call %s+ returned %d after %Ld usecs\n", dev_name(dev), + error, (unsigned long long)ktime_to_ns(delta) >> 10); + } +} + /** * pm_op - Execute the PM operation appropriate for given PM event. * @dev: Device to handle. @@ -172,13 +198,9 @@ static int pm_op(struct device *dev, pm_message_t state) { int error = 0; - ktime_t calltime, delta, rettime; + ktime_t calltime; - if (initcall_debug) { - pr_info("calling %s+ @ %i\n", - dev_name(dev), task_pid_nr(current)); - calltime = ktime_get(); - } + calltime = initcall_debug_start(dev); switch (state.event) { #ifdef CONFIG_SUSPEND @@ -227,12 +249,7 @@ static int pm_op(struct device *dev, error = -EINVAL; } - if (initcall_debug) { - rettime = ktime_get(); - delta = ktime_sub(rettime, calltime); - pr_info("call %s+ returned %d after %Ld usecs\n", dev_name(dev), - error, (unsigned long long)ktime_to_ns(delta) >> 10); - } + initcall_debug_report(dev, calltime, error); return error; } @@ -309,8 +326,9 @@ static int pm_noirq_op(struct device *dev, if (initcall_debug) { rettime = ktime_get(); delta = ktime_sub(rettime, calltime); - printk("initcall %s_i+ returned %d after %Ld usecs\n", dev_name(dev), - error, (unsigned long long)ktime_to_ns(delta) >> 10); + printk("initcall %s_i+ returned %d after %Ld usecs\n", + dev_name(dev), error, + (unsigned long long)ktime_to_ns(delta) >> 10); } return error; @@ -408,6 +426,26 @@ void dpm_resume_noirq(pm_message_t state) EXPORT_SYMBOL_GPL(dpm_resume_noirq); /** + * legacy_resume - Execute a legacy (bus or class) resume callback for device. + * dev: Device to resume. + * cb: Resume callback to execute. + */ +static int legacy_resume(struct device *dev, int (*cb)(struct device *dev)) +{ + int error; + ktime_t calltime; + + calltime = initcall_debug_start(dev); + + error = cb(dev); + suspend_report_result(cb, error); + + initcall_debug_report(dev, calltime, error); + + return error; +} + +/** * device_resume - Execute "resume" callbacks for given device. * @dev: Device to handle. * @state: PM transition of the system being carried out. @@ -427,7 +465,7 @@ static int device_resume(struct device *dev, pm_message_t state) error = pm_op(dev, dev->bus->pm, state); } else if (dev->bus->resume) { pm_dev_dbg(dev, state, "legacy "); - error = dev->bus->resume(dev); + error = legacy_resume(dev, dev->bus->resume); } if (error) goto End; @@ -448,7 +486,7 @@ static int device_resume(struct device *dev, pm_message_t state) error = pm_op(dev, dev->class->pm, state); } else if (dev->class->resume) { pm_dev_dbg(dev, state, "legacy class "); - error = dev->class->resume(dev); + error = legacy_resume(dev, dev->class->resume); } } End: @@ -648,6 +686,27 @@ int dpm_suspend_noirq(pm_message_t state) EXPORT_SYMBOL_GPL(dpm_suspend_noirq); /** + * legacy_suspend - Execute a legacy (bus or class) suspend callback for device. + * dev: Device to suspend. + * cb: Suspend callback to execute. + */ +static int legacy_suspend(struct device *dev, pm_message_t state, + int (*cb)(struct device *dev, pm_message_t state)) +{ + int error; + ktime_t calltime; + + calltime = initcall_debug_start(dev); + + error = cb(dev, state); + suspend_report_result(cb, error); + + initcall_debug_report(dev, calltime, error); + + return error; +} + +/** * device_suspend - Execute "suspend" callbacks for given device. * @dev: Device to handle. * @state: PM transition of the system being carried out. @@ -664,8 +723,7 @@ static int device_suspend(struct device *dev, pm_message_t state) error = pm_op(dev, dev->class->pm, state); } else if (dev->class->suspend) { pm_dev_dbg(dev, state, "legacy class "); - error = dev->class->suspend(dev, state); - suspend_report_result(dev->class->suspend, error); + error = legacy_suspend(dev, state, dev->class->suspend); } if (error) goto End; @@ -686,8 +744,7 @@ static int device_suspend(struct device *dev, pm_message_t state) error = pm_op(dev, dev->bus->pm, state); } else if (dev->bus->suspend) { pm_dev_dbg(dev, state, "legacy "); - error = dev->bus->suspend(dev, state); - suspend_report_result(dev->bus->suspend, error); + error = legacy_suspend(dev, state, dev->bus->suspend); } } End: -- cgit v0.10.2 From ecf762b2581e12ac761d12a6e4e297c2224aa899 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 18 Dec 2009 01:57:47 +0100 Subject: PM: Measure device suspend and resume times Measure and print the time of suspending and resuming all devices. Signed-off-by: Rafael J. Wysocki diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index c448d59..8052daf 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -372,6 +372,23 @@ static void pm_dev_err(struct device *dev, pm_message_t state, char *info, kobject_name(&dev->kobj), pm_verb(state.event), info, error); } +static void dpm_show_time(ktime_t starttime, pm_message_t state, char *info) +{ + ktime_t calltime; + s64 usecs64; + int usecs; + + calltime = ktime_get(); + usecs64 = ktime_to_ns(ktime_sub(calltime, starttime)); + do_div(usecs64, NSEC_PER_USEC); + usecs = usecs64; + if (usecs == 0) + usecs = 1; + pr_info("PM: %s%s%s of devices complete after %ld.%03ld msecs\n", + info ?: "", info ? " " : "", pm_verb(state.event), + usecs / USEC_PER_MSEC, usecs % USEC_PER_MSEC); +} + /*------------------------- Resume routines -------------------------*/ /** @@ -408,6 +425,7 @@ static int device_resume_noirq(struct device *dev, pm_message_t state) void dpm_resume_noirq(pm_message_t state) { struct device *dev; + ktime_t starttime = ktime_get(); mutex_lock(&dpm_list_mtx); transition_started = false; @@ -421,6 +439,7 @@ void dpm_resume_noirq(pm_message_t state) pm_dev_err(dev, state, " early", error); } mutex_unlock(&dpm_list_mtx); + dpm_show_time(starttime, state, "early"); resume_device_irqs(); } EXPORT_SYMBOL_GPL(dpm_resume_noirq); @@ -506,6 +525,7 @@ static int device_resume(struct device *dev, pm_message_t state) static void dpm_resume(pm_message_t state) { struct list_head list; + ktime_t starttime = ktime_get(); INIT_LIST_HEAD(&list); mutex_lock(&dpm_list_mtx); @@ -534,6 +554,7 @@ static void dpm_resume(pm_message_t state) } list_splice(&list, &dpm_list); mutex_unlock(&dpm_list_mtx); + dpm_show_time(starttime, state, NULL); } /** @@ -666,6 +687,7 @@ static int device_suspend_noirq(struct device *dev, pm_message_t state) int dpm_suspend_noirq(pm_message_t state) { struct device *dev; + ktime_t starttime = ktime_get(); int error = 0; suspend_device_irqs(); @@ -681,6 +703,8 @@ int dpm_suspend_noirq(pm_message_t state) mutex_unlock(&dpm_list_mtx); if (error) dpm_resume_noirq(resume_event(state)); + else + dpm_show_time(starttime, state, "late"); return error; } EXPORT_SYMBOL_GPL(dpm_suspend_noirq); @@ -760,6 +784,7 @@ static int device_suspend(struct device *dev, pm_message_t state) static int dpm_suspend(pm_message_t state) { struct list_head list; + ktime_t starttime = ktime_get(); int error = 0; INIT_LIST_HEAD(&list); @@ -785,6 +810,8 @@ static int dpm_suspend(pm_message_t state) } list_splice(&list, dpm_list.prev); mutex_unlock(&dpm_list_mtx); + if (!error) + dpm_show_time(starttime, state, NULL); return error; } -- cgit v0.10.2 From 55639353a0035052d9ea6cfe4dde0ac7fcbb2c9f Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 17 Dec 2009 17:14:40 -0800 Subject: Linux 2.6.33-rc1 diff --git a/Makefile b/Makefile index 8491b21..0ac5812 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 -SUBLEVEL = 32 -EXTRAVERSION = +SUBLEVEL = 33 +EXTRAVERSION = -rc1 NAME = Man-Eating Seals of Antiquity # *DOCUMENTATION* -- cgit v0.10.2 From ed8b67040965e4fe695db333d5914e18ea5f146f Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 16 Dec 2009 22:17:09 +0000 Subject: drm: convert drm_ioctl to unlocked_ioctl drm_ioctl is called with the Big Kernel Lock held, which shows up very high in statistics on vfs_ioctl. Moving the lock into the drm_ioctl function itself makes sure we blame the right subsystem and it gets us one step closer to eliminating the locked version of fops->ioctl. Since drm_ioctl does not require the lock itself, we only need to hold it while calling the specific handler. The 32 bit conversion handlers do not interact with any other code, so they don't need the BKL here either and can just call drm_ioctl. As a bonus, this cleans up all the other users of drm_ioctl which now no longer have to find the inode or call lock_kernel. [airlied: squashed the non-driver bits of the second patch in here, this provides the flag for drivers to use to select unlocked ioctls - but doesn't modify any drivers]. Signed-off-by: Arnd Bergmann Cc: David Airlie Cc: dri-devel@lists.sourceforge.net Cc: Frederic Weisbecker Cc: Thomas Gleixner Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index ff2f104..766c468 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -434,11 +434,11 @@ static int drm_version(struct drm_device *dev, void *data, * Looks up the ioctl function in the ::ioctls table, checking for root * previleges if so required, and dispatches to the respective function. */ -int drm_ioctl(struct inode *inode, struct file *filp, +long drm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct drm_file *file_priv = filp->private_data; - struct drm_device *dev = file_priv->minor->dev; + struct drm_device *dev; struct drm_ioctl_desc *ioctl; drm_ioctl_t *func; unsigned int nr = DRM_IOCTL_NR(cmd); @@ -446,6 +446,7 @@ int drm_ioctl(struct inode *inode, struct file *filp, char stack_kdata[128]; char *kdata = NULL; + dev = file_priv->minor->dev; atomic_inc(&dev->ioctl_count); atomic_inc(&dev->counts[_DRM_STAT_IOCTLS]); ++file_priv->ioctl_count; @@ -501,7 +502,13 @@ int drm_ioctl(struct inode *inode, struct file *filp, goto err_i1; } } - retcode = func(dev, kdata, file_priv); + if (ioctl->flags & DRM_UNLOCKED) + retcode = func(dev, kdata, file_priv); + else { + lock_kernel(); + retcode = func(dev, kdata, file_priv); + unlock_kernel(); + } if (cmd & IOC_OUT) { if (copy_to_user((void __user *)arg, kdata, diff --git a/drivers/gpu/drm/drm_ioc32.c b/drivers/gpu/drm/drm_ioc32.c index 282d9fd..d61d185 100644 --- a/drivers/gpu/drm/drm_ioc32.c +++ b/drivers/gpu/drm/drm_ioc32.c @@ -104,7 +104,7 @@ static int compat_drm_version(struct file *file, unsigned int cmd, &version->desc)) return -EFAULT; - err = drm_ioctl(file->f_path.dentry->d_inode, file, + err = drm_ioctl(file, DRM_IOCTL_VERSION, (unsigned long)version); if (err) return err; @@ -145,8 +145,7 @@ static int compat_drm_getunique(struct file *file, unsigned int cmd, &u->unique)) return -EFAULT; - err = drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_GET_UNIQUE, (unsigned long)u); + err = drm_ioctl(file, DRM_IOCTL_GET_UNIQUE, (unsigned long)u); if (err) return err; @@ -174,8 +173,7 @@ static int compat_drm_setunique(struct file *file, unsigned int cmd, &u->unique)) return -EFAULT; - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_SET_UNIQUE, (unsigned long)u); + return drm_ioctl(file, DRM_IOCTL_SET_UNIQUE, (unsigned long)u); } typedef struct drm_map32 { @@ -205,8 +203,7 @@ static int compat_drm_getmap(struct file *file, unsigned int cmd, if (__put_user(idx, &map->offset)) return -EFAULT; - err = drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_GET_MAP, (unsigned long)map); + err = drm_ioctl(file, DRM_IOCTL_GET_MAP, (unsigned long)map); if (err) return err; @@ -246,8 +243,7 @@ static int compat_drm_addmap(struct file *file, unsigned int cmd, || __put_user(m32.flags, &map->flags)) return -EFAULT; - err = drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_ADD_MAP, (unsigned long)map); + err = drm_ioctl(file, DRM_IOCTL_ADD_MAP, (unsigned long)map); if (err) return err; @@ -284,8 +280,7 @@ static int compat_drm_rmmap(struct file *file, unsigned int cmd, if (__put_user((void *)(unsigned long)handle, &map->handle)) return -EFAULT; - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_RM_MAP, (unsigned long)map); + return drm_ioctl(file, DRM_IOCTL_RM_MAP, (unsigned long)map); } typedef struct drm_client32 { @@ -314,8 +309,7 @@ static int compat_drm_getclient(struct file *file, unsigned int cmd, if (__put_user(idx, &client->idx)) return -EFAULT; - err = drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_GET_CLIENT, (unsigned long)client); + err = drm_ioctl(file, DRM_IOCTL_GET_CLIENT, (unsigned long)client); if (err) return err; @@ -351,8 +345,7 @@ static int compat_drm_getstats(struct file *file, unsigned int cmd, if (!access_ok(VERIFY_WRITE, stats, sizeof(*stats))) return -EFAULT; - err = drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_GET_STATS, (unsigned long)stats); + err = drm_ioctl(file, DRM_IOCTL_GET_STATS, (unsigned long)stats); if (err) return err; @@ -395,8 +388,7 @@ static int compat_drm_addbufs(struct file *file, unsigned int cmd, || __put_user(agp_start, &buf->agp_start)) return -EFAULT; - err = drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_ADD_BUFS, (unsigned long)buf); + err = drm_ioctl(file, DRM_IOCTL_ADD_BUFS, (unsigned long)buf); if (err) return err; @@ -427,8 +419,7 @@ static int compat_drm_markbufs(struct file *file, unsigned int cmd, || __put_user(b32.high_mark, &buf->high_mark)) return -EFAULT; - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_MARK_BUFS, (unsigned long)buf); + return drm_ioctl(file, DRM_IOCTL_MARK_BUFS, (unsigned long)buf); } typedef struct drm_buf_info32 { @@ -469,8 +460,7 @@ static int compat_drm_infobufs(struct file *file, unsigned int cmd, || __put_user(list, &request->list)) return -EFAULT; - err = drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_INFO_BUFS, (unsigned long)request); + err = drm_ioctl(file, DRM_IOCTL_INFO_BUFS, (unsigned long)request); if (err) return err; @@ -531,8 +521,7 @@ static int compat_drm_mapbufs(struct file *file, unsigned int cmd, || __put_user(list, &request->list)) return -EFAULT; - err = drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_MAP_BUFS, (unsigned long)request); + err = drm_ioctl(file, DRM_IOCTL_MAP_BUFS, (unsigned long)request); if (err) return err; @@ -578,8 +567,7 @@ static int compat_drm_freebufs(struct file *file, unsigned int cmd, &request->list)) return -EFAULT; - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_FREE_BUFS, (unsigned long)request); + return drm_ioctl(file, DRM_IOCTL_FREE_BUFS, (unsigned long)request); } typedef struct drm_ctx_priv_map32 { @@ -605,8 +593,7 @@ static int compat_drm_setsareactx(struct file *file, unsigned int cmd, &request->handle)) return -EFAULT; - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_SET_SAREA_CTX, (unsigned long)request); + return drm_ioctl(file, DRM_IOCTL_SET_SAREA_CTX, (unsigned long)request); } static int compat_drm_getsareactx(struct file *file, unsigned int cmd, @@ -628,8 +615,7 @@ static int compat_drm_getsareactx(struct file *file, unsigned int cmd, if (__put_user(ctx_id, &request->ctx_id)) return -EFAULT; - err = drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_GET_SAREA_CTX, (unsigned long)request); + err = drm_ioctl(file, DRM_IOCTL_GET_SAREA_CTX, (unsigned long)request); if (err) return err; @@ -664,8 +650,7 @@ static int compat_drm_resctx(struct file *file, unsigned int cmd, &res->contexts)) return -EFAULT; - err = drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_RES_CTX, (unsigned long)res); + err = drm_ioctl(file, DRM_IOCTL_RES_CTX, (unsigned long)res); if (err) return err; @@ -718,8 +703,7 @@ static int compat_drm_dma(struct file *file, unsigned int cmd, &d->request_sizes)) return -EFAULT; - err = drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_DMA, (unsigned long)d); + err = drm_ioctl(file, DRM_IOCTL_DMA, (unsigned long)d); if (err) return err; @@ -751,8 +735,7 @@ static int compat_drm_agp_enable(struct file *file, unsigned int cmd, if (put_user(m32.mode, &mode->mode)) return -EFAULT; - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_AGP_ENABLE, (unsigned long)mode); + return drm_ioctl(file, DRM_IOCTL_AGP_ENABLE, (unsigned long)mode); } typedef struct drm_agp_info32 { @@ -781,8 +764,7 @@ static int compat_drm_agp_info(struct file *file, unsigned int cmd, if (!access_ok(VERIFY_WRITE, info, sizeof(*info))) return -EFAULT; - err = drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_AGP_INFO, (unsigned long)info); + err = drm_ioctl(file, DRM_IOCTL_AGP_INFO, (unsigned long)info); if (err) return err; @@ -827,16 +809,14 @@ static int compat_drm_agp_alloc(struct file *file, unsigned int cmd, || __put_user(req32.type, &request->type)) return -EFAULT; - err = drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_AGP_ALLOC, (unsigned long)request); + err = drm_ioctl(file, DRM_IOCTL_AGP_ALLOC, (unsigned long)request); if (err) return err; if (__get_user(req32.handle, &request->handle) || __get_user(req32.physical, &request->physical) || copy_to_user(argp, &req32, sizeof(req32))) { - drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_AGP_FREE, (unsigned long)request); + drm_ioctl(file, DRM_IOCTL_AGP_FREE, (unsigned long)request); return -EFAULT; } @@ -856,8 +836,7 @@ static int compat_drm_agp_free(struct file *file, unsigned int cmd, || __put_user(handle, &request->handle)) return -EFAULT; - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_AGP_FREE, (unsigned long)request); + return drm_ioctl(file, DRM_IOCTL_AGP_FREE, (unsigned long)request); } typedef struct drm_agp_binding32 { @@ -881,8 +860,7 @@ static int compat_drm_agp_bind(struct file *file, unsigned int cmd, || __put_user(req32.offset, &request->offset)) return -EFAULT; - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_AGP_BIND, (unsigned long)request); + return drm_ioctl(file, DRM_IOCTL_AGP_BIND, (unsigned long)request); } static int compat_drm_agp_unbind(struct file *file, unsigned int cmd, @@ -898,8 +876,7 @@ static int compat_drm_agp_unbind(struct file *file, unsigned int cmd, || __put_user(handle, &request->handle)) return -EFAULT; - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_AGP_UNBIND, (unsigned long)request); + return drm_ioctl(file, DRM_IOCTL_AGP_UNBIND, (unsigned long)request); } #endif /* __OS_HAS_AGP */ @@ -923,8 +900,7 @@ static int compat_drm_sg_alloc(struct file *file, unsigned int cmd, || __put_user(x, &request->size)) return -EFAULT; - err = drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_SG_ALLOC, (unsigned long)request); + err = drm_ioctl(file, DRM_IOCTL_SG_ALLOC, (unsigned long)request); if (err) return err; @@ -950,8 +926,7 @@ static int compat_drm_sg_free(struct file *file, unsigned int cmd, || __put_user(x << PAGE_SHIFT, &request->handle)) return -EFAULT; - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_SG_FREE, (unsigned long)request); + return drm_ioctl(file, DRM_IOCTL_SG_FREE, (unsigned long)request); } #if defined(CONFIG_X86) || defined(CONFIG_IA64) @@ -981,8 +956,7 @@ static int compat_drm_update_draw(struct file *file, unsigned int cmd, __put_user(update32.data, &request->data)) return -EFAULT; - err = drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_UPDATE_DRAW, (unsigned long)request); + err = drm_ioctl(file, DRM_IOCTL_UPDATE_DRAW, (unsigned long)request); return err; } #endif @@ -1023,8 +997,7 @@ static int compat_drm_wait_vblank(struct file *file, unsigned int cmd, || __put_user(req32.request.signal, &request->request.signal)) return -EFAULT; - err = drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_WAIT_VBLANK, (unsigned long)request); + err = drm_ioctl(file, DRM_IOCTL_WAIT_VBLANK, (unsigned long)request); if (err) return err; @@ -1094,16 +1067,14 @@ long drm_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) * than always failing. */ if (nr >= ARRAY_SIZE(drm_compat_ioctls)) - return drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg); + return drm_ioctl(filp, cmd, arg); fn = drm_compat_ioctls[nr]; - lock_kernel(); /* XXX for now */ if (fn != NULL) ret = (*fn) (filp, cmd, arg); else - ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg); - unlock_kernel(); + ret = drm_ioctl(filp, cmd, arg); return ret; } diff --git a/drivers/gpu/drm/i810/i810_dma.c b/drivers/gpu/drm/i810/i810_dma.c index 7d1d88c..de32d22 100644 --- a/drivers/gpu/drm/i810/i810_dma.c +++ b/drivers/gpu/drm/i810/i810_dma.c @@ -115,7 +115,7 @@ static int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma) static const struct file_operations i810_buffer_fops = { .open = drm_open, .release = drm_release, - .ioctl = drm_ioctl, + .unlocked_ioctl = drm_ioctl, .mmap = i810_mmap_buffers, .fasync = drm_fasync, }; diff --git a/drivers/gpu/drm/i810/i810_drv.c b/drivers/gpu/drm/i810/i810_drv.c index fabb9a8..c1e0275 100644 --- a/drivers/gpu/drm/i810/i810_drv.c +++ b/drivers/gpu/drm/i810/i810_drv.c @@ -59,7 +59,7 @@ static struct drm_driver driver = { .owner = THIS_MODULE, .open = drm_open, .release = drm_release, - .ioctl = drm_ioctl, + .unlocked_ioctl = drm_ioctl, .mmap = drm_mmap, .poll = drm_poll, .fasync = drm_fasync, diff --git a/drivers/gpu/drm/i830/i830_dma.c b/drivers/gpu/drm/i830/i830_dma.c index 877bf6c..06bd732 100644 --- a/drivers/gpu/drm/i830/i830_dma.c +++ b/drivers/gpu/drm/i830/i830_dma.c @@ -117,7 +117,7 @@ static int i830_mmap_buffers(struct file *filp, struct vm_area_struct *vma) static const struct file_operations i830_buffer_fops = { .open = drm_open, .release = drm_release, - .ioctl = drm_ioctl, + .unlocked_ioctl = drm_ioctl, .mmap = i830_mmap_buffers, .fasync = drm_fasync, }; diff --git a/drivers/gpu/drm/i830/i830_drv.c b/drivers/gpu/drm/i830/i830_drv.c index 389597e..44f990b 100644 --- a/drivers/gpu/drm/i830/i830_drv.c +++ b/drivers/gpu/drm/i830/i830_drv.c @@ -70,7 +70,7 @@ static struct drm_driver driver = { .owner = THIS_MODULE, .open = drm_open, .release = drm_release, - .ioctl = drm_ioctl, + .unlocked_ioctl = drm_ioctl, .mmap = drm_mmap, .poll = drm_poll, .fasync = drm_fasync, diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 2fa2178..24286ca 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -329,7 +329,7 @@ static struct drm_driver driver = { .owner = THIS_MODULE, .open = drm_open, .release = drm_release, - .ioctl = drm_ioctl, + .unlocked_ioctl = drm_ioctl, .mmap = drm_gem_mmap, .poll = drm_poll, .fasync = drm_fasync, diff --git a/drivers/gpu/drm/i915/i915_ioc32.c b/drivers/gpu/drm/i915/i915_ioc32.c index 1fe68a2..13b0289 100644 --- a/drivers/gpu/drm/i915/i915_ioc32.c +++ b/drivers/gpu/drm/i915/i915_ioc32.c @@ -66,8 +66,7 @@ static int compat_i915_batchbuffer(struct file *file, unsigned int cmd, &batchbuffer->cliprects)) return -EFAULT; - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_I915_BATCHBUFFER, + return drm_ioctl(file, DRM_IOCTL_I915_BATCHBUFFER, (unsigned long)batchbuffer); } @@ -102,8 +101,8 @@ static int compat_i915_cmdbuffer(struct file *file, unsigned int cmd, &cmdbuffer->cliprects)) return -EFAULT; - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_I915_CMDBUFFER, (unsigned long)cmdbuffer); + return drm_ioctl(file, DRM_IOCTL_I915_CMDBUFFER, + (unsigned long)cmdbuffer); } typedef struct drm_i915_irq_emit32 { @@ -125,8 +124,8 @@ static int compat_i915_irq_emit(struct file *file, unsigned int cmd, &request->irq_seq)) return -EFAULT; - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_I915_IRQ_EMIT, (unsigned long)request); + return drm_ioctl(file, DRM_IOCTL_I915_IRQ_EMIT, + (unsigned long)request); } typedef struct drm_i915_getparam32 { int param; @@ -149,8 +148,8 @@ static int compat_i915_getparam(struct file *file, unsigned int cmd, &request->value)) return -EFAULT; - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_I915_GETPARAM, (unsigned long)request); + return drm_ioctl(file, DRM_IOCTL_I915_GETPARAM, + (unsigned long)request); } typedef struct drm_i915_mem_alloc32 { @@ -178,8 +177,8 @@ static int compat_i915_alloc(struct file *file, unsigned int cmd, &request->region_offset)) return -EFAULT; - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_I915_ALLOC, (unsigned long)request); + return drm_ioctl(file, DRM_IOCTL_I915_ALLOC, + (unsigned long)request); } drm_ioctl_compat_t *i915_compat_ioctls[] = { @@ -211,12 +210,10 @@ long i915_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(i915_compat_ioctls)) fn = i915_compat_ioctls[nr - DRM_COMMAND_BASE]; - lock_kernel(); /* XXX for now */ if (fn != NULL) ret = (*fn) (filp, cmd, arg); else - ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg); - unlock_kernel(); + ret = drm_ioctl(filp, cmd, arg); return ret; } diff --git a/drivers/gpu/drm/mga/mga_drv.c b/drivers/gpu/drm/mga/mga_drv.c index 97ee566..ddfe161 100644 --- a/drivers/gpu/drm/mga/mga_drv.c +++ b/drivers/gpu/drm/mga/mga_drv.c @@ -68,7 +68,7 @@ static struct drm_driver driver = { .owner = THIS_MODULE, .open = drm_open, .release = drm_release, - .ioctl = drm_ioctl, + .unlocked_ioctl = drm_ioctl, .mmap = drm_mmap, .poll = drm_poll, .fasync = drm_fasync, diff --git a/drivers/gpu/drm/mga/mga_ioc32.c b/drivers/gpu/drm/mga/mga_ioc32.c index 30d0047..c1f877b 100644 --- a/drivers/gpu/drm/mga/mga_ioc32.c +++ b/drivers/gpu/drm/mga/mga_ioc32.c @@ -100,8 +100,7 @@ static int compat_mga_init(struct file *file, unsigned int cmd, if (err) return -EFAULT; - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_MGA_INIT, (unsigned long)init); + return drm_ioctl(file, DRM_IOCTL_MGA_INIT, (unsigned long)init); } typedef struct drm_mga_getparam32 { @@ -125,8 +124,7 @@ static int compat_mga_getparam(struct file *file, unsigned int cmd, &getparam->value)) return -EFAULT; - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_MGA_GETPARAM, (unsigned long)getparam); + return drm_ioctl(file, DRM_IOCTL_MGA_GETPARAM, (unsigned long)getparam); } typedef struct drm_mga_drm_bootstrap32 { @@ -166,8 +164,7 @@ static int compat_mga_dma_bootstrap(struct file *file, unsigned int cmd, || __put_user(dma_bootstrap32.agp_size, &dma_bootstrap->agp_size)) return -EFAULT; - err = drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_MGA_DMA_BOOTSTRAP, + err = drm_ioctl(file, DRM_IOCTL_MGA_DMA_BOOTSTRAP, (unsigned long)dma_bootstrap); if (err) return err; @@ -220,12 +217,10 @@ long mga_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(mga_compat_ioctls)) fn = mga_compat_ioctls[nr - DRM_COMMAND_BASE]; - lock_kernel(); /* XXX for now */ if (fn != NULL) ret = (*fn) (filp, cmd, arg); else - ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg); - unlock_kernel(); + ret = drm_ioctl(filp, cmd, arg); return ret; } diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c index 35249c3..3f943c0 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.c +++ b/drivers/gpu/drm/nouveau/nouveau_drv.c @@ -341,7 +341,7 @@ static struct drm_driver driver = { .owner = THIS_MODULE, .open = drm_open, .release = drm_release, - .ioctl = drm_ioctl, + .unlocked_ioctl = drm_ioctl, .mmap = nouveau_ttm_mmap, .poll = drm_poll, .fasync = drm_fasync, diff --git a/drivers/gpu/drm/nouveau/nouveau_ioc32.c b/drivers/gpu/drm/nouveau/nouveau_ioc32.c index a2c30f4..475ba81 100644 --- a/drivers/gpu/drm/nouveau/nouveau_ioc32.c +++ b/drivers/gpu/drm/nouveau/nouveau_ioc32.c @@ -61,12 +61,10 @@ long nouveau_compat_ioctl(struct file *filp, unsigned int cmd, if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(mga_compat_ioctls)) fn = nouveau_compat_ioctls[nr - DRM_COMMAND_BASE]; #endif - lock_kernel(); /* XXX for now */ if (fn != NULL) ret = (*fn)(filp, cmd, arg); else - ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg); - unlock_kernel(); + ret = drm_ioctl(filp, cmd, arg); return ret; } diff --git a/drivers/gpu/drm/r128/r128_drv.c b/drivers/gpu/drm/r128/r128_drv.c index 601f4c0..b806fdc 100644 --- a/drivers/gpu/drm/r128/r128_drv.c +++ b/drivers/gpu/drm/r128/r128_drv.c @@ -64,7 +64,7 @@ static struct drm_driver driver = { .owner = THIS_MODULE, .open = drm_open, .release = drm_release, - .ioctl = drm_ioctl, + .unlocked_ioctl = drm_ioctl, .mmap = drm_mmap, .poll = drm_poll, .fasync = drm_fasync, diff --git a/drivers/gpu/drm/r128/r128_ioc32.c b/drivers/gpu/drm/r128/r128_ioc32.c index d3cb676..51c99fc 100644 --- a/drivers/gpu/drm/r128/r128_ioc32.c +++ b/drivers/gpu/drm/r128/r128_ioc32.c @@ -95,8 +95,7 @@ static int compat_r128_init(struct file *file, unsigned int cmd, &init->agp_textures_offset)) return -EFAULT; - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_R128_INIT, (unsigned long)init); + return drm_ioctl(file, DRM_IOCTL_R128_INIT, (unsigned long)init); } typedef struct drm_r128_depth32 { @@ -129,8 +128,7 @@ static int compat_r128_depth(struct file *file, unsigned int cmd, &depth->mask)) return -EFAULT; - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_R128_DEPTH, (unsigned long)depth); + return drm_ioctl(file, DRM_IOCTL_R128_DEPTH, (unsigned long)depth); } @@ -153,8 +151,7 @@ static int compat_r128_stipple(struct file *file, unsigned int cmd, &stipple->mask)) return -EFAULT; - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_R128_STIPPLE, (unsigned long)stipple); + return drm_ioctl(file, DRM_IOCTL_R128_STIPPLE, (unsigned long)stipple); } typedef struct drm_r128_getparam32 { @@ -178,8 +175,7 @@ static int compat_r128_getparam(struct file *file, unsigned int cmd, &getparam->value)) return -EFAULT; - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_R128_GETPARAM, (unsigned long)getparam); + return drm_ioctl(file, DRM_IOCTL_R128_GETPARAM, (unsigned long)getparam); } drm_ioctl_compat_t *r128_compat_ioctls[] = { @@ -210,12 +206,10 @@ long r128_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(r128_compat_ioctls)) fn = r128_compat_ioctls[nr - DRM_COMMAND_BASE]; - lock_kernel(); /* XXX for now */ if (fn != NULL) ret = (*fn) (filp, cmd, arg); else - ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg); - unlock_kernel(); + ret = drm_ioctl(filp, cmd, arg); return ret; } diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index dbd56ef..8ba3de7 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -196,7 +196,7 @@ static struct drm_driver driver_old = { .owner = THIS_MODULE, .open = drm_open, .release = drm_release, - .ioctl = drm_ioctl, + .unlocked_ioctl = drm_ioctl, .mmap = drm_mmap, .poll = drm_poll, .fasync = drm_fasync, @@ -284,7 +284,7 @@ static struct drm_driver kms_driver = { .owner = THIS_MODULE, .open = drm_open, .release = drm_release, - .ioctl = drm_ioctl, + .unlocked_ioctl = drm_ioctl, .mmap = radeon_mmap, .poll = drm_poll, .fasync = drm_fasync, diff --git a/drivers/gpu/drm/radeon/radeon_ioc32.c b/drivers/gpu/drm/radeon/radeon_ioc32.c index a1bf11d..48b7cea 100644 --- a/drivers/gpu/drm/radeon/radeon_ioc32.c +++ b/drivers/gpu/drm/radeon/radeon_ioc32.c @@ -92,8 +92,7 @@ static int compat_radeon_cp_init(struct file *file, unsigned int cmd, &init->gart_textures_offset)) return -EFAULT; - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_RADEON_CP_INIT, (unsigned long)init); + return drm_ioctl(file, DRM_IOCTL_RADEON_CP_INIT, (unsigned long)init); } typedef struct drm_radeon_clear32 { @@ -125,8 +124,7 @@ static int compat_radeon_cp_clear(struct file *file, unsigned int cmd, &clr->depth_boxes)) return -EFAULT; - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_RADEON_CLEAR, (unsigned long)clr); + return drm_ioctl(file, DRM_IOCTL_RADEON_CLEAR, (unsigned long)clr); } typedef struct drm_radeon_stipple32 { @@ -149,8 +147,7 @@ static int compat_radeon_cp_stipple(struct file *file, unsigned int cmd, &request->mask)) return -EFAULT; - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_RADEON_STIPPLE, (unsigned long)request); + return drm_ioctl(file, DRM_IOCTL_RADEON_STIPPLE, (unsigned long)request); } typedef struct drm_radeon_tex_image32 { @@ -204,8 +201,7 @@ static int compat_radeon_cp_texture(struct file *file, unsigned int cmd, &image->data)) return -EFAULT; - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_RADEON_TEXTURE, (unsigned long)request); + return drm_ioctl(file, DRM_IOCTL_RADEON_TEXTURE, (unsigned long)request); } typedef struct drm_radeon_vertex2_32 { @@ -238,8 +234,7 @@ static int compat_radeon_cp_vertex2(struct file *file, unsigned int cmd, &request->prim)) return -EFAULT; - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_RADEON_VERTEX2, (unsigned long)request); + return drm_ioctl(file, DRM_IOCTL_RADEON_VERTEX2, (unsigned long)request); } typedef struct drm_radeon_cmd_buffer32 { @@ -268,8 +263,7 @@ static int compat_radeon_cp_cmdbuf(struct file *file, unsigned int cmd, &request->boxes)) return -EFAULT; - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_RADEON_CMDBUF, (unsigned long)request); + return drm_ioctl(file, DRM_IOCTL_RADEON_CMDBUF, (unsigned long)request); } typedef struct drm_radeon_getparam32 { @@ -293,8 +287,7 @@ static int compat_radeon_cp_getparam(struct file *file, unsigned int cmd, &request->value)) return -EFAULT; - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_RADEON_GETPARAM, (unsigned long)request); + return drm_ioctl(file, DRM_IOCTL_RADEON_GETPARAM, (unsigned long)request); } typedef struct drm_radeon_mem_alloc32 { @@ -322,8 +315,7 @@ static int compat_radeon_mem_alloc(struct file *file, unsigned int cmd, &request->region_offset)) return -EFAULT; - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_RADEON_ALLOC, (unsigned long)request); + return drm_ioctl(file, DRM_IOCTL_RADEON_ALLOC, (unsigned long)request); } typedef struct drm_radeon_irq_emit32 { @@ -345,8 +337,7 @@ static int compat_radeon_irq_emit(struct file *file, unsigned int cmd, &request->irq_seq)) return -EFAULT; - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_RADEON_IRQ_EMIT, (unsigned long)request); + return drm_ioctl(file, DRM_IOCTL_RADEON_IRQ_EMIT, (unsigned long)request); } /* The two 64-bit arches where alignof(u64)==4 in 32-bit code */ @@ -372,8 +363,7 @@ static int compat_radeon_cp_setparam(struct file *file, unsigned int cmd, &request->value)) return -EFAULT; - return drm_ioctl(file->f_dentry->d_inode, file, - DRM_IOCTL_RADEON_SETPARAM, (unsigned long) request); + return drm_ioctl(file, DRM_IOCTL_RADEON_SETPARAM, (unsigned long) request); } #else #define compat_radeon_cp_setparam NULL @@ -413,12 +403,10 @@ long radeon_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(radeon_compat_ioctls)) fn = radeon_compat_ioctls[nr - DRM_COMMAND_BASE]; - lock_kernel(); /* XXX for now */ if (fn != NULL) ret = (*fn) (filp, cmd, arg); else - ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg); - unlock_kernel(); + ret = drm_ioctl(filp, cmd, arg); return ret; } @@ -431,9 +419,7 @@ long radeon_kms_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long if (nr < DRM_COMMAND_BASE) return drm_compat_ioctl(filp, cmd, arg); - lock_kernel(); /* XXX for now */ - ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg); - unlock_kernel(); + ret = drm_ioctl(filp, cmd, arg); return ret; } diff --git a/drivers/gpu/drm/savage/savage_drv.c b/drivers/gpu/drm/savage/savage_drv.c index eee52aa..021de44 100644 --- a/drivers/gpu/drm/savage/savage_drv.c +++ b/drivers/gpu/drm/savage/savage_drv.c @@ -50,7 +50,7 @@ static struct drm_driver driver = { .owner = THIS_MODULE, .open = drm_open, .release = drm_release, - .ioctl = drm_ioctl, + .unlocked_ioctl = drm_ioctl, .mmap = drm_mmap, .poll = drm_poll, .fasync = drm_fasync, diff --git a/drivers/gpu/drm/sis/sis_drv.c b/drivers/gpu/drm/sis/sis_drv.c index e725cc0..4fd1f06 100644 --- a/drivers/gpu/drm/sis/sis_drv.c +++ b/drivers/gpu/drm/sis/sis_drv.c @@ -80,7 +80,7 @@ static struct drm_driver driver = { .owner = THIS_MODULE, .open = drm_open, .release = drm_release, - .ioctl = drm_ioctl, + .unlocked_ioctl = drm_ioctl, .mmap = drm_mmap, .poll = drm_poll, .fasync = drm_fasync, diff --git a/drivers/gpu/drm/tdfx/tdfx_drv.c b/drivers/gpu/drm/tdfx/tdfx_drv.c index 012ff2e..ec5a43e 100644 --- a/drivers/gpu/drm/tdfx/tdfx_drv.c +++ b/drivers/gpu/drm/tdfx/tdfx_drv.c @@ -48,7 +48,7 @@ static struct drm_driver driver = { .owner = THIS_MODULE, .open = drm_open, .release = drm_release, - .ioctl = drm_ioctl, + .unlocked_ioctl = drm_ioctl, .mmap = drm_mmap, .poll = drm_poll, .fasync = drm_fasync, diff --git a/drivers/gpu/drm/via/via_drv.c b/drivers/gpu/drm/via/via_drv.c index bc2f518..7a1b210 100644 --- a/drivers/gpu/drm/via/via_drv.c +++ b/drivers/gpu/drm/via/via_drv.c @@ -58,7 +58,7 @@ static struct drm_driver driver = { .owner = THIS_MODULE, .open = drm_open, .release = drm_release, - .ioctl = drm_ioctl, + .unlocked_ioctl = drm_ioctl, .mmap = drm_mmap, .poll = drm_poll, .fasync = drm_fasync, diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 19ef8eb..71dafb6 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -296,6 +296,7 @@ typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd, #define DRM_MASTER 0x2 #define DRM_ROOT_ONLY 0x4 #define DRM_CONTROL_ALLOW 0x8 +#define DRM_UNLOCKED 0x10 struct drm_ioctl_desc { unsigned int cmd; @@ -1128,8 +1129,8 @@ static inline int drm_mtrr_del(int handle, unsigned long offset, /* Driver support (drm_drv.h) */ extern int drm_init(struct drm_driver *driver); extern void drm_exit(struct drm_driver *driver); -extern int drm_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); +extern long drm_ioctl(struct file *filp, + unsigned int cmd, unsigned long arg); extern long drm_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); extern int drm_lastclose(struct drm_device *dev); -- cgit v0.10.2 From 925cc71e512a29e2594bcc17dc58d0a0e9c4d524 Mon Sep 17 00:00:00 2001 From: Robert Jennings Date: Thu, 17 Dec 2009 14:44:38 +0000 Subject: mm: Add notifier in pageblock isolation for balloon drivers Memory balloon drivers can allocate a large amount of memory which is not movable but could be freed to accomodate memory hotplug remove. Prior to calling the memory hotplug notifier chain the memory in the pageblock is isolated. Currently, if the migrate type is not MIGRATE_MOVABLE the isolation will not proceed, causing the memory removal for that page range to fail. Rather than failing pageblock isolation if the migrateteype is not MIGRATE_MOVABLE, this patch checks if all of the pages in the pageblock, and not on the LRU, are owned by a registered balloon driver (or other entity) using a notifier chain. If all of the non-movable pages are owned by a balloon, they can be freed later through the memory notifier chain and the range can still be isolated in set_migratetype_isolate(). Signed-off-by: Robert Jennings Cc: Mel Gorman Cc: Ingo Molnar Cc: Brian King Cc: Paul Mackerras Cc: Martin Schwidefsky Cc: Gerald Schaefer Cc: KAMEZAWA Hiroyuki Cc: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Benjamin Herrenschmidt diff --git a/drivers/base/memory.c b/drivers/base/memory.c index c4c8f2e..d7d77d4 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -63,6 +63,20 @@ void unregister_memory_notifier(struct notifier_block *nb) } EXPORT_SYMBOL(unregister_memory_notifier); +static ATOMIC_NOTIFIER_HEAD(memory_isolate_chain); + +int register_memory_isolate_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_register(&memory_isolate_chain, nb); +} +EXPORT_SYMBOL(register_memory_isolate_notifier); + +void unregister_memory_isolate_notifier(struct notifier_block *nb) +{ + atomic_notifier_chain_unregister(&memory_isolate_chain, nb); +} +EXPORT_SYMBOL(unregister_memory_isolate_notifier); + /* * register_memory - Setup a sysfs device for a memory block */ @@ -157,6 +171,11 @@ int memory_notify(unsigned long val, void *v) return blocking_notifier_call_chain(&memory_chain, val, v); } +int memory_isolate_notify(unsigned long val, void *v) +{ + return atomic_notifier_call_chain(&memory_isolate_chain, val, v); +} + /* * MEMORY_HOTPLUG depends on SPARSEMEM in mm/Kconfig, so it is * OK to have direct references to sparsemem variables in here. diff --git a/include/linux/memory.h b/include/linux/memory.h index 37fa19b..1adfe77 100644 --- a/include/linux/memory.h +++ b/include/linux/memory.h @@ -50,6 +50,19 @@ struct memory_notify { int status_change_nid; }; +/* + * During pageblock isolation, count the number of pages within the + * range [start_pfn, start_pfn + nr_pages) which are owned by code + * in the notifier chain. + */ +#define MEM_ISOLATE_COUNT (1<<0) + +struct memory_isolate_notify { + unsigned long start_pfn; /* Start of range to check */ + unsigned int nr_pages; /* # pages in range to check */ + unsigned int pages_found; /* # pages owned found by callbacks */ +}; + struct notifier_block; struct mem_section; @@ -76,14 +89,28 @@ static inline int memory_notify(unsigned long val, void *v) { return 0; } +static inline int register_memory_isolate_notifier(struct notifier_block *nb) +{ + return 0; +} +static inline void unregister_memory_isolate_notifier(struct notifier_block *nb) +{ +} +static inline int memory_isolate_notify(unsigned long val, void *v) +{ + return 0; +} #else extern int register_memory_notifier(struct notifier_block *nb); extern void unregister_memory_notifier(struct notifier_block *nb); +extern int register_memory_isolate_notifier(struct notifier_block *nb); +extern void unregister_memory_isolate_notifier(struct notifier_block *nb); extern int register_new_memory(int, struct mem_section *); extern int unregister_memory_section(struct mem_section *); extern int memory_dev_init(void); extern int remove_memory_block(unsigned long, struct mem_section *, int); extern int memory_notify(unsigned long val, void *v); +extern int memory_isolate_notify(unsigned long val, void *v); extern struct memory_block *find_memory_block(struct mem_section *); #define CONFIG_MEM_BLOCK_SIZE (PAGES_PER_SECTION< #include #include +#include #include #include @@ -5008,23 +5009,65 @@ void set_pageblock_flags_group(struct page *page, unsigned long flags, int set_migratetype_isolate(struct page *page) { struct zone *zone; - unsigned long flags; + struct page *curr_page; + unsigned long flags, pfn, iter; + unsigned long immobile = 0; + struct memory_isolate_notify arg; + int notifier_ret; int ret = -EBUSY; int zone_idx; zone = page_zone(page); zone_idx = zone_idx(zone); + spin_lock_irqsave(&zone->lock, flags); + if (get_pageblock_migratetype(page) == MIGRATE_MOVABLE || + zone_idx == ZONE_MOVABLE) { + ret = 0; + goto out; + } + + pfn = page_to_pfn(page); + arg.start_pfn = pfn; + arg.nr_pages = pageblock_nr_pages; + arg.pages_found = 0; + /* - * In future, more migrate types will be able to be isolation target. + * It may be possible to isolate a pageblock even if the + * migratetype is not MIGRATE_MOVABLE. The memory isolation + * notifier chain is used by balloon drivers to return the + * number of pages in a range that are held by the balloon + * driver to shrink memory. If all the pages are accounted for + * by balloons, are free, or on the LRU, isolation can continue. + * Later, for example, when memory hotplug notifier runs, these + * pages reported as "can be isolated" should be isolated(freed) + * by the balloon driver through the memory notifier chain. */ - if (get_pageblock_migratetype(page) != MIGRATE_MOVABLE && - zone_idx != ZONE_MOVABLE) + notifier_ret = memory_isolate_notify(MEM_ISOLATE_COUNT, &arg); + notifier_ret = notifier_to_errno(notifier_ret); + if (notifier_ret || !arg.pages_found) goto out; - set_pageblock_migratetype(page, MIGRATE_ISOLATE); - move_freepages_block(zone, page, MIGRATE_ISOLATE); - ret = 0; + + for (iter = pfn; iter < (pfn + pageblock_nr_pages); iter++) { + if (!pfn_valid_within(pfn)) + continue; + + curr_page = pfn_to_page(iter); + if (!page_count(curr_page) || PageLRU(curr_page)) + continue; + + immobile++; + } + + if (arg.pages_found == immobile) + ret = 0; + out: + if (!ret) { + set_pageblock_migratetype(page, MIGRATE_ISOLATE); + move_freepages_block(zone, page, MIGRATE_ISOLATE); + } + spin_unlock_irqrestore(&zone->lock, flags); if (!ret) drain_all_pages(); -- cgit v0.10.2 From 14b8a76b9d53346f2871bf419da2aaf219940c50 Mon Sep 17 00:00:00 2001 From: Robert Jennings Date: Thu, 17 Dec 2009 14:44:52 +0000 Subject: powerpc: Make the CMM memory hotplug aware The Collaborative Memory Manager (CMM) module allocates individual pages over time that are not migratable. On a long running system this can severely impact the ability to find enough pages to support a hotplug memory remove operation. This patch adds a memory isolation notifier and a memory hotplug notifier. The memory isolation notifier will return the number of pages found in the range specified. This is used to determine if all of the used pages in a pageblock are owned by the balloon (or other entities in the notifier chain). The hotplug notifier will free pages in the range which is to be removed. The priority of this hotplug notifier is low so that it will be called near last, this helps avoids removing loaned pages in operations that fail due to other handlers. CMM activity will be halted when hotplug remove operations are active and resume activity after a delay period to allow the hypervisor time to adjust. Signed-off-by: Robert Jennings Cc: Mel Gorman Cc: Ingo Molnar Cc: Brian King Cc: Paul Mackerras Cc: Martin Schwidefsky Cc: Gerald Schaefer Cc: KAMEZAWA Hiroyuki Cc: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/platforms/pseries/cmm.c b/arch/powerpc/platforms/pseries/cmm.c index bcdcf0c..a277f2e 100644 --- a/arch/powerpc/platforms/pseries/cmm.c +++ b/arch/powerpc/platforms/pseries/cmm.c @@ -38,19 +38,28 @@ #include #include #include +#include #include "plpar_wrappers.h" #define CMM_DRIVER_VERSION "1.0.0" #define CMM_DEFAULT_DELAY 1 +#define CMM_HOTPLUG_DELAY 5 #define CMM_DEBUG 0 #define CMM_DISABLE 0 #define CMM_OOM_KB 1024 #define CMM_MIN_MEM_MB 256 #define KB2PAGES(_p) ((_p)>>(PAGE_SHIFT-10)) #define PAGES2KB(_p) ((_p)<<(PAGE_SHIFT-10)) +/* + * The priority level tries to ensure that this notifier is called as + * late as possible to reduce thrashing in the shared memory pool. + */ +#define CMM_MEM_HOTPLUG_PRI 1 +#define CMM_MEM_ISOLATE_PRI 15 static unsigned int delay = CMM_DEFAULT_DELAY; +static unsigned int hotplug_delay = CMM_HOTPLUG_DELAY; static unsigned int oom_kb = CMM_OOM_KB; static unsigned int cmm_debug = CMM_DEBUG; static unsigned int cmm_disabled = CMM_DISABLE; @@ -65,6 +74,10 @@ MODULE_VERSION(CMM_DRIVER_VERSION); module_param_named(delay, delay, uint, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(delay, "Delay (in seconds) between polls to query hypervisor paging requests. " "[Default=" __stringify(CMM_DEFAULT_DELAY) "]"); +module_param_named(hotplug_delay, hotplug_delay, uint, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(delay, "Delay (in seconds) after memory hotplug remove " + "before loaning resumes. " + "[Default=" __stringify(CMM_HOTPLUG_DELAY) "]"); module_param_named(oom_kb, oom_kb, uint, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(oom_kb, "Amount of memory in kb to free on OOM. " "[Default=" __stringify(CMM_OOM_KB) "]"); @@ -92,6 +105,9 @@ static unsigned long oom_freed_pages; static struct cmm_page_array *cmm_page_list; static DEFINE_SPINLOCK(cmm_lock); +static DEFINE_MUTEX(hotplug_mutex); +static int hotplug_occurred; /* protected by the hotplug mutex */ + static struct task_struct *cmm_thread_ptr; /** @@ -110,6 +126,17 @@ static long cmm_alloc_pages(long nr) cmm_dbg("Begin request for %ld pages\n", nr); while (nr) { + /* Exit if a hotplug operation is in progress or occurred */ + if (mutex_trylock(&hotplug_mutex)) { + if (hotplug_occurred) { + mutex_unlock(&hotplug_mutex); + break; + } + mutex_unlock(&hotplug_mutex); + } else { + break; + } + addr = __get_free_page(GFP_NOIO | __GFP_NOWARN | __GFP_NORETRY | __GFP_NOMEMALLOC); if (!addr) @@ -119,8 +146,9 @@ static long cmm_alloc_pages(long nr) if (!pa || pa->index >= CMM_NR_PAGES) { /* Need a new page for the page list. */ spin_unlock(&cmm_lock); - npa = (struct cmm_page_array *)__get_free_page(GFP_NOIO | __GFP_NOWARN | - __GFP_NORETRY | __GFP_NOMEMALLOC); + npa = (struct cmm_page_array *)__get_free_page( + GFP_NOIO | __GFP_NOWARN | + __GFP_NORETRY | __GFP_NOMEMALLOC); if (!npa) { pr_info("%s: Can not allocate new page list\n", __func__); free_page(addr); @@ -282,9 +310,28 @@ static int cmm_thread(void *dummy) while (1) { timeleft = msleep_interruptible(delay * 1000); - if (kthread_should_stop() || timeleft) { - loaned_pages_target = loaned_pages; + if (kthread_should_stop() || timeleft) break; + + if (mutex_trylock(&hotplug_mutex)) { + if (hotplug_occurred) { + hotplug_occurred = 0; + mutex_unlock(&hotplug_mutex); + cmm_dbg("Hotplug operation has occurred, " + "loaning activity suspended " + "for %d seconds.\n", + hotplug_delay); + timeleft = msleep_interruptible(hotplug_delay * + 1000); + if (kthread_should_stop() || timeleft) + break; + continue; + } + mutex_unlock(&hotplug_mutex); + } else { + cmm_dbg("Hotplug operation in progress, activity " + "suspended\n"); + continue; } cmm_get_mpp(); @@ -414,6 +461,193 @@ static struct notifier_block cmm_reboot_nb = { }; /** + * cmm_count_pages - Count the number of pages loaned in a particular range. + * + * @arg: memory_isolate_notify structure with address range and count + * + * Return value: + * 0 on success + **/ +static unsigned long cmm_count_pages(void *arg) +{ + struct memory_isolate_notify *marg = arg; + struct cmm_page_array *pa; + unsigned long start = (unsigned long)pfn_to_kaddr(marg->start_pfn); + unsigned long end = start + (marg->nr_pages << PAGE_SHIFT); + unsigned long idx; + + spin_lock(&cmm_lock); + pa = cmm_page_list; + while (pa) { + if ((unsigned long)pa >= start && (unsigned long)pa < end) + marg->pages_found++; + for (idx = 0; idx < pa->index; idx++) + if (pa->page[idx] >= start && pa->page[idx] < end) + marg->pages_found++; + pa = pa->next; + } + spin_unlock(&cmm_lock); + return 0; +} + +/** + * cmm_memory_isolate_cb - Handle memory isolation notifier calls + * @self: notifier block struct + * @action: action to take + * @arg: struct memory_isolate_notify data for handler + * + * Return value: + * NOTIFY_OK or notifier error based on subfunction return value + **/ +static int cmm_memory_isolate_cb(struct notifier_block *self, + unsigned long action, void *arg) +{ + int ret = 0; + + if (action == MEM_ISOLATE_COUNT) + ret = cmm_count_pages(arg); + + if (ret) + ret = notifier_from_errno(ret); + else + ret = NOTIFY_OK; + + return ret; +} + +static struct notifier_block cmm_mem_isolate_nb = { + .notifier_call = cmm_memory_isolate_cb, + .priority = CMM_MEM_ISOLATE_PRI +}; + +/** + * cmm_mem_going_offline - Unloan pages where memory is to be removed + * @arg: memory_notify structure with page range to be offlined + * + * Return value: + * 0 on success + **/ +static int cmm_mem_going_offline(void *arg) +{ + struct memory_notify *marg = arg; + unsigned long start_page = (unsigned long)pfn_to_kaddr(marg->start_pfn); + unsigned long end_page = start_page + (marg->nr_pages << PAGE_SHIFT); + struct cmm_page_array *pa_curr, *pa_last, *npa; + unsigned long idx; + unsigned long freed = 0; + + cmm_dbg("Memory going offline, searching 0x%lx (%ld pages).\n", + start_page, marg->nr_pages); + spin_lock(&cmm_lock); + + /* Search the page list for pages in the range to be offlined */ + pa_last = pa_curr = cmm_page_list; + while (pa_curr) { + for (idx = (pa_curr->index - 1); (idx + 1) > 0; idx--) { + if ((pa_curr->page[idx] < start_page) || + (pa_curr->page[idx] >= end_page)) + continue; + + plpar_page_set_active(__pa(pa_curr->page[idx])); + free_page(pa_curr->page[idx]); + freed++; + loaned_pages--; + totalram_pages++; + pa_curr->page[idx] = pa_last->page[--pa_last->index]; + if (pa_last->index == 0) { + if (pa_curr == pa_last) + pa_curr = pa_last->next; + pa_last = pa_last->next; + free_page((unsigned long)cmm_page_list); + cmm_page_list = pa_last; + continue; + } + } + pa_curr = pa_curr->next; + } + + /* Search for page list structures in the range to be offlined */ + pa_last = NULL; + pa_curr = cmm_page_list; + while (pa_curr) { + if (((unsigned long)pa_curr >= start_page) && + ((unsigned long)pa_curr < end_page)) { + npa = (struct cmm_page_array *)__get_free_page( + GFP_NOIO | __GFP_NOWARN | + __GFP_NORETRY | __GFP_NOMEMALLOC); + if (!npa) { + spin_unlock(&cmm_lock); + cmm_dbg("Failed to allocate memory for list " + "management. Memory hotplug " + "failed.\n"); + return ENOMEM; + } + memcpy(npa, pa_curr, PAGE_SIZE); + if (pa_curr == cmm_page_list) + cmm_page_list = npa; + if (pa_last) + pa_last->next = npa; + free_page((unsigned long) pa_curr); + freed++; + pa_curr = npa; + } + + pa_last = pa_curr; + pa_curr = pa_curr->next; + } + + spin_unlock(&cmm_lock); + cmm_dbg("Released %ld pages in the search range.\n", freed); + + return 0; +} + +/** + * cmm_memory_cb - Handle memory hotplug notifier calls + * @self: notifier block struct + * @action: action to take + * @arg: struct memory_notify data for handler + * + * Return value: + * NOTIFY_OK or notifier error based on subfunction return value + * + **/ +static int cmm_memory_cb(struct notifier_block *self, + unsigned long action, void *arg) +{ + int ret = 0; + + switch (action) { + case MEM_GOING_OFFLINE: + mutex_lock(&hotplug_mutex); + hotplug_occurred = 1; + ret = cmm_mem_going_offline(arg); + break; + case MEM_OFFLINE: + case MEM_CANCEL_OFFLINE: + mutex_unlock(&hotplug_mutex); + cmm_dbg("Memory offline operation complete.\n"); + break; + case MEM_GOING_ONLINE: + case MEM_ONLINE: + case MEM_CANCEL_ONLINE: + break; + } + + if (ret) + ret = notifier_from_errno(ret); + else + ret = NOTIFY_OK; + + return ret; +} + +static struct notifier_block cmm_mem_nb = { + .notifier_call = cmm_memory_cb, + .priority = CMM_MEM_HOTPLUG_PRI +}; + +/** * cmm_init - Module initialization * * Return value: @@ -435,18 +669,24 @@ static int cmm_init(void) if ((rc = cmm_sysfs_register(&cmm_sysdev))) goto out_reboot_notifier; + if (register_memory_notifier(&cmm_mem_nb) || + register_memory_isolate_notifier(&cmm_mem_isolate_nb)) + goto out_unregister_notifier; + if (cmm_disabled) return rc; cmm_thread_ptr = kthread_run(cmm_thread, NULL, "cmmthread"); if (IS_ERR(cmm_thread_ptr)) { rc = PTR_ERR(cmm_thread_ptr); - goto out_unregister_sysfs; + goto out_unregister_notifier; } return rc; -out_unregister_sysfs: +out_unregister_notifier: + unregister_memory_notifier(&cmm_mem_nb); + unregister_memory_isolate_notifier(&cmm_mem_isolate_nb); cmm_unregister_sysfs(&cmm_sysdev); out_reboot_notifier: unregister_reboot_notifier(&cmm_reboot_nb); @@ -467,6 +707,8 @@ static void cmm_exit(void) kthread_stop(cmm_thread_ptr); unregister_oom_notifier(&cmm_oom_nb); unregister_reboot_notifier(&cmm_reboot_nb); + unregister_memory_notifier(&cmm_mem_nb); + unregister_memory_isolate_notifier(&cmm_mem_isolate_nb); cmm_free_pages(loaned_pages); cmm_unregister_sysfs(&cmm_sysdev); } -- cgit v0.10.2 From 5c916a295f27dbc0df4769a53b109666506bd061 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Thu, 17 Dec 2009 14:45:05 +0000 Subject: powerpc/iseries: Convert to proc_fops Signed-off-by: Alexey Dobriyan Cc: Benjamin Herrenschmidt Cc: Michael Ellerman Signed-off-by: Andrew Morton Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/platforms/iseries/mf.c b/arch/powerpc/platforms/iseries/mf.c index 0d9343d..6617915 100644 --- a/arch/powerpc/platforms/iseries/mf.c +++ b/arch/powerpc/platforms/iseries/mf.c @@ -855,59 +855,58 @@ static int mf_get_boot_rtc(struct rtc_time *tm) } #ifdef CONFIG_PROC_FS - -static int proc_mf_dump_cmdline(char *page, char **start, off_t off, - int count, int *eof, void *data) +static int mf_cmdline_proc_show(struct seq_file *m, void *v) { - int len; - char *p; + char *page, *p; struct vsp_cmd_data vsp_cmd; int rc; dma_addr_t dma_addr; /* The HV appears to return no more than 256 bytes of command line */ - if (off >= 256) - return 0; - if ((off + count) > 256) - count = 256 - off; + page = kmalloc(256, GFP_KERNEL); + if (!page) + return -ENOMEM; - dma_addr = iseries_hv_map(page, off + count, DMA_FROM_DEVICE); - if (dma_addr == DMA_ERROR_CODE) + dma_addr = iseries_hv_map(page, 256, DMA_FROM_DEVICE); + if (dma_addr == DMA_ERROR_CODE) { + kfree(page); return -ENOMEM; - memset(page, 0, off + count); + } + memset(page, 0, 256); memset(&vsp_cmd, 0, sizeof(vsp_cmd)); vsp_cmd.cmd = 33; vsp_cmd.sub_data.kern.token = dma_addr; vsp_cmd.sub_data.kern.address_type = HvLpDma_AddressType_TceIndex; - vsp_cmd.sub_data.kern.side = (u64)data; - vsp_cmd.sub_data.kern.length = off + count; + vsp_cmd.sub_data.kern.side = (u64)m->private; + vsp_cmd.sub_data.kern.length = 256; mb(); rc = signal_vsp_instruction(&vsp_cmd); - iseries_hv_unmap(dma_addr, off + count, DMA_FROM_DEVICE); - if (rc) + iseries_hv_unmap(dma_addr, 256, DMA_FROM_DEVICE); + if (rc) { + kfree(page); return rc; - if (vsp_cmd.result_code != 0) + } + if (vsp_cmd.result_code != 0) { + kfree(page); return -ENOMEM; + } p = page; - len = 0; - while (len < (off + count)) { - if ((*p == '\0') || (*p == '\n')) { - if (*p == '\0') - *p = '\n'; - p++; - len++; - *eof = 1; + while (p - page < 256) { + if (*p == '\0' || *p == '\n') { + *p = '\n'; break; } p++; - len++; - } - if (len < off) { - *eof = 1; - len = 0; } - return len; + seq_write(m, page, p - page); + kfree(page); + return 0; +} + +static int mf_cmdline_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, mf_cmdline_proc_show, PDE(inode)->data); } #if 0 @@ -962,10 +961,8 @@ static int proc_mf_dump_vmlinux(char *page, char **start, off_t off, } #endif -static int proc_mf_dump_side(char *page, char **start, off_t off, - int count, int *eof, void *data) +static int mf_side_proc_show(struct seq_file *m, void *v) { - int len; char mf_current_side = ' '; struct vsp_cmd_data vsp_cmd; @@ -989,21 +986,17 @@ static int proc_mf_dump_side(char *page, char **start, off_t off, } } - len = sprintf(page, "%c\n", mf_current_side); + seq_printf(m, "%c\n", mf_current_side); + return 0; +} - if (len <= (off + count)) - *eof = 1; - *start = page + off; - len -= off; - if (len > count) - len = count; - if (len < 0) - len = 0; - return len; +static int mf_side_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, mf_side_proc_show, NULL); } -static int proc_mf_change_side(struct file *file, const char __user *buffer, - unsigned long count, void *data) +static ssize_t mf_side_proc_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) { char side; u64 newSide; @@ -1041,6 +1034,15 @@ static int proc_mf_change_side(struct file *file, const char __user *buffer, return count; } +static const struct file_operations mf_side_proc_fops = { + .owner = THIS_MODULE, + .open = mf_side_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = mf_side_proc_write, +}; + #if 0 static void mf_getSrcHistory(char *buffer, int size) { @@ -1087,8 +1089,7 @@ static void mf_getSrcHistory(char *buffer, int size) } #endif -static int proc_mf_dump_src(char *page, char **start, off_t off, - int count, int *eof, void *data) +static int mf_src_proc_show(struct seq_file *m, void *v) { #if 0 int len; @@ -1109,8 +1110,13 @@ static int proc_mf_dump_src(char *page, char **start, off_t off, #endif } -static int proc_mf_change_src(struct file *file, const char __user *buffer, - unsigned long count, void *data) +static int mf_src_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, mf_src_proc_show, NULL); +} + +static ssize_t mf_src_proc_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) { char stkbuf[10]; @@ -1135,9 +1141,19 @@ static int proc_mf_change_src(struct file *file, const char __user *buffer, return count; } -static int proc_mf_change_cmdline(struct file *file, const char __user *buffer, - unsigned long count, void *data) +static const struct file_operations mf_src_proc_fops = { + .owner = THIS_MODULE, + .open = mf_src_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = mf_src_proc_write, +}; + +static ssize_t mf_cmdline_proc_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) { + void *data = PDE(file->f_path.dentry->d_inode)->data; struct vsp_cmd_data vsp_cmd; dma_addr_t dma_addr; char *page; @@ -1172,6 +1188,15 @@ out: return ret; } +static const struct file_operations mf_cmdline_proc_fops = { + .owner = THIS_MODULE, + .open = mf_cmdline_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = mf_cmdline_proc_write, +}; + static ssize_t proc_mf_change_vmlinux(struct file *file, const char __user *buf, size_t count, loff_t *ppos) @@ -1246,12 +1271,10 @@ static int __init mf_proc_init(void) if (!mf) return 1; - ent = create_proc_entry("cmdline", S_IFREG|S_IRUSR|S_IWUSR, mf); + ent = proc_create_data("cmdline", S_IRUSR|S_IWUSR, mf, + &mf_cmdline_proc_fops, (void *)(long)i); if (!ent) return 1; - ent->data = (void *)(long)i; - ent->read_proc = proc_mf_dump_cmdline; - ent->write_proc = proc_mf_change_cmdline; if (i == 3) /* no vmlinux entry for 'D' */ continue; @@ -1263,19 +1286,15 @@ static int __init mf_proc_init(void) return 1; } - ent = create_proc_entry("side", S_IFREG|S_IRUSR|S_IWUSR, mf_proc_root); + ent = proc_create("side", S_IFREG|S_IRUSR|S_IWUSR, mf_proc_root, + &mf_side_proc_fops); if (!ent) return 1; - ent->data = (void *)0; - ent->read_proc = proc_mf_dump_side; - ent->write_proc = proc_mf_change_side; - ent = create_proc_entry("src", S_IFREG|S_IRUSR|S_IWUSR, mf_proc_root); + ent = proc_create("src", S_IFREG|S_IRUSR|S_IWUSR, mf_proc_root, + &mf_src_proc_fops); if (!ent) return 1; - ent->data = (void *)0; - ent->read_proc = proc_mf_dump_src; - ent->write_proc = proc_mf_change_src; return 0; } -- cgit v0.10.2 From 29827b02dc5d1eed8a1ff8b34cd1926966a87e89 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Thu, 17 Dec 2009 14:45:15 +0000 Subject: powerpc/85xx: Wrong variable returned on error The wrong variable was returned in the case of an error. Signed-off-by: Roel Kluin Cc: Kumar Gala Cc: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c index c5028a2..21f61b8 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c @@ -86,7 +86,7 @@ static int mpc8568_fixup_125_clock(struct phy_device *phydev) scr = phy_read(phydev, MV88E1111_SCR); if (scr < 0) - return err; + return scr; err = phy_write(phydev, MV88E1111_SCR, scr | 0x0008); -- cgit v0.10.2 From 8a55c4ba3ed95f3f73f5ee371e863a1deadaec5f Mon Sep 17 00:00:00 2001 From: Mel Gorman Date: Fri, 27 Nov 2009 06:33:58 +0000 Subject: powerpc/pseries: Select XICS and PCI_MSI PSERIES It's possible to set CONFIG_XICS without CONFIG_PCI_MSI. When that happens, the kernel fails to build with arch/powerpc/platforms/built-in.o: In function `.xics_startup': xics.c:(.text+0x12f60): undefined reference to `.unmask_msi_irq' make: *** [.tmp_vmlinux1] Error 1 Furthermore, as noted by Benjamin Herrenschmidt, "CONFIG_XICS should be made invisible and selected by PSERIES." This patch fixes PSERIES to select both options Signed-off-by: Mel Gorman Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig index 27554c8..c667f0f 100644 --- a/arch/powerpc/platforms/pseries/Kconfig +++ b/arch/powerpc/platforms/pseries/Kconfig @@ -2,6 +2,8 @@ config PPC_PSERIES depends on PPC64 && PPC_BOOK3S bool "IBM pSeries & new (POWER5-based) iSeries" select MPIC + select PCI_MSI + select XICS select PPC_I8259 select PPC_RTAS select PPC_RTAS_DAEMON -- cgit v0.10.2 From c2613c7f80eca4d334b3da18a2059d82b750b628 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Sun, 6 Dec 2009 17:45:09 +0000 Subject: powerpc/defconfigs: Reduce 64bit vmlinux by making acenic and cramfs modules Machines with acenic adapters are rare these days, so we may as well make it a module. Cramfs is also very rarely used so we can make it a module. Together this saves 143kB on a 64bit compile: text data bss dec hex filename 8247176 1729404 1221988 11198568 aae068 vmlinux~ 8134997 1727588 1188836 11051421 a8a19d vmlinux Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/configs/g5_defconfig b/arch/powerpc/configs/g5_defconfig index fc90592..6a66135 100644 --- a/arch/powerpc/configs/g5_defconfig +++ b/arch/powerpc/configs/g5_defconfig @@ -757,7 +757,7 @@ CONFIG_SUNGEM=y # CONFIG_B44 is not set # CONFIG_ATL2 is not set CONFIG_NETDEV_1000=y -CONFIG_ACENIC=y +CONFIG_ACENIC=m CONFIG_ACENIC_OMIT_TIGON_I=y # CONFIG_DL2K is not set CONFIG_E1000=y diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig index 2524018..34a6b12 100644 --- a/arch/powerpc/configs/ppc64_defconfig +++ b/arch/powerpc/configs/ppc64_defconfig @@ -980,7 +980,7 @@ CONFIG_E100=y # CONFIG_SC92031 is not set # CONFIG_ATL2 is not set CONFIG_NETDEV_1000=y -CONFIG_ACENIC=y +CONFIG_ACENIC=m CONFIG_ACENIC_OMIT_TIGON_I=y # CONFIG_DL2K is not set CONFIG_E1000=y @@ -1863,7 +1863,7 @@ CONFIG_HFSPLUS_FS=m # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set -CONFIG_CRAMFS=y +CONFIG_CRAMFS=m # CONFIG_VXFS_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_OMFS_FS is not set diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig index c568329..6ea82df4 100644 --- a/arch/powerpc/configs/pseries_defconfig +++ b/arch/powerpc/configs/pseries_defconfig @@ -796,7 +796,7 @@ CONFIG_E100=y # CONFIG_NET_POCKET is not set # CONFIG_ATL2 is not set CONFIG_NETDEV_1000=y -CONFIG_ACENIC=y +CONFIG_ACENIC=m CONFIG_ACENIC_OMIT_TIGON_I=y # CONFIG_DL2K is not set CONFIG_E1000=y @@ -1494,7 +1494,7 @@ CONFIG_CONFIGFS_FS=m # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set -CONFIG_CRAMFS=y +CONFIG_CRAMFS=m # CONFIG_VXFS_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_OMFS_FS is not set -- cgit v0.10.2 From 55f2fa147392ffd23cec56cbb3d85ab5b3ebc125 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Sun, 6 Dec 2009 17:45:55 +0000 Subject: powerpc/defconfigs: Disable token ring in powerpc defconfigs Token what? Lets save some space in our powerpc kernels and remove token ring support. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/configs/g5_defconfig b/arch/powerpc/configs/g5_defconfig index 6a66135..826a65d 100644 --- a/arch/powerpc/configs/g5_defconfig +++ b/arch/powerpc/configs/g5_defconfig @@ -794,8 +794,8 @@ CONFIG_NETDEV_10000=y # CONFIG_BNX2X is not set # CONFIG_QLGE is not set # CONFIG_SFC is not set -CONFIG_TR=y -CONFIG_IBMOL=y +# CONFIG_TR is not set +# CONFIG_IBMOL is not set # CONFIG_3C359 is not set # CONFIG_TMS380TR is not set diff --git a/arch/powerpc/configs/iseries_defconfig b/arch/powerpc/configs/iseries_defconfig index f925c55..76982c5 100644 --- a/arch/powerpc/configs/iseries_defconfig +++ b/arch/powerpc/configs/iseries_defconfig @@ -714,8 +714,8 @@ CONFIG_NETDEV_10000=y # CONFIG_BNX2X is not set # CONFIG_QLGE is not set # CONFIG_SFC is not set -CONFIG_TR=y -CONFIG_IBMOL=y +# CONFIG_TR is not set +# CONFIG_IBMOL is not set # CONFIG_3C359 is not set # CONFIG_TMS380TR is not set diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig index 34a6b12..4b043f9 100644 --- a/arch/powerpc/configs/ppc64_defconfig +++ b/arch/powerpc/configs/ppc64_defconfig @@ -1023,8 +1023,8 @@ CONFIG_PASEMI_MAC=y # CONFIG_BNX2X is not set # CONFIG_QLGE is not set # CONFIG_SFC is not set -CONFIG_TR=y -CONFIG_IBMOL=y +# CONFIG_TR is not set +# CONFIG_IBMOL is not set # CONFIG_3C359 is not set # CONFIG_TMS380TR is not set diff --git a/arch/powerpc/configs/ppc64e_defconfig b/arch/powerpc/configs/ppc64e_defconfig index 18af460..8195f16 100644 --- a/arch/powerpc/configs/ppc64e_defconfig +++ b/arch/powerpc/configs/ppc64e_defconfig @@ -1008,8 +1008,8 @@ CONFIG_IXGB=m # CONFIG_QLGE is not set # CONFIG_SFC is not set # CONFIG_BE2NET is not set -CONFIG_TR=y -CONFIG_IBMOL=y +# CONFIG_TR is not set +# CONFIG_IBMOL is not set # CONFIG_3C359 is not set # CONFIG_TMS380TR is not set CONFIG_WLAN=y diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig index 6ea82df4..e89fccb 100644 --- a/arch/powerpc/configs/pseries_defconfig +++ b/arch/powerpc/configs/pseries_defconfig @@ -834,8 +834,8 @@ CONFIG_S2IO=m # CONFIG_BNX2X is not set # CONFIG_QLGE is not set # CONFIG_SFC is not set -CONFIG_TR=y -CONFIG_IBMOL=y +# CONFIG_TR is not set +# CONFIG_IBMOL is not set # CONFIG_3C359 is not set # CONFIG_TMS380TR is not set -- cgit v0.10.2 From 030bdc3fd0807b6097a937468859f4b4baf1b950 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Sun, 6 Dec 2009 17:48:33 +0000 Subject: powerpc/defconfigs: Set HZ=100 on pseries and ppc64 defconfigs Now we have high res timers there is less of a reason for a high HZ value. Furthermore I think there a few reasons we should reduce HZ to 100: - Timer interrupt overhead. While this overhead is small, there are applications that are very sensitive to jitter (eg some HPC apps). - Issues with the timer wheel code. When coming out of NO_HZ idle we work our way through the timer code one tick at a time. If we have been idle a long time, this adds up - I sometimes see milliseconds of time spent in that loop. Long term we should fix the timer wheel algorithm, but for now if we reduce HZ then we reduce the amount of work the timer code has to do when coming out of idle. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig index 4b043f9..7b3804a 100644 --- a/arch/powerpc/configs/ppc64_defconfig +++ b/arch/powerpc/configs/ppc64_defconfig @@ -304,11 +304,11 @@ CONFIG_TICK_ONESHOT=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_GENERIC_CLOCKEVENTS_BUILD=y -# CONFIG_HZ_100 is not set -CONFIG_HZ_250=y +CONFIG_HZ_100=y +# CONFIG_HZ_250 is not set # CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set -CONFIG_HZ=250 +CONFIG_HZ=100 CONFIG_SCHED_HRTICK=y CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig index e89fccb..ca9ff9a 100644 --- a/arch/powerpc/configs/pseries_defconfig +++ b/arch/powerpc/configs/pseries_defconfig @@ -230,11 +230,11 @@ CONFIG_TICK_ONESHOT=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_GENERIC_CLOCKEVENTS_BUILD=y -# CONFIG_HZ_100 is not set -CONFIG_HZ_250=y +CONFIG_HZ_100=y +# CONFIG_HZ_250 is not set # CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set -CONFIG_HZ=250 +CONFIG_HZ=100 CONFIG_SCHED_HRTICK=y CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set -- cgit v0.10.2 From 50891457f1001450be61be0861b2b49abdcb5fb9 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Tue, 8 Dec 2009 21:08:44 +0000 Subject: powerpc/mm: Fix a WARN_ON() with CONFIG_DEBUG_PAGEALLOC and CONFIG_DEBUG_VM Set need to call __set_pte_at() and not set_pte_at() from __change_page_attr() since the later will perform checks with CONFIG_DEBUG_VM that aren't suitable to the way we override an existing PTE. (More specifically, it doesn't let you write over a present PTE). Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c index 177e403..573b3bd 100644 --- a/arch/powerpc/mm/pgtable_32.c +++ b/arch/powerpc/mm/pgtable_32.c @@ -382,7 +382,7 @@ static int __change_page_attr(struct page *page, pgprot_t prot) return 0; if (!get_pteptr(&init_mm, address, &kpte, &kpmd)) return -EINVAL; - set_pte_at(&init_mm, address, kpte, mk_pte(page, prot)); + __set_pte_at(&init_mm, address, kpte, mk_pte(page, prot), 0); wmb(); #ifdef CONFIG_PPC_STD_MMU flush_hash_pages(0, address, pmd_val(*kpmd), 1); -- cgit v0.10.2 From e9edb232d3b0848457a83a5b697f55264542892f Mon Sep 17 00:00:00 2001 From: Gautham R Shenoy Date: Thu, 10 Dec 2009 01:19:37 +0000 Subject: powerpc/pseries: Don't panic when H_PROD fails during cpu-online. If an online-attempt on a CPU which has been offlined using H_CEDE with an appropriate cede latency hint fails, don't panic. Instead print the error message and let the __cpu_up() code notify the CPU Hotplug framework of the failure, which in turn can notify the other subsystem through CPU_UP_CANCELED. Signed-off-by: Gautham R Shenoy Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c index 8868c01..b488663 100644 --- a/arch/powerpc/platforms/pseries/smp.c +++ b/arch/powerpc/platforms/pseries/smp.c @@ -144,8 +144,8 @@ static void __devinit smp_pSeries_kick_cpu(int nr) hcpuid = get_hard_smp_processor_id(nr); rc = plpar_hcall_norets(H_PROD, hcpuid); if (rc != H_SUCCESS) - panic("Error: Prod to wake up processor %d Ret= %ld\n", - nr, rc); + printk(KERN_ERR "Error: Prod to wake up processor %d\ + Ret= %ld\n", nr, rc); } } -- cgit v0.10.2 From 3d9b740b2d8d73795d745a46eabd55479ee68dcc Mon Sep 17 00:00:00 2001 From: Gautham R Shenoy Date: Thu, 10 Dec 2009 01:19:42 +0000 Subject: powerpc/pseries: Make declarations of cpu_hotplug_driver_lock() ANSI compatible. And add the __acquires() and __releases() annotations, while at it. Signed-off-by: Gautham R Shenoy Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c index 12df9e8..67b7a10 100644 --- a/arch/powerpc/platforms/pseries/dlpar.c +++ b/arch/powerpc/platforms/pseries/dlpar.c @@ -346,12 +346,14 @@ int dlpar_release_drc(u32 drc_index) static DEFINE_MUTEX(pseries_cpu_hotplug_mutex); -void cpu_hotplug_driver_lock() +void cpu_hotplug_driver_lock(void) +__acquires(pseries_cpu_hotplug_mutex) { mutex_lock(&pseries_cpu_hotplug_mutex); } -void cpu_hotplug_driver_unlock() +void cpu_hotplug_driver_unlock(void) +__releases(pseries_cpu_hotplug_mutex) { mutex_unlock(&pseries_cpu_hotplug_mutex); } -- cgit v0.10.2 From 01ae45bcd48527e90923d4a247259770eb836d2b Mon Sep 17 00:00:00 2001 From: David Daney Date: Thu, 10 Dec 2009 07:28:19 +0000 Subject: powerpc: Convert BUG() to use unreachable() Use the new unreachable() macro instead of for(;;); Signed-off-by: David Daney CC: Benjamin Herrenschmidt CC: Paul Mackerras CC: linuxppc-dev@ozlabs.org Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/include/asm/bug.h b/arch/powerpc/include/asm/bug.h index 64e1fdc..2c15212 100644 --- a/arch/powerpc/include/asm/bug.h +++ b/arch/powerpc/include/asm/bug.h @@ -68,7 +68,7 @@ _EMIT_BUG_ENTRY \ : : "i" (__FILE__), "i" (__LINE__), \ "i" (0), "i" (sizeof(struct bug_entry))); \ - for(;;) ; \ + unreachable(); \ } while (0) #define BUG_ON(x) do { \ -- cgit v0.10.2 From 5c3399198791f7f828eb9fd504dbb46eef3cb472 Mon Sep 17 00:00:00 2001 From: "Sachin P. Sant" Date: Sun, 13 Dec 2009 21:15:12 +0000 Subject: powerpc/mm: Fix hash_utils_64.c compile errors with DEBUG enabled. This time without the funny characters. Fix following build errors generated with DEBUG=1 cc1: warnings being treated as errors arch/powerpc/mm/hash_utils_64.c: In function 'htab_dt_scan_page_sizes': arch/powerpc/mm/hash_utils_64.c:343: error: format '%04x' expects type 'unsigned int', but argument 4 has type 'long unsigned int' arch/powerpc/mm/hash_utils_64.c:343: error: format '%08x' expects type 'unsigned int', but argument 5 has type 'long unsigned int' arch/powerpc/mm/hash_utils_64.c: In function 'htab_initialize': arch/powerpc/mm/hash_utils_64.c:666: error: format '%x' expects type 'unsigned int', but argument 4 has type 'long unsigned int' ... SNIP ... Signed-off-by: Sachin Sant Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index 50f867d..c7fa4da 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c @@ -340,7 +340,7 @@ static int __init htab_dt_scan_page_sizes(unsigned long node, else def->tlbiel = 0; - DBG(" %d: shift=%02x, sllp=%04x, avpnm=%08x, " + DBG(" %d: shift=%02x, sllp=%04lx, avpnm=%08lx, " "tlbiel=%d, penc=%d\n", idx, shift, def->sllp, def->avpnm, def->tlbiel, def->penc); @@ -663,7 +663,7 @@ static void __init htab_initialize(void) base = (unsigned long)__va(lmb.memory.region[i].base); size = lmb.memory.region[i].size; - DBG("creating mapping for region: %lx..%lx (prot: %x)\n", + DBG("creating mapping for region: %lx..%lx (prot: %lx)\n", base, size, prot); #ifdef CONFIG_U3_DART @@ -1115,7 +1115,7 @@ void flush_hash_page(unsigned long va, real_pte_t pte, int psize, int ssize, { unsigned long hash, index, shift, hidx, slot; - DBG_LOW("flush_hash_page(va=%016x)\n", va); + DBG_LOW("flush_hash_page(va=%016lx)\n", va); pte_iterate_hashed_subpages(pte, psize, va, index, shift) { hash = hpt_hash(va, shift, ssize); hidx = __rpte_to_hidx(pte, index); @@ -1123,7 +1123,7 @@ void flush_hash_page(unsigned long va, real_pte_t pte, int psize, int ssize, hash = ~hash; slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; slot += hidx & _PTEIDX_GROUP_IX; - DBG_LOW(" sub %d: hash=%x, hidx=%x\n", index, slot, hidx); + DBG_LOW(" sub %ld: hash=%lx, hidx=%lx\n", index, slot, hidx); ppc_md.hpte_invalidate(slot, va, psize, ssize, local); } pte_iterate_hashed_end(); } -- cgit v0.10.2 From f04b10cddb0fbceadbad7af38c31543298948d8f Mon Sep 17 00:00:00 2001 From: Yang Li Date: Mon, 14 Dec 2009 03:01:49 +0000 Subject: powerpc/mm: Fix typo of cpumask_clear_cpu() The function name of cpumask_clear_cpu was not correct. Fortunately nobody uses that code with hotplug yet :-) Reported-by: Jin Qing Signed-off-by: Li Yang Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/mm/mmu_context_nohash.c b/arch/powerpc/mm/mmu_context_nohash.c index be4f34c..1044a63 100644 --- a/arch/powerpc/mm/mmu_context_nohash.c +++ b/arch/powerpc/mm/mmu_context_nohash.c @@ -353,7 +353,7 @@ static int __cpuinit mmu_context_cpu_notify(struct notifier_block *self, read_lock(&tasklist_lock); for_each_process(p) { if (p->mm) - cpu_mask_clear_cpu(cpu, mm_cpumask(p->mm)); + cpumask_clear_cpu(cpu, mm_cpumask(p->mm)); } read_unlock(&tasklist_lock); break; -- cgit v0.10.2 From bb7f20b1c639606def3b91f4e4aca6daeee5d80a Mon Sep 17 00:00:00 2001 From: Neil Campbell Date: Mon, 14 Dec 2009 04:08:57 +0000 Subject: powerpc: Handle VSX alignment faults correctly in little-endian mode This patch fixes the handling of VSX alignment faults in little-endian mode (the current code assumes the processor is in big-endian mode). The patch also makes the handlers clear the top 8 bytes of the register when handling an 8 byte VSX load. This is based on 2.6.32. Signed-off-by: Neil Campbell Cc: Acked-by: Michael Neuling Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c index 3839839..b876e989 100644 --- a/arch/powerpc/kernel/align.c +++ b/arch/powerpc/kernel/align.c @@ -642,10 +642,14 @@ static int emulate_spe(struct pt_regs *regs, unsigned int reg, */ static int emulate_vsx(unsigned char __user *addr, unsigned int reg, unsigned int areg, struct pt_regs *regs, - unsigned int flags, unsigned int length) + unsigned int flags, unsigned int length, + unsigned int elsize) { char *ptr; + unsigned long *lptr; int ret = 0; + int sw = 0; + int i, j; flush_vsx_to_thread(current); @@ -654,19 +658,35 @@ static int emulate_vsx(unsigned char __user *addr, unsigned int reg, else ptr = (char *) ¤t->thread.vr[reg - 32]; - if (flags & ST) - ret = __copy_to_user(addr, ptr, length); - else { - if (flags & SPLT){ - ret = __copy_from_user(ptr, addr, length); - ptr += length; + lptr = (unsigned long *) ptr; + + if (flags & SW) + sw = elsize-1; + + for (j = 0; j < length; j += elsize) { + for (i = 0; i < elsize; ++i) { + if (flags & ST) + ret |= __put_user(ptr[i^sw], addr + i); + else + ret |= __get_user(ptr[i^sw], addr + i); } - ret |= __copy_from_user(ptr, addr, length); + ptr += elsize; + addr += elsize; } - if (flags & U) - regs->gpr[areg] = regs->dar; - if (ret) + + if (!ret) { + if (flags & U) + regs->gpr[areg] = regs->dar; + + /* Splat load copies the same data to top and bottom 8 bytes */ + if (flags & SPLT) + lptr[1] = lptr[0]; + /* For 8 byte loads, zero the top 8 bytes */ + else if (!(flags & ST) && (8 == length)) + lptr[1] = 0; + } else return -EFAULT; + return 1; } #endif @@ -767,16 +787,25 @@ int fix_alignment(struct pt_regs *regs) #ifdef CONFIG_VSX if ((instruction & 0xfc00003e) == 0x7c000018) { - /* Additional register addressing bit (64 VSX vs 32 FPR/GPR */ + unsigned int elsize; + + /* Additional register addressing bit (64 VSX vs 32 FPR/GPR) */ reg |= (instruction & 0x1) << 5; /* Simple inline decoder instead of a table */ + /* VSX has only 8 and 16 byte memory accesses */ + nb = 8; if (instruction & 0x200) nb = 16; - else if (instruction & 0x080) - nb = 8; - else - nb = 4; + + /* Vector stores in little-endian mode swap individual + elements, so process them separately */ + elsize = 4; + if (instruction & 0x80) + elsize = 8; + flags = 0; + if (regs->msr & MSR_LE) + flags |= SW; if (instruction & 0x100) flags |= ST; if (instruction & 0x040) @@ -787,7 +816,7 @@ int fix_alignment(struct pt_regs *regs) nb = 8; } PPC_WARN_ALIGNMENT(vsx, regs); - return emulate_vsx(addr, reg, areg, regs, flags, nb); + return emulate_vsx(addr, reg, areg, regs, flags, nb, elsize); } #endif /* A size of 0 indicates an instruction we don't support, with -- cgit v0.10.2 From 7a96c6b22efbd84e195836e192a3ce478cd6e14c Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Mon, 14 Dec 2009 15:31:13 +0000 Subject: powerpc: Fix MSI support on U4 bridge PCIe slot On machines using the Apple U4 bridge (AKA IBM CPC945) PCIe interface such as the latest generation G5 machines x16 slot or the x16 slot of the PowerStation, MSIs are currently broken (and will oops when enabling). This fixes the oops and implements proper support for those. Instead of using the PCIe <-> HT bridge conversion, on such slots we need to use a bunch of magic registers in the bridge as the MSI target, encoding the interrupt number in the low bits of the address itself Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/sysdev/mpic_msi.c b/arch/powerpc/sysdev/mpic_msi.c index 1d44eee..0f67cd7 100644 --- a/arch/powerpc/sysdev/mpic_msi.c +++ b/arch/powerpc/sysdev/mpic_msi.c @@ -39,7 +39,12 @@ static int mpic_msi_reserve_u3_hwirqs(struct mpic *mpic) pr_debug("mpic: found U3, guessing msi allocator setup\n"); - /* Reserve source numbers we know are reserved in the HW */ + /* Reserve source numbers we know are reserved in the HW. + * + * This is a bit of a mix of U3 and U4 reserves but that's going + * to work fine, we have plenty enugh numbers left so let's just + * mark anything we don't like reserved. + */ for (i = 0; i < 8; i++) msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, i); @@ -49,6 +54,10 @@ static int mpic_msi_reserve_u3_hwirqs(struct mpic *mpic) for (i = 100; i < 105; i++) msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, i); + for (i = 124; i < mpic->irq_count; i++) + msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, i); + + np = NULL; while ((np = of_find_all_nodes(np))) { pr_debug("mpic: mapping hwirqs for %s\n", np->full_name); diff --git a/arch/powerpc/sysdev/mpic_u3msi.c b/arch/powerpc/sysdev/mpic_u3msi.c index d3caf23..bcbfe79 100644 --- a/arch/powerpc/sysdev/mpic_u3msi.c +++ b/arch/powerpc/sysdev/mpic_u3msi.c @@ -64,12 +64,12 @@ static u64 read_ht_magic_addr(struct pci_dev *pdev, unsigned int pos) return addr; } -static u64 find_ht_magic_addr(struct pci_dev *pdev) +static u64 find_ht_magic_addr(struct pci_dev *pdev, unsigned int hwirq) { struct pci_bus *bus; unsigned int pos; - for (bus = pdev->bus; bus; bus = bus->parent) { + for (bus = pdev->bus; bus && bus->self; bus = bus->parent) { pos = pci_find_ht_capability(bus->self, HT_CAPTYPE_MSI_MAPPING); if (pos) return read_ht_magic_addr(bus->self, pos); @@ -78,13 +78,41 @@ static u64 find_ht_magic_addr(struct pci_dev *pdev) return 0; } +static u64 find_u4_magic_addr(struct pci_dev *pdev, unsigned int hwirq) +{ + struct pci_controller *hose = pci_bus_to_host(pdev->bus); + + /* U4 PCIe MSIs need to write to the special register in + * the bridge that generates interrupts. There should be + * theorically a register at 0xf8005000 where you just write + * the MSI number and that triggers the right interrupt, but + * unfortunately, this is busted in HW, the bridge endian swaps + * the value and hits the wrong nibble in the register. + * + * So instead we use another register set which is used normally + * for converting HT interrupts to MPIC interrupts, which decodes + * the interrupt number as part of the low address bits + * + * This will not work if we ever use more than one legacy MSI in + * a block but we never do. For one MSI or multiple MSI-X where + * each interrupt address can be specified separately, it works + * just fine. + */ + if (of_device_is_compatible(hose->dn, "u4-pcie") || + of_device_is_compatible(hose->dn, "U4-pcie")) + return 0xf8004000 | (hwirq << 4); + + return 0; +} + static int u3msi_msi_check_device(struct pci_dev *pdev, int nvec, int type) { if (type == PCI_CAP_ID_MSIX) pr_debug("u3msi: MSI-X untested, trying anyway.\n"); /* If we can't find a magic address then MSI ain't gonna work */ - if (find_ht_magic_addr(pdev) == 0) { + if (find_ht_magic_addr(pdev, 0) == 0 && + find_u4_magic_addr(pdev, 0) == 0) { pr_debug("u3msi: no magic address found for %s\n", pci_name(pdev)); return -ENXIO; @@ -118,10 +146,6 @@ static int u3msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) u64 addr; int hwirq; - addr = find_ht_magic_addr(pdev); - msg.address_lo = addr & 0xFFFFFFFF; - msg.address_hi = addr >> 32; - list_for_each_entry(entry, &pdev->msi_list, list) { hwirq = msi_bitmap_alloc_hwirqs(&msi_mpic->msi_bitmap, 1); if (hwirq < 0) { @@ -129,6 +153,12 @@ static int u3msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) return hwirq; } + addr = find_ht_magic_addr(pdev, hwirq); + if (addr == 0) + addr = find_u4_magic_addr(pdev, hwirq); + msg.address_lo = addr & 0xFFFFFFFF; + msg.address_hi = addr >> 32; + virq = irq_create_mapping(msi_mpic->irqhost, hwirq); if (virq == NO_IRQ) { pr_debug("u3msi: failed mapping hwirq 0x%x\n", hwirq); @@ -143,6 +173,8 @@ static int u3msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) pr_debug("u3msi: allocated virq 0x%x (hw 0x%x) addr 0x%lx\n", virq, hwirq, (unsigned long)addr); + printk("u3msi: allocated virq 0x%x (hw 0x%x) addr 0x%lx\n", + virq, hwirq, (unsigned long)addr); msg.data = hwirq; write_msi_msg(virq, &msg); -- cgit v0.10.2 From c3a66359398028cd8e5f32611950dc7dc32ea2f2 Mon Sep 17 00:00:00 2001 From: Yong Zhang Date: Wed, 16 Dec 2009 04:35:57 +0000 Subject: powerpc/iseries: use DECLARE_COMPLETION_ONSTACK for non-constant completion The _ONSTACK variant should be used for on-stack completion, otherwise it will break lockdep. Signed-off-by: Yong Zhang Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: linuxppc-dev@ozlabs.org Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/platforms/iseries/viopath.c b/arch/powerpc/platforms/iseries/viopath.c index 49ff4dc..5aea94f 100644 --- a/arch/powerpc/platforms/iseries/viopath.c +++ b/arch/powerpc/platforms/iseries/viopath.c @@ -116,7 +116,7 @@ static int proc_viopath_show(struct seq_file *m, void *v) u16 vlanMap; dma_addr_t handle; HvLpEvent_Rc hvrc; - DECLARE_COMPLETION(done); + DECLARE_COMPLETION_ONSTACK(done); struct device_node *node; const char *sysid; -- cgit v0.10.2 From a1128f8f0ff06ccbea5d6b4a69446b506c57bfbc Mon Sep 17 00:00:00 2001 From: David Gibson Date: Wed, 16 Dec 2009 14:29:56 +0000 Subject: powerpc/mm: Fix stupid bug in subpge protection handling Commit d28513bc7f675d28b479db666d572e078ecf182d ("Fix bug in pagetable cache cleanup with CONFIG_PPC_SUBPAGE_PROT"), itself a fix for breakage caused by an earlier clean up patch of mine, contains a stupid bug. I changed the parameters of the subpage_protection() function, but failed to update one of the callers. This patch fixes it, and replaces a void * with a typed pointer so that the compiler will warn on such an error in future. Signed-off-by: David Gibson Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index c7fa4da..3ecdcec 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c @@ -879,7 +879,7 @@ static inline int subpage_protection(struct mm_struct *mm, unsigned long ea) */ int hash_page(unsigned long ea, unsigned long access, unsigned long trap) { - void *pgdir; + pgd_t *pgdir; unsigned long vsid; struct mm_struct *mm; pte_t *ptep; @@ -1025,7 +1025,7 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap) else #endif /* CONFIG_PPC_HAS_HASH_64K */ { - int spp = subpage_protection(pgdir, ea); + int spp = subpage_protection(mm, ea); if (access & spp) rc = -2; else -- cgit v0.10.2 From 38e1313fc753482b93aa6c6f11cfbd43a5bcd963 Mon Sep 17 00:00:00 2001 From: Yang Li Date: Wed, 16 Dec 2009 20:18:11 +0000 Subject: powerpc/mpic: Fix problem that affinity is not updated Since commit 57b150cce8e004ddd36330490a68bfb59b7271e9, desc->affinity of an irq is changed after calling desc->chip->set_affinity. Therefore we need to fix the irq_choose_cpu() not to depend on the desc->affinity for new mask. Signed-off-by: Jiajun Wu Signed-off-by: Li Yang Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index aa9d06e..470dc6c1 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -567,13 +567,11 @@ static void __init mpic_scan_ht_pics(struct mpic *mpic) #endif /* CONFIG_MPIC_U3_HT_IRQS */ #ifdef CONFIG_SMP -static int irq_choose_cpu(unsigned int virt_irq) +static int irq_choose_cpu(const cpumask_t *mask) { - cpumask_t mask; int cpuid; - cpumask_copy(&mask, irq_to_desc(virt_irq)->affinity); - if (cpus_equal(mask, CPU_MASK_ALL)) { + if (cpumask_equal(mask, cpu_all_mask)) { static int irq_rover; static DEFINE_SPINLOCK(irq_rover_lock); unsigned long flags; @@ -594,20 +592,15 @@ static int irq_choose_cpu(unsigned int virt_irq) spin_unlock_irqrestore(&irq_rover_lock, flags); } else { - cpumask_t tmp; - - cpus_and(tmp, cpu_online_map, mask); - - if (cpus_empty(tmp)) + cpuid = cpumask_first_and(mask, cpu_online_mask); + if (cpuid >= nr_cpu_ids) goto do_round_robin; - - cpuid = first_cpu(tmp); } return get_hard_smp_processor_id(cpuid); } #else -static int irq_choose_cpu(unsigned int virt_irq) +static int irq_choose_cpu(const cpumask_t *mask) { return hard_smp_processor_id(); } @@ -816,7 +809,7 @@ int mpic_set_affinity(unsigned int irq, const struct cpumask *cpumask) unsigned int src = mpic_irq_to_hw(irq); if (mpic->flags & MPIC_SINGLE_DEST_CPU) { - int cpuid = irq_choose_cpu(irq); + int cpuid = irq_choose_cpu(cpumask); mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION), 1 << cpuid); } else { -- cgit v0.10.2 From 698cd335a782561b79504d4e98c7df62b08e7abd Mon Sep 17 00:00:00 2001 From: Albert Herranz Date: Thu, 17 Dec 2009 08:33:41 +0000 Subject: powerpc/gamecube/wii: Fix off-by-one error in ugecon/usbgecko_udbg The retry logic in ug_putc() is broken. If the TX fifo is not ready and the counter runs out it will have a value of -1 and no transfer should be attempted. Also, a counter with a value of 0 means that the TX fifo got ready in the last try and the transfer should be attempted. Reported-by: "Juha Leppanen" Signed-off-by: "Juha Leppanen" Signed-off-by: Albert Herranz Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/boot/ugecon.c b/arch/powerpc/boot/ugecon.c index 50609ea..8f2a6b3 100644 --- a/arch/powerpc/boot/ugecon.c +++ b/arch/powerpc/boot/ugecon.c @@ -86,7 +86,7 @@ static void ug_putc(char ch) while (!ug_is_txfifo_ready() && count--) barrier(); - if (count) + if (count >= 0) ug_raw_putc(ch); } diff --git a/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.c b/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.c index edc956c..20a8ed9 100644 --- a/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.c +++ b/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.c @@ -120,7 +120,7 @@ static void ug_putc(char ch) while (!ug_is_txfifo_ready() && count--) barrier(); - if (count) + if (count >= 0) ug_raw_putc(ch); } -- cgit v0.10.2 From 3a05d7961e6b5fb77660849b56a22feca5d1e0c5 Mon Sep 17 00:00:00 2001 From: Coly Li Date: Fri, 4 Dec 2009 02:02:35 +0800 Subject: ocfs2: explicit declare uninitialized var in user_cluster_connect() This patch explicitly declares an uninitialized local variable in user_cluster_connect(), to remove a compiling warning. Signed-off-by: Coly Li Signed-off-by: Joel Becker diff --git a/fs/ocfs2/stack_user.c b/fs/ocfs2/stack_user.c index ff4c798..da78a2a 100644 --- a/fs/ocfs2/stack_user.c +++ b/fs/ocfs2/stack_user.c @@ -814,7 +814,7 @@ static int fs_protocol_compare(struct ocfs2_protocol_version *existing, static int user_cluster_connect(struct ocfs2_cluster_connection *conn) { dlm_lockspace_t *fsdlm; - struct ocfs2_live_connection *control; + struct ocfs2_live_connection *uninitialized_var(control); int rc = 0; BUG_ON(conn == NULL); -- cgit v0.10.2 From 936545401624217955df4dd44bb71615900e5397 Mon Sep 17 00:00:00 2001 From: Coly Li Date: Sun, 6 Dec 2009 22:38:53 +0800 Subject: ocfs2: replace u8 by __u8 in ocfs2_fs.h This patch replaces date type 'u8' with '__u8', which follows the coding style of ocfs2_fs.h, and portable to user space for ocfs2-tools. Signed-off-by: Coly Li Signed-off-by: Joel Becker diff --git a/fs/ocfs2/ocfs2_fs.h b/fs/ocfs2/ocfs2_fs.h index e9431e4..1a1a679 100644 --- a/fs/ocfs2/ocfs2_fs.h +++ b/fs/ocfs2/ocfs2_fs.h @@ -1202,7 +1202,7 @@ struct ocfs2_local_disk_dqinfo { /* Header of one chunk of a quota file */ struct ocfs2_local_disk_chunk { __le32 dqc_free; /* Number of free entries in the bitmap */ - u8 dqc_bitmap[0]; /* Bitmap of entries in the corresponding + __u8 dqc_bitmap[0]; /* Bitmap of entries in the corresponding * chunk of quota file */ }; -- cgit v0.10.2 From 8c0414cd524e9f1c483ffb3ff1c2d860f5c567c8 Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Thu, 3 Dec 2009 12:46:51 -0800 Subject: fiemap: Add new extent flag FIEMAP_EXTENT_SHARED Some filesystems may allow multiple files to point to a particular extent. This patch adds flag FIEMAP_EXTENT_SHARED to denote extents that are shared with other inodes. Signed-off-by: Sunil Mushran Acked-by: Mark Fasheh Signed-off-by: Joel Becker diff --git a/include/linux/fiemap.h b/include/linux/fiemap.h index 934e22d..d830747 100644 --- a/include/linux/fiemap.h +++ b/include/linux/fiemap.h @@ -62,5 +62,7 @@ struct fiemap { #define FIEMAP_EXTENT_MERGED 0x00001000 /* File does not natively * support extents. Result * merged for efficiency. */ +#define FIEMAP_EXTENT_SHARED 0x00002000 /* Space shared with other + * files. */ #endif /* _LINUX_FIEMAP_H */ -- cgit v0.10.2 From faf8b70f79edf56fedd531dfcd41f3e73c3e9696 Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Thu, 3 Dec 2009 12:46:52 -0800 Subject: ocfs2: Use FIEMAP_EXTENT_SHARED Adds FIEMAP_EXTENT_SHARED flag to refcounted extents. Signed-off-by: Sunil Mushran Acked-by: Mark Fasheh Signed-off-by: Joel Becker diff --git a/fs/ocfs2/extent_map.c b/fs/ocfs2/extent_map.c index 843db64..cdce5f8 100644 --- a/fs/ocfs2/extent_map.c +++ b/fs/ocfs2/extent_map.c @@ -786,6 +786,8 @@ int ocfs2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, fe_flags = 0; if (rec.e_flags & OCFS2_EXT_UNWRITTEN) fe_flags |= FIEMAP_EXTENT_UNWRITTEN; + if (rec.e_flags & OCFS2_EXT_REFCOUNTED) + fe_flags |= FIEMAP_EXTENT_SHARED; if (is_last) fe_flags |= FIEMAP_EXTENT_LAST; len_bytes = (u64)le16_to_cpu(rec.e_leaf_clusters) << osb->s_clustersize_bits; -- cgit v0.10.2 From 55f4946ed23cbf78efe9f818c4b55e890fe2beff Mon Sep 17 00:00:00 2001 From: Tristan Ye Date: Thu, 17 Dec 2009 18:42:16 +0800 Subject: Ocfs2: Should ocfs2 support fiemap for S_IFDIR inode? Let userspace have a chance to get the extent info of a directory just like extN did. Signed-off-by: Tristan Ye Signed-off-by: Joel Becker diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index f010b22..0b9f35e 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c @@ -2326,4 +2326,5 @@ const struct inode_operations ocfs2_dir_iops = { .getxattr = generic_getxattr, .listxattr = ocfs2_listxattr, .removexattr = generic_removexattr, + .fiemap = ocfs2_fiemap, }; -- cgit v0.10.2 From 18374d89e5fe96772102f44f535efb1198d9be08 Mon Sep 17 00:00:00 2001 From: Suresh Siddha Date: Thu, 17 Dec 2009 18:29:46 -0800 Subject: x86, irq: Allow 0xff for /proc/irq/[n]/smp_affinity on an 8-cpu system John Blackwood reported: > on an older Dell PowerEdge 6650 system with 8 cpus (4 are hyper-threaded), > and 32 bit (x86) kernel, once you change the irq smp_affinity of an irq > to be less than all cpus in the system, you can never change really the > irq smp_affinity back to be all cpus in the system (0xff) again, > even though no error status is returned on the "/bin/echo ff > > /proc/irq/[n]/smp_affinity" operation. > > This is due to that fact that BAD_APICID has the same value as > all cpus (0xff) on 32bit kernels, and thus the value returned from > set_desc_affinity() via the cpu_mask_to_apicid_and() function is treated > as a failure in set_ioapic_affinity_irq_desc(), and no affinity changes > are made. set_desc_affinity() is already checking if the incoming cpu mask intersects with the cpu online mask or not. So there is no need for the apic op cpu_mask_to_apicid_and() to check again and return BAD_APICID. Remove the BAD_APICID return value from cpu_mask_to_apicid_and() and also fix set_desc_affinity() to return -1 instead of using BAD_APICID to represent error conditions (as cpu_mask_to_apicid_and() can return logical or physical apicid values and BAD_APICID is really to represent bad physical apic id). Reported-by: John Blackwood Root-caused-by: John Blackwood Signed-off-by: Suresh Siddha LKML-Reference: <1261103386.2535.409.camel@sbs-t61> Signed-off-by: H. Peter Anvin diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h index 08c48a8..eeac829 100644 --- a/arch/x86/include/asm/hw_irq.h +++ b/arch/x86/include/asm/hw_irq.h @@ -103,7 +103,8 @@ extern int assign_irq_vector(int, struct irq_cfg *, const struct cpumask *); extern void send_cleanup_vector(struct irq_cfg *); struct irq_desc; -extern unsigned int set_desc_affinity(struct irq_desc *, const struct cpumask *); +extern unsigned int set_desc_affinity(struct irq_desc *, const struct cpumask *, + unsigned int *dest_id); extern int IO_APIC_get_PCI_irq_vector(int bus, int devfn, int pin, struct io_apic_irq_attr *irq_attr); extern void setup_ioapic_dest(void); diff --git a/arch/x86/kernel/apic/apic_flat_64.c b/arch/x86/kernel/apic/apic_flat_64.c index d0c99ab..eacbd2b 100644 --- a/arch/x86/kernel/apic/apic_flat_64.c +++ b/arch/x86/kernel/apic/apic_flat_64.c @@ -306,10 +306,7 @@ physflat_cpu_mask_to_apicid_and(const struct cpumask *cpumask, if (cpumask_test_cpu(cpu, cpu_online_mask)) break; } - if (cpu < nr_cpu_ids) - return per_cpu(x86_cpu_to_apicid, cpu); - - return BAD_APICID; + return per_cpu(x86_cpu_to_apicid, cpu); } struct apic apic_physflat = { diff --git a/arch/x86/kernel/apic/bigsmp_32.c b/arch/x86/kernel/apic/bigsmp_32.c index 38dcecf..cb804c5 100644 --- a/arch/x86/kernel/apic/bigsmp_32.c +++ b/arch/x86/kernel/apic/bigsmp_32.c @@ -131,10 +131,7 @@ static unsigned int bigsmp_cpu_mask_to_apicid_and(const struct cpumask *cpumask, if (cpumask_test_cpu(cpu, cpu_online_mask)) break; } - if (cpu < nr_cpu_ids) - return bigsmp_cpu_to_logical_apicid(cpu); - - return BAD_APICID; + return bigsmp_cpu_to_logical_apicid(cpu); } static int bigsmp_phys_pkg_id(int cpuid_apic, int index_msb) diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index d5d498f..98ced70 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -2276,26 +2276,28 @@ static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, struct irq /* * Either sets desc->affinity to a valid value, and returns - * ->cpu_mask_to_apicid of that, or returns BAD_APICID and + * ->cpu_mask_to_apicid of that in dest_id, or returns -1 and * leaves desc->affinity untouched. */ unsigned int -set_desc_affinity(struct irq_desc *desc, const struct cpumask *mask) +set_desc_affinity(struct irq_desc *desc, const struct cpumask *mask, + unsigned int *dest_id) { struct irq_cfg *cfg; unsigned int irq; if (!cpumask_intersects(mask, cpu_online_mask)) - return BAD_APICID; + return -1; irq = desc->irq; cfg = desc->chip_data; if (assign_irq_vector(irq, cfg, mask)) - return BAD_APICID; + return -1; cpumask_copy(desc->affinity, mask); - return apic->cpu_mask_to_apicid_and(desc->affinity, cfg->domain); + *dest_id = apic->cpu_mask_to_apicid_and(desc->affinity, cfg->domain); + return 0; } static int @@ -2311,12 +2313,11 @@ set_ioapic_affinity_irq_desc(struct irq_desc *desc, const struct cpumask *mask) cfg = desc->chip_data; spin_lock_irqsave(&ioapic_lock, flags); - dest = set_desc_affinity(desc, mask); - if (dest != BAD_APICID) { + ret = set_desc_affinity(desc, mask, &dest); + if (!ret) { /* Only the high 8 bits are valid. */ dest = SET_APIC_LOGICAL_ID(dest); __target_IO_APIC_irq(irq, dest, cfg); - ret = 0; } spin_unlock_irqrestore(&ioapic_lock, flags); @@ -3351,8 +3352,7 @@ static int set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask) struct msi_msg msg; unsigned int dest; - dest = set_desc_affinity(desc, mask); - if (dest == BAD_APICID) + if (set_desc_affinity(desc, mask, &dest)) return -1; cfg = desc->chip_data; @@ -3384,8 +3384,7 @@ ir_set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask) if (get_irte(irq, &irte)) return -1; - dest = set_desc_affinity(desc, mask); - if (dest == BAD_APICID) + if (set_desc_affinity(desc, mask, &dest)) return -1; irte.vector = cfg->vector; @@ -3567,8 +3566,7 @@ static int dmar_msi_set_affinity(unsigned int irq, const struct cpumask *mask) struct msi_msg msg; unsigned int dest; - dest = set_desc_affinity(desc, mask); - if (dest == BAD_APICID) + if (set_desc_affinity(desc, mask, &dest)) return -1; cfg = desc->chip_data; @@ -3623,8 +3621,7 @@ static int hpet_msi_set_affinity(unsigned int irq, const struct cpumask *mask) struct msi_msg msg; unsigned int dest; - dest = set_desc_affinity(desc, mask); - if (dest == BAD_APICID) + if (set_desc_affinity(desc, mask, &dest)) return -1; cfg = desc->chip_data; @@ -3730,8 +3727,7 @@ static int set_ht_irq_affinity(unsigned int irq, const struct cpumask *mask) struct irq_cfg *cfg; unsigned int dest; - dest = set_desc_affinity(desc, mask); - if (dest == BAD_APICID) + if (set_desc_affinity(desc, mask, &dest)) return -1; cfg = desc->chip_data; diff --git a/arch/x86/kernel/apic/x2apic_cluster.c b/arch/x86/kernel/apic/x2apic_cluster.c index a5371ec..cf69c59 100644 --- a/arch/x86/kernel/apic/x2apic_cluster.c +++ b/arch/x86/kernel/apic/x2apic_cluster.c @@ -148,10 +148,7 @@ x2apic_cpu_mask_to_apicid_and(const struct cpumask *cpumask, break; } - if (cpu < nr_cpu_ids) - return per_cpu(x86_cpu_to_logical_apicid, cpu); - - return BAD_APICID; + return per_cpu(x86_cpu_to_logical_apicid, cpu); } static unsigned int x2apic_cluster_phys_get_apic_id(unsigned long x) diff --git a/arch/x86/kernel/apic/x2apic_phys.c b/arch/x86/kernel/apic/x2apic_phys.c index a8989aa..8972f38 100644 --- a/arch/x86/kernel/apic/x2apic_phys.c +++ b/arch/x86/kernel/apic/x2apic_phys.c @@ -146,10 +146,7 @@ x2apic_cpu_mask_to_apicid_and(const struct cpumask *cpumask, break; } - if (cpu < nr_cpu_ids) - return per_cpu(x86_cpu_to_apicid, cpu); - - return BAD_APICID; + return per_cpu(x86_cpu_to_apicid, cpu); } static unsigned int x2apic_phys_get_apic_id(unsigned long x) diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index b684bb3..d56b0ef 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c @@ -225,10 +225,7 @@ uv_cpu_mask_to_apicid_and(const struct cpumask *cpumask, if (cpumask_test_cpu(cpu, cpu_online_mask)) break; } - if (cpu < nr_cpu_ids) - return per_cpu(x86_cpu_to_apicid, cpu); - - return BAD_APICID; + return per_cpu(x86_cpu_to_apicid, cpu); } static unsigned int x2apic_get_apic_id(unsigned long x) diff --git a/arch/x86/kernel/uv_irq.c b/arch/x86/kernel/uv_irq.c index 61d805d..ece73d8 100644 --- a/arch/x86/kernel/uv_irq.c +++ b/arch/x86/kernel/uv_irq.c @@ -215,8 +215,7 @@ static int uv_set_irq_affinity(unsigned int irq, const struct cpumask *mask) unsigned long mmr_offset; unsigned mmr_pnode; - dest = set_desc_affinity(desc, mask); - if (dest == BAD_APICID) + if (set_desc_affinity(desc, mask, &dest)) return -1; mmr_value = 0; -- cgit v0.10.2 From 21797c599c710d3851d241c4b50690f2482bf618 Mon Sep 17 00:00:00 2001 From: Daniele Calore Date: Tue, 8 Dec 2009 13:59:47 -0500 Subject: alpha: Wire up missing/new syscalls This wire up the: fallocate, timerfd_create, timerfd_settime, timerfd_gettime, signalfd4, eventfd2, epoll_create1, dup3, pipe2, inotify_init1, preadv, pwritev and rt_tgsigqueueinfo syscalls for the alpha port. For umount2, alpha have an "old" and "new" version called: oldumount and umount; so ignore umount2. Rebased on top of 6e17e8b9fb74b9fb9f6ea331f7f4a049c5b4c4b8 by Matt Turner. Signed-off-by: Daniele Calore Cc: Richard Henderson Cc: Ivan Kokshaysky Signed-off-by: Matt Turner diff --git a/arch/alpha/include/asm/unistd.h b/arch/alpha/include/asm/unistd.h index 7f23665..62e823e 100644 --- a/arch/alpha/include/asm/unistd.h +++ b/arch/alpha/include/asm/unistd.h @@ -247,6 +247,7 @@ #define __IGNORE_pause #define __IGNORE_time #define __IGNORE_utime +#define __IGNORE_umount2 /* * Linux-specific system calls begin at 300 @@ -434,10 +435,23 @@ #define __NR_timerfd 477 #define __NR_eventfd 478 #define __NR_recvmmsg 479 +#define __NR_fallocate 480 +#define __NR_timerfd_create 481 +#define __NR_timerfd_settime 482 +#define __NR_timerfd_gettime 483 +#define __NR_signalfd4 484 +#define __NR_eventfd2 485 +#define __NR_epoll_create1 486 +#define __NR_dup3 487 +#define __NR_pipe2 488 +#define __NR_inotify_init1 489 +#define __NR_preadv 490 +#define __NR_pwritev 491 +#define __NR_rt_tgsigqueueinfo 492 #ifdef __KERNEL__ -#define NR_SYSCALLS 480 +#define NR_SYSCALLS 493 #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR diff --git a/arch/alpha/kernel/systbls.S b/arch/alpha/kernel/systbls.S index cda6b8b..d0bc3c8 100644 --- a/arch/alpha/kernel/systbls.S +++ b/arch/alpha/kernel/systbls.S @@ -495,9 +495,22 @@ sys_call_table: .quad sys_epoll_pwait .quad sys_utimensat /* 475 */ .quad sys_signalfd - .quad sys_ni_syscall + .quad sys_ni_syscall /* sys_timerfd */ .quad sys_eventfd .quad sys_recvmmsg + .quad sys_fallocate /* 480 */ + .quad sys_timerfd_create + .quad sys_timerfd_settime + .quad sys_timerfd_gettime + .quad sys_signalfd4 + .quad sys_eventfd2 /* 485 */ + .quad sys_epoll_create1 + .quad sys_dup3 + .quad sys_pipe2 + .quad sys_inotify_init1 + .quad sys_preadv /* 490 */ + .quad sys_pwritev + .quad sys_rt_tgsigqueueinfo .size sys_call_table, . - sys_call_table .type sys_call_table, @object -- cgit v0.10.2 From a582e6f01b90211933e70edcec9bc0bbb1157402 Mon Sep 17 00:00:00 2001 From: Michael Cree Date: Tue, 8 Dec 2009 14:27:01 -0500 Subject: alpha: Add minimal support for software performance events In the kernel the patch enables configuration of the perf event option, adds the perf_event_open syscall, and includes a minimal architecture specific asm/perf_event.h header file. Signed-off-by: Michael Cree Cc: Richard Henderson Cc: Ivan Kokshaysky Cc: Peter Zijlstra Cc: Paul Mackerras Cc: Ingo Molnar Signed-off-by: Matt Turner diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig index 4434481..bd7261e 100644 --- a/arch/alpha/Kconfig +++ b/arch/alpha/Kconfig @@ -9,6 +9,7 @@ config ALPHA select HAVE_IDE select HAVE_OPROFILE select HAVE_SYSCALL_WRAPPERS + select HAVE_PERF_EVENTS help The Alpha is a 64-bit general-purpose processor designed and marketed by the Digital Equipment Corporation of blessed memory, diff --git a/arch/alpha/include/asm/perf_event.h b/arch/alpha/include/asm/perf_event.h new file mode 100644 index 0000000..3bef852 --- /dev/null +++ b/arch/alpha/include/asm/perf_event.h @@ -0,0 +1,9 @@ +#ifndef __ASM_ALPHA_PERF_EVENT_H +#define __ASM_ALPHA_PERF_EVENT_H + +/* Alpha only supports software events through this interface. */ +static inline void set_perf_event_pending(void) { } + +#define PERF_EVENT_INDEX_OFFSET 0 + +#endif /* __ASM_ALPHA_PERF_EVENT_H */ diff --git a/arch/alpha/include/asm/unistd.h b/arch/alpha/include/asm/unistd.h index 62e823e..804e531 100644 --- a/arch/alpha/include/asm/unistd.h +++ b/arch/alpha/include/asm/unistd.h @@ -448,10 +448,11 @@ #define __NR_preadv 490 #define __NR_pwritev 491 #define __NR_rt_tgsigqueueinfo 492 +#define __NR_perf_event_open 493 #ifdef __KERNEL__ -#define NR_SYSCALLS 493 +#define NR_SYSCALLS 494 #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR diff --git a/arch/alpha/kernel/systbls.S b/arch/alpha/kernel/systbls.S index d0bc3c8..09acb78 100644 --- a/arch/alpha/kernel/systbls.S +++ b/arch/alpha/kernel/systbls.S @@ -511,6 +511,7 @@ sys_call_table: .quad sys_preadv /* 490 */ .quad sys_pwritev .quad sys_rt_tgsigqueueinfo + .quad sys_perf_event_open .size sys_call_table, . - sys_call_table .type sys_call_table, @object -- cgit v0.10.2 From acadbfb90a54673d6c8b05aa4e93218433890411 Mon Sep 17 00:00:00 2001 From: David Daney Date: Thu, 10 Dec 2009 18:07:24 -0500 Subject: alpha: Convert BUG() to use unreachable() Use the new unreachable() macro instead of for(;;); Signed-off-by: David Daney CC: Richard Henderson CC: Ivan Kokshaysky CC: linux-alpha@vger.kernel.org Signed-off-by: Matt Turner diff --git a/arch/alpha/include/asm/bug.h b/arch/alpha/include/asm/bug.h index 1720c8a..f091682 100644 --- a/arch/alpha/include/asm/bug.h +++ b/arch/alpha/include/asm/bug.h @@ -13,7 +13,8 @@ "call_pal %0 # bugchk\n\t" \ ".long %1\n\t.8byte %2" \ : : "i"(PAL_bugchk), "i"(__LINE__), "i"(__FILE__)); \ - for ( ; ; ); } while (0) + unreachable(); \ + } while (0) #define HAVE_ARCH_BUG #endif -- cgit v0.10.2 From 2fef62c825f09e29d2f52dc187ddf6f99e28c7f1 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 18 Dec 2009 08:48:42 +0100 Subject: ALSA: hda - Fix quirk for Maxdata obook4-1 Works fine with the auto-parser. Reference: Novell bnc#564940 https://bugzilla.novell.com/show_bug.cgi?id=564940 Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index d9a9f0c..84bc2c7 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -8921,7 +8921,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = { SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG), SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG), SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */ - SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG), + SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO), SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG), SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG), SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG), -- cgit v0.10.2 From 1de6129f381b4907013ccea08a3bdea8c966d50a Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Fri, 18 Dec 2009 12:37:48 +0100 Subject: block: remove Documentation/block/as-iosched.txt Commit 492af6350a5ccf087e4964104a276ed358811458 removed the AS IO scheduler, so remove its documentation too. Signed-off-by: FUJITA Tomonori Signed-off-by: Jens Axboe diff --git a/Documentation/block/00-INDEX b/Documentation/block/00-INDEX index 961a051..a406286 100644 --- a/Documentation/block/00-INDEX +++ b/Documentation/block/00-INDEX @@ -1,7 +1,5 @@ 00-INDEX - This file -as-iosched.txt - - Anticipatory IO scheduler barrier.txt - I/O Barriers biodoc.txt diff --git a/Documentation/block/as-iosched.txt b/Documentation/block/as-iosched.txt deleted file mode 100644 index 738b72b..0000000 --- a/Documentation/block/as-iosched.txt +++ /dev/null @@ -1,172 +0,0 @@ -Anticipatory IO scheduler -------------------------- -Nick Piggin 13 Sep 2003 - -Attention! Database servers, especially those using "TCQ" disks should -investigate performance with the 'deadline' IO scheduler. Any system with high -disk performance requirements should do so, in fact. - -If you see unusual performance characteristics of your disk systems, or you -see big performance regressions versus the deadline scheduler, please email -me. Database users don't bother unless you're willing to test a lot of patches -from me ;) its a known issue. - -Also, users with hardware RAID controllers, doing striping, may find -highly variable performance results with using the as-iosched. The -as-iosched anticipatory implementation is based on the notion that a disk -device has only one physical seeking head. A striped RAID controller -actually has a head for each physical device in the logical RAID device. - -However, setting the antic_expire (see tunable parameters below) produces -very similar behavior to the deadline IO scheduler. - -Selecting IO schedulers ------------------------ -Refer to Documentation/block/switching-sched.txt for information on -selecting an io scheduler on a per-device basis. - -Anticipatory IO scheduler Policies ----------------------------------- -The as-iosched implementation implements several layers of policies -to determine when an IO request is dispatched to the disk controller. -Here are the policies outlined, in order of application. - -1. one-way Elevator algorithm. - -The elevator algorithm is similar to that used in deadline scheduler, with -the addition that it allows limited backward movement of the elevator -(i.e. seeks backwards). A seek backwards can occur when choosing between -two IO requests where one is behind the elevator's current position, and -the other is in front of the elevator's position. If the seek distance to -the request in back of the elevator is less than half the seek distance to -the request in front of the elevator, then the request in back can be chosen. -Backward seeks are also limited to a maximum of MAXBACK (1024*1024) sectors. -This favors forward movement of the elevator, while allowing opportunistic -"short" backward seeks. - -2. FIFO expiration times for reads and for writes. - -This is again very similar to the deadline IO scheduler. The expiration -times for requests on these lists is tunable using the parameters read_expire -and write_expire discussed below. When a read or a write expires in this way, -the IO scheduler will interrupt its current elevator sweep or read anticipation -to service the expired request. - -3. Read and write request batching - -A batch is a collection of read requests or a collection of write -requests. The as scheduler alternates dispatching read and write batches -to the driver. In the case a read batch, the scheduler submits read -requests to the driver as long as there are read requests to submit, and -the read batch time limit has not been exceeded (read_batch_expire). -The read batch time limit begins counting down only when there are -competing write requests pending. - -In the case of a write batch, the scheduler submits write requests to -the driver as long as there are write requests available, and the -write batch time limit has not been exceeded (write_batch_expire). -However, the length of write batches will be gradually shortened -when read batches frequently exceed their time limit. - -When changing between batch types, the scheduler waits for all requests -from the previous batch to complete before scheduling requests for the -next batch. - -The read and write fifo expiration times described in policy 2 above -are checked only when in scheduling IO of a batch for the corresponding -(read/write) type. So for example, the read FIFO timeout values are -tested only during read batches. Likewise, the write FIFO timeout -values are tested only during write batches. For this reason, -it is generally not recommended for the read batch time -to be longer than the write expiration time, nor for the write batch -time to exceed the read expiration time (see tunable parameters below). - -When the IO scheduler changes from a read to a write batch, -it begins the elevator from the request that is on the head of the -write expiration FIFO. Likewise, when changing from a write batch to -a read batch, scheduler begins the elevator from the first entry -on the read expiration FIFO. - -4. Read anticipation. - -Read anticipation occurs only when scheduling a read batch. -This implementation of read anticipation allows only one read request -to be dispatched to the disk controller at a time. In -contrast, many write requests may be dispatched to the disk controller -at a time during a write batch. It is this characteristic that can make -the anticipatory scheduler perform anomalously with controllers supporting -TCQ, or with hardware striped RAID devices. Setting the antic_expire -queue parameter (see below) to zero disables this behavior, and the -anticipatory scheduler behaves essentially like the deadline scheduler. - -When read anticipation is enabled (antic_expire is not zero), reads -are dispatched to the disk controller one at a time. -At the end of each read request, the IO scheduler examines its next -candidate read request from its sorted read list. If that next request -is from the same process as the request that just completed, -or if the next request in the queue is "very close" to the -just completed request, it is dispatched immediately. Otherwise, -statistics (average think time, average seek distance) on the process -that submitted the just completed request are examined. If it seems -likely that that process will submit another request soon, and that -request is likely to be near the just completed request, then the IO -scheduler will stop dispatching more read requests for up to (antic_expire) -milliseconds, hoping that process will submit a new request near the one -that just completed. If such a request is made, then it is dispatched -immediately. If the antic_expire wait time expires, then the IO scheduler -will dispatch the next read request from the sorted read queue. - -To decide whether an anticipatory wait is worthwhile, the scheduler -maintains statistics for each process that can be used to compute -mean "think time" (the time between read requests), and mean seek -distance for that process. One observation is that these statistics -are associated with each process, but those statistics are not associated -with a specific IO device. So for example, if a process is doing IO -on several file systems on separate devices, the statistics will be -a combination of IO behavior from all those devices. - - -Tuning the anticipatory IO scheduler ------------------------------------- -When using 'as', the anticipatory IO scheduler there are 5 parameters under -/sys/block/*/queue/iosched/. All are units of milliseconds. - -The parameters are: -* read_expire - Controls how long until a read request becomes "expired". It also controls the - interval between which expired requests are served, so set to 50, a request - might take anywhere < 100ms to be serviced _if_ it is the next on the - expired list. Obviously request expiration strategies won't make the disk - go faster. The result basically equates to the timeslice a single reader - gets in the presence of other IO. 100*((seek time / read_expire) + 1) is - very roughly the % streaming read efficiency your disk should get with - multiple readers. - -* read_batch_expire - Controls how much time a batch of reads is given before pending writes are - served. A higher value is more efficient. This might be set below read_expire - if writes are to be given higher priority than reads, but reads are to be - as efficient as possible when there are no writes. Generally though, it - should be some multiple of read_expire. - -* write_expire, and -* write_batch_expire are equivalent to the above, for writes. - -* antic_expire - Controls the maximum amount of time we can anticipate a good read (one - with a short seek distance from the most recently completed request) before - giving up. Many other factors may cause anticipation to be stopped early, - or some processes will not be "anticipated" at all. Should be a bit higher - for big seek time devices though not a linear correspondence - most - processes have only a few ms thinktime. - -In addition to the tunables above there is a read-only file named est_time -which, when read, will show: - - - The probability of a task exiting without a cooperating task - submitting an anticipated IO. - - - The current mean think time. - - - The seek distance used to determine if an incoming IO is better. - -- cgit v0.10.2 From 4a63b030d75a063b910b2bab014d84837cb33eb7 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Fri, 18 Dec 2009 12:38:11 +0100 Subject: drbd: fix test of unsigned in _drbd_fault_random() rsp->count is unsigned so the test does not work. Signed-off-by: Roel Kluin Cc: Lars Ellenberg Cc: Philipp Reisner Signed-off-by: Jens Axboe diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 157d1e4..c2594c1 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -3623,7 +3623,7 @@ _drbd_fault_random(struct fault_random_state *rsp) { long refresh; - if (--rsp->count < 0) { + if (!rsp->count--) { get_random_bytes(&refresh, sizeof(refresh)); rsp->state += refresh; rsp->count = FAULT_RANDOM_REFRESH; -- cgit v0.10.2 From 1db32c40600437c5e049796bd32f49f61244c6ef Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Wed, 16 Dec 2009 17:52:57 -0500 Subject: cfq-iosched: Remove the check for same cfq group from allow_merge o allow_merge() already checks if submitting task is pointing to same cfqq as rq has been queued in. If everything is fine, we should not be having a task in one cgroup and having a pointer to cfqq in other cgroup. Well I guess in some situations it can happen and that is, when a random IO queue has been moved into root cgroup for group_isolation=0. In this case, tasks's cgroup/group is different from where actually cfqq is, but this is intentional and in this case merging should be allowed. The second situation is where due to close cooperator patches, multiple processes can be sharing a cfqq. If everything implemented right, we should not end up in a situation where tasks from different processes in different groups are sharing the same cfqq as we allow merging of cooperating queues only if they are in same group. Signed-off-by: Vivek Goyal Reviewed-by: Gui Jianfeng Signed-off-by: Jens Axboe diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index e2f8046..a0e5347 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -1513,9 +1513,6 @@ static int cfq_allow_merge(struct request_queue *q, struct request *rq, struct cfq_io_context *cic; struct cfq_queue *cfqq; - /* Deny merge if bio and rq don't belong to same cfq group */ - if ((RQ_CFQQ(rq))->cfqg != cfq_get_cfqg(cfqd, 0)) - return false; /* * Disallow merge of a sync bio into an async request. */ -- cgit v0.10.2 From fb104db41e6e006c85ce1097f372cd1e10c1755c Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Wed, 16 Dec 2009 17:52:58 -0500 Subject: cfq-iosched: Get rid of nr_groups o Currently code does not seem to be using cfqd->nr_groups. Get rid of it. Signed-off-by: Vivek Goyal Reviewed-by: Gui Jianfeng Signed-off-by: Jens Axboe diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index a0e5347..d9bfa09 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -208,8 +208,6 @@ struct cfq_data { /* Root service tree for cfq_groups */ struct cfq_rb_root grp_service_tree; struct cfq_group root_group; - /* Number of active cfq groups on group service tree */ - int nr_groups; /* * The priority currently being served @@ -842,7 +840,6 @@ cfq_group_service_tree_add(struct cfq_data *cfqd, struct cfq_group *cfqg) __cfq_group_service_tree_add(st, cfqg); cfqg->on_st = true; - cfqd->nr_groups++; st->total_weight += cfqg->weight; } @@ -863,7 +860,6 @@ cfq_group_service_tree_del(struct cfq_data *cfqd, struct cfq_group *cfqg) cfq_log_cfqg(cfqd, cfqg, "del_from_rr group"); cfqg->on_st = false; - cfqd->nr_groups--; st->total_weight -= cfqg->weight; if (!RB_EMPTY_NODE(&cfqg->rb_node)) cfq_rb_erase(&cfqg->rb_node, st); -- cgit v0.10.2 From 65b32a573eefa1cdd3cbe5ea59326308e6c3b9ad Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Wed, 16 Dec 2009 17:52:59 -0500 Subject: cfq-iosched: Remove prio_change logic for workload selection o CFQ now internally divides cfq queues in therr workload categories. sync-idle, sync-noidle and async. Which workload to run depends primarily on rb_key offset across three service trees. Which is a combination of mulitiple things including what time queue got queued on the service tree. There is one exception though. That is if we switched the prio class, say we served some RT tasks and again started serving BE class, then with-in BE class we always started with sync-noidle workload irrespective of rb_key offset in service trees. This can provide better latencies for sync-noidle workload in the presence of RT tasks. o This patch gets rid of that exception and which workload to run with-in class always depends on lowest rb_key across service trees. The reason being that now we have multiple BE class groups and if we always switch to sync-noidle workload with-in group, we can potentially starve a sync-idle workload with-in group. Same is true for async workload which will be in root group. Also the workload-switching with-in group will become very unpredictable as it now depends whether some RT workload was running in the system or not. Signed-off-by: Vivek Goyal Reviewed-by: Gui Jianfeng Acked-by: Corrado Zoccolo Signed-off-by: Jens Axboe diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index d9bfa09..8df4fe5 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -292,8 +292,7 @@ static struct cfq_group *cfq_get_next_cfqg(struct cfq_data *cfqd); static struct cfq_rb_root *service_tree_for(struct cfq_group *cfqg, enum wl_prio_t prio, - enum wl_type_t type, - struct cfq_data *cfqd) + enum wl_type_t type) { if (!cfqg) return NULL; @@ -1146,7 +1145,7 @@ static void cfq_service_tree_add(struct cfq_data *cfqd, struct cfq_queue *cfqq, #endif service_tree = service_tree_for(cfqq->cfqg, cfqq_prio(cfqq), - cfqq_type(cfqq), cfqd); + cfqq_type(cfqq)); if (cfq_class_idle(cfqq)) { rb_key = CFQ_IDLE_DELAY; parent = rb_last(&service_tree->rb); @@ -1609,7 +1608,7 @@ static struct cfq_queue *cfq_get_next_queue(struct cfq_data *cfqd) { struct cfq_rb_root *service_tree = service_tree_for(cfqd->serving_group, cfqd->serving_prio, - cfqd->serving_type, cfqd); + cfqd->serving_type); if (!cfqd->rq_queued) return NULL; @@ -1956,8 +1955,7 @@ static void cfq_setup_merge(struct cfq_queue *cfqq, struct cfq_queue *new_cfqq) } static enum wl_type_t cfq_choose_wl(struct cfq_data *cfqd, - struct cfq_group *cfqg, enum wl_prio_t prio, - bool prio_changed) + struct cfq_group *cfqg, enum wl_prio_t prio) { struct cfq_queue *queue; int i; @@ -1965,24 +1963,9 @@ static enum wl_type_t cfq_choose_wl(struct cfq_data *cfqd, unsigned long lowest_key = 0; enum wl_type_t cur_best = SYNC_NOIDLE_WORKLOAD; - if (prio_changed) { - /* - * When priorities switched, we prefer starting - * from SYNC_NOIDLE (first choice), or just SYNC - * over ASYNC - */ - if (service_tree_for(cfqg, prio, cur_best, cfqd)->count) - return cur_best; - cur_best = SYNC_WORKLOAD; - if (service_tree_for(cfqg, prio, cur_best, cfqd)->count) - return cur_best; - - return ASYNC_WORKLOAD; - } - - for (i = 0; i < 3; ++i) { - /* otherwise, select the one with lowest rb_key */ - queue = cfq_rb_first(service_tree_for(cfqg, prio, i, cfqd)); + for (i = 0; i <= SYNC_WORKLOAD; ++i) { + /* select the one with lowest rb_key */ + queue = cfq_rb_first(service_tree_for(cfqg, prio, i)); if (queue && (!key_valid || time_before(queue->rb_key, lowest_key))) { lowest_key = queue->rb_key; @@ -1996,8 +1979,6 @@ static enum wl_type_t cfq_choose_wl(struct cfq_data *cfqd, static void choose_service_tree(struct cfq_data *cfqd, struct cfq_group *cfqg) { - enum wl_prio_t previous_prio = cfqd->serving_prio; - bool prio_changed; unsigned slice; unsigned count; struct cfq_rb_root *st; @@ -2025,24 +2006,19 @@ static void choose_service_tree(struct cfq_data *cfqd, struct cfq_group *cfqg) * (SYNC, SYNC_NOIDLE, ASYNC), and to compute a workload * expiration time */ - prio_changed = (cfqd->serving_prio != previous_prio); - st = service_tree_for(cfqg, cfqd->serving_prio, cfqd->serving_type, - cfqd); + st = service_tree_for(cfqg, cfqd->serving_prio, cfqd->serving_type); count = st->count; /* - * If priority didn't change, check workload expiration, - * and that we still have other queues ready + * check workload expiration, and that we still have other queues ready */ - if (!prio_changed && count && - !time_after(jiffies, cfqd->workload_expires)) + if (count && !time_after(jiffies, cfqd->workload_expires)) return; /* otherwise select new workload type */ cfqd->serving_type = - cfq_choose_wl(cfqd, cfqg, cfqd->serving_prio, prio_changed); - st = service_tree_for(cfqg, cfqd->serving_prio, cfqd->serving_type, - cfqd); + cfq_choose_wl(cfqd, cfqg, cfqd->serving_prio); + st = service_tree_for(cfqg, cfqd->serving_prio, cfqd->serving_type); count = st->count; /* -- cgit v0.10.2 From 3e85fd614c7b6bb7f33bb04a0dcb5a3bfca4c0fe Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Fri, 18 Dec 2009 09:27:24 +0100 Subject: sound: sgio2audio/pdaudiocf/usb-audio: initialize PCM buffer When allocating the PCM buffer, use vmalloc_user() instead of vmalloc(). Otherwise, it would be possible for applications to play the previous contents of the kernel memory to the speakers, or to read it directly if the buffer is exported to userspace. Signed-off-by: Clemens Ladisch Cc: Signed-off-by: Takashi Iwai diff --git a/sound/mips/sgio2audio.c b/sound/mips/sgio2audio.c index 8691f4c..f1d9d16 100644 --- a/sound/mips/sgio2audio.c +++ b/sound/mips/sgio2audio.c @@ -609,7 +609,7 @@ static int snd_sgio2audio_pcm_hw_params(struct snd_pcm_substream *substream, /* alloc virtual 'dma' area */ if (runtime->dma_area) vfree(runtime->dma_area); - runtime->dma_area = vmalloc(size); + runtime->dma_area = vmalloc_user(size); if (runtime->dma_area == NULL) return -ENOMEM; runtime->dma_bytes = size; diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c b/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c index d057e64..5cfa608 100644 --- a/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c +++ b/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c @@ -51,7 +51,7 @@ static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, size_t s return 0; /* already enough large */ vfree(runtime->dma_area); } - runtime->dma_area = vmalloc_32(size); + runtime->dma_area = vmalloc_32_user(size); if (! runtime->dma_area) return -ENOMEM; runtime->dma_bytes = size; diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index b074a59..4963def 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c @@ -752,7 +752,7 @@ static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, size_t s return 0; /* already large enough */ vfree(runtime->dma_area); } - runtime->dma_area = vmalloc(size); + runtime->dma_area = vmalloc_user(size); if (!runtime->dma_area) return -ENOMEM; runtime->dma_bytes = size; -- cgit v0.10.2 From 2395d66d09ce10c25b6756575c4aeb219760d1fc Mon Sep 17 00:00:00 2001 From: Anand Gadiyar Date: Fri, 18 Dec 2009 12:56:10 +0100 Subject: ARM: 5853/1: ARM: Fix build break on ARM v6 and v7 Commit 2c9b9c849 added an argument to __cpuc_flush_dcache_page and renamed it. Update a caller of the old function to fix this build error: CC arch/arm/mm/copypage-v6.o arch/arm/mm/copypage-v6.c: In function 'v6_copy_user_highpage_nonaliasing': arch/arm/mm/copypage-v6.c:51: error: implicit declaration of function '__cpuc_flush_dcache_page' make[1]: *** [arch/arm/mm/copypage-v6.o] Error 1 make: *** [arch/arm/mm] Error 2 Reported-by: Jinsung Yang Signed-off-by: Anand Gadiyar Signed-off-by: Russell King diff --git a/arch/arm/mm/copypage-v6.c b/arch/arm/mm/copypage-v6.c index 841f355..0fa1319 100644 --- a/arch/arm/mm/copypage-v6.c +++ b/arch/arm/mm/copypage-v6.c @@ -48,7 +48,7 @@ static void v6_copy_user_highpage_nonaliasing(struct page *to, */ if (page_address(to) != NULL) #endif - __cpuc_flush_dcache_page(kto); + __cpuc_flush_dcache_area(kto, PAGE_SIZE); kunmap_atomic(kto, KM_USER1); kunmap_atomic(kfrom, KM_USER0); } -- cgit v0.10.2 From 48c03ce72f2665f79a3fe54fc6d71b8cc3d30803 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 17 Dec 2009 14:51:35 +0100 Subject: ASoC: wm8974: fix a wrong bit definition The wm8974 datasheet defines BUFIOEN as bit 2. Signed-off-by: Guennadi Liakhovetski Acked-by: Liam Girdwood Signed-off-by: Mark Brown Cc: stable@kernel.org diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c index 81c57b5..a808675 100644 --- a/sound/soc/codecs/wm8974.c +++ b/sound/soc/codecs/wm8974.c @@ -47,7 +47,7 @@ static const u16 wm8974_reg[WM8974_CACHEREGNUM] = { }; #define WM8974_POWER1_BIASEN 0x08 -#define WM8974_POWER1_BUFIOEN 0x10 +#define WM8974_POWER1_BUFIOEN 0x04 struct wm8974_priv { struct snd_soc_codec codec; -- cgit v0.10.2 From 797245f5da543074ee7db0e0516da744c89aa17f Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 18 Dec 2009 14:34:43 +0000 Subject: ARM: Convert VFP/Crunch/XscaleCP thread_release() to exit_thread() This avoids races in the VFP code where the dead thread may have state on another CPU. By moving this code to exit_thread(), we will be running as the thread, and therefore be running on the current CPU. This means that we can ensure that the only local state is accessed in the thread notifiers. Acked-by: Catalin Marinas Signed-off-by: Russell King diff --git a/arch/arm/include/asm/thread_notify.h b/arch/arm/include/asm/thread_notify.h index f27379d..c4391ba 100644 --- a/arch/arm/include/asm/thread_notify.h +++ b/arch/arm/include/asm/thread_notify.h @@ -41,7 +41,7 @@ static inline void thread_notify(unsigned long rc, struct thread_info *thread) * These are the reason codes for the thread notifier. */ #define THREAD_NOTIFY_FLUSH 0 -#define THREAD_NOTIFY_RELEASE 1 +#define THREAD_NOTIFY_EXIT 1 #define THREAD_NOTIFY_SWITCH 2 #endif diff --git a/arch/arm/kernel/crunch.c b/arch/arm/kernel/crunch.c index 769abe1..25ef223 100644 --- a/arch/arm/kernel/crunch.c +++ b/arch/arm/kernel/crunch.c @@ -51,7 +51,7 @@ static int crunch_do(struct notifier_block *self, unsigned long cmd, void *t) * initialised state information on the first fault. */ - case THREAD_NOTIFY_RELEASE: + case THREAD_NOTIFY_EXIT: crunch_task_release(thread); break; diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 0d96d01..6730413 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -274,17 +274,18 @@ void show_regs(struct pt_regs * regs) __backtrace(); } +ATOMIC_NOTIFIER_HEAD(thread_notify_head); + +EXPORT_SYMBOL_GPL(thread_notify_head); + /* * Free current thread data structures etc.. */ void exit_thread(void) { + thread_notify(THREAD_NOTIFY_EXIT, current_thread_info()); } -ATOMIC_NOTIFIER_HEAD(thread_notify_head); - -EXPORT_SYMBOL_GPL(thread_notify_head); - void flush_thread(void) { struct thread_info *thread = current_thread_info(); @@ -299,9 +300,6 @@ void flush_thread(void) void release_thread(struct task_struct *dead_task) { - struct thread_info *thread = task_thread_info(dead_task); - - thread_notify(THREAD_NOTIFY_RELEASE, thread); } asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); diff --git a/arch/arm/kernel/xscale-cp0.c b/arch/arm/kernel/xscale-cp0.c index 17127db..1796157 100644 --- a/arch/arm/kernel/xscale-cp0.c +++ b/arch/arm/kernel/xscale-cp0.c @@ -70,7 +70,7 @@ static int iwmmxt_do(struct notifier_block *self, unsigned long cmd, void *t) * initialised state information on the first fault. */ - case THREAD_NOTIFY_RELEASE: + case THREAD_NOTIFY_EXIT: iwmmxt_task_release(thread); break; diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index aed05bc..f60a540 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c @@ -63,14 +63,15 @@ static void vfp_thread_flush(struct thread_info *thread) put_cpu(); } -static void vfp_thread_release(struct thread_info *thread) +static void vfp_thread_exit(struct thread_info *thread) { /* release case: Per-thread VFP cleanup. */ union vfp_state *vfp = &thread->vfpstate; - unsigned int cpu = thread->cpu; + unsigned int cpu = get_cpu(); if (last_VFP_context[cpu] == vfp) last_VFP_context[cpu] = NULL; + put_cpu(); } /* @@ -88,11 +89,13 @@ static void vfp_thread_release(struct thread_info *thread) * but may change at any time. * - we could be preempted if tree preempt rcu is enabled, so * it is unsafe to use thread->cpu. - * THREAD_NOTIFY_RELEASE: - * - the thread (v) will not be running on any CPU; it is a dead thread. - * - thread->cpu will be the last CPU the thread ran on, which may not - * be the current CPU. - * - we could be preempted if tree preempt rcu is enabled. + * THREAD_NOTIFY_EXIT + * - the thread (v) will be running on the local CPU, so + * v === current_thread_info() + * - thread->cpu is the local CPU number at the time it is accessed, + * but may change at any time. + * - we could be preempted if tree preempt rcu is enabled, so + * it is unsafe to use thread->cpu. */ static int vfp_notifier(struct notifier_block *self, unsigned long cmd, void *v) { @@ -133,7 +136,7 @@ static int vfp_notifier(struct notifier_block *self, unsigned long cmd, void *v) if (cmd == THREAD_NOTIFY_FLUSH) vfp_thread_flush(thread); else - vfp_thread_release(thread); + vfp_thread_exit(thread); return NOTIFY_DONE; } -- cgit v0.10.2 From 4da8b8208eded0ba21e3ed7cee79e7454b2b973d Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 18 Dec 2009 16:06:32 +0000 Subject: ARM: Kill CONFIG_CPU_32 26-bit ARM support was removed a long time ago, and this symbol has been defined to be 'y' ever since. As it's never disabled anymore, we can kill it without any side effects. Signed-off-by: Russell King diff --git a/arch/arm/configs/acs5k_defconfig b/arch/arm/configs/acs5k_defconfig index 1cab4e7..6e32a85 100644 --- a/arch/arm/configs/acs5k_defconfig +++ b/arch/arm/configs/acs5k_defconfig @@ -187,7 +187,6 @@ CONFIG_MACH_ACS5K=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM922T=y CONFIG_CPU_32v4T=y CONFIG_CPU_ABRT_EV4T=y diff --git a/arch/arm/configs/acs5k_tiny_defconfig b/arch/arm/configs/acs5k_tiny_defconfig index 8e3d084..b34b1ea 100644 --- a/arch/arm/configs/acs5k_tiny_defconfig +++ b/arch/arm/configs/acs5k_tiny_defconfig @@ -186,7 +186,6 @@ CONFIG_MACH_ACS5K=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM922T=y CONFIG_CPU_32v4T=y CONFIG_CPU_ABRT_EV4T=y diff --git a/arch/arm/configs/afeb9260_defconfig b/arch/arm/configs/afeb9260_defconfig index f7a272c..64fe7f1 100644 --- a/arch/arm/configs/afeb9260_defconfig +++ b/arch/arm/configs/afeb9260_defconfig @@ -227,7 +227,6 @@ CONFIG_AT91_EARLY_DBGU=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM926T=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5TJ=y diff --git a/arch/arm/configs/am200epdkit_defconfig b/arch/arm/configs/am200epdkit_defconfig index 5e68420..30927ca 100644 --- a/arch/arm/configs/am200epdkit_defconfig +++ b/arch/arm/configs/am200epdkit_defconfig @@ -189,7 +189,6 @@ CONFIG_PXA25x=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_XSCALE=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5T=y diff --git a/arch/arm/configs/am3517_evm_defconfig b/arch/arm/configs/am3517_evm_defconfig index ad54e92..abe9966 100644 --- a/arch/arm/configs/am3517_evm_defconfig +++ b/arch/arm/configs/am3517_evm_defconfig @@ -233,7 +233,6 @@ CONFIG_MACH_OMAP3517EVM=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_32v6K=y CONFIG_CPU_V7=y CONFIG_CPU_32v7=y diff --git a/arch/arm/configs/ams_delta_defconfig b/arch/arm/configs/ams_delta_defconfig index e8f7380b..3b3a3775 100644 --- a/arch/arm/configs/ams_delta_defconfig +++ b/arch/arm/configs/ams_delta_defconfig @@ -210,7 +210,6 @@ CONFIG_OMAP_ARM_150MHZ=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM925T=y CONFIG_CPU_32v4T=y CONFIG_CPU_ABRT_EV4T=y diff --git a/arch/arm/configs/assabet_defconfig b/arch/arm/configs/assabet_defconfig index c66dd39..daa75bc 100644 --- a/arch/arm/configs/assabet_defconfig +++ b/arch/arm/configs/assabet_defconfig @@ -101,7 +101,6 @@ CONFIG_SA1100_ASSABET=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_SA1100=y CONFIG_CPU_32v4=y CONFIG_CPU_ABRT_EV4=y diff --git a/arch/arm/configs/at91cap9adk_defconfig b/arch/arm/configs/at91cap9adk_defconfig index bc6bd9f..b1ab50b 100644 --- a/arch/arm/configs/at91cap9adk_defconfig +++ b/arch/arm/configs/at91cap9adk_defconfig @@ -181,7 +181,6 @@ CONFIG_AT91_TIMER_HZ=100 # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM926T=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5TJ=y diff --git a/arch/arm/configs/at91rm9200dk_defconfig b/arch/arm/configs/at91rm9200dk_defconfig index c97e102..1fffec8 100644 --- a/arch/arm/configs/at91rm9200dk_defconfig +++ b/arch/arm/configs/at91rm9200dk_defconfig @@ -130,7 +130,6 @@ CONFIG_AT91_PROGRAMMABLE_CLOCKS=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM920T=y CONFIG_CPU_32v4=y CONFIG_CPU_ABRT_EV4T=y diff --git a/arch/arm/configs/at91rm9200ek_defconfig b/arch/arm/configs/at91rm9200ek_defconfig index 9f7a99a..c846a79 100644 --- a/arch/arm/configs/at91rm9200ek_defconfig +++ b/arch/arm/configs/at91rm9200ek_defconfig @@ -129,7 +129,6 @@ CONFIG_AT91_PROGRAMMABLE_CLOCKS=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM920T=y CONFIG_CPU_32v4=y CONFIG_CPU_ABRT_EV4T=y diff --git a/arch/arm/configs/at91sam9260ek_defconfig b/arch/arm/configs/at91sam9260ek_defconfig index 98e2f3d..472ea11 100644 --- a/arch/arm/configs/at91sam9260ek_defconfig +++ b/arch/arm/configs/at91sam9260ek_defconfig @@ -188,7 +188,6 @@ CONFIG_AT91_TIMER_HZ=100 # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM926T=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5TJ=y diff --git a/arch/arm/configs/at91sam9261ek_defconfig b/arch/arm/configs/at91sam9261ek_defconfig index 1494561..4ecde42 100644 --- a/arch/arm/configs/at91sam9261ek_defconfig +++ b/arch/arm/configs/at91sam9261ek_defconfig @@ -181,7 +181,6 @@ CONFIG_AT91_TIMER_HZ=100 # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM926T=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5TJ=y diff --git a/arch/arm/configs/at91sam9263ek_defconfig b/arch/arm/configs/at91sam9263ek_defconfig index 21599f3..9b792b6 100644 --- a/arch/arm/configs/at91sam9263ek_defconfig +++ b/arch/arm/configs/at91sam9263ek_defconfig @@ -181,7 +181,6 @@ CONFIG_AT91_TIMER_HZ=100 # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM926T=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5TJ=y diff --git a/arch/arm/configs/at91sam9g20ek_defconfig b/arch/arm/configs/at91sam9g20ek_defconfig index 7e018a0..64ce106 100644 --- a/arch/arm/configs/at91sam9g20ek_defconfig +++ b/arch/arm/configs/at91sam9g20ek_defconfig @@ -187,7 +187,6 @@ CONFIG_AT91_EARLY_DBGU=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM926T=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5TJ=y diff --git a/arch/arm/configs/at91sam9rlek_defconfig b/arch/arm/configs/at91sam9rlek_defconfig index e2df81a..90e48bf 100644 --- a/arch/arm/configs/at91sam9rlek_defconfig +++ b/arch/arm/configs/at91sam9rlek_defconfig @@ -179,7 +179,6 @@ CONFIG_AT91_TIMER_HZ=100 # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM926T=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5TJ=y diff --git a/arch/arm/configs/ateb9200_defconfig b/arch/arm/configs/ateb9200_defconfig index a19e824..6315534 100644 --- a/arch/arm/configs/ateb9200_defconfig +++ b/arch/arm/configs/ateb9200_defconfig @@ -132,7 +132,6 @@ CONFIG_MACH_ATEB9200=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM920T=y CONFIG_CPU_32v4=y CONFIG_CPU_ABRT_EV4T=y diff --git a/arch/arm/configs/badge4_defconfig b/arch/arm/configs/badge4_defconfig index f264846..b175b6b 100644 --- a/arch/arm/configs/badge4_defconfig +++ b/arch/arm/configs/badge4_defconfig @@ -103,7 +103,6 @@ CONFIG_SA1100_BADGE4=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_SA1100=y CONFIG_CPU_32v4=y CONFIG_CPU_ABRT_EV4=y diff --git a/arch/arm/configs/bcmring_defconfig b/arch/arm/configs/bcmring_defconfig index bcc0bac..1e12167 100644 --- a/arch/arm/configs/bcmring_defconfig +++ b/arch/arm/configs/bcmring_defconfig @@ -181,7 +181,6 @@ CONFIG_BCM_ZRELADDR=0x8000 # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_V6=y CONFIG_CPU_32v6K=y CONFIG_CPU_32v6=y diff --git a/arch/arm/configs/cam60_defconfig b/arch/arm/configs/cam60_defconfig index 8448108..eef33de 100644 --- a/arch/arm/configs/cam60_defconfig +++ b/arch/arm/configs/cam60_defconfig @@ -196,7 +196,6 @@ CONFIG_AT91_EARLY_DBGU=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM926T=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5TJ=y diff --git a/arch/arm/configs/carmeva_defconfig b/arch/arm/configs/carmeva_defconfig index d392833..b6a7063 100644 --- a/arch/arm/configs/carmeva_defconfig +++ b/arch/arm/configs/carmeva_defconfig @@ -97,7 +97,6 @@ CONFIG_MACH_CARMEVA=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM920T=y CONFIG_CPU_32v4=y CONFIG_CPU_ABRT_EV4T=y diff --git a/arch/arm/configs/cerfcube_defconfig b/arch/arm/configs/cerfcube_defconfig index 2b4c066..d662cab 100644 --- a/arch/arm/configs/cerfcube_defconfig +++ b/arch/arm/configs/cerfcube_defconfig @@ -105,7 +105,6 @@ CONFIG_SA1100_CERF_FLASH_16MB=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_SA1100=y CONFIG_CPU_32v4=y CONFIG_CPU_ABRT_EV4=y diff --git a/arch/arm/configs/cm_t35_defconfig b/arch/arm/configs/cm_t35_defconfig index e42c5c8..893cd26 100644 --- a/arch/arm/configs/cm_t35_defconfig +++ b/arch/arm/configs/cm_t35_defconfig @@ -236,7 +236,6 @@ CONFIG_MACH_CM_T35=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_32v6K=y CONFIG_CPU_V7=y CONFIG_CPU_32v7=y diff --git a/arch/arm/configs/cm_x2xx_defconfig b/arch/arm/configs/cm_x2xx_defconfig index 797b790..47d22d0 100644 --- a/arch/arm/configs/cm_x2xx_defconfig +++ b/arch/arm/configs/cm_x2xx_defconfig @@ -205,7 +205,6 @@ CONFIG_PXA_SSP=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_XSCALE=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5T=y diff --git a/arch/arm/configs/cm_x300_defconfig b/arch/arm/configs/cm_x300_defconfig index a017086..a334069 100644 --- a/arch/arm/configs/cm_x300_defconfig +++ b/arch/arm/configs/cm_x300_defconfig @@ -247,7 +247,6 @@ CONFIG_PLAT_PXA=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_XSC3=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5T=y diff --git a/arch/arm/configs/colibri_pxa270_defconfig b/arch/arm/configs/colibri_pxa270_defconfig index 4cf3bde..c962870 100644 --- a/arch/arm/configs/colibri_pxa270_defconfig +++ b/arch/arm/configs/colibri_pxa270_defconfig @@ -204,7 +204,6 @@ CONFIG_PXA27x=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_XSCALE=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5T=y diff --git a/arch/arm/configs/colibri_pxa300_defconfig b/arch/arm/configs/colibri_pxa300_defconfig index 4774a36..11fdb5a 100644 --- a/arch/arm/configs/colibri_pxa300_defconfig +++ b/arch/arm/configs/colibri_pxa300_defconfig @@ -212,7 +212,6 @@ CONFIG_PXA3xx=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_XSC3=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5T=y diff --git a/arch/arm/configs/collie_defconfig b/arch/arm/configs/collie_defconfig index 1aa6224..26e458d 100644 --- a/arch/arm/configs/collie_defconfig +++ b/arch/arm/configs/collie_defconfig @@ -125,7 +125,6 @@ CONFIG_SA1100_COLLIE=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_SA1100=y CONFIG_CPU_32v4=y CONFIG_CPU_ABRT_EV4=y diff --git a/arch/arm/configs/corgi_defconfig b/arch/arm/configs/corgi_defconfig index d6cd165..5e4069f 100644 --- a/arch/arm/configs/corgi_defconfig +++ b/arch/arm/configs/corgi_defconfig @@ -214,7 +214,6 @@ CONFIG_PXA_HAVE_BOARD_IRQS=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_XSCALE=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5T=y diff --git a/arch/arm/configs/cpu9260_defconfig b/arch/arm/configs/cpu9260_defconfig index 601e7f3..c9137aa 100644 --- a/arch/arm/configs/cpu9260_defconfig +++ b/arch/arm/configs/cpu9260_defconfig @@ -229,7 +229,6 @@ CONFIG_AT91_EARLY_DBGU=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM926T=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5TJ=y diff --git a/arch/arm/configs/cpu9g20_defconfig b/arch/arm/configs/cpu9g20_defconfig index b5b9cbb..d234479 100644 --- a/arch/arm/configs/cpu9g20_defconfig +++ b/arch/arm/configs/cpu9g20_defconfig @@ -219,7 +219,6 @@ CONFIG_AT91_EARLY_DBGU=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM926T=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5TJ=y diff --git a/arch/arm/configs/cpuat91_defconfig b/arch/arm/configs/cpuat91_defconfig index 4901827..1f8dda6 100644 --- a/arch/arm/configs/cpuat91_defconfig +++ b/arch/arm/configs/cpuat91_defconfig @@ -230,7 +230,6 @@ CONFIG_AT91_EARLY_DBGU=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM920T=y CONFIG_CPU_32v4T=y CONFIG_CPU_ABRT_EV4T=y diff --git a/arch/arm/configs/csb337_defconfig b/arch/arm/configs/csb337_defconfig index 29f68c2..f095040 100644 --- a/arch/arm/configs/csb337_defconfig +++ b/arch/arm/configs/csb337_defconfig @@ -193,7 +193,6 @@ CONFIG_AT91_TIMER_HZ=128 # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM920T=y CONFIG_CPU_32v4T=y CONFIG_CPU_ABRT_EV4T=y diff --git a/arch/arm/configs/csb637_defconfig b/arch/arm/configs/csb637_defconfig index f7b60ce..5071540 100644 --- a/arch/arm/configs/csb637_defconfig +++ b/arch/arm/configs/csb637_defconfig @@ -215,7 +215,6 @@ CONFIG_AT91_EARLY_DBGU=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM920T=y CONFIG_CPU_32v4T=y CONFIG_CPU_ABRT_EV4T=y diff --git a/arch/arm/configs/da8xx_omapl_defconfig b/arch/arm/configs/da8xx_omapl_defconfig index 50bd25a..e14c99c 100644 --- a/arch/arm/configs/da8xx_omapl_defconfig +++ b/arch/arm/configs/da8xx_omapl_defconfig @@ -225,7 +225,6 @@ CONFIG_DAVINCI_RESET_CLOCKS=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM926T=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5TJ=y diff --git a/arch/arm/configs/davinci_all_defconfig b/arch/arm/configs/davinci_all_defconfig index bd656e8..625035f 100644 --- a/arch/arm/configs/davinci_all_defconfig +++ b/arch/arm/configs/davinci_all_defconfig @@ -223,7 +223,6 @@ CONFIG_DAVINCI_RESET_CLOCKS=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM926T=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5TJ=y diff --git a/arch/arm/configs/dove_defconfig b/arch/arm/configs/dove_defconfig index b3a4916..b7b2ab0 100644 --- a/arch/arm/configs/dove_defconfig +++ b/arch/arm/configs/dove_defconfig @@ -186,7 +186,6 @@ CONFIG_PLAT_ORION=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_V6=y CONFIG_CPU_32v6K=y CONFIG_CPU_32v6=y diff --git a/arch/arm/configs/ebsa110_defconfig b/arch/arm/configs/ebsa110_defconfig index afcfff6..d5e8279 100644 --- a/arch/arm/configs/ebsa110_defconfig +++ b/arch/arm/configs/ebsa110_defconfig @@ -83,7 +83,6 @@ CONFIG_ARCH_EBSA110=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_SA110=y CONFIG_CPU_32v4=y CONFIG_CPU_ABRT_EV4=y diff --git a/arch/arm/configs/ecbat91_defconfig b/arch/arm/configs/ecbat91_defconfig index ca52073..25dd53b 100644 --- a/arch/arm/configs/ecbat91_defconfig +++ b/arch/arm/configs/ecbat91_defconfig @@ -186,7 +186,6 @@ CONFIG_AT91_PROGRAMMABLE_CLOCKS=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM920T=y CONFIG_CPU_32v4T=y CONFIG_CPU_ABRT_EV4T=y diff --git a/arch/arm/configs/edb7211_defconfig b/arch/arm/configs/edb7211_defconfig index 6ba7355..e3a6cd3 100644 --- a/arch/arm/configs/edb7211_defconfig +++ b/arch/arm/configs/edb7211_defconfig @@ -90,7 +90,6 @@ CONFIG_ARCH_EP7211=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM720T=y CONFIG_CPU_32v4=y CONFIG_CPU_ABRT_LV4T=y diff --git a/arch/arm/configs/em_x270_defconfig b/arch/arm/configs/em_x270_defconfig index e9955b7..2bee932 100644 --- a/arch/arm/configs/em_x270_defconfig +++ b/arch/arm/configs/em_x270_defconfig @@ -202,7 +202,6 @@ CONFIG_PXA_SSP=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_XSCALE=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5T=y diff --git a/arch/arm/configs/ep93xx_defconfig b/arch/arm/configs/ep93xx_defconfig index 3fb083b..35d735e 100644 --- a/arch/arm/configs/ep93xx_defconfig +++ b/arch/arm/configs/ep93xx_defconfig @@ -198,7 +198,6 @@ CONFIG_EP93XX_EARLY_UART1=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM920T=y CONFIG_CPU_32v4T=y CONFIG_CPU_ABRT_EV4T=y diff --git a/arch/arm/configs/eseries_pxa_defconfig b/arch/arm/configs/eseries_pxa_defconfig index b6c5cbb..74baf57 100644 --- a/arch/arm/configs/eseries_pxa_defconfig +++ b/arch/arm/configs/eseries_pxa_defconfig @@ -203,7 +203,6 @@ CONFIG_PXA_HAVE_BOARD_IRQS=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_XSCALE=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5T=y diff --git a/arch/arm/configs/ezx_defconfig b/arch/arm/configs/ezx_defconfig index 492f29a..9e9057c 100644 --- a/arch/arm/configs/ezx_defconfig +++ b/arch/arm/configs/ezx_defconfig @@ -240,7 +240,6 @@ CONFIG_PLAT_PXA=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_XSCALE=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5T=y diff --git a/arch/arm/configs/footbridge_defconfig b/arch/arm/configs/footbridge_defconfig index 6ace512..04d9793 100644 --- a/arch/arm/configs/footbridge_defconfig +++ b/arch/arm/configs/footbridge_defconfig @@ -95,7 +95,6 @@ CONFIG_ARCH_EBSA285=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_SA110=y CONFIG_CPU_32v4=y CONFIG_CPU_ABRT_EV4=y diff --git a/arch/arm/configs/fortunet_defconfig b/arch/arm/configs/fortunet_defconfig index 65dc73a..d58142b 100644 --- a/arch/arm/configs/fortunet_defconfig +++ b/arch/arm/configs/fortunet_defconfig @@ -88,7 +88,6 @@ CONFIG_ARCH_FORTUNET=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM720T=y CONFIG_CPU_32v4=y CONFIG_CPU_ABRT_LV4T=y diff --git a/arch/arm/configs/h3600_defconfig b/arch/arm/configs/h3600_defconfig index efa78e1..a8ad8fb 100644 --- a/arch/arm/configs/h3600_defconfig +++ b/arch/arm/configs/h3600_defconfig @@ -205,7 +205,6 @@ CONFIG_SA1100_H3600=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_SA1100=y CONFIG_CPU_32v4=y CONFIG_CPU_ABRT_EV4=y diff --git a/arch/arm/configs/h5000_defconfig b/arch/arm/configs/h5000_defconfig index 649baa3..5bb7372 100644 --- a/arch/arm/configs/h5000_defconfig +++ b/arch/arm/configs/h5000_defconfig @@ -206,7 +206,6 @@ CONFIG_PXA25x=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_XSCALE=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5T=y diff --git a/arch/arm/configs/h7201_defconfig b/arch/arm/configs/h7201_defconfig index 116920a..09a6c6a 100644 --- a/arch/arm/configs/h7201_defconfig +++ b/arch/arm/configs/h7201_defconfig @@ -87,7 +87,6 @@ CONFIG_CPU_H7201=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM720T=y CONFIG_CPU_32v4=y CONFIG_CPU_ABRT_LV4T=y diff --git a/arch/arm/configs/h7202_defconfig b/arch/arm/configs/h7202_defconfig index 0e739af..fedc52b 100644 --- a/arch/arm/configs/h7202_defconfig +++ b/arch/arm/configs/h7202_defconfig @@ -91,7 +91,6 @@ CONFIG_CPU_H7202=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM720T=y CONFIG_CPU_32v4=y CONFIG_CPU_ABRT_LV4T=y diff --git a/arch/arm/configs/hackkit_defconfig b/arch/arm/configs/hackkit_defconfig index db0708d..2da1acf 100644 --- a/arch/arm/configs/hackkit_defconfig +++ b/arch/arm/configs/hackkit_defconfig @@ -103,7 +103,6 @@ CONFIG_SA1100_HACKKIT=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_SA1100=y CONFIG_CPU_32v4=y CONFIG_CPU_ABRT_EV4=y diff --git a/arch/arm/configs/htcherald_defconfig b/arch/arm/configs/htcherald_defconfig index 1b39691..e0ef0d1 100644 --- a/arch/arm/configs/htcherald_defconfig +++ b/arch/arm/configs/htcherald_defconfig @@ -241,7 +241,6 @@ CONFIG_OMAP_ARM_195MHZ=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM925T=y CONFIG_CPU_ARM926T=y CONFIG_CPU_32v4T=y diff --git a/arch/arm/configs/igep0020_defconfig b/arch/arm/configs/igep0020_defconfig index c97f8d0..a192248 100644 --- a/arch/arm/configs/igep0020_defconfig +++ b/arch/arm/configs/igep0020_defconfig @@ -238,7 +238,6 @@ CONFIG_MACH_IGEP0020=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_32v6K=y CONFIG_CPU_V7=y CONFIG_CPU_32v7=y diff --git a/arch/arm/configs/integrator_defconfig b/arch/arm/configs/integrator_defconfig index 3ce96e6..6b0d043 100644 --- a/arch/arm/configs/integrator_defconfig +++ b/arch/arm/configs/integrator_defconfig @@ -92,7 +92,6 @@ CONFIG_ARCH_INTEGRATOR_AP=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM720T=y CONFIG_CPU_ARM920T=y # CONFIG_CPU_ARM922T is not set diff --git a/arch/arm/configs/iop13xx_defconfig b/arch/arm/configs/iop13xx_defconfig index 89c1776..3c040cc 100644 --- a/arch/arm/configs/iop13xx_defconfig +++ b/arch/arm/configs/iop13xx_defconfig @@ -163,7 +163,6 @@ CONFIG_PLAT_IOP=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_XSC3=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5T=y diff --git a/arch/arm/configs/iop32x_defconfig b/arch/arm/configs/iop32x_defconfig index d70177b..62a8549 100644 --- a/arch/arm/configs/iop32x_defconfig +++ b/arch/arm/configs/iop32x_defconfig @@ -168,7 +168,6 @@ CONFIG_PLAT_IOP=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_XSCALE=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5T=y diff --git a/arch/arm/configs/iop33x_defconfig b/arch/arm/configs/iop33x_defconfig index ed2d59d..0bc23ec 100644 --- a/arch/arm/configs/iop33x_defconfig +++ b/arch/arm/configs/iop33x_defconfig @@ -198,7 +198,6 @@ CONFIG_PLAT_IOP=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_XSCALE=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5T=y diff --git a/arch/arm/configs/ixp2000_defconfig b/arch/arm/configs/ixp2000_defconfig index 57526c1..8b5b576 100644 --- a/arch/arm/configs/ixp2000_defconfig +++ b/arch/arm/configs/ixp2000_defconfig @@ -151,7 +151,6 @@ CONFIG_ARCH_IXDP2X01=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_XSCALE=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5T=y diff --git a/arch/arm/configs/ixp23xx_defconfig b/arch/arm/configs/ixp23xx_defconfig index ef97561..59c11c9 100644 --- a/arch/arm/configs/ixp23xx_defconfig +++ b/arch/arm/configs/ixp23xx_defconfig @@ -145,7 +145,6 @@ CONFIG_MACH_ROADRUNNER=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_XSC3=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5T=y diff --git a/arch/arm/configs/ixp4xx_defconfig b/arch/arm/configs/ixp4xx_defconfig index 95cd8df..a907ad5 100644 --- a/arch/arm/configs/ixp4xx_defconfig +++ b/arch/arm/configs/ixp4xx_defconfig @@ -189,7 +189,6 @@ CONFIG_IXP4XX_NPE=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_XSCALE=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5T=y diff --git a/arch/arm/configs/jornada720_defconfig b/arch/arm/configs/jornada720_defconfig index df9bfbe..d1f1646 100644 --- a/arch/arm/configs/jornada720_defconfig +++ b/arch/arm/configs/jornada720_defconfig @@ -202,7 +202,6 @@ CONFIG_SA1100_SSP=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_SA1100=y CONFIG_CPU_32v4=y CONFIG_CPU_ABRT_EV4=y diff --git a/arch/arm/configs/kafa_defconfig b/arch/arm/configs/kafa_defconfig index 9f92fc5..f661e76 100644 --- a/arch/arm/configs/kafa_defconfig +++ b/arch/arm/configs/kafa_defconfig @@ -132,7 +132,6 @@ CONFIG_MACH_KAFA=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM920T=y CONFIG_CPU_32v4=y CONFIG_CPU_ABRT_EV4T=y diff --git a/arch/arm/configs/kb9202_defconfig b/arch/arm/configs/kb9202_defconfig index 605a846..668ba59 100644 --- a/arch/arm/configs/kb9202_defconfig +++ b/arch/arm/configs/kb9202_defconfig @@ -230,7 +230,6 @@ CONFIG_AT91_EARLY_DBGU=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM920T=y CONFIG_CPU_32v4T=y CONFIG_CPU_ABRT_EV4T=y diff --git a/arch/arm/configs/kirkwood_defconfig b/arch/arm/configs/kirkwood_defconfig index bcfade3..5fc44c9 100644 --- a/arch/arm/configs/kirkwood_defconfig +++ b/arch/arm/configs/kirkwood_defconfig @@ -201,7 +201,6 @@ CONFIG_PLAT_ORION=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_FEROCEON=y # CONFIG_CPU_FEROCEON_OLD_ID is not set CONFIG_CPU_32v5=y diff --git a/arch/arm/configs/ks8695_defconfig b/arch/arm/configs/ks8695_defconfig index d25c41b..e6f2276 100644 --- a/arch/arm/configs/ks8695_defconfig +++ b/arch/arm/configs/ks8695_defconfig @@ -186,7 +186,6 @@ CONFIG_MACH_DSM320=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM922T=y CONFIG_CPU_32v4T=y CONFIG_CPU_ABRT_EV4T=y diff --git a/arch/arm/configs/lart_defconfig b/arch/arm/configs/lart_defconfig index 56ae568..af75951 100644 --- a/arch/arm/configs/lart_defconfig +++ b/arch/arm/configs/lart_defconfig @@ -99,7 +99,6 @@ CONFIG_SA1100_LART=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_SA1100=y CONFIG_CPU_32v4=y CONFIG_CPU_ABRT_EV4=y diff --git a/arch/arm/configs/loki_defconfig b/arch/arm/configs/loki_defconfig index b720fcf..6df7b14 100644 --- a/arch/arm/configs/loki_defconfig +++ b/arch/arm/configs/loki_defconfig @@ -174,7 +174,6 @@ CONFIG_PLAT_ORION=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_FEROCEON=y # CONFIG_CPU_FEROCEON_OLD_ID is not set CONFIG_CPU_32v5=y diff --git a/arch/arm/configs/lpd270_defconfig b/arch/arm/configs/lpd270_defconfig index 1a38d8e..aeb7686 100644 --- a/arch/arm/configs/lpd270_defconfig +++ b/arch/arm/configs/lpd270_defconfig @@ -143,7 +143,6 @@ CONFIG_PXA27x=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_XSCALE=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5T=y diff --git a/arch/arm/configs/lpd7a400_defconfig b/arch/arm/configs/lpd7a400_defconfig index f8ac29d..6116fee 100644 --- a/arch/arm/configs/lpd7a400_defconfig +++ b/arch/arm/configs/lpd7a400_defconfig @@ -95,7 +95,6 @@ CONFIG_LPD7A40X_CPLD_SSP=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM922T=y CONFIG_CPU_32v4=y CONFIG_CPU_ABRT_EV4T=y diff --git a/arch/arm/configs/lpd7a404_defconfig b/arch/arm/configs/lpd7a404_defconfig index 7a2e932..142cccd 100644 --- a/arch/arm/configs/lpd7a404_defconfig +++ b/arch/arm/configs/lpd7a404_defconfig @@ -117,7 +117,6 @@ CONFIG_ARCH_LH7A404=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM922T=y CONFIG_CPU_32v4=y CONFIG_CPU_ABRT_EV4T=y diff --git a/arch/arm/configs/lubbock_defconfig b/arch/arm/configs/lubbock_defconfig index e544bfb..75c6293 100644 --- a/arch/arm/configs/lubbock_defconfig +++ b/arch/arm/configs/lubbock_defconfig @@ -92,7 +92,6 @@ CONFIG_PXA25x=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_XSCALE=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5T=y diff --git a/arch/arm/configs/lusl7200_defconfig b/arch/arm/configs/lusl7200_defconfig index 42f6a77..c1a1fb0 100644 --- a/arch/arm/configs/lusl7200_defconfig +++ b/arch/arm/configs/lusl7200_defconfig @@ -82,7 +82,6 @@ CONFIG_ARCH_L7200=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM720T=y CONFIG_CPU_32v4=y CONFIG_CPU_ABRT_LV4T=y diff --git a/arch/arm/configs/magician_defconfig b/arch/arm/configs/magician_defconfig index 957fd5f..8e9a723 100644 --- a/arch/arm/configs/magician_defconfig +++ b/arch/arm/configs/magician_defconfig @@ -204,7 +204,6 @@ CONFIG_PXA_HAVE_BOARD_IRQS=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_XSCALE=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5T=y diff --git a/arch/arm/configs/mainstone_defconfig b/arch/arm/configs/mainstone_defconfig index cc8c95b..1cddb61 100644 --- a/arch/arm/configs/mainstone_defconfig +++ b/arch/arm/configs/mainstone_defconfig @@ -93,7 +93,6 @@ CONFIG_IWMMXT=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_XSCALE=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5T=y diff --git a/arch/arm/configs/mini2440_defconfig b/arch/arm/configs/mini2440_defconfig index e49ed40..d2a90eb 100644 --- a/arch/arm/configs/mini2440_defconfig +++ b/arch/arm/configs/mini2440_defconfig @@ -256,7 +256,6 @@ CONFIG_MACH_MINI2440=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM920T=y CONFIG_CPU_32v4T=y CONFIG_CPU_ABRT_EV4T=y diff --git a/arch/arm/configs/msm_defconfig b/arch/arm/configs/msm_defconfig index cc3b06e..fe25e3b 100644 --- a/arch/arm/configs/msm_defconfig +++ b/arch/arm/configs/msm_defconfig @@ -155,7 +155,6 @@ CONFIG_MSM_SMD=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_V6=y # CONFIG_CPU_32v6K is not set CONFIG_CPU_32v6=y diff --git a/arch/arm/configs/mv78xx0_defconfig b/arch/arm/configs/mv78xx0_defconfig index 398274b..6afa2c1 100644 --- a/arch/arm/configs/mv78xx0_defconfig +++ b/arch/arm/configs/mv78xx0_defconfig @@ -181,7 +181,6 @@ CONFIG_PLAT_ORION=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_FEROCEON=y CONFIG_CPU_FEROCEON_OLD_ID=y CONFIG_CPU_32v5=y diff --git a/arch/arm/configs/mx1_defconfig b/arch/arm/configs/mx1_defconfig index 0200d67..f575070 100644 --- a/arch/arm/configs/mx1_defconfig +++ b/arch/arm/configs/mx1_defconfig @@ -190,7 +190,6 @@ CONFIG_MXC_IRQ_PRIOR=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM920T=y CONFIG_CPU_32v4T=y CONFIG_CPU_ABRT_EV4T=y diff --git a/arch/arm/configs/mx1ads_defconfig b/arch/arm/configs/mx1ads_defconfig index 577d7e1..3cabbb6 100644 --- a/arch/arm/configs/mx1ads_defconfig +++ b/arch/arm/configs/mx1ads_defconfig @@ -88,7 +88,6 @@ CONFIG_ARCH_MX1ADS=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM920T=y CONFIG_CPU_32v4=y CONFIG_CPU_ABRT_EV4T=y diff --git a/arch/arm/configs/mx21_defconfig b/arch/arm/configs/mx21_defconfig index 4b04290..1ecd627 100644 --- a/arch/arm/configs/mx21_defconfig +++ b/arch/arm/configs/mx21_defconfig @@ -185,7 +185,6 @@ CONFIG_MXC_PWM=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM926T=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5TJ=y diff --git a/arch/arm/configs/mx27_defconfig b/arch/arm/configs/mx27_defconfig index 75263a8..edfdd6f 100644 --- a/arch/arm/configs/mx27_defconfig +++ b/arch/arm/configs/mx27_defconfig @@ -207,7 +207,6 @@ CONFIG_MXC_PWM=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM926T=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5TJ=y diff --git a/arch/arm/configs/mx31pdk_defconfig b/arch/arm/configs/mx31pdk_defconfig index 95ffc0d..d409537 100644 --- a/arch/arm/configs/mx31pdk_defconfig +++ b/arch/arm/configs/mx31pdk_defconfig @@ -173,7 +173,6 @@ CONFIG_MACH_MX31_3DS=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_V6=y # CONFIG_CPU_32v6K is not set CONFIG_CPU_32v6=y diff --git a/arch/arm/configs/mx3_defconfig b/arch/arm/configs/mx3_defconfig index 7734cca..8a06bc6 100644 --- a/arch/arm/configs/mx3_defconfig +++ b/arch/arm/configs/mx3_defconfig @@ -218,7 +218,6 @@ CONFIG_ARCH_MXC_IOMUX_V3=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_V6=y # CONFIG_CPU_32v6K is not set CONFIG_CPU_32v6=y diff --git a/arch/arm/configs/n770_defconfig b/arch/arm/configs/n770_defconfig index a1657b7..75cae18 100644 --- a/arch/arm/configs/n770_defconfig +++ b/arch/arm/configs/n770_defconfig @@ -210,7 +210,6 @@ CONFIG_OMAP_ARM_216MHZ=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM926T=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5TJ=y diff --git a/arch/arm/configs/n8x0_defconfig b/arch/arm/configs/n8x0_defconfig index 264f52b..e6f667c 100644 --- a/arch/arm/configs/n8x0_defconfig +++ b/arch/arm/configs/n8x0_defconfig @@ -232,7 +232,6 @@ CONFIG_MACH_NOKIA_N8X0=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_V6=y # CONFIG_CPU_32v6K is not set CONFIG_CPU_32v6=y diff --git a/arch/arm/configs/neocore926_defconfig b/arch/arm/configs/neocore926_defconfig index e0e4e98..d165c75 100644 --- a/arch/arm/configs/neocore926_defconfig +++ b/arch/arm/configs/neocore926_defconfig @@ -218,7 +218,6 @@ CONFIG_AT91_EARLY_DBGU=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM926T=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5TJ=y diff --git a/arch/arm/configs/neponset_defconfig b/arch/arm/configs/neponset_defconfig index 36cd62e..171265e 100644 --- a/arch/arm/configs/neponset_defconfig +++ b/arch/arm/configs/neponset_defconfig @@ -103,7 +103,6 @@ CONFIG_ASSABET_NEPONSET=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_SA1100=y CONFIG_CPU_32v4=y CONFIG_CPU_ABRT_EV4=y diff --git a/arch/arm/configs/netwinder_defconfig b/arch/arm/configs/netwinder_defconfig index c1a63a3..78f58a9 100644 --- a/arch/arm/configs/netwinder_defconfig +++ b/arch/arm/configs/netwinder_defconfig @@ -89,7 +89,6 @@ CONFIG_FOOTBRIDGE_HOST=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_SA110=y CONFIG_CPU_32v4=y CONFIG_CPU_ABRT_EV4=y diff --git a/arch/arm/configs/netx_defconfig b/arch/arm/configs/netx_defconfig index 61d0fc5..2a97e36 100644 --- a/arch/arm/configs/netx_defconfig +++ b/arch/arm/configs/netx_defconfig @@ -122,7 +122,6 @@ CONFIG_MACH_NXEB500HMI=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM926T=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5TJ=y diff --git a/arch/arm/configs/nhk8815_defconfig b/arch/arm/configs/nhk8815_defconfig index 600cb27..92d9086 100644 --- a/arch/arm/configs/nhk8815_defconfig +++ b/arch/arm/configs/nhk8815_defconfig @@ -191,7 +191,6 @@ CONFIG_I2C_BITBANG_8815NHK=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM926T=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5TJ=y diff --git a/arch/arm/configs/nuc910_defconfig b/arch/arm/configs/nuc910_defconfig index 5245655..f80848a 100644 --- a/arch/arm/configs/nuc910_defconfig +++ b/arch/arm/configs/nuc910_defconfig @@ -180,7 +180,6 @@ CONFIG_MACH_W90P910EVB=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM926T=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5TJ=y diff --git a/arch/arm/configs/nuc950_defconfig b/arch/arm/configs/nuc950_defconfig index df1de9b..97300ec 100644 --- a/arch/arm/configs/nuc950_defconfig +++ b/arch/arm/configs/nuc950_defconfig @@ -201,7 +201,6 @@ CONFIG_MACH_W90P950EVB=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM926T=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5TJ=y diff --git a/arch/arm/configs/nuc960_defconfig b/arch/arm/configs/nuc960_defconfig index 4b2cd9e..aa7e128 100644 --- a/arch/arm/configs/nuc960_defconfig +++ b/arch/arm/configs/nuc960_defconfig @@ -201,7 +201,6 @@ CONFIG_MACH_W90N960EVB=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM926T=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5TJ=y diff --git a/arch/arm/configs/omap3_beagle_defconfig b/arch/arm/configs/omap3_beagle_defconfig index 9cfae37..c7999f5 100644 --- a/arch/arm/configs/omap3_beagle_defconfig +++ b/arch/arm/configs/omap3_beagle_defconfig @@ -213,7 +213,6 @@ CONFIG_MACH_OMAP3_BEAGLE=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_32v6K=y CONFIG_CPU_V7=y CONFIG_CPU_32v7=y diff --git a/arch/arm/configs/omap3_defconfig b/arch/arm/configs/omap3_defconfig index 2af28ea..367be98 100644 --- a/arch/arm/configs/omap3_defconfig +++ b/arch/arm/configs/omap3_defconfig @@ -245,7 +245,6 @@ CONFIG_MACH_OMAP_3630SDP=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_32v6K=y CONFIG_CPU_V7=y CONFIG_CPU_32v7=y diff --git a/arch/arm/configs/omap3_evm_defconfig b/arch/arm/configs/omap3_evm_defconfig index e190fc8..86cc4be 100644 --- a/arch/arm/configs/omap3_evm_defconfig +++ b/arch/arm/configs/omap3_evm_defconfig @@ -220,7 +220,6 @@ CONFIG_MACH_OMAP3EVM=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_32v6K=y CONFIG_CPU_V7=y CONFIG_CPU_32v7=y diff --git a/arch/arm/configs/omap3_pandora_defconfig b/arch/arm/configs/omap3_pandora_defconfig index b7a8d9f..f74eb9a 100644 --- a/arch/arm/configs/omap3_pandora_defconfig +++ b/arch/arm/configs/omap3_pandora_defconfig @@ -211,7 +211,6 @@ CONFIG_MACH_OMAP3_PANDORA=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_32v6K=y CONFIG_CPU_V7=y CONFIG_CPU_32v7=y diff --git a/arch/arm/configs/omap3_touchbook_defconfig b/arch/arm/configs/omap3_touchbook_defconfig index 7c8515e..74fe6be 100644 --- a/arch/arm/configs/omap3_touchbook_defconfig +++ b/arch/arm/configs/omap3_touchbook_defconfig @@ -246,7 +246,6 @@ CONFIG_MACH_OMAP3_TOUCHBOOK=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_32v6K=y CONFIG_CPU_V7=y CONFIG_CPU_32v7=y diff --git a/arch/arm/configs/omap_2430sdp_defconfig b/arch/arm/configs/omap_2430sdp_defconfig index 640e9af..45b4eba 100644 --- a/arch/arm/configs/omap_2430sdp_defconfig +++ b/arch/arm/configs/omap_2430sdp_defconfig @@ -197,7 +197,6 @@ CONFIG_MACH_OMAP_2430SDP=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_V6=y # CONFIG_CPU_32v6K is not set CONFIG_CPU_32v6=y diff --git a/arch/arm/configs/omap_3430sdp_defconfig b/arch/arm/configs/omap_3430sdp_defconfig index 592457c..bb2917e 100644 --- a/arch/arm/configs/omap_3430sdp_defconfig +++ b/arch/arm/configs/omap_3430sdp_defconfig @@ -232,7 +232,6 @@ CONFIG_MACH_OMAP_3430SDP=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_32v6K=y CONFIG_CPU_V7=y CONFIG_CPU_32v7=y diff --git a/arch/arm/configs/omap_3630sdp_defconfig b/arch/arm/configs/omap_3630sdp_defconfig index e836c8a..d25c3d4 100644 --- a/arch/arm/configs/omap_3630sdp_defconfig +++ b/arch/arm/configs/omap_3630sdp_defconfig @@ -236,7 +236,6 @@ CONFIG_MACH_OMAP_3630SDP=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_32v6K=y CONFIG_CPU_V7=y CONFIG_CPU_32v7=y diff --git a/arch/arm/configs/omap_4430sdp_defconfig b/arch/arm/configs/omap_4430sdp_defconfig index 2319113..3de640a 100644 --- a/arch/arm/configs/omap_4430sdp_defconfig +++ b/arch/arm/configs/omap_4430sdp_defconfig @@ -220,7 +220,6 @@ CONFIG_MACH_OMAP_4430SDP=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_32v6K=y CONFIG_CPU_V7=y CONFIG_CPU_32v7=y diff --git a/arch/arm/configs/omap_apollon_2420_defconfig b/arch/arm/configs/omap_apollon_2420_defconfig index ac7adf3..cc86342 100644 --- a/arch/arm/configs/omap_apollon_2420_defconfig +++ b/arch/arm/configs/omap_apollon_2420_defconfig @@ -196,7 +196,6 @@ CONFIG_MACH_OMAP_APOLLON=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_V6=y # CONFIG_CPU_32v6K is not set CONFIG_CPU_32v6=y diff --git a/arch/arm/configs/omap_generic_1510_defconfig b/arch/arm/configs/omap_generic_1510_defconfig index ccdc661..61744e5 100644 --- a/arch/arm/configs/omap_generic_1510_defconfig +++ b/arch/arm/configs/omap_generic_1510_defconfig @@ -205,7 +205,6 @@ CONFIG_OMAP_ARM_168MHZ=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM925T=y CONFIG_CPU_32v4T=y CONFIG_CPU_ABRT_EV4T=y diff --git a/arch/arm/configs/omap_generic_1610_defconfig b/arch/arm/configs/omap_generic_1610_defconfig index 0c42c89..d773857 100644 --- a/arch/arm/configs/omap_generic_1610_defconfig +++ b/arch/arm/configs/omap_generic_1610_defconfig @@ -207,7 +207,6 @@ CONFIG_OMAP_ARM_192MHZ=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM926T=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5TJ=y diff --git a/arch/arm/configs/omap_generic_1710_defconfig b/arch/arm/configs/omap_generic_1710_defconfig index 0a00a70..6ec487e 100644 --- a/arch/arm/configs/omap_generic_1710_defconfig +++ b/arch/arm/configs/omap_generic_1710_defconfig @@ -201,7 +201,6 @@ CONFIG_OMAP_ARM_192MHZ=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM926T=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5TJ=y diff --git a/arch/arm/configs/omap_generic_2420_defconfig b/arch/arm/configs/omap_generic_2420_defconfig index cf4073b..7218b96 100644 --- a/arch/arm/configs/omap_generic_2420_defconfig +++ b/arch/arm/configs/omap_generic_2420_defconfig @@ -191,7 +191,6 @@ CONFIG_ARCH_OMAP2420=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_V6=y # CONFIG_CPU_32v6K is not set CONFIG_CPU_32v6=y diff --git a/arch/arm/configs/omap_h2_1610_defconfig b/arch/arm/configs/omap_h2_1610_defconfig index 74dbdc6..5231895 100644 --- a/arch/arm/configs/omap_h2_1610_defconfig +++ b/arch/arm/configs/omap_h2_1610_defconfig @@ -231,7 +231,6 @@ CONFIG_OMAP_ARM_60MHZ=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM926T=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5TJ=y diff --git a/arch/arm/configs/omap_h4_2420_defconfig b/arch/arm/configs/omap_h4_2420_defconfig index a4aab8e..b12b406 100644 --- a/arch/arm/configs/omap_h4_2420_defconfig +++ b/arch/arm/configs/omap_h4_2420_defconfig @@ -201,7 +201,6 @@ CONFIG_MACH_OMAP_H4=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_V6=y # CONFIG_CPU_32v6K is not set CONFIG_CPU_32v6=y diff --git a/arch/arm/configs/omap_innovator_1510_defconfig b/arch/arm/configs/omap_innovator_1510_defconfig index 0cfe363..e9c1408 100644 --- a/arch/arm/configs/omap_innovator_1510_defconfig +++ b/arch/arm/configs/omap_innovator_1510_defconfig @@ -205,7 +205,6 @@ CONFIG_OMAP_ARM_168MHZ=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM925T=y CONFIG_CPU_32v4T=y CONFIG_CPU_ABRT_EV4T=y diff --git a/arch/arm/configs/omap_innovator_1610_defconfig b/arch/arm/configs/omap_innovator_1610_defconfig index 95d9f2b..fea9319 100644 --- a/arch/arm/configs/omap_innovator_1610_defconfig +++ b/arch/arm/configs/omap_innovator_1610_defconfig @@ -206,7 +206,6 @@ CONFIG_OMAP_ARM_192MHZ=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM926T=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5TJ=y diff --git a/arch/arm/configs/omap_ldp_defconfig b/arch/arm/configs/omap_ldp_defconfig index 9139532..0efb4b0 100644 --- a/arch/arm/configs/omap_ldp_defconfig +++ b/arch/arm/configs/omap_ldp_defconfig @@ -214,7 +214,6 @@ CONFIG_MACH_OMAP_LDP=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_32v6K=y CONFIG_CPU_V7=y CONFIG_CPU_32v7=y diff --git a/arch/arm/configs/omap_osk_5912_defconfig b/arch/arm/configs/omap_osk_5912_defconfig index 6b3b5c6..556fcca 100644 --- a/arch/arm/configs/omap_osk_5912_defconfig +++ b/arch/arm/configs/omap_osk_5912_defconfig @@ -212,7 +212,6 @@ CONFIG_OMAP_ARM_192MHZ=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM926T=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5TJ=y diff --git a/arch/arm/configs/omap_perseus2_730_defconfig b/arch/arm/configs/omap_perseus2_730_defconfig index b94800c..9a15d5d 100644 --- a/arch/arm/configs/omap_perseus2_730_defconfig +++ b/arch/arm/configs/omap_perseus2_730_defconfig @@ -199,7 +199,6 @@ CONFIG_OMAP_ARM_182MHZ=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM926T=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5TJ=y diff --git a/arch/arm/configs/omap_zoom2_defconfig b/arch/arm/configs/omap_zoom2_defconfig index 4b00a43..a82e813 100644 --- a/arch/arm/configs/omap_zoom2_defconfig +++ b/arch/arm/configs/omap_zoom2_defconfig @@ -222,7 +222,6 @@ CONFIG_MACH_OMAP_ZOOM2=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_32v6K=y CONFIG_CPU_V7=y CONFIG_CPU_32v7=y diff --git a/arch/arm/configs/omap_zoom3_defconfig b/arch/arm/configs/omap_zoom3_defconfig index 0d7e37a..a3e3c82 100644 --- a/arch/arm/configs/omap_zoom3_defconfig +++ b/arch/arm/configs/omap_zoom3_defconfig @@ -236,7 +236,6 @@ CONFIG_MACH_OMAP_ZOOM3=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_32v6K=y CONFIG_CPU_V7=y CONFIG_CPU_32v7=y diff --git a/arch/arm/configs/onearm_defconfig b/arch/arm/configs/onearm_defconfig index f8701fa..19b91de 100644 --- a/arch/arm/configs/onearm_defconfig +++ b/arch/arm/configs/onearm_defconfig @@ -161,7 +161,6 @@ CONFIG_AT91_PROGRAMMABLE_CLOCKS=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM920T=y CONFIG_CPU_32v4T=y CONFIG_CPU_ABRT_EV4T=y diff --git a/arch/arm/configs/orion5x_defconfig b/arch/arm/configs/orion5x_defconfig index 5383cd0..85b05d3 100644 --- a/arch/arm/configs/orion5x_defconfig +++ b/arch/arm/configs/orion5x_defconfig @@ -210,7 +210,6 @@ CONFIG_PLAT_ORION=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_FEROCEON=y CONFIG_CPU_FEROCEON_OLD_ID=y CONFIG_CPU_32v5=y diff --git a/arch/arm/configs/overo_defconfig b/arch/arm/configs/overo_defconfig index b3ea2c4..bf06d36 100644 --- a/arch/arm/configs/overo_defconfig +++ b/arch/arm/configs/overo_defconfig @@ -217,7 +217,6 @@ CONFIG_MACH_OVERO=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_32v6K=y CONFIG_CPU_V7=y CONFIG_CPU_32v7=y diff --git a/arch/arm/configs/palmte_defconfig b/arch/arm/configs/palmte_defconfig index 40fc6a7..feffaa2 100644 --- a/arch/arm/configs/palmte_defconfig +++ b/arch/arm/configs/palmte_defconfig @@ -196,7 +196,6 @@ CONFIG_OMAP_CLOCKS_SET_BY_BOOTLOADER=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM925T=y CONFIG_CPU_32v4T=y CONFIG_CPU_ABRT_EV4T=y diff --git a/arch/arm/configs/palmtt_defconfig b/arch/arm/configs/palmtt_defconfig index e54ced4..55d5b7d 100644 --- a/arch/arm/configs/palmtt_defconfig +++ b/arch/arm/configs/palmtt_defconfig @@ -176,7 +176,6 @@ CONFIG_OMAP_CLOCKS_SET_BY_BOOTLOADER=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM925T=y CONFIG_CPU_32v4T=y CONFIG_CPU_ABRT_EV4T=y diff --git a/arch/arm/configs/palmz71_defconfig b/arch/arm/configs/palmz71_defconfig index 08e1406..6efc746 100644 --- a/arch/arm/configs/palmz71_defconfig +++ b/arch/arm/configs/palmz71_defconfig @@ -200,7 +200,6 @@ CONFIG_OMAP_CLOCKS_SET_BY_BOOTLOADER=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM925T=y CONFIG_CPU_32v4T=y CONFIG_CPU_ABRT_EV4T=y diff --git a/arch/arm/configs/palmz72_defconfig b/arch/arm/configs/palmz72_defconfig index a0dc37c..6d162b1 100644 --- a/arch/arm/configs/palmz72_defconfig +++ b/arch/arm/configs/palmz72_defconfig @@ -209,7 +209,6 @@ CONFIG_PXA_PWM=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_XSCALE=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5T=y diff --git a/arch/arm/configs/pcm027_defconfig b/arch/arm/configs/pcm027_defconfig index 05ad96a..fa153f2 100644 --- a/arch/arm/configs/pcm027_defconfig +++ b/arch/arm/configs/pcm027_defconfig @@ -168,7 +168,6 @@ CONFIG_PXA27x=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_XSCALE=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5T=y diff --git a/arch/arm/configs/picotux200_defconfig b/arch/arm/configs/picotux200_defconfig index 9018f0f..6e7155c 100644 --- a/arch/arm/configs/picotux200_defconfig +++ b/arch/arm/configs/picotux200_defconfig @@ -168,7 +168,6 @@ CONFIG_AT91_PROGRAMMABLE_CLOCKS=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM920T=y CONFIG_CPU_32v4T=y CONFIG_CPU_ABRT_EV4T=y diff --git a/arch/arm/configs/pleb_defconfig b/arch/arm/configs/pleb_defconfig index f2d2dda..dbfabb5 100644 --- a/arch/arm/configs/pleb_defconfig +++ b/arch/arm/configs/pleb_defconfig @@ -100,7 +100,6 @@ CONFIG_SA1100_PLEB=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_SA1100=y CONFIG_CPU_32v4=y CONFIG_CPU_ABRT_EV4=y diff --git a/arch/arm/configs/pnx4008_defconfig b/arch/arm/configs/pnx4008_defconfig index 67b5f1e..2f7b9ce 100644 --- a/arch/arm/configs/pnx4008_defconfig +++ b/arch/arm/configs/pnx4008_defconfig @@ -121,7 +121,6 @@ CONFIG_ARCH_PNX4008=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM926T=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5TJ=y diff --git a/arch/arm/configs/pxa168_defconfig b/arch/arm/configs/pxa168_defconfig index db5faea..791b8c3 100644 --- a/arch/arm/configs/pxa168_defconfig +++ b/arch/arm/configs/pxa168_defconfig @@ -184,7 +184,6 @@ CONFIG_PLAT_PXA=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_MOHAWK=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5T=y diff --git a/arch/arm/configs/pxa255-idp_defconfig b/arch/arm/configs/pxa255-idp_defconfig index 46e5089..3365c5d 100644 --- a/arch/arm/configs/pxa255-idp_defconfig +++ b/arch/arm/configs/pxa255-idp_defconfig @@ -92,7 +92,6 @@ CONFIG_PXA25x=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_XSCALE=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5T=y diff --git a/arch/arm/configs/pxa3xx_defconfig b/arch/arm/configs/pxa3xx_defconfig index 733b851..82ca6c8 100644 --- a/arch/arm/configs/pxa3xx_defconfig +++ b/arch/arm/configs/pxa3xx_defconfig @@ -240,7 +240,6 @@ CONFIG_PLAT_PXA=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_XSC3=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5T=y diff --git a/arch/arm/configs/pxa910_defconfig b/arch/arm/configs/pxa910_defconfig index 8c7e299..94e20fe 100644 --- a/arch/arm/configs/pxa910_defconfig +++ b/arch/arm/configs/pxa910_defconfig @@ -184,7 +184,6 @@ CONFIG_PLAT_PXA=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_MOHAWK=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5T=y diff --git a/arch/arm/configs/qil-a9260_defconfig b/arch/arm/configs/qil-a9260_defconfig index 9b32d0e..12d0d64 100644 --- a/arch/arm/configs/qil-a9260_defconfig +++ b/arch/arm/configs/qil-a9260_defconfig @@ -195,7 +195,6 @@ CONFIG_AT91_EARLY_USART0=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM926T=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5TJ=y diff --git a/arch/arm/configs/realview-smp_defconfig b/arch/arm/configs/realview-smp_defconfig index 21db4b3..1237017 100644 --- a/arch/arm/configs/realview-smp_defconfig +++ b/arch/arm/configs/realview-smp_defconfig @@ -186,7 +186,6 @@ CONFIG_REALVIEW_HIGH_PHYS_OFFSET=y # # Processor Type # -CONFIG_CPU_32=y # CONFIG_CPU_ARM926T is not set CONFIG_CPU_V6=y CONFIG_CPU_32v6K=y diff --git a/arch/arm/configs/realview_defconfig b/arch/arm/configs/realview_defconfig index 9a75c30..a509a5e 100644 --- a/arch/arm/configs/realview_defconfig +++ b/arch/arm/configs/realview_defconfig @@ -184,7 +184,6 @@ CONFIG_MACH_REALVIEW_PB1176=y # # Processor Type # -CONFIG_CPU_32=y # CONFIG_CPU_ARM926T is not set CONFIG_CPU_V6=y # CONFIG_CPU_32v6K is not set diff --git a/arch/arm/configs/rpc_defconfig b/arch/arm/configs/rpc_defconfig index a29d61f..e9124a0 100644 --- a/arch/arm/configs/rpc_defconfig +++ b/arch/arm/configs/rpc_defconfig @@ -150,7 +150,6 @@ CONFIG_ARCH_ACORN=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM610=y CONFIG_CPU_ARM710=y CONFIG_CPU_SA110=y diff --git a/arch/arm/configs/rx51_defconfig b/arch/arm/configs/rx51_defconfig index 1559734..b6eeebb 100644 --- a/arch/arm/configs/rx51_defconfig +++ b/arch/arm/configs/rx51_defconfig @@ -212,7 +212,6 @@ CONFIG_MACH_NOKIA_RX51=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_32v6K=y CONFIG_CPU_V7=y CONFIG_CPU_32v7=y diff --git a/arch/arm/configs/s3c2410_defconfig b/arch/arm/configs/s3c2410_defconfig index b498104..2f10dae 100644 --- a/arch/arm/configs/s3c2410_defconfig +++ b/arch/arm/configs/s3c2410_defconfig @@ -277,7 +277,6 @@ CONFIG_MACH_SMDK2443=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM920T=y CONFIG_CPU_ARM926T=y CONFIG_CPU_32v4T=y diff --git a/arch/arm/configs/s3c6400_defconfig b/arch/arm/configs/s3c6400_defconfig index 3286060..f56e50f 100644 --- a/arch/arm/configs/s3c6400_defconfig +++ b/arch/arm/configs/s3c6400_defconfig @@ -192,7 +192,6 @@ CONFIG_SMDK6410_SD_CH0=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_V6=y CONFIG_CPU_32v6K=y CONFIG_CPU_32v6=y diff --git a/arch/arm/configs/s5pc100_defconfig b/arch/arm/configs/s5pc100_defconfig index b0d7d3d..dc108af 100644 --- a/arch/arm/configs/s5pc100_defconfig +++ b/arch/arm/configs/s5pc100_defconfig @@ -202,7 +202,6 @@ CONFIG_MACH_SMDKC100=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_32v6K=y CONFIG_CPU_V7=y CONFIG_CPU_32v7=y diff --git a/arch/arm/configs/sam9_l9260_defconfig b/arch/arm/configs/sam9_l9260_defconfig index 1174e27..81b290a 100644 --- a/arch/arm/configs/sam9_l9260_defconfig +++ b/arch/arm/configs/sam9_l9260_defconfig @@ -175,7 +175,6 @@ CONFIG_MTD_AT91_DATAFLASH_CARD=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM926T=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5TJ=y diff --git a/arch/arm/configs/shannon_defconfig b/arch/arm/configs/shannon_defconfig index 984f7096..7c49bc3 100644 --- a/arch/arm/configs/shannon_defconfig +++ b/arch/arm/configs/shannon_defconfig @@ -99,7 +99,6 @@ CONFIG_SA1100_SHANNON=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_SA1100=y CONFIG_CPU_32v4=y CONFIG_CPU_ABRT_EV4=y diff --git a/arch/arm/configs/shark_defconfig b/arch/arm/configs/shark_defconfig index 90235bf..46de124 100644 --- a/arch/arm/configs/shark_defconfig +++ b/arch/arm/configs/shark_defconfig @@ -173,7 +173,6 @@ CONFIG_ARCH_SHARK=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_SA110=y CONFIG_CPU_32v4=y CONFIG_CPU_ABRT_EV4=y diff --git a/arch/arm/configs/simpad_defconfig b/arch/arm/configs/simpad_defconfig index 685d2b5..ee25e63 100644 --- a/arch/arm/configs/simpad_defconfig +++ b/arch/arm/configs/simpad_defconfig @@ -101,7 +101,6 @@ CONFIG_SA1100_SIMPAD=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_SA1100=y CONFIG_CPU_32v4=y CONFIG_CPU_ABRT_EV4=y diff --git a/arch/arm/configs/spitz_defconfig b/arch/arm/configs/spitz_defconfig index 745c68f..7d89489 100644 --- a/arch/arm/configs/spitz_defconfig +++ b/arch/arm/configs/spitz_defconfig @@ -212,7 +212,6 @@ CONFIG_PXA_SSP=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_XSCALE=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5T=y diff --git a/arch/arm/configs/stmp378x_defconfig b/arch/arm/configs/stmp378x_defconfig index 44461f1..b1a3a97 100644 --- a/arch/arm/configs/stmp378x_defconfig +++ b/arch/arm/configs/stmp378x_defconfig @@ -193,7 +193,6 @@ CONFIG_MACH_STMP378X=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM926T=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5TJ=y diff --git a/arch/arm/configs/stmp37xx_defconfig b/arch/arm/configs/stmp37xx_defconfig index 401279d..a3751c9 100644 --- a/arch/arm/configs/stmp37xx_defconfig +++ b/arch/arm/configs/stmp37xx_defconfig @@ -182,7 +182,6 @@ CONFIG_MACH_STMP37XX=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM926T=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5TJ=y diff --git a/arch/arm/configs/sx1_defconfig b/arch/arm/configs/sx1_defconfig index 25b007f..8a9e7e6 100644 --- a/arch/arm/configs/sx1_defconfig +++ b/arch/arm/configs/sx1_defconfig @@ -210,7 +210,6 @@ CONFIG_OMAP_ARM_168MHZ=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM925T=y CONFIG_CPU_32v4T=y CONFIG_CPU_ABRT_EV4T=y diff --git a/arch/arm/configs/tct_hammer_defconfig b/arch/arm/configs/tct_hammer_defconfig index 9d32fae..dccf14b 100644 --- a/arch/arm/configs/tct_hammer_defconfig +++ b/arch/arm/configs/tct_hammer_defconfig @@ -215,7 +215,6 @@ CONFIG_MACH_TCT_HAMMER=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM920T=y CONFIG_CPU_32v4T=y CONFIG_CPU_ABRT_EV4T=y diff --git a/arch/arm/configs/trizeps4_defconfig b/arch/arm/configs/trizeps4_defconfig index b6f8381..1e8f5a2 100644 --- a/arch/arm/configs/trizeps4_defconfig +++ b/arch/arm/configs/trizeps4_defconfig @@ -156,7 +156,6 @@ CONFIG_PXA27x=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_XSCALE=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5T=y diff --git a/arch/arm/configs/u300_defconfig b/arch/arm/configs/u300_defconfig index 953ba02..610ac3c 100644 --- a/arch/arm/configs/u300_defconfig +++ b/arch/arm/configs/u300_defconfig @@ -207,7 +207,6 @@ CONFIG_MACH_U300_SPIDUMMY=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM926T=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5TJ=y diff --git a/arch/arm/configs/u8500_defconfig b/arch/arm/configs/u8500_defconfig index 15fde22..727aff9 100644 --- a/arch/arm/configs/u8500_defconfig +++ b/arch/arm/configs/u8500_defconfig @@ -201,7 +201,6 @@ CONFIG_MACH_U8500_MOP=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_32v6K=y CONFIG_CPU_V7=y CONFIG_CPU_32v7=y diff --git a/arch/arm/configs/usb-a9260_defconfig b/arch/arm/configs/usb-a9260_defconfig index fd77740..87b700e 100644 --- a/arch/arm/configs/usb-a9260_defconfig +++ b/arch/arm/configs/usb-a9260_defconfig @@ -195,7 +195,6 @@ CONFIG_AT91_EARLY_DBGU=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM926T=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5TJ=y diff --git a/arch/arm/configs/usb-a9263_defconfig b/arch/arm/configs/usb-a9263_defconfig index e7c19dd..7f018ed 100644 --- a/arch/arm/configs/usb-a9263_defconfig +++ b/arch/arm/configs/usb-a9263_defconfig @@ -187,7 +187,6 @@ CONFIG_AT91_EARLY_DBGU=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM926T=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5TJ=y diff --git a/arch/arm/configs/versatile_defconfig b/arch/arm/configs/versatile_defconfig index b11c5da..a1af0b9 100644 --- a/arch/arm/configs/versatile_defconfig +++ b/arch/arm/configs/versatile_defconfig @@ -117,7 +117,6 @@ CONFIG_MACH_VERSATILE_AB=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM926T=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5TJ=y diff --git a/arch/arm/configs/viper_defconfig b/arch/arm/configs/viper_defconfig index 6ab5dd5..909887a 100644 --- a/arch/arm/configs/viper_defconfig +++ b/arch/arm/configs/viper_defconfig @@ -204,7 +204,6 @@ CONFIG_PXA_HAVE_ISA_IRQS=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_XSCALE=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5T=y diff --git a/arch/arm/configs/xcep_defconfig b/arch/arm/configs/xcep_defconfig index 33bb725..84a72ac 100644 --- a/arch/arm/configs/xcep_defconfig +++ b/arch/arm/configs/xcep_defconfig @@ -208,7 +208,6 @@ CONFIG_PLAT_PXA=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_XSCALE=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5T=y diff --git a/arch/arm/configs/yl9200_defconfig b/arch/arm/configs/yl9200_defconfig index 9192e59..3b627aa 100644 --- a/arch/arm/configs/yl9200_defconfig +++ b/arch/arm/configs/yl9200_defconfig @@ -183,7 +183,6 @@ CONFIG_MACH_YL9200=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_ARM920T=y CONFIG_CPU_32v4T=y CONFIG_CPU_ABRT_EV4T=y diff --git a/arch/arm/configs/zeus_defconfig b/arch/arm/configs/zeus_defconfig index 823b11e..fca5ff6 100644 --- a/arch/arm/configs/zeus_defconfig +++ b/arch/arm/configs/zeus_defconfig @@ -271,7 +271,6 @@ CONFIG_PLAT_PXA=y # # Processor Type # -CONFIG_CPU_32=y CONFIG_CPU_XSCALE=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5T=y diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h index 3976412..8fdae9b 100644 --- a/arch/arm/include/asm/proc-fns.h +++ b/arch/arm/include/asm/proc-fns.h @@ -24,206 +24,228 @@ * CPU_NAME - the prefix for CPU related functions */ -#ifdef CONFIG_CPU_32 -# ifdef CONFIG_CPU_ARM610 -# ifdef CPU_NAME -# undef MULTI_CPU -# define MULTI_CPU -# else -# define CPU_NAME cpu_arm6 -# endif +#ifdef CONFIG_CPU_ARM610 +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_arm6 # endif -# ifdef CONFIG_CPU_ARM7TDMI -# ifdef CPU_NAME -# undef MULTI_CPU -# define MULTI_CPU -# else -# define CPU_NAME cpu_arm7tdmi -# endif +#endif + +#ifdef CONFIG_CPU_ARM7TDMI +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_arm7tdmi # endif -# ifdef CONFIG_CPU_ARM710 -# ifdef CPU_NAME -# undef MULTI_CPU -# define MULTI_CPU -# else -# define CPU_NAME cpu_arm7 -# endif +#endif + +#ifdef CONFIG_CPU_ARM710 +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_arm7 # endif -# ifdef CONFIG_CPU_ARM720T -# ifdef CPU_NAME -# undef MULTI_CPU -# define MULTI_CPU -# else -# define CPU_NAME cpu_arm720 -# endif +#endif + +#ifdef CONFIG_CPU_ARM720T +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_arm720 # endif -# ifdef CONFIG_CPU_ARM740T -# ifdef CPU_NAME -# undef MULTI_CPU -# define MULTI_CPU -# else -# define CPU_NAME cpu_arm740 -# endif +#endif + +#ifdef CONFIG_CPU_ARM740T +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_arm740 # endif -# ifdef CONFIG_CPU_ARM9TDMI -# ifdef CPU_NAME -# undef MULTI_CPU -# define MULTI_CPU -# else -# define CPU_NAME cpu_arm9tdmi -# endif +#endif + +#ifdef CONFIG_CPU_ARM9TDMI +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_arm9tdmi # endif -# ifdef CONFIG_CPU_ARM920T -# ifdef CPU_NAME -# undef MULTI_CPU -# define MULTI_CPU -# else -# define CPU_NAME cpu_arm920 -# endif +#endif + +#ifdef CONFIG_CPU_ARM920T +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_arm920 # endif -# ifdef CONFIG_CPU_ARM922T -# ifdef CPU_NAME -# undef MULTI_CPU -# define MULTI_CPU -# else -# define CPU_NAME cpu_arm922 -# endif +#endif + +#ifdef CONFIG_CPU_ARM922T +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_arm922 # endif -# ifdef CONFIG_CPU_FA526 -# ifdef CPU_NAME -# undef MULTI_CPU -# define MULTI_CPU -# else -# define CPU_NAME cpu_fa526 -# endif +#endif + +#ifdef CONFIG_CPU_FA526 +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_fa526 # endif -# ifdef CONFIG_CPU_ARM925T -# ifdef CPU_NAME -# undef MULTI_CPU -# define MULTI_CPU -# else -# define CPU_NAME cpu_arm925 -# endif +#endif + +#ifdef CONFIG_CPU_ARM925T +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_arm925 # endif -# ifdef CONFIG_CPU_ARM926T -# ifdef CPU_NAME -# undef MULTI_CPU -# define MULTI_CPU -# else -# define CPU_NAME cpu_arm926 -# endif +#endif + +#ifdef CONFIG_CPU_ARM926T +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_arm926 # endif -# ifdef CONFIG_CPU_ARM940T -# ifdef CPU_NAME -# undef MULTI_CPU -# define MULTI_CPU -# else -# define CPU_NAME cpu_arm940 -# endif +#endif + +#ifdef CONFIG_CPU_ARM940T +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_arm940 # endif -# ifdef CONFIG_CPU_ARM946E -# ifdef CPU_NAME -# undef MULTI_CPU -# define MULTI_CPU -# else -# define CPU_NAME cpu_arm946 -# endif +#endif + +#ifdef CONFIG_CPU_ARM946E +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_arm946 # endif -# ifdef CONFIG_CPU_SA110 -# ifdef CPU_NAME -# undef MULTI_CPU -# define MULTI_CPU -# else -# define CPU_NAME cpu_sa110 -# endif +#endif + +#ifdef CONFIG_CPU_SA110 +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_sa110 # endif -# ifdef CONFIG_CPU_SA1100 -# ifdef CPU_NAME -# undef MULTI_CPU -# define MULTI_CPU -# else -# define CPU_NAME cpu_sa1100 -# endif +#endif + +#ifdef CONFIG_CPU_SA1100 +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_sa1100 # endif -# ifdef CONFIG_CPU_ARM1020 -# ifdef CPU_NAME -# undef MULTI_CPU -# define MULTI_CPU -# else -# define CPU_NAME cpu_arm1020 -# endif +#endif + +#ifdef CONFIG_CPU_ARM1020 +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_arm1020 # endif -# ifdef CONFIG_CPU_ARM1020E -# ifdef CPU_NAME -# undef MULTI_CPU -# define MULTI_CPU -# else -# define CPU_NAME cpu_arm1020e -# endif +#endif + +#ifdef CONFIG_CPU_ARM1020E +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_arm1020e # endif -# ifdef CONFIG_CPU_ARM1022 -# ifdef CPU_NAME -# undef MULTI_CPU -# define MULTI_CPU -# else -# define CPU_NAME cpu_arm1022 -# endif +#endif + +#ifdef CONFIG_CPU_ARM1022 +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_arm1022 # endif -# ifdef CONFIG_CPU_ARM1026 -# ifdef CPU_NAME -# undef MULTI_CPU -# define MULTI_CPU -# else -# define CPU_NAME cpu_arm1026 -# endif +#endif + +#ifdef CONFIG_CPU_ARM1026 +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_arm1026 # endif -# ifdef CONFIG_CPU_XSCALE -# ifdef CPU_NAME -# undef MULTI_CPU -# define MULTI_CPU -# else -# define CPU_NAME cpu_xscale -# endif +#endif + +#ifdef CONFIG_CPU_XSCALE +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_xscale # endif -# ifdef CONFIG_CPU_XSC3 -# ifdef CPU_NAME -# undef MULTI_CPU -# define MULTI_CPU -# else -# define CPU_NAME cpu_xsc3 -# endif +#endif + +#ifdef CONFIG_CPU_XSC3 +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_xsc3 # endif -# ifdef CONFIG_CPU_MOHAWK -# ifdef CPU_NAME -# undef MULTI_CPU -# define MULTI_CPU -# else -# define CPU_NAME cpu_mohawk -# endif +#endif + +#ifdef CONFIG_CPU_MOHAWK +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_mohawk # endif -# ifdef CONFIG_CPU_FEROCEON -# ifdef CPU_NAME -# undef MULTI_CPU -# define MULTI_CPU -# else -# define CPU_NAME cpu_feroceon -# endif +#endif + +#ifdef CONFIG_CPU_FEROCEON +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_feroceon # endif -# ifdef CONFIG_CPU_V6 -# ifdef CPU_NAME -# undef MULTI_CPU -# define MULTI_CPU -# else -# define CPU_NAME cpu_v6 -# endif +#endif + +#ifdef CONFIG_CPU_V6 +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_v6 # endif -# ifdef CONFIG_CPU_V7 -# ifdef CPU_NAME -# undef MULTI_CPU -# define MULTI_CPU -# else -# define CPU_NAME cpu_v7 -# endif +#endif + +#ifdef CONFIG_CPU_V7 +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_v7 # endif #endif diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index dd4698c..baf6384 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -1,9 +1,5 @@ comment "Processor Type" -config CPU_32 - bool - default y - # Select CPU types depending on the architecture selected. This selects # which CPUs we support in the kernel image, and the compiler instruction # optimiser behaviour. diff --git a/arch/arm/nwfpe/Makefile b/arch/arm/nwfpe/Makefile index b29178c..deb3a82 100644 --- a/arch/arm/nwfpe/Makefile +++ b/arch/arm/nwfpe/Makefile @@ -6,7 +6,7 @@ obj-$(CONFIG_FPE_NWFPE) += nwfpe.o nwfpe-y += fpa11.o fpa11_cpdo.o fpa11_cpdt.o \ fpa11_cprt.o fpmodule.o fpopcode.o \ - softfloat.o single_cpdo.o double_cpdo.o + softfloat.o single_cpdo.o double_cpdo.o \ + entry.o nwfpe-$(CONFIG_FPE_NWFPE_XP) += extended_cpdo.o -nwfpe-$(CONFIG_CPU_32) += entry.o -- cgit v0.10.2 From 70ee9518cfc8baec618e69e4ef22566dcb2f29d3 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 18 Dec 2009 17:43:14 +0100 Subject: [S390] wire up sys_recvmmsg Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky diff --git a/arch/s390/include/asm/unistd.h b/arch/s390/include/asm/unistd.h index cb5232d..192a720 100644 --- a/arch/s390/include/asm/unistd.h +++ b/arch/s390/include/asm/unistd.h @@ -269,7 +269,8 @@ #define __NR_pwritev 329 #define __NR_rt_tgsigqueueinfo 330 #define __NR_perf_event_open 331 -#define NR_syscalls 332 +#define __NR_recvmmsg 332 +#define NR_syscalls 333 /* * There are some system calls that are not present on 64 bit, some diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index 30de2d0..faeaccc 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S @@ -1853,3 +1853,12 @@ sys32_execve_wrapper: llgtr %r3,%r3 # compat_uptr_t * llgtr %r4,%r4 # compat_uptr_t * jg sys32_execve # branch to system call + + .globl compat_sys_recvmmsg_wrapper +compat_sys_recvmmsg_wrapper: + lgfr %r2,%r2 # int + llgtr %r3,%r3 # struct compat_mmsghdr * + llgfr %r4,%r4 # unsigned int + llgfr %r5,%r5 # unsigned int + llgtr %r6,%r6 # struct compat_timespec * + jg compat_sys_recvmmsg diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index 30eca07..4f292c9 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S @@ -340,3 +340,4 @@ SYSCALL(sys_preadv,sys_preadv,compat_sys_preadv_wrapper) SYSCALL(sys_pwritev,sys_pwritev,compat_sys_pwritev_wrapper) SYSCALL(sys_rt_tgsigqueueinfo,sys_rt_tgsigqueueinfo,compat_sys_rt_tgsigqueueinfo_wrapper) /* 330 */ SYSCALL(sys_perf_event_open,sys_perf_event_open,sys_perf_event_open_wrapper) +SYSCALL(sys_recvmmsg,sys_recvmmsg,compat_sys_recvmmsg_wrapper) -- cgit v0.10.2 From ffa8d2a3e80a3f0dee9886947dbd506d2bb226d2 Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Fri, 18 Dec 2009 17:43:15 +0100 Subject: [S390] cio: fix drvdata usage for the console subchannel Using dev_set_drvdata prior to device_register will force the driver core to kmalloc its private data. Since we use this for the console subchannel lets set the drvdata before taking the subchannels spinlock. Signed-off-by: Sebastian Ott Signed-off-by: Martin Schwidefsky diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index 73901c9..a6c7d54 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c @@ -1519,6 +1519,7 @@ static int ccw_device_console_enable(struct ccw_device *cdev, sch->driver = &io_subchannel_driver; /* Initialize the ccw_device structure. */ cdev->dev.parent= &sch->dev; + sch_set_cdev(sch, cdev); io_subchannel_recog(cdev, sch); /* Now wait for the async. recognition to come to an end. */ spin_lock_irq(cdev->ccwlock); -- cgit v0.10.2 From ea058544542a60e92fd023d93aa901709be18daa Mon Sep 17 00:00:00 2001 From: Stefan Haberland Date: Fri, 18 Dec 2009 17:43:16 +0100 Subject: [S390] dasd: move dasd-diag kmsg to dasd The DIAG discipline does not have a own driver name. It shows up as dasd-eckd or dasd-fba. So messages for dasd-diag are moved to the generic dasd part. Signed-off-by: Stefan Haberland Signed-off-by: Martin Schwidefsky diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c index f64d0db8..6e14863 100644 --- a/drivers/s390/block/dasd_diag.c +++ b/drivers/s390/block/dasd_diag.c @@ -8,7 +8,7 @@ * */ -#define KMSG_COMPONENT "dasd-diag" +#define KMSG_COMPONENT "dasd" #include #include @@ -146,16 +146,16 @@ dasd_diag_erp(struct dasd_device *device) rc = mdsk_init_io(device, device->block->bp_block, 0, NULL); if (rc == 4) { if (!(device->features & DASD_FEATURE_READONLY)) { - dev_warn(&device->cdev->dev, - "The access mode of a DIAG device changed" - " to read-only"); + pr_warning("%s: The access mode of a DIAG device " + "changed to read-only\n", + dev_name(&device->cdev->dev)); device->features |= DASD_FEATURE_READONLY; } rc = 0; } if (rc) - dev_warn(&device->cdev->dev, "DIAG ERP failed with " - "rc=%d\n", rc); + pr_warning("%s: DIAG ERP failed with " + "rc=%d\n", dev_name(&device->cdev->dev), rc); } /* Start a given request at the device. Return zero on success, non-zero @@ -371,8 +371,9 @@ dasd_diag_check_device(struct dasd_device *device) private->pt_block = 2; break; default: - dev_warn(&device->cdev->dev, "Device type %d is not supported " - "in DIAG mode\n", private->rdc_data.vdev_class); + pr_warning("%s: Device type %d is not supported " + "in DIAG mode\n", dev_name(&device->cdev->dev), + private->rdc_data.vdev_class); rc = -EOPNOTSUPP; goto out; } @@ -413,8 +414,8 @@ dasd_diag_check_device(struct dasd_device *device) private->iob.flaga = DASD_DIAG_FLAGA_DEFAULT; rc = dia250(&private->iob, RW_BIO); if (rc == 3) { - dev_warn(&device->cdev->dev, - "A 64-bit DIAG call failed\n"); + pr_warning("%s: A 64-bit DIAG call failed\n", + dev_name(&device->cdev->dev)); rc = -EOPNOTSUPP; goto out_label; } @@ -423,8 +424,9 @@ dasd_diag_check_device(struct dasd_device *device) break; } if (bsize > PAGE_SIZE) { - dev_warn(&device->cdev->dev, "Accessing the DASD failed because" - " of an incorrect format (rc=%d)\n", rc); + pr_warning("%s: Accessing the DASD failed because of an " + "incorrect format (rc=%d)\n", + dev_name(&device->cdev->dev), rc); rc = -EIO; goto out_label; } @@ -442,18 +444,18 @@ dasd_diag_check_device(struct dasd_device *device) block->s2b_shift++; rc = mdsk_init_io(device, block->bp_block, 0, NULL); if (rc && (rc != 4)) { - dev_warn(&device->cdev->dev, "DIAG initialization " - "failed with rc=%d\n", rc); + pr_warning("%s: DIAG initialization failed with rc=%d\n", + dev_name(&device->cdev->dev), rc); rc = -EIO; } else { if (rc == 4) device->features |= DASD_FEATURE_READONLY; - dev_info(&device->cdev->dev, - "New DASD with %ld byte/block, total size %ld KB%s\n", - (unsigned long) block->bp_block, - (unsigned long) (block->blocks << - block->s2b_shift) >> 1, - (rc == 4) ? ", read-only device" : ""); + pr_info("%s: New DASD with %ld byte/block, total size %ld " + "KB%s\n", dev_name(&device->cdev->dev), + (unsigned long) block->bp_block, + (unsigned long) (block->blocks << + block->s2b_shift) >> 1, + (rc == 4) ? ", read-only device" : ""); rc = 0; } out_label: -- cgit v0.10.2 From 6d53cfe590c17c28ebae2c869bb7a5ab9554b4da Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Fri, 18 Dec 2009 17:43:17 +0100 Subject: [S390] dasd: PTR_ERR return of wrong pointer in Return the PTR_ERR of the correct pointer. Signed-off-by: Roel Kluin Signed-off-by: Martin Schwidefsky diff --git a/drivers/s390/block/dasd_alias.c b/drivers/s390/block/dasd_alias.c index fd12317..148b1dd 100644 --- a/drivers/s390/block/dasd_alias.c +++ b/drivers/s390/block/dasd_alias.c @@ -218,7 +218,7 @@ int dasd_alias_make_device_known_to_lcu(struct dasd_device *device) spin_unlock_irqrestore(&aliastree.lock, flags); newlcu = _allocate_lcu(uid); if (IS_ERR(newlcu)) - return PTR_ERR(lcu); + return PTR_ERR(newlcu); spin_lock_irqsave(&aliastree.lock, flags); lcu = _find_lcu(server, uid); if (!lcu) { -- cgit v0.10.2 From b59cdcb339fc7286161b80403f6af63acf26876f Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Fri, 18 Dec 2009 17:43:18 +0100 Subject: [S390] s390: PTR_ERR return of wrong pointer in fallback_init_cip() Return the PTR_ERR of the correct pointer. Signed-off-by: Roel Kluin Signed-off-by: Martin Schwidefsky diff --git a/arch/s390/crypto/aes_s390.c b/arch/s390/crypto/aes_s390.c index 6118890..6be4503 100644 --- a/arch/s390/crypto/aes_s390.c +++ b/arch/s390/crypto/aes_s390.c @@ -174,7 +174,7 @@ static int fallback_init_cip(struct crypto_tfm *tfm) if (IS_ERR(sctx->fallback.cip)) { pr_err("Allocating AES fallback algorithm %s failed\n", name); - return PTR_ERR(sctx->fallback.blk); + return PTR_ERR(sctx->fallback.cip); } return 0; -- cgit v0.10.2 From 2b31001d306a2b5fd690eee878d2ee61a0a0674c Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Fri, 18 Dec 2009 17:43:19 +0100 Subject: [S390] tty: PTR_ERR return of wrong pointer in fs3270_open() Return the PTR_ERR of the correct pointer. Signed-off-by: Roel Kluin Signed-off-by: Martin Schwidefsky diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c index 28e4649..247b2b9 100644 --- a/drivers/s390/char/fs3270.c +++ b/drivers/s390/char/fs3270.c @@ -467,7 +467,7 @@ fs3270_open(struct inode *inode, struct file *filp) if (IS_ERR(ib)) { raw3270_put_view(&fp->view); raw3270_del_view(&fp->view); - rc = PTR_ERR(fp); + rc = PTR_ERR(ib); goto out; } fp->rdbuf = ib; -- cgit v0.10.2 From 622e99bf0d54c4517cb0524540cd77257db8621a Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Fri, 18 Dec 2009 17:43:20 +0100 Subject: [S390] rename NT_PRXSTATUS to NT_S390_HIGHREGS The elf notes number for the upper register halves is s390 specific. Change the name of the elf notes to include S390. Signed-off-by: Martin Schwidefsky Signed-off-by: Martin Schwidefsky diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index 653c6a1..13815d3 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c @@ -959,7 +959,7 @@ static const struct user_regset s390_compat_regsets[] = { .set = s390_fpregs_set, }, [REGSET_GENERAL_EXTENDED] = { - .core_note_type = NT_PRXSTATUS, + .core_note_type = NT_S390_HIGH_GPRS, .n = sizeof(s390_compat_regs_high) / sizeof(compat_long_t), .size = sizeof(compat_long_t), .align = sizeof(compat_long_t), diff --git a/include/linux/elf.h b/include/linux/elf.h index 90a4ed0..0cc4d55 100644 --- a/include/linux/elf.h +++ b/include/linux/elf.h @@ -361,7 +361,7 @@ typedef struct elf64_shdr { #define NT_PPC_VSX 0x102 /* PowerPC VSX registers */ #define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */ #define NT_386_IOPERM 0x201 /* x86 io permission bitmap (1=deny) */ -#define NT_PRXSTATUS 0x300 /* s390 upper register halves */ +#define NT_S390_HIGH_GPRS 0x300 /* s390 upper register halves */ /* Note header in a PT_NOTE section */ -- cgit v0.10.2 From bb509912481214cf6ad1181c968295c62ff1ad9e Mon Sep 17 00:00:00 2001 From: Michael Holzheu Date: Fri, 18 Dec 2009 17:43:21 +0100 Subject: [S390] tape: Add pr_fmt() macro to all tape source files Without defining the pr_fmt() macro, the "tape: " prefix will not be printed when using the pr_xxx printk macros. This patch adds the missing definitions. Signed-off-by: Michael Holzheu Signed-off-by: Martin Schwidefsky diff --git a/drivers/s390/char/tape_34xx.c b/drivers/s390/char/tape_34xx.c index 3657fe1..cb70fa1 100644 --- a/drivers/s390/char/tape_34xx.c +++ b/drivers/s390/char/tape_34xx.c @@ -9,6 +9,7 @@ */ #define KMSG_COMPONENT "tape_34xx" +#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt #include #include diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c index 0c72aad..b2eb94a 100644 --- a/drivers/s390/char/tape_3590.c +++ b/drivers/s390/char/tape_3590.c @@ -9,6 +9,7 @@ */ #define KMSG_COMPONENT "tape_3590" +#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt #include #include diff --git a/drivers/s390/char/tape_block.c b/drivers/s390/char/tape_block.c index 4799cc2..96816149 100644 --- a/drivers/s390/char/tape_block.c +++ b/drivers/s390/char/tape_block.c @@ -11,6 +11,7 @@ */ #define KMSG_COMPONENT "tape" +#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt #include #include diff --git a/drivers/s390/char/tape_char.c b/drivers/s390/char/tape_char.c index 23d773a..2125ec7 100644 --- a/drivers/s390/char/tape_char.c +++ b/drivers/s390/char/tape_char.c @@ -10,6 +10,9 @@ * Martin Schwidefsky */ +#define KMSG_COMPONENT "tape" +#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt + #include #include #include diff --git a/drivers/s390/char/tape_class.c b/drivers/s390/char/tape_class.c index ddc914cc..b2864e3 100644 --- a/drivers/s390/char/tape_class.c +++ b/drivers/s390/char/tape_class.c @@ -7,6 +7,10 @@ * Author: Stefan Bader * Based on simple class device code by Greg K-H */ + +#define KMSG_COMPONENT "tape" +#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt + #include "tape_class.h" MODULE_AUTHOR("Stefan Bader "); diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c index f5d6802..81b094e 100644 --- a/drivers/s390/char/tape_core.c +++ b/drivers/s390/char/tape_core.c @@ -12,6 +12,8 @@ */ #define KMSG_COMPONENT "tape" +#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt + #include #include // for kernel parameters #include // for requesting modules diff --git a/drivers/s390/char/tape_proc.c b/drivers/s390/char/tape_proc.c index ebd820c..0ceb379 100644 --- a/drivers/s390/char/tape_proc.c +++ b/drivers/s390/char/tape_proc.c @@ -11,6 +11,9 @@ * PROCFS Functions */ +#define KMSG_COMPONENT "tape" +#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt + #include #include #include diff --git a/drivers/s390/char/tape_std.c b/drivers/s390/char/tape_std.c index 750354a..03f07e5 100644 --- a/drivers/s390/char/tape_std.c +++ b/drivers/s390/char/tape_std.c @@ -11,6 +11,9 @@ * Stefan Bader */ +#define KMSG_COMPONENT "tape" +#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt + #include #include #include -- cgit v0.10.2 From 83e56d0b23f91b70a7e708ce0979a57b6c6a1507 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Fri, 18 Dec 2009 17:43:22 +0100 Subject: [S390] drivers: Correct size given to memset Memset should be given the size of the structure, not the size of the pointer. The semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ type T; T *x; expression E; @@ memset(x, E, sizeof( + * x)) // Signed-off-by: Julia Lawall Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky diff --git a/drivers/s390/cio/fcx.c b/drivers/s390/cio/fcx.c index 61677df..ca5e9bb 100644 --- a/drivers/s390/cio/fcx.c +++ b/drivers/s390/cio/fcx.c @@ -163,7 +163,7 @@ void tcw_finalize(struct tcw *tcw, int num_tidaws) /* Add tcat to tccb. */ tccb = tcw_get_tccb(tcw); tcat = (struct tccb_tcat *) &tccb->tca[tca_size(tccb)]; - memset(tcat, 0, sizeof(tcat)); + memset(tcat, 0, sizeof(*tcat)); /* Calculate tcw input/output count and tcat transport count. */ count = calc_dcw_count(tccb); if (tcw->w && (tcw->flags & TCW_FLAGS_OUTPUT_TIDA)) @@ -269,7 +269,7 @@ EXPORT_SYMBOL(tccb_init); */ void tsb_init(struct tsb *tsb) { - memset(tsb, 0, sizeof(tsb)); + memset(tsb, 0, sizeof(*tsb)); } EXPORT_SYMBOL(tsb_init); -- cgit v0.10.2 From d302e1a5dbe1677a495033a2d310656a55139cdf Mon Sep 17 00:00:00 2001 From: Peter Oberparleiter Date: Fri, 18 Dec 2009 17:43:23 +0100 Subject: [S390] cio: fix channel path vary Channel path vary is currently broken: channel paths which are varied offline are still used by Linux. The reason for this is that: * the path mask indicating which paths of an I/O device can be used is reset by each internal I/O request * the logic that checks if a path group is already in its designated target state incorrectly interprets the result "is correctly set" as "is correctly set and available" Fix this by resetting the path mask only for internal I/O requests which affect the path mask and by correcting the pgid check logic. Signed-off-by: Peter Oberparleiter Signed-off-by: Martin Schwidefsky diff --git a/drivers/s390/cio/ccwreq.c b/drivers/s390/cio/ccwreq.c index 9509e38..7a28a30 100644 --- a/drivers/s390/cio/ccwreq.c +++ b/drivers/s390/cio/ccwreq.c @@ -49,7 +49,6 @@ static u16 ccwreq_next_path(struct ccw_device *cdev) */ static void ccwreq_stop(struct ccw_device *cdev, int rc) { - struct subchannel *sch = to_subchannel(cdev->dev.parent); struct ccw_request *req = &cdev->private->req; if (req->done) @@ -57,7 +56,6 @@ static void ccwreq_stop(struct ccw_device *cdev, int rc) req->done = 1; ccw_device_set_timeout(cdev, 0); memset(&cdev->private->irb, 0, sizeof(struct irb)); - sch->lpm = sch->schib.pmcw.pam; if (rc && rc != -ENODEV && req->drc) rc = req->drc; req->callback(cdev, req->data, rc); @@ -80,7 +78,6 @@ static void ccwreq_do(struct ccw_device *cdev) continue; } /* Perform start function. */ - sch->lpm = 0xff; memset(&cdev->private->irb, 0, sizeof(struct irb)); rc = cio_start(sch, cp, (u8) req->mask); if (rc == 0) { diff --git a/drivers/s390/cio/device_pgid.c b/drivers/s390/cio/device_pgid.c index aad188e..6facb54 100644 --- a/drivers/s390/cio/device_pgid.c +++ b/drivers/s390/cio/device_pgid.c @@ -142,7 +142,7 @@ static void spid_do(struct ccw_device *cdev) u8 fn; /* Use next available path that is not already in correct state. */ - req->lpm = lpm_adjust(req->lpm, sch->schib.pmcw.pam & ~sch->vpm); + req->lpm = lpm_adjust(req->lpm, cdev->private->pgid_todo_mask); if (!req->lpm) goto out_nopath; /* Channel program setup. */ @@ -254,15 +254,15 @@ static void pgid_analyze(struct ccw_device *cdev, struct pgid **p, *p = first; } -static u8 pgid_to_vpm(struct ccw_device *cdev) +static u8 pgid_to_donepm(struct ccw_device *cdev) { struct subchannel *sch = to_subchannel(cdev->dev.parent); struct pgid *pgid; int i; int lpm; - u8 vpm = 0; + u8 donepm = 0; - /* Set VPM bits for paths which are already in the target state. */ + /* Set bits for paths which are already in the target state. */ for (i = 0; i < 8; i++) { lpm = 0x80 >> i; if ((cdev->private->pgid_valid_mask & lpm) == 0) @@ -282,10 +282,10 @@ static u8 pgid_to_vpm(struct ccw_device *cdev) if (pgid->inf.ps.state3 != SNID_STATE3_SINGLE_PATH) continue; } - vpm |= lpm; + donepm |= lpm; } - return vpm; + return donepm; } static void pgid_fill(struct ccw_device *cdev, struct pgid *pgid) @@ -307,6 +307,7 @@ static void snid_done(struct ccw_device *cdev, int rc) int mismatch = 0; int reserved = 0; int reset = 0; + u8 donepm; if (rc) goto out; @@ -316,18 +317,20 @@ static void snid_done(struct ccw_device *cdev, int rc) else if (mismatch) rc = -EOPNOTSUPP; else { - sch->vpm = pgid_to_vpm(cdev); + donepm = pgid_to_donepm(cdev); + sch->vpm = donepm & sch->opm; + cdev->private->pgid_todo_mask &= ~donepm; pgid_fill(cdev, pgid); } out: CIO_MSG_EVENT(2, "snid: device 0.%x.%04x: rc=%d pvm=%02x vpm=%02x " - "mism=%d rsvd=%d reset=%d\n", id->ssid, id->devno, rc, - cdev->private->pgid_valid_mask, sch->vpm, mismatch, - reserved, reset); + "todo=%02x mism=%d rsvd=%d reset=%d\n", id->ssid, + id->devno, rc, cdev->private->pgid_valid_mask, sch->vpm, + cdev->private->pgid_todo_mask, mismatch, reserved, reset); switch (rc) { case 0: /* Anything left to do? */ - if (sch->vpm == sch->schib.pmcw.pam) { + if (cdev->private->pgid_todo_mask == 0) { verify_done(cdev, sch->vpm == 0 ? -EACCES : 0); return; } @@ -411,6 +414,7 @@ static void verify_start(struct ccw_device *cdev) struct ccw_dev_id *devid = &cdev->private->dev_id; sch->vpm = 0; + sch->lpm = sch->schib.pmcw.pam; /* Initialize request data. */ memset(req, 0, sizeof(*req)); req->timeout = PGID_TIMEOUT; @@ -442,11 +446,14 @@ static void verify_start(struct ccw_device *cdev) */ void ccw_device_verify_start(struct ccw_device *cdev) { + struct subchannel *sch = to_subchannel(cdev->dev.parent); + CIO_TRACE_EVENT(4, "vrfy"); CIO_HEX_EVENT(4, &cdev->private->dev_id, sizeof(cdev->private->dev_id)); /* Initialize PGID data. */ memset(cdev->private->pgid, 0, sizeof(cdev->private->pgid)); cdev->private->pgid_valid_mask = 0; + cdev->private->pgid_todo_mask = sch->schib.pmcw.pam; /* * Initialize pathgroup and multipath state with target values. * They may change in the course of path verification. diff --git a/drivers/s390/cio/io_sch.h b/drivers/s390/cio/io_sch.h index d72ae4c..b9ce712 100644 --- a/drivers/s390/cio/io_sch.h +++ b/drivers/s390/cio/io_sch.h @@ -150,6 +150,7 @@ struct ccw_device_private { struct ccw_request req; /* internal I/O request */ int iretry; u8 pgid_valid_mask; /* mask of valid PGIDs */ + u8 pgid_todo_mask; /* mask of PGIDs to be adjusted */ struct { unsigned int fast:1; /* post with "channel end" */ unsigned int repall:1; /* report every interrupt status */ -- cgit v0.10.2 From ca633fd006486ed2c2d3b542283067aab61e6dc8 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Fri, 18 Dec 2009 17:43:24 +0100 Subject: [S390] ptrace: dont abuse PT_PTRACED Nobody except ptrace itself should use task->ptrace or PT_PTRACED directly, change arch/s390/kernel/traps.c to use the helper. Signed-off-by: Oleg Nesterov Acked-by: Roland McGrath Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c index c2e42cc..6e7ad63 100644 --- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include #include @@ -382,7 +382,7 @@ void __kprobes do_single_step(struct pt_regs *regs) SIGTRAP) == NOTIFY_STOP){ return; } - if ((current->ptrace & PT_PTRACED) != 0) + if (tracehook_consider_fatal_signal(current, SIGTRAP)) force_sig(SIGTRAP, current); } @@ -483,7 +483,7 @@ static void illegal_op(struct pt_regs * regs, long interruption_code) if (get_user(*((__u16 *) opcode), (__u16 __user *) location)) return; if (*((__u16 *) opcode) == S390_BREAKPOINT_U16) { - if (current->ptrace & PT_PTRACED) + if (tracehook_consider_fatal_signal(current, SIGTRAP)) force_sig(SIGTRAP, current); else signal = SIGILL; -- cgit v0.10.2 From 7883097f1602c8cbb1da764a6ac43e0b8a7f56d9 Mon Sep 17 00:00:00 2001 From: Jan Glauber Date: Fri, 18 Dec 2009 17:43:25 +0100 Subject: [S390] qdio: remove superfluous log entries and WARN_ONs. * Don't write debug feature log entries for sl, slsb and sbal since these elements can be located from the qdio_q pointer which is also logged. * Convert WARN_ON for wrong alignment of sbal to BUG_ON. * Remove WARN_ON's for wrong alignment of q / qib / slib since these alignments should be guaranteed by kmem_cache_alloc alignment / struct aligned attribute / __get_free_page. Signed-off-by: Jan Glauber Signed-off-by: Martin Schwidefsky diff --git a/drivers/s390/cio/qdio_setup.c b/drivers/s390/cio/qdio_setup.c index 18d54fc..8c2dea5 100644 --- a/drivers/s390/cio/qdio_setup.c +++ b/drivers/s390/cio/qdio_setup.c @@ -48,7 +48,6 @@ static void set_impl_params(struct qdio_irq *irq_ptr, if (!irq_ptr) return; - WARN_ON((unsigned long)&irq_ptr->qib & 0xff); irq_ptr->qib.pfmt = qib_param_field_format; if (qib_param_field) memcpy(irq_ptr->qib.parm, qib_param_field, @@ -82,14 +81,12 @@ static int __qdio_allocate_qs(struct qdio_q **irq_ptr_qs, int nr_queues) q = kmem_cache_alloc(qdio_q_cache, GFP_KERNEL); if (!q) return -ENOMEM; - WARN_ON((unsigned long)q & 0xff); q->slib = (struct slib *) __get_free_page(GFP_KERNEL); if (!q->slib) { kmem_cache_free(qdio_q_cache, q); return -ENOMEM; } - WARN_ON((unsigned long)q->slib & 0x7ff); irq_ptr_qs[i] = q; } return 0; @@ -131,7 +128,7 @@ static void setup_storage_lists(struct qdio_q *q, struct qdio_irq *irq_ptr, /* fill in sbal */ for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; j++) { q->sbal[j] = *sbals_array++; - WARN_ON((unsigned long)q->sbal[j] & 0xff); + BUG_ON((unsigned long)q->sbal[j] & 0xff); } /* fill in slib */ @@ -147,11 +144,6 @@ static void setup_storage_lists(struct qdio_q *q, struct qdio_irq *irq_ptr, /* fill in sl */ for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; j++) q->sl->element[j].sbal = (unsigned long)q->sbal[j]; - - DBF_EVENT("sl-slsb-sbal"); - DBF_HEX(q->sl, sizeof(void *)); - DBF_HEX(&q->slsb, sizeof(void *)); - DBF_HEX(q->sbal, sizeof(void *)); } static void setup_queues(struct qdio_irq *irq_ptr, -- cgit v0.10.2 From 8bcd9b04fdbab9cee4948501f8862af2a288f1b5 Mon Sep 17 00:00:00 2001 From: Jan Glauber Date: Fri, 18 Dec 2009 17:43:26 +0100 Subject: [S390] qdio: add counter for input queue full condition Add a counter to the qdio performance statistics that indicates that no free buffers were left in the input queue. If the counter gets increased it means that the qdio adapter filled all available buffers and possibly had more buffers ready but could not transmit them. Signed-off-by: Jan Glauber Signed-off-by: Martin Schwidefsky diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c index 4be6e84..b2275c5 100644 --- a/drivers/s390/cio/qdio_main.c +++ b/drivers/s390/cio/qdio_main.c @@ -486,7 +486,8 @@ static int get_inbound_buffer_frontier(struct qdio_q *q) case SLSB_P_INPUT_PRIMED: inbound_primed(q, count); q->first_to_check = add_buf(q->first_to_check, count); - atomic_sub(count, &q->nr_buf_used); + if (atomic_sub(count, &q->nr_buf_used) == 0) + qdio_perf_stat_inc(&perf_stats.inbound_queue_full); break; case SLSB_P_INPUT_ERROR: announce_buffer_error(q, count); diff --git a/drivers/s390/cio/qdio_perf.c b/drivers/s390/cio/qdio_perf.c index 968e3c7..54f7c32 100644 --- a/drivers/s390/cio/qdio_perf.c +++ b/drivers/s390/cio/qdio_perf.c @@ -64,6 +64,8 @@ static int qdio_perf_proc_show(struct seq_file *m, void *v) (long)atomic_long_read(&perf_stats.fast_requeue)); seq_printf(m, "Number of outbound target full condition\t: %li\n", (long)atomic_long_read(&perf_stats.outbound_target_full)); + seq_printf(m, "Number of inbound queue full condition\t\t: %li\n", + (long)atomic_long_read(&perf_stats.inbound_queue_full)); seq_printf(m, "Number of outbound tasklet mod_timer calls\t: %li\n", (long)atomic_long_read(&perf_stats.debug_tl_out_timer)); seq_printf(m, "Number of stop polling calls\t\t\t: %li\n", diff --git a/drivers/s390/cio/qdio_perf.h b/drivers/s390/cio/qdio_perf.h index ff4504c..1245423 100644 --- a/drivers/s390/cio/qdio_perf.h +++ b/drivers/s390/cio/qdio_perf.h @@ -36,6 +36,7 @@ struct qdio_perf_stats { atomic_long_t outbound_handler; atomic_long_t fast_requeue; atomic_long_t outbound_target_full; + atomic_long_t inbound_queue_full; /* for debugging */ atomic_long_t debug_tl_out_timer; -- cgit v0.10.2 From 1d802e24774c94ec7bdb12b6515226f3341533c1 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 18 Dec 2009 17:43:27 +0100 Subject: [S390] Use strim instead of strstrip to avoid false warnings. Cc: Michael Holzheu Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky diff --git a/arch/s390/hypfs/hypfs_diag.c b/arch/s390/hypfs/hypfs_diag.c index 77df726..2b92d50 100644 --- a/arch/s390/hypfs/hypfs_diag.c +++ b/arch/s390/hypfs/hypfs_diag.c @@ -164,7 +164,7 @@ static inline void part_hdr__part_name(enum diag204_format type, void *hdr, LPAR_NAME_LEN); EBCASC(name, LPAR_NAME_LEN); name[LPAR_NAME_LEN] = 0; - strstrip(name); + strim(name); } struct cpu_info { @@ -523,7 +523,7 @@ static int diag224_idx2name(int index, char *name) memcpy(name, diag224_cpu_names + ((index + 1) * CPU_NAME_LEN), CPU_NAME_LEN); name[CPU_NAME_LEN] = 0; - strstrip(name); + strim(name); return 0; } diff --git a/arch/s390/hypfs/hypfs_vm.c b/arch/s390/hypfs/hypfs_vm.c index d01fc8f..f0b0d31 100644 --- a/arch/s390/hypfs/hypfs_vm.c +++ b/arch/s390/hypfs/hypfs_vm.c @@ -124,7 +124,7 @@ static int hpyfs_vm_create_guest(struct super_block *sb, /* guest dir */ memcpy(guest_name, data->guest_name, NAME_LEN); EBCASC(guest_name, NAME_LEN); - strstrip(guest_name); + strim(guest_name); guest_dir = hypfs_mkdir(sb, systems_dir, guest_name); if (IS_ERR(guest_dir)) return PTR_ERR(guest_dir); diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index 4890ac6..4d73296 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c @@ -221,7 +221,7 @@ static ssize_t sys_##_prefix##_##_name##_store(struct kobject *kobj, \ const char *buf, size_t len) \ { \ strncpy(_value, buf, sizeof(_value) - 1); \ - strstrip(_value); \ + strim(_value); \ return len; \ } \ static struct kobj_attribute sys_##_prefix##_##_name##_attr = \ @@ -472,7 +472,7 @@ static ssize_t ipl_ccw_loadparm_show(struct kobject *kobj, return sprintf(page, "#unknown#\n"); memcpy(loadparm, &sclp_ipl_info.loadparm, LOADPARM_LEN); EBCASC(loadparm, LOADPARM_LEN); - strstrip(loadparm); + strim(loadparm); return sprintf(page, "%s\n", loadparm); } @@ -776,7 +776,7 @@ static void reipl_get_ascii_loadparm(char *loadparm, memcpy(loadparm, ibp->ipl_info.ccw.load_parm, LOADPARM_LEN); EBCASC(loadparm, LOADPARM_LEN); loadparm[LOADPARM_LEN] = 0; - strstrip(loadparm); + strim(loadparm); } static ssize_t reipl_generic_loadparm_show(struct ipl_parameter_block *ipb, diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c index b2eb94a..9821c58 100644 --- a/drivers/s390/char/tape_3590.c +++ b/drivers/s390/char/tape_3590.c @@ -137,7 +137,7 @@ static void int_to_ext_kekl(struct tape3592_kekl *in, out->type_on_tape = TAPE390_KEKL_TYPE_LABEL; memcpy(out->label, in->label, sizeof(in->label)); EBCASC(out->label, sizeof(in->label)); - strstrip(out->label); + strim(out->label); } static void int_to_ext_kekl_pair(struct tape3592_kekl_pair *in, -- cgit v0.10.2 From 8bee738bb1979c8bf7b42716b772522ab7d26b0c Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Fri, 18 Dec 2009 10:40:13 -0500 Subject: x86: Fix objdump version check in chkobjdump.awk for different formats. Different version of objdump says its version in different way; GNU objdump 2.16.1 or GNU objdump version 2.19.51.0.14-1.fc11 20090722 This patch uses the first argument which starts with a number as version string. Changes in v2: - Remove unneeded increment. Signed-off-by: Masami Hiramatsu LKML-Reference: <20091218154012.16960.5113.stgit@dhcp-100-2-132.bos.redhat.com> Suggested-by: H. Peter Anvin Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Andrew Morton Signed-off-by: H. Peter Anvin diff --git a/arch/x86/tools/chkobjdump.awk b/arch/x86/tools/chkobjdump.awk index 5bbb5a3..fd1ab80 100644 --- a/arch/x86/tools/chkobjdump.awk +++ b/arch/x86/tools/chkobjdump.awk @@ -8,14 +8,24 @@ BEGIN { od_sver = 19; } -/^GNU/ { - split($3, ver, "."); +/^GNU objdump/ { + verstr = "" + for (i = 3; i <= NF; i++) + if (match($(i), "^[0-9]")) { + verstr = $(i); + break; + } + if (verstr == "") { + printf("Warning: Failed to find objdump version number.\n"); + exit 0; + } + split(verstr, ver, "."); if (ver[1] > od_ver || (ver[1] == od_ver && ver[2] >= od_sver)) { exit 1; } else { printf("Warning: objdump version %s is older than %d.%d\n", - $4, od_ver, od_sver); + verstr, od_ver, od_sver); print("Warning: Skipping posttest."); # Logic is inverted, because we just skip test without error. exit 0; -- cgit v0.10.2 From 9b0fd1149747b117e7c3e9917fdea03b774ae3d0 Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Fri, 18 Dec 2009 13:02:38 -0500 Subject: watchdog: update geodewdt for new MFGPT API Update to the new cs5535_mfgpt* API. The geode-specific wording should eventually be dropped from this driver... Signed-off-by: Andres Salomon Signed-off-by: Linus Torvalds diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index da84fd0..088f32f 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -368,7 +368,7 @@ config ALIM7101_WDT config GEODE_WDT tristate "AMD Geode CS5535/CS5536 Watchdog" - depends on MGEODE_LX + depends on CS5535_MFGPT help This driver enables a watchdog capability built into the CS5535/CS5536 companion chips for the AMD Geode GX and LX diff --git a/drivers/watchdog/geodewdt.c b/drivers/watchdog/geodewdt.c index 9acf001..38252ff 100644 --- a/drivers/watchdog/geodewdt.c +++ b/drivers/watchdog/geodewdt.c @@ -1,6 +1,7 @@ -/* Watchdog timer for the Geode GX/LX with the CS5535/CS5536 companion chip +/* Watchdog timer for machines with the CS5535/CS5536 companion chip * * Copyright (C) 2006-2007, Advanced Micro Devices, Inc. + * Copyright (C) 2009 Andres Salomon * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -19,7 +20,7 @@ #include #include -#include +#include #define GEODEWDT_HZ 500 #define GEODEWDT_SCALE 6 @@ -46,25 +47,25 @@ MODULE_PARM_DESC(nowayout, static struct platform_device *geodewdt_platform_device; static unsigned long wdt_flags; -static int wdt_timer; +static struct cs5535_mfgpt_timer *wdt_timer; static int safe_close; static void geodewdt_ping(void) { /* Stop the counter */ - geode_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, 0); + cs5535_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, 0); /* Reset the counter */ - geode_mfgpt_write(wdt_timer, MFGPT_REG_COUNTER, 0); + cs5535_mfgpt_write(wdt_timer, MFGPT_REG_COUNTER, 0); /* Enable the counter */ - geode_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, MFGPT_SETUP_CNTEN); + cs5535_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, MFGPT_SETUP_CNTEN); } static void geodewdt_disable(void) { - geode_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, 0); - geode_mfgpt_write(wdt_timer, MFGPT_REG_COUNTER, 0); + cs5535_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, 0); + cs5535_mfgpt_write(wdt_timer, MFGPT_REG_COUNTER, 0); } static int geodewdt_set_heartbeat(int val) @@ -72,10 +73,10 @@ static int geodewdt_set_heartbeat(int val) if (val < 1 || val > GEODEWDT_MAX_SECONDS) return -EINVAL; - geode_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, 0); - geode_mfgpt_write(wdt_timer, MFGPT_REG_CMP2, val * GEODEWDT_HZ); - geode_mfgpt_write(wdt_timer, MFGPT_REG_COUNTER, 0); - geode_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, MFGPT_SETUP_CNTEN); + cs5535_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, 0); + cs5535_mfgpt_write(wdt_timer, MFGPT_REG_CMP2, val * GEODEWDT_HZ); + cs5535_mfgpt_write(wdt_timer, MFGPT_REG_COUNTER, 0); + cs5535_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, MFGPT_SETUP_CNTEN); timeout = val; return 0; @@ -215,28 +216,25 @@ static struct miscdevice geodewdt_miscdev = { static int __devinit geodewdt_probe(struct platform_device *dev) { - int ret, timer; - - timer = geode_mfgpt_alloc_timer(MFGPT_TIMER_ANY, MFGPT_DOMAIN_WORKING); + int ret; - if (timer == -1) { + wdt_timer = cs5535_mfgpt_alloc_timer(MFGPT_TIMER_ANY, MFGPT_DOMAIN_WORKING); + if (!wdt_timer) { printk(KERN_ERR "geodewdt: No timers were available\n"); return -ENODEV; } - wdt_timer = timer; - /* Set up the timer */ - geode_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, + cs5535_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, GEODEWDT_SCALE | (3 << 8)); /* Set up comparator 2 to reset when the event fires */ - geode_mfgpt_toggle_event(wdt_timer, MFGPT_CMP2, MFGPT_EVENT_RESET, 1); + cs5535_mfgpt_toggle_event(wdt_timer, MFGPT_CMP2, MFGPT_EVENT_RESET, 1); /* Set up the initial timeout */ - geode_mfgpt_write(wdt_timer, MFGPT_REG_CMP2, + cs5535_mfgpt_write(wdt_timer, MFGPT_REG_CMP2, timeout * GEODEWDT_HZ); ret = misc_register(&geodewdt_miscdev); -- cgit v0.10.2 From d49464318a7c51676c44cbd1e2480f651cc43807 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 18 Dec 2009 20:25:30 +0100 Subject: ALSA: aaci - Fix a typo Fixed a typo of the max buffer size specified for buffer allocation changed in the commit d6797322231af98b9bb4afb175dd614cf511e5f7. Signed-off-by: Takashi Iwai diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c index 1497dce..ae38f2c 100644 --- a/sound/arm/aaci.c +++ b/sound/arm/aaci.c @@ -1028,7 +1028,7 @@ static int __devinit aaci_init_pcm(struct aaci *aaci) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &aaci_playback_ops); snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &aaci_capture_ops); snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, - NULL, 0, 64 * 104); + NULL, 0, 64 * 1024); } return ret; -- cgit v0.10.2 From 6ca867c827c84d21316e9dc4035abe9480f8347c Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 18 Dec 2009 17:48:35 +0000 Subject: ALSA: AACI: simplify codec rate information There's no need for a specific rule; ALSA's generic AC'97 support calculates the necessary rate constraint information itself, and we can use this directly. Signed-off-by: Russell King Signed-off-by: Takashi Iwai diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c index ae38f2c..ea3be87 100644 --- a/sound/arm/aaci.c +++ b/sound/arm/aaci.c @@ -330,63 +330,6 @@ static irqreturn_t aaci_irq(int irq, void *devid) /* * ALSA support. */ - -struct aaci_stream { - unsigned char codec_idx; - unsigned char rate_idx; -}; - -static struct aaci_stream aaci_streams[] = { - [ACSTREAM_FRONT] = { - .codec_idx = 0, - .rate_idx = AC97_RATES_FRONT_DAC, - }, - [ACSTREAM_SURROUND] = { - .codec_idx = 0, - .rate_idx = AC97_RATES_SURR_DAC, - }, - [ACSTREAM_LFE] = { - .codec_idx = 0, - .rate_idx = AC97_RATES_LFE_DAC, - }, -}; - -static inline unsigned int aaci_rate_mask(struct aaci *aaci, int streamid) -{ - struct aaci_stream *s = aaci_streams + streamid; - return aaci->ac97_bus->codec[s->codec_idx]->rates[s->rate_idx]; -} - -static unsigned int rate_list[] = { - 5512, 8000, 11025, 16000, 22050, 32000, 44100, - 48000, 64000, 88200, 96000, 176400, 192000 -}; - -/* - * Double-rate rule: we can support double rate iff channels == 2 - * (unimplemented) - */ -static int -aaci_rule_rate_by_channels(struct snd_pcm_hw_params *p, struct snd_pcm_hw_rule *rule) -{ - struct aaci *aaci = rule->private; - unsigned int rate_mask = SNDRV_PCM_RATE_8000_48000|SNDRV_PCM_RATE_5512; - struct snd_interval *c = hw_param_interval(p, SNDRV_PCM_HW_PARAM_CHANNELS); - - switch (c->max) { - case 6: - rate_mask &= aaci_rate_mask(aaci, ACSTREAM_LFE); - case 4: - rate_mask &= aaci_rate_mask(aaci, ACSTREAM_SURROUND); - case 2: - rate_mask &= aaci_rate_mask(aaci, ACSTREAM_FRONT); - } - - return snd_interval_list(hw_param_interval(p, rule->var), - ARRAY_SIZE(rate_list), rate_list, - rate_mask); -} - static struct snd_pcm_hardware aaci_hw_info = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | @@ -400,10 +343,7 @@ static struct snd_pcm_hardware aaci_hw_info = { */ .formats = SNDRV_PCM_FMTBIT_S16_LE, - /* should this be continuous or knot? */ - .rates = SNDRV_PCM_RATE_CONTINUOUS, - .rate_max = 48000, - .rate_min = 4000, + /* rates are setup from the AC'97 codec */ .channels_min = 2, .channels_max = 6, .buffer_bytes_max = 64 * 1024, @@ -423,6 +363,8 @@ static int __aaci_pcm_open(struct aaci *aaci, aacirun->substream = substream; runtime->private_data = aacirun; runtime->hw = aaci_hw_info; + runtime->hw.rates = aacirun->pcm->rates; + snd_pcm_limit_hw_rates(runtime); /* * FIXME: ALSA specifies fifo_size in bytes. If we're in normal @@ -433,17 +375,6 @@ static int __aaci_pcm_open(struct aaci *aaci, */ runtime->hw.fifo_size = aaci->fifosize * 2; - /* - * Add rule describing hardware rate dependency - * on the number of channels. - */ - ret = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, - aaci_rule_rate_by_channels, aaci, - SNDRV_PCM_HW_PARAM_CHANNELS, - SNDRV_PCM_HW_PARAM_RATE, -1); - if (ret) - goto out; - ret = request_irq(aaci->dev->irq[0], aaci_irq, IRQF_SHARED|IRQF_DISABLED, DRIVER_NAME, aaci); if (ret) -- cgit v0.10.2 From 4e30b69108b20eca80f1a323f969bf7629c7795f Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 18 Dec 2009 17:48:37 +0000 Subject: ALSA: AACI: cleanup aaci_pcm_hw_params Since the recording and playback paths are now the same, eliminate the needless conditionals. Signed-off-by: Russell King Signed-off-by: Takashi Iwai diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c index ea3be87..2e28748 100644 --- a/sound/arm/aaci.c +++ b/sound/arm/aaci.c @@ -438,18 +438,14 @@ static int aaci_pcm_hw_params(struct snd_pcm_substream *substream, err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); - if (err < 0) - goto out; - - err = snd_ac97_pcm_open(aacirun->pcm, params_rate(params), - params_channels(params), - aacirun->pcm->r[0].slots); - if (err) - goto out; + if (err >= 0) { + err = snd_ac97_pcm_open(aacirun->pcm, params_rate(params), + params_channels(params), + aacirun->pcm->r[0].slots); - aacirun->pcm_open = 1; + aacirun->pcm_open = err == 0; + } - out: return err; } @@ -458,7 +454,7 @@ static int aaci_pcm_prepare(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; struct aaci_runtime *aacirun = runtime->private_data; - aacirun->start = (void *)runtime->dma_area; + aacirun->start = runtime->dma_area; aacirun->end = aacirun->start + snd_pcm_lib_buffer_bytes(substream); aacirun->ptr = aacirun->start; aacirun->period = -- cgit v0.10.2 From d3aee7996c30f928bbbbfd0994148e35d2e83084 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 18 Dec 2009 17:48:40 +0000 Subject: ALSA: AACI: factor common hw_params logic into aaci_pcm_hw_params Signed-off-by: Russell King Signed-off-by: Takashi Iwai diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c index 2e28748..b88bbde 100644 --- a/sound/arm/aaci.c +++ b/sound/arm/aaci.c @@ -444,6 +444,11 @@ static int aaci_pcm_hw_params(struct snd_pcm_substream *substream, aacirun->pcm->r[0].slots); aacirun->pcm_open = err == 0; + aacirun->cr = CR_FEN | CR_COMPACT | CR_SZ16; + aacirun->fifosz = aaci->fifosize * 4; + + if (aacirun->cr & CR_COMPACT) + aacirun->fifosz >>= 1; } return err; @@ -554,14 +559,9 @@ static int aaci_pcm_playback_hw_params(struct snd_pcm_substream *substream, * Enable FIFO, compact mode, 16 bits per sample. * FIXME: double rate slots? */ - if (ret >= 0) { - aacirun->cr = CR_FEN | CR_COMPACT | CR_SZ16; + if (ret >= 0) aacirun->cr |= channels_to_txmask[channels]; - aacirun->fifosz = aaci->fifosize * 4; - if (aacirun->cr & CR_COMPACT) - aacirun->fifosz >>= 1; - } return ret; } @@ -648,18 +648,10 @@ static int aaci_pcm_capture_hw_params(struct snd_pcm_substream *substream, int ret; ret = aaci_pcm_hw_params(substream, aacirun, params); - - if (ret >= 0) { - aacirun->cr = CR_FEN | CR_COMPACT | CR_SZ16; - + if (ret >= 0) /* Line in record: slot 3 and 4 */ aacirun->cr |= CR_SL3 | CR_SL4; - aacirun->fifosz = aaci->fifosize * 4; - - if (aacirun->cr & CR_COMPACT) - aacirun->fifosz >>= 1; - } return ret; } -- cgit v0.10.2 From a08d56583f6b87e2981d1b6e9ee891bdc741cc44 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 18 Dec 2009 17:48:45 +0000 Subject: ALSA: AACI: add double-rate support Signed-off-by: Russell King Signed-off-by: Takashi Iwai diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c index b88bbde..b377370 100644 --- a/sound/arm/aaci.c +++ b/sound/arm/aaci.c @@ -366,6 +366,10 @@ static int __aaci_pcm_open(struct aaci *aaci, runtime->hw.rates = aacirun->pcm->rates; snd_pcm_limit_hw_rates(runtime); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && + aacirun->pcm->r[1].slots) + snd_ac97_pcm_double_rate_rules(runtime); + /* * FIXME: ALSA specifies fifo_size in bytes. If we're in normal * mode, each 32-bit word contains one sample. If we're in @@ -439,9 +443,12 @@ static int aaci_pcm_hw_params(struct snd_pcm_substream *substream, err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); if (err >= 0) { - err = snd_ac97_pcm_open(aacirun->pcm, params_rate(params), + unsigned int rate = params_rate(params); + int dbl = rate > 48000; + + err = snd_ac97_pcm_open(aacirun->pcm, rate, params_channels(params), - aacirun->pcm->r[0].slots); + aacirun->pcm->r[dbl].slots); aacirun->pcm_open = err == 0; aacirun->cr = CR_FEN | CR_COMPACT | CR_SZ16; @@ -808,6 +815,12 @@ static struct ac97_pcm ac97_defs[] __devinitdata = { (1 << AC97_SLOT_PCM_SRIGHT) | (1 << AC97_SLOT_LFE), }, + [1] = { + .slots = (1 << AC97_SLOT_PCM_LEFT) | + (1 << AC97_SLOT_PCM_RIGHT) | + (1 << AC97_SLOT_PCM_LEFT_0) | + (1 << AC97_SLOT_PCM_RIGHT_0), + }, }, }, [1] = { /* PCM in */ -- cgit v0.10.2 From d6a89fefa50feda5516cd5210ad0008a44632b52 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 18 Dec 2009 17:48:50 +0000 Subject: ALSA: AACI: switch to per-pcm locking We can use finer-grained locking, which makes things easier when we gain DMA support. Signed-off-by: Russell King Signed-off-by: Takashi Iwai diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c index b377370..c569986 100644 --- a/sound/arm/aaci.c +++ b/sound/arm/aaci.c @@ -172,14 +172,15 @@ static unsigned short aaci_ac97_read(struct snd_ac97 *ac97, unsigned short reg) return v; } -static inline void aaci_chan_wait_ready(struct aaci_runtime *aacirun) +static inline void +aaci_chan_wait_ready(struct aaci_runtime *aacirun, unsigned long mask) { u32 val; int timeout = 5000; do { val = readl(aacirun->base + AACI_SR); - } while (val & (SR_TXB|SR_RXB) && timeout--); + } while (val & mask && timeout--); } @@ -208,8 +209,10 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask) writel(0, aacirun->base + AACI_IE); return; } - ptr = aacirun->ptr; + spin_lock(&aacirun->lock); + + ptr = aacirun->ptr; do { unsigned int len = aacirun->fifosz; u32 val; @@ -217,9 +220,9 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask) if (aacirun->bytes <= 0) { aacirun->bytes += aacirun->period; aacirun->ptr = ptr; - spin_unlock(&aaci->lock); + spin_unlock(&aacirun->lock); snd_pcm_period_elapsed(aacirun->substream); - spin_lock(&aaci->lock); + spin_lock(&aacirun->lock); } if (!(aacirun->cr & CR_EN)) break; @@ -245,7 +248,10 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask) ptr = aacirun->start; } } while(1); + aacirun->ptr = ptr; + + spin_unlock(&aacirun->lock); } if (mask & ISR_URINTR) { @@ -263,6 +269,8 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask) return; } + spin_lock(&aacirun->lock); + ptr = aacirun->ptr; do { unsigned int len = aacirun->fifosz; @@ -271,9 +279,9 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask) if (aacirun->bytes <= 0) { aacirun->bytes += aacirun->period; aacirun->ptr = ptr; - spin_unlock(&aaci->lock); + spin_unlock(&aacirun->lock); snd_pcm_period_elapsed(aacirun->substream); - spin_lock(&aaci->lock); + spin_lock(&aacirun->lock); } if (!(aacirun->cr & CR_EN)) break; @@ -301,6 +309,8 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask) } while (1); aacirun->ptr = ptr; + + spin_unlock(&aacirun->lock); } } @@ -310,7 +320,6 @@ static irqreturn_t aaci_irq(int irq, void *devid) u32 mask; int i; - spin_lock(&aaci->lock); mask = readl(aaci->base + AACI_ALLINTS); if (mask) { u32 m = mask; @@ -320,7 +329,6 @@ static irqreturn_t aaci_irq(int irq, void *devid) } } } - spin_unlock(&aaci->lock); return mask ? IRQ_HANDLED : IRQ_NONE; } @@ -580,7 +588,7 @@ static void aaci_pcm_playback_stop(struct aaci_runtime *aacirun) ie &= ~(IE_URIE|IE_TXIE); writel(ie, aacirun->base + AACI_IE); aacirun->cr &= ~CR_EN; - aaci_chan_wait_ready(aacirun); + aaci_chan_wait_ready(aacirun, SR_TXB); writel(aacirun->cr, aacirun->base + AACI_TXCR); } @@ -588,7 +596,7 @@ static void aaci_pcm_playback_start(struct aaci_runtime *aacirun) { u32 ie; - aaci_chan_wait_ready(aacirun); + aaci_chan_wait_ready(aacirun, SR_TXB); aacirun->cr |= CR_EN; ie = readl(aacirun->base + AACI_IE); @@ -599,12 +607,12 @@ static void aaci_pcm_playback_start(struct aaci_runtime *aacirun) static int aaci_pcm_playback_trigger(struct snd_pcm_substream *substream, int cmd) { - struct aaci *aaci = substream->private_data; struct aaci_runtime *aacirun = substream->runtime->private_data; unsigned long flags; int ret = 0; - spin_lock_irqsave(&aaci->lock, flags); + spin_lock_irqsave(&aacirun->lock, flags); + switch (cmd) { case SNDRV_PCM_TRIGGER_START: aaci_pcm_playback_start(aacirun); @@ -631,7 +639,8 @@ static int aaci_pcm_playback_trigger(struct snd_pcm_substream *substream, int cm default: ret = -EINVAL; } - spin_unlock_irqrestore(&aaci->lock, flags); + + spin_unlock_irqrestore(&aacirun->lock, flags); return ret; } @@ -666,7 +675,7 @@ static void aaci_pcm_capture_stop(struct aaci_runtime *aacirun) { u32 ie; - aaci_chan_wait_ready(aacirun); + aaci_chan_wait_ready(aacirun, SR_RXB); ie = readl(aacirun->base + AACI_IE); ie &= ~(IE_ORIE | IE_RXIE); @@ -681,7 +690,7 @@ static void aaci_pcm_capture_start(struct aaci_runtime *aacirun) { u32 ie; - aaci_chan_wait_ready(aacirun); + aaci_chan_wait_ready(aacirun, SR_RXB); #ifdef DEBUG /* RX Timeout value: bits 28:17 in RXCR */ @@ -698,12 +707,11 @@ static void aaci_pcm_capture_start(struct aaci_runtime *aacirun) static int aaci_pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd) { - struct aaci *aaci = substream->private_data; struct aaci_runtime *aacirun = substream->runtime->private_data; unsigned long flags; int ret = 0; - spin_lock_irqsave(&aaci->lock, flags); + spin_lock_irqsave(&aacirun->lock, flags); switch (cmd) { case SNDRV_PCM_TRIGGER_START: @@ -732,7 +740,7 @@ static int aaci_pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd ret = -EINVAL; } - spin_unlock_irqrestore(&aaci->lock, flags); + spin_unlock_irqrestore(&aacirun->lock, flags); return ret; } @@ -933,7 +941,6 @@ static struct aaci * __devinit aaci_init_card(struct amba_device *dev) aaci = card->private_data; mutex_init(&aaci->ac97_sem); - spin_lock_init(&aaci->lock); aaci->card = card; aaci->dev = dev; @@ -1020,12 +1027,14 @@ static int __devinit aaci_probe(struct amba_device *dev, struct amba_id *id) /* * Playback uses AACI channel 0 */ + spin_lock_init(&aaci->playback.lock); aaci->playback.base = aaci->base + AACI_CSCH1; aaci->playback.fifo = aaci->base + AACI_DR1; /* * Capture uses AACI channel 0 */ + spin_lock_init(&aaci->capture.lock); aaci->capture.base = aaci->base + AACI_CSCH1; aaci->capture.fifo = aaci->base + AACI_DR1; diff --git a/sound/arm/aaci.h b/sound/arm/aaci.h index 924f69c..6a4a2ee 100644 --- a/sound/arm/aaci.h +++ b/sound/arm/aaci.h @@ -202,6 +202,7 @@ struct aaci_runtime { void __iomem *base; void __iomem *fifo; + spinlock_t lock; struct ac97_pcm *pcm; int pcm_open; @@ -232,7 +233,6 @@ struct aaci { struct snd_ac97 *ac97; u32 maincr; - spinlock_t lock; struct aaci_runtime playback; struct aaci_runtime capture; -- cgit v0.10.2 From 14ace024b1e16d2bb9445c8387494fbbd820a738 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Fri, 18 Dec 2009 16:28:05 -0500 Subject: SUNRPC: Fix up an error return value in gss_import_sec_context_kerberos() If the context allocation fails, the function currently returns a random error code, since the variable 'p' still points to a valid memory location. Ensure that it returns ENOMEM... Cc: stable@kernel.org Signed-off-by: Trond Myklebust diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c index ef45eba..2deb0ed 100644 --- a/net/sunrpc/auth_gss/gss_krb5_mech.c +++ b/net/sunrpc/auth_gss/gss_krb5_mech.c @@ -131,8 +131,10 @@ gss_import_sec_context_kerberos(const void *p, struct krb5_ctx *ctx; int tmp; - if (!(ctx = kzalloc(sizeof(*ctx), GFP_NOFS))) + if (!(ctx = kzalloc(sizeof(*ctx), GFP_NOFS))) { + p = ERR_PTR(-ENOMEM); goto out_err; + } p = simple_get_bytes(p, end, &ctx->initiate, sizeof(ctx->initiate)); if (IS_ERR(p)) -- cgit v0.10.2 From b891e4a05ef6beac85465295a032431577c66b16 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Fri, 18 Dec 2009 16:28:12 -0500 Subject: SUNRPC: Fix the return value in gss_import_sec_context() If the context allocation fails, it will return GSS_S_FAILURE, which is neither a valid error code, nor is it even negative. Return ENOMEM instead... Reported-by: Jeff Layton Cc: stable@kernel.org Signed-off-by: Trond Myklebust diff --git a/net/sunrpc/auth_gss/gss_mech_switch.c b/net/sunrpc/auth_gss/gss_mech_switch.c index 6efbb0c..76e4c6f 100644 --- a/net/sunrpc/auth_gss/gss_mech_switch.c +++ b/net/sunrpc/auth_gss/gss_mech_switch.c @@ -252,7 +252,7 @@ gss_import_sec_context(const void *input_token, size_t bufsize, struct gss_ctx **ctx_id) { if (!(*ctx_id = kzalloc(sizeof(**ctx_id), GFP_KERNEL))) - return GSS_S_FAILURE; + return -ENOMEM; (*ctx_id)->mech_type = gss_mech_get(mech); return mech->gm_ops -- cgit v0.10.2 From 486bad2e40e938cd68fd853b7a9fa3115a9d3a4a Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Fri, 18 Dec 2009 16:28:20 -0500 Subject: sunrpc: on successful gss error pipe write, don't return error When handling the gssd downcall, the kernel should distinguish between a successful downcall that contains an error code and a failed downcall (i.e. where the parsing failed or some other sort of problem occurred). In the former case, gss_pipe_downcall should be returning the number of bytes written to the pipe instead of an error. In the event of other errors, we generally want the initiating task to retry the upcall so we set msg.errno to -EAGAIN. An unexpected error code here is a bug however, so BUG() in that case. Signed-off-by: Jeff Layton Cc: stable@kernel.org Signed-off-by: Trond Myklebust diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 3c3c50f..66cb89c 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c @@ -644,7 +644,22 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) p = gss_fill_context(p, end, ctx, gss_msg->auth->mech); if (IS_ERR(p)) { err = PTR_ERR(p); - gss_msg->msg.errno = (err == -EAGAIN) ? -EAGAIN : -EACCES; + switch (err) { + case -EACCES: + gss_msg->msg.errno = err; + err = mlen; + break; + case -EFAULT: + case -ENOMEM: + case -EINVAL: + case -ENOSYS: + gss_msg->msg.errno = -EAGAIN; + break; + default: + printk(KERN_CRIT "%s: bad return from " + "gss_fill_context: %ld\n", __func__, err); + BUG(); + } goto err_release_msg; } gss_msg->ctx = gss_get_ctx(ctx); -- cgit v0.10.2 From c7d260afcbc0f9f4074e74796d4e3646875c08e1 Mon Sep 17 00:00:00 2001 From: Tao Ma Date: Fri, 18 Dec 2009 10:24:54 +0800 Subject: ocfs2: Add reflinked file's inode to inode hash eariler. We used to add reflinked file's inode to inode hash when we add it to the dest dir. But actually there is a race. Consider the following sequence. 1. reflink happens and create the inode in orphan dir. 2. reflink thread is scheduled out because of some io. 3. recovery begins to work and calls ocfs2_recover_orphans. It calls ocfs2_iget and get a new inode and i_count = 1. It calls iput then and delete inode. the buffer's uptodate state is cleared. This patch move insert_inode_hash to the create function so that it can be found by step 3 and prevented from deleting because i_count > 1. This resolves the bug http://oss.oracle.com/bugzilla/show_bug.cgi?id=1183. Signed-off-by: Tao Ma Signed-off-by: Joel Becker diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index f010b22..5ac4d52 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c @@ -2136,6 +2136,7 @@ int ocfs2_create_inode_in_orphan(struct inode *dir, if (status < 0) mlog_errno(status); + insert_inode_hash(inode); leave: if (status < 0 && did_quota_inode) vfs_dq_free_inode(inode); @@ -2284,7 +2285,6 @@ int ocfs2_mv_orphaned_inode_to_new(struct inode *dir, goto out_commit; } - insert_inode_hash(inode); dentry->d_op = &ocfs2_dentry_ops; d_instantiate(dentry, inode); status = 0; -- cgit v0.10.2 From 10cf1a02f444fdcd50be47cce3fa8bf08251dd9c Mon Sep 17 00:00:00 2001 From: Tao Ma Date: Fri, 18 Dec 2009 10:24:55 +0800 Subject: ocfs2: Set i_nlink properly during reflink. We create a file in orphan dir for reflink so that if there is any error, we don't create any wrong dentry in the dir. But actually the file in orphan dir should be i_nlink = 0 so that it can be replayed and freed successfully. This patch first set i_nlink to 0 when creating the file in orphan dir and then set it to 1(reflink now only works for regular file) when we move it to the dest dir. Signed-off-by: Tao Ma Signed-off-by: Joel Becker diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index 5ac4d52..3e9b46002 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c @@ -2108,6 +2108,7 @@ int ocfs2_create_inode_in_orphan(struct inode *dir, } did_quota_inode = 1; + inode->i_nlink = 0; /* do the real work now. */ status = ocfs2_mknod_locked(osb, dir, inode, 0, &new_di_bh, parent_di_bh, handle, @@ -2268,6 +2269,8 @@ int ocfs2_mv_orphaned_inode_to_new(struct inode *dir, di = (struct ocfs2_dinode *)di_bh->b_data; le32_add_cpu(&di->i_flags, -OCFS2_ORPHANED_FL); di->i_orphaned_slot = 0; + inode->i_nlink = 1; + ocfs2_set_links_count(di, inode->i_nlink); ocfs2_journal_dirty(handle, di_bh); status = ocfs2_add_entry(handle, dentry, inode, -- cgit v0.10.2 From 9c69fabe789b0eb468a0c7031ae7bb850760aea8 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Fri, 18 Dec 2009 20:11:03 -0800 Subject: netns: fix net.ipv6.route.gc_min_interval_ms in netns sysctl table was copied, all right, but ->data for net.ipv6.route.gc_min_interval_ms was not reinitialized for "!= &init_net" case. In init_net everthing works by accident due to correct ->data initialization in source table. Signed-off-by: Alexey Dobriyan Signed-off-by: David S. Miller diff --git a/net/ipv6/route.c b/net/ipv6/route.c index db3b273..c2bd74c 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -2630,6 +2630,7 @@ struct ctl_table *ipv6_route_sysctl_init(struct net *net) table[6].data = &net->ipv6.sysctl.ip6_rt_gc_elasticity; table[7].data = &net->ipv6.sysctl.ip6_rt_mtu_expires; table[8].data = &net->ipv6.sysctl.ip6_rt_min_advmss; + table[9].data = &net->ipv6.sysctl.ip6_rt_gc_min_interval; } return table; -- cgit v0.10.2 From afdafff130142ef4d6478dcff6d9e879394fd348 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Fri, 18 Dec 2009 20:13:35 -0800 Subject: netxen: use module parameter correctly Netxen driver is doing this bogus thing to create a control file. This fails if device doesn't exist, and overall is a bad way to do the module parameter. Rather than fix borked code, just rewrite. Just using a writeable module parameter of 0/1 is the correct way Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index f499684..6cae26a 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -57,7 +57,9 @@ static int use_msi = 1; static int use_msi_x = 1; -static unsigned long auto_fw_reset = AUTO_FW_RESET_ENABLED; +static int auto_fw_reset = AUTO_FW_RESET_ENABLED; +module_param(auto_fw_reset, int, 0644); +MODULE_PARM_DESC(auto_fw_reset,"Auto firmware reset (0=disabled, 1=enabled"); static int __devinit netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent); @@ -2534,42 +2536,6 @@ static struct bin_attribute bin_attr_mem = { .write = netxen_sysfs_write_mem, }; -#ifdef CONFIG_MODULES -static ssize_t -netxen_store_auto_fw_reset(struct module_attribute *mattr, - struct module *mod, const char *buf, size_t count) - -{ - unsigned long new; - - if (strict_strtoul(buf, 16, &new)) - return -EINVAL; - - if ((new == AUTO_FW_RESET_ENABLED) || (new == AUTO_FW_RESET_DISABLED)) { - auto_fw_reset = new; - return count; - } - - return -EINVAL; -} - -static ssize_t -netxen_show_auto_fw_reset(struct module_attribute *mattr, - struct module *mod, char *buf) - -{ - if (auto_fw_reset == AUTO_FW_RESET_ENABLED) - return sprintf(buf, "enabled\n"); - else - return sprintf(buf, "disabled\n"); -} - -static struct module_attribute mod_attr_fw_reset = { - .attr = {.name = "auto_fw_reset", .mode = (S_IRUGO | S_IWUSR)}, - .show = netxen_show_auto_fw_reset, - .store = netxen_store_auto_fw_reset, -}; -#endif static void netxen_create_sysfs_entries(struct netxen_adapter *adapter) @@ -2775,23 +2741,12 @@ static struct pci_driver netxen_driver = { static int __init netxen_init_module(void) { -#ifdef CONFIG_MODULES - struct module *mod = THIS_MODULE; -#endif - printk(KERN_INFO "%s\n", netxen_nic_driver_string); #ifdef CONFIG_INET register_netdevice_notifier(&netxen_netdev_cb); register_inetaddr_notifier(&netxen_inetaddr_cb); #endif - -#ifdef CONFIG_MODULES - if (sysfs_create_file(&mod->mkobj.kobj, &mod_attr_fw_reset.attr)) - printk(KERN_ERR "%s: Failed to create auto_fw_reset " - "sysfs entry.", netxen_nic_driver_name); -#endif - return pci_register_driver(&netxen_driver); } @@ -2799,12 +2754,6 @@ module_init(netxen_init_module); static void __exit netxen_exit_module(void) { -#ifdef CONFIG_MODULES - struct module *mod = THIS_MODULE; - - sysfs_remove_file(&mod->mkobj.kobj, &mod_attr_fw_reset.attr); -#endif - pci_unregister_driver(&netxen_driver); #ifdef CONFIG_INET -- cgit v0.10.2 From db94ce90d3d571c11637a912cc39cfb80df3879c Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 18 Dec 2009 20:14:59 -0800 Subject: e1000e: LED settings in EEPROM ignored on 82571 and 82572 Do not override the customizable LED configuration set in the EEPROM. Signed-off-by: Bruce Allan Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c index c1a42cf..b979464 100644 --- a/drivers/net/e1000e/82571.c +++ b/drivers/net/e1000e/82571.c @@ -1290,7 +1290,6 @@ static s32 e1000_setup_link_82571(struct e1000_hw *hw) static s32 e1000_setup_copper_link_82571(struct e1000_hw *hw) { u32 ctrl; - u32 led_ctrl; s32 ret_val; ctrl = er32(CTRL); @@ -1305,11 +1304,6 @@ static s32 e1000_setup_copper_link_82571(struct e1000_hw *hw) break; case e1000_phy_igp_2: ret_val = e1000e_copper_link_setup_igp(hw); - /* Setup activity LED */ - led_ctrl = er32(LEDCTL); - led_ctrl &= IGP_ACTIVITY_LED_MASK; - led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE); - ew32(LEDCTL, led_ctrl); break; default: return -E1000_ERR_PHY; -- cgit v0.10.2 From 5ee6f6a17cfde9c3141e4d57cf88b5cdf638b463 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Fri, 18 Dec 2009 20:16:10 -0800 Subject: broadcom: bcm54xx_shadow_read() errors ignored in bcm54xx_adjust_rxrefclk() If not signed read errors are ignored. Signed-off-by: Roel Kluin Acked-by: Matt Carlson Signed-off-by: David S. Miller diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c index f63c96a..c13cf64 100644 --- a/drivers/net/phy/broadcom.c +++ b/drivers/net/phy/broadcom.c @@ -326,7 +326,8 @@ error: static void bcm54xx_adjust_rxrefclk(struct phy_device *phydev) { - u32 val, orig; + u32 orig; + int val; bool clk125en = true; /* Abort if we are using an untested phy. */ -- cgit v0.10.2 From 70abc8cb90e679d8519721e2761d8366a18212a6 Mon Sep 17 00:00:00 2001 From: Roger Oksanen Date: Fri, 18 Dec 2009 20:18:21 -0800 Subject: e100: Fix broken cbs accounting due to missing memset. Alan Stern noticed that e100 caused slab corruption. commit 98468efddb101f8a29af974101c17ba513b07be1 changed the allocation of cbs to use dma pools that don't return zeroed memory, especially the cb->status field used to track which cb to clean, causing (the visible) double freeing of skbs and a wrong free cbs count. Now the cbs are explicitly zeroed at allocation time. Reported-by: Alan Stern Tested-by: Alan Stern Signed-off-by: Roger Oksanen Acked-by: Jesse Brandeburg Signed-off-by: David S. Miller diff --git a/drivers/net/e100.c b/drivers/net/e100.c index 929701c..839fb2b 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c @@ -1829,6 +1829,7 @@ static int e100_alloc_cbs(struct nic *nic) &nic->cbs_dma_addr); if (!nic->cbs) return -ENOMEM; + memset(nic->cbs, 0, count * sizeof(struct cb)); for (cb = nic->cbs, i = 0; i < count; cb++, i++) { cb->next = (i + 1 < count) ? cb + 1 : nic->cbs; @@ -1837,7 +1838,6 @@ static int e100_alloc_cbs(struct nic *nic) cb->dma_addr = nic->cbs_dma_addr + i * sizeof(struct cb); cb->link = cpu_to_le32(nic->cbs_dma_addr + ((i+1) % count) * sizeof(struct cb)); - cb->skb = NULL; } nic->cb_to_use = nic->cb_to_send = nic->cb_to_clean = nic->cbs; -- cgit v0.10.2 From f9c4171e01f6befdf5d15346070b819d341c9c73 Mon Sep 17 00:00:00 2001 From: Nageswari Srinivasan Date: Fri, 18 Dec 2009 20:21:21 -0800 Subject: TI DaVinci EMAC: Fix MDIO bus frequency configuration There was a typo in "if condition" checking for validity of MDIO bus frequency passed as part of platform data. Bitwise AND was being used instead of a Logical AND. Tested on: DM6467 EVM Signed-off-by: Nageswari Srinivasan Acked-by: Anant Gole Signed-off-by: David S. Miller diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c index 8edac89..34e0310 100644 --- a/drivers/net/davinci_emac.c +++ b/drivers/net/davinci_emac.c @@ -2272,7 +2272,7 @@ static int emac_mii_reset(struct mii_bus *bus) unsigned int clk_div; int mdio_bus_freq = emac_bus_frequency; - if (mdio_max_freq & mdio_bus_freq) + if (mdio_max_freq && mdio_bus_freq) clk_div = ((mdio_bus_freq / mdio_max_freq) - 1); else clk_div = 0xFF; -- cgit v0.10.2 From 3705e11a21bcdffe7422ee7870e1b23fe4ac70f4 Mon Sep 17 00:00:00 2001 From: Yang Hongyang Date: Fri, 18 Dec 2009 20:25:13 -0800 Subject: ipv6: fix an oops when force unload ipv6 module When I do an ipv6 module force unload,I got the following oops: #rmmod -f ipv6 ------------[ cut here ]------------ kernel BUG at mm/slub.c:2969! invalid opcode: 0000 [#1] SMP last sysfs file: /sys/devices/pci0000:00/0000:00:11.0/0000:02:03.0/net/eth2/ifindex Modules linked in: ipv6(-) dm_multipath uinput ppdev tpm_tis tpm tpm_bios pcspkr pcnet32 mii parport_pc i2c_piix4 parport i2c_core floppy mptspi mptscsih mptbase scsi_transport_spi Pid: 2530, comm: rmmod Tainted: G R 2.6.32 #2 440BX Desktop Reference Platform/VMware Virtual Platform EIP: 0060:[] EFLAGS: 00010246 CPU: 0 EIP is at kfree+0x6a/0xdd EAX: 00000000 EBX: c09e86bc ECX: c043e4dd EDX: c14293e0 ESI: e141f1d8 EDI: e140fc31 EBP: dec58ef0 ESP: dec58ed0 DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068 Process rmmod (pid: 2530, ti=dec58000 task=decb1940 task.ti=dec58000) Stack: c14293e0 00000282 df624240 c0897d08 c09e86bc c09e86bc e141f1d8 dec58f1c <0> dec58f00 e140fc31 c09e84c4 e141f1bc dec58f14 c0689d21 dec58f1c e141f1bc <0> 00000000 dec58f2c c0689eff c09e84d8 c09e84d8 e141f1bc bff33a90 dec58f38 Call Trace: [] ? ipv6_frags_exit_net+0x22/0x32 [ipv6] [] ? ops_exit_list+0x19/0x3d [] ? unregister_pernet_operations+0x2a/0x51 [] ? unregister_pernet_subsys+0x17/0x24 [] ? ipv6_frag_exit+0x21/0x32 [ipv6] [] ? inet6_exit+0x47/0x122 [ipv6] [] ? sys_delete_module+0x198/0x1f6 [] ? remove_vma+0x57/0x5d [] ? do_page_fault+0x2e7/0x315 [] ? sysenter_do_call+0x12/0x28 Code: 86 00 00 00 40 c1 e8 0c c1 e0 05 01 d0 89 45 e0 66 83 38 00 79 06 8b 40 0c 89 45 e0 8b 55 e0 8b 02 84 c0 78 14 66 a9 00 c0 75 04 <0f> 0b eb fe 8b 45 e0 e8 35 15 fe ff eb 5d 8b 45 04 8b 55 e0 89 EIP: [] kfree+0x6a/0xdd SS:ESP 0068:dec58ed0 ---[ end trace 4475d1a5b0afa7e5 ]--- It's because in ip6_frags_ns_sysctl_register, "table" only alloced when "net" is not equals to "init_net".So when we free "table" in ip6_frags_ns_sysctl_unregister,we should check this first. This patch fix the problem. Signed-off-by: Yang Hongyang Signed-off-by: David S. Miller diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index 3b3a956..2cddea3 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c @@ -708,7 +708,8 @@ static void ip6_frags_ns_sysctl_unregister(struct net *net) table = net->ipv6.sysctl.frags_hdr->ctl_table_arg; unregister_net_sysctl_table(net->ipv6.sysctl.frags_hdr); - kfree(table); + if (!net_eq(net, &init_net)) + kfree(table); } static struct ctl_table_header *ip6_ctl_header; -- cgit v0.10.2 From 4529819c45161e4a119134f56ef504e69420bc98 Mon Sep 17 00:00:00 2001 From: Breno Leitao Date: Fri, 18 Dec 2009 20:29:04 -0800 Subject: bnx2: reset_task is crashing the kernel. Fixing it. If bnx2 schedules a reset via the reset_task, e.g., due to a TX timeout, it's possible for the NIC to be disabled with packets pending for transmit. In this case, napi_disable will loop forever, eventually crashing the kernel. This patch moves the disable of the device to after the napi_disable call. Signed-off-by: Breno Leitao Acked-by: Michael Chan Signed-off-by: David S. Miller diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 4bfc808..c3e2b27 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -653,7 +653,6 @@ static void bnx2_netif_stop(struct bnx2 *bp) { bnx2_cnic_stop(bp); - bnx2_disable_int_sync(bp); if (netif_running(bp->dev)) { bnx2_napi_disable(bp); netif_tx_disable(bp->dev); @@ -672,6 +671,7 @@ bnx2_netif_start(struct bnx2 *bp) bnx2_cnic_start(bp); } } + bnx2_disable_int_sync(bp); } static void -- cgit v0.10.2 From 01a1e7ec6c3769dc7c5fde23ebc253c6be5f68eb Mon Sep 17 00:00:00 2001 From: Yong Zhang Date: Fri, 18 Dec 2009 20:30:11 -0800 Subject: mISDN: use DECLARE_COMPLETION_ONSTACK for non-constant completion The _ONSTACK variant should be used for on-stack completion, otherwise it will break lockdep. Signed-off-by: Yong Zhang Acked-by: Karsten Keil Signed-off-by: David S. Miller diff --git a/drivers/isdn/mISDN/l1oip_core.c b/drivers/isdn/mISDN/l1oip_core.c index 7e5f30d..f1e8af5 100644 --- a/drivers/isdn/mISDN/l1oip_core.c +++ b/drivers/isdn/mISDN/l1oip_core.c @@ -661,7 +661,7 @@ l1oip_socket_thread(void *data) size_t recvbuf_size = 1500; int recvlen; struct socket *socket = NULL; - DECLARE_COMPLETION(wait); + DECLARE_COMPLETION_ONSTACK(wait); /* allocate buffer memory */ recvbuf = kmalloc(recvbuf_size, GFP_KERNEL); -- cgit v0.10.2 From 4773a47d8a564633cd80b94df397e91e946893e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 Dec 2009 20:31:56 -0800 Subject: can/at91: don't check platform_get_irq's return value against zero MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit platform_get_irq returns -ENXIO on failure, so !irq was probably always true. Better use (int)irq <= 0. Note that a return value of zero is still handled as error even though this could mean irq0. This is a followup to 305b3228f9ff4d59f49e6d34a7034d44ee8ce2f0 that changed the return value of platform_get_irq from 0 to -ENXIO on error. Signed-off-by: Uwe Kleine-König Signed-off-by: Wolfgang Grandegger Signed-off-by: David S. Miller diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c index d0ec178..166cc7e 100644 --- a/drivers/net/can/at91_can.c +++ b/drivers/net/can/at91_can.c @@ -1037,7 +1037,7 @@ static int __init at91_can_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_MEM, 0); irq = platform_get_irq(pdev, 0); - if (!res || !irq) { + if (!res || irq <= 0) { err = -ENODEV; goto exit_put; } -- cgit v0.10.2 From e6bf95ffa8d6f8f4b7ee33ea01490d95b0bbeb6e Mon Sep 17 00:00:00 2001 From: Breno Leitao Date: Fri, 18 Dec 2009 20:35:34 -0800 Subject: bnx2: fixing a timout error due not refreshing TX timers correctly When running the following script on an active bnx2 interface: while(true); do ifconfig ethX mtu 9000; ifconfig ethX mtu 1500; done A timeout error appears and dumps the following stack: NETDEV WATCHDOG: eth4 (bnx2): transmit queue 0 timed out ------------[ cut here ]------------ Badness at net/sched/sch_generic.c:261 This patch just fixes the way that ->trans_start is refreshed. Signed-off-by: Breno Leitao Acked-by: Michael Chan Signed-off-by: David S. Miller diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index c3e2b27..f38764e 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -654,9 +654,17 @@ bnx2_netif_stop(struct bnx2 *bp) { bnx2_cnic_stop(bp); if (netif_running(bp->dev)) { + int i; + bnx2_napi_disable(bp); netif_tx_disable(bp->dev); - bp->dev->trans_start = jiffies; /* prevent tx timeout */ + /* prevent tx timeout */ + for (i = 0; i < bp->dev->num_tx_queues; i++) { + struct netdev_queue *txq; + + txq = netdev_get_tx_queue(bp->dev, i); + txq->trans_start = jiffies; + } } } -- cgit v0.10.2 From 1ccb8389f26f2d513b06abe45d8e0b8f32458302 Mon Sep 17 00:00:00 2001 From: Sandeep Gopalpet Date: Wed, 16 Dec 2009 01:14:58 +0000 Subject: gianfar: Fix a filer bug We need to enable filer whenever we need to use multiple RX queues. Also, need to program RIR0 register with the required distribution we require, if using RX filer hashing support for packet distribution to multiple queues. Signed-off-by: Sandeep Gopalpet Signed-off-by: David S. Miller diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 6850dc0..1616531 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -357,8 +357,11 @@ static void gfar_init_mac(struct net_device *ndev) /* Configure the coalescing support */ gfar_configure_coalescing(priv, 0xFF, 0xFF); - if (priv->rx_filer_enable) + if (priv->rx_filer_enable) { rctrl |= RCTRL_FILREN; + /* Program the RIR0 reg with the required distribution */ + gfar_write(®s->rir0, DEFAULT_RIR0); + } if (priv->rx_csum_enable) rctrl |= RCTRL_CHECKSUMMING; @@ -1022,6 +1025,9 @@ static int gfar_probe(struct of_device *ofdev, priv->rx_queue[i]->rxic = DEFAULT_RXIC; } + /* enable filer if using multiple RX queues*/ + if(priv->num_rx_queues > 1) + priv->rx_filer_enable = 1; /* Enable most messages by default */ priv->msg_enable = (NETIF_MSG_IFUP << 1 ) - 1; diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h index cbb4510..68d16dc 100644 --- a/drivers/net/gianfar.h +++ b/drivers/net/gianfar.h @@ -401,6 +401,10 @@ extern const char gfar_driver_version[]; #define FPR_FILER_MASK 0xFFFFFFFF #define MAX_FILER_IDX 0xFF +/* This default RIR value directly corresponds + * to the 3-bit hash value generated */ +#define DEFAULT_RIR0 0x05397700 + /* RQFCR register bits */ #define RQFCR_GPI 0x80000000 #define RQFCR_HASHTBL_Q 0x00000000 -- cgit v0.10.2 From a7f38041b8c38d0721b042c123bd5d6bd2d21feb Mon Sep 17 00:00:00 2001 From: Sandeep Gopalpet Date: Wed, 16 Dec 2009 01:15:07 +0000 Subject: gianfar: Fix stats support This patch updates the per rx/tx queue stats. To update the per rx queue stats a new structure has been introduced rx_q_stats. The per tx queue stats are updated via the netdev_queue structure itself. Note that we update only the tx_packtes, tx_bytes, rx_packets, rx_bytes and rx_dropped stats on a per queue basis. Signed-off-by: Sandeep Gopalpet Signed-off-by: David S. Miller diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 1616531..e0620d0 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -417,6 +417,36 @@ static void gfar_init_mac(struct net_device *ndev) gfar_write(®s->fifo_tx_starve_shutoff, priv->fifo_starve_off); } +static struct net_device_stats *gfar_get_stats(struct net_device *dev) +{ + struct gfar_private *priv = netdev_priv(dev); + struct netdev_queue *txq; + unsigned long rx_packets = 0, rx_bytes = 0, rx_dropped = 0; + unsigned long tx_packets = 0, tx_bytes = 0; + int i = 0; + + for (i = 0; i < priv->num_rx_queues; i++) { + rx_packets += priv->rx_queue[i]->stats.rx_packets; + rx_bytes += priv->rx_queue[i]->stats.rx_bytes; + rx_dropped += priv->rx_queue[i]->stats.rx_dropped; + } + + dev->stats.rx_packets = rx_packets; + dev->stats.rx_bytes = rx_bytes; + dev->stats.rx_dropped = rx_dropped; + + for (i = 0; i < priv->num_tx_queues; i++) { + txq = netdev_get_tx_queue(dev, i); + tx_bytes += txq->tx_bytes; + tx_packets += txq->tx_packets; + } + + dev->stats.tx_bytes = tx_bytes; + dev->stats.tx_packets = tx_packets; + + return &dev->stats; +} + static const struct net_device_ops gfar_netdev_ops = { .ndo_open = gfar_enet_open, .ndo_start_xmit = gfar_start_xmit, @@ -426,6 +456,7 @@ static const struct net_device_ops gfar_netdev_ops = { .ndo_tx_timeout = gfar_timeout, .ndo_do_ioctl = gfar_ioctl, .ndo_select_queue = gfar_select_queue, + .ndo_get_stats = gfar_get_stats, .ndo_vlan_rx_register = gfar_vlan_rx_register, .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, @@ -1943,7 +1974,8 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) } /* Update transmit stats */ - dev->stats.tx_bytes += skb->len; + txq->tx_bytes += skb->len; + txq->tx_packets ++; txbdp = txbdp_start = tx_queue->cur_tx; @@ -2301,8 +2333,6 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue) tx_queue->skb_dirtytx = skb_dirtytx; tx_queue->dirty_tx = bdp; - dev->stats.tx_packets += howmany; - return howmany; } @@ -2516,14 +2546,14 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit) } } else { /* Increment the number of packets */ - dev->stats.rx_packets++; + rx_queue->stats.rx_packets++; howmany++; if (likely(skb)) { pkt_len = bdp->length - ETH_FCS_LEN; /* Remove the FCS from the packet length */ skb_put(skb, pkt_len); - dev->stats.rx_bytes += pkt_len; + rx_queue->stats.rx_bytes += pkt_len; gfar_process_frame(dev, skb, amount_pull); @@ -2531,7 +2561,7 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit) if (netif_msg_rx_err(priv)) printk(KERN_WARNING "%s: Missing skb!\n", dev->name); - dev->stats.rx_dropped++; + rx_queue->stats.rx_dropped++; priv->extra_stats.rx_skbmissing++; } diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h index 68d16dc..4943cbe 100644 --- a/drivers/net/gianfar.h +++ b/drivers/net/gianfar.h @@ -940,6 +940,15 @@ struct gfar_priv_tx_q { unsigned short txtime; }; +/* + * Per RX queue stats + */ +struct rx_q_stats { + unsigned long rx_packets; + unsigned long rx_bytes; + unsigned long rx_dropped; +}; + /** * struct gfar_priv_rx_q - per rx queue structure * @rxlock: per queue rx spin lock @@ -962,6 +971,7 @@ struct gfar_priv_rx_q { struct rxbd8 *cur_rx; struct net_device *dev; struct gfar_priv_grp *grp; + struct rx_q_stats stats; u16 skb_currx; u16 qindex; unsigned int rx_ring_size; -- cgit v0.10.2 From 7c65ec7958f4f301d5d2ff50476a21e7735c73e8 Mon Sep 17 00:00:00 2001 From: Sandeep Gopalpet Date: Wed, 16 Dec 2009 01:15:17 +0000 Subject: gianfar: Fix bit definitions of IMASK_GRSC and IMASK_GTSC Signed-off-by: Sandeep Gopalpet Signed-off-by: David S. Miller diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h index 4943cbe..3d72dc4 100644 --- a/drivers/net/gianfar.h +++ b/drivers/net/gianfar.h @@ -333,7 +333,7 @@ extern const char gfar_driver_version[]; #define IMASK_BSY 0x20000000 #define IMASK_EBERR 0x10000000 #define IMASK_MSRO 0x04000000 -#define IMASK_GRSC 0x02000000 +#define IMASK_GTSC 0x02000000 #define IMASK_BABT 0x01000000 #define IMASK_TXC 0x00800000 #define IMASK_TXEEN 0x00400000 @@ -344,7 +344,7 @@ extern const char gfar_driver_version[]; #define IMASK_XFUN 0x00010000 #define IMASK_RXB0 0x00008000 #define IMASK_MAG 0x00000800 -#define IMASK_GTSC 0x00000100 +#define IMASK_GRSC 0x00000100 #define IMASK_RXFEN0 0x00000080 #define IMASK_FIR 0x00000008 #define IMASK_FIQ 0x00000004 -- cgit v0.10.2 From ef86f581f7e8b29cb58d7f4e892e1a91b3805124 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 19 Dec 2009 08:18:03 +0100 Subject: ALSA: Use kzalloc for allocating only one thing Use kzalloc rather than kcalloc(1,...) The semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ @@ - kcalloc(1, + kzalloc( ...) // Signed-off-by: Julia Lawall Signed-off-by: Takashi Iwai diff --git a/sound/isa/msnd/msnd_midi.c b/sound/isa/msnd/msnd_midi.c index cb9aa4c..4be562b 100644 --- a/sound/isa/msnd/msnd_midi.c +++ b/sound/isa/msnd/msnd_midi.c @@ -162,7 +162,7 @@ int snd_msndmidi_new(struct snd_card *card, int device) err = snd_rawmidi_new(card, "MSND-MIDI", device, 1, 1, &rmidi); if (err < 0) return err; - mpu = kcalloc(1, sizeof(*mpu), GFP_KERNEL); + mpu = kzalloc(sizeof(*mpu), GFP_KERNEL); if (mpu == NULL) { snd_device_free(card, rmidi); return -ENOMEM; diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index aeed4cc..20c1828 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -12857,7 +12857,7 @@ static int patch_alc268(struct hda_codec *codec) int board_config; int i, has_beep, err; - spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); + spec = kzalloc(sizeof(*spec), GFP_KERNEL); if (spec == NULL) return -ENOMEM; -- cgit v0.10.2 From 6f5d51148921c242680a7a1d9913384a30ab3cbe Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 19 Dec 2009 15:59:45 +0000 Subject: fix braindamage in audit_tree.c untag_chunk() ... aka "Al had badly fscked up when writing that thing and nobody noticed until Eric had fixed leaks that used to mask the breakage". The function essentially creates a copy of old array sans one element and replaces the references to elements of original (they are on cyclic lists) with those to corresponding elements of new one. After that the old one is fair game for freeing. First of all, there's a dumb braino: when we get to list_replace_init we use indices for wrong arrays - position in new one with the old array and vice versa. Another bug is more subtle - termination condition is wrong if the element to be excluded happens to be the last one. We shouldn't go until we fill the new array, we should go until we'd finished the old one. Otherwise the element we are trying to kill will remain on the cyclic lists... That crap used to be masked by several leaks, so it was not quite trivial to hit. Eric had fixed some of those leaks a while ago and the shit had hit the fan... Signed-off-by: Al Viro Signed-off-by: Linus Torvalds diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c index 2451dc6..b36aa96 100644 --- a/kernel/audit_tree.c +++ b/kernel/audit_tree.c @@ -277,7 +277,7 @@ static void untag_chunk(struct node *p) owner->root = NULL; } - for (i = j = 0; i < size; i++, j++) { + for (i = j = 0; j <= size; i++, j++) { struct audit_tree *s; if (&chunk->owners[j] == p) { list_del_init(&p->list); @@ -290,7 +290,7 @@ static void untag_chunk(struct node *p) if (!s) /* result of earlier fallback */ continue; get_tree(s); - list_replace_init(&chunk->owners[i].list, &new->owners[j].list); + list_replace_init(&chunk->owners[j].list, &new->owners[i].list); } list_replace_rcu(&chunk->hash, &new->hash); -- cgit v0.10.2 From b4c30aad39805902cf5b855aa8a8b22d728ad057 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 19 Dec 2009 16:03:30 +0000 Subject: fix more leaks in audit_tree.c tag_chunk() Several leaks in audit_tree didn't get caught by commit 318b6d3d7ddbcad3d6867e630711b8a705d873d7, including the leak on normal exit in case of multiple rules refering to the same chunk. Signed-off-by: Al Viro Signed-off-by: Linus Torvalds diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c index b36aa96..4b05bd9 100644 --- a/kernel/audit_tree.c +++ b/kernel/audit_tree.c @@ -373,15 +373,17 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree) for (n = 0; n < old->count; n++) { if (old->owners[n].owner == tree) { spin_unlock(&hash_lock); - put_inotify_watch(watch); + put_inotify_watch(&old->watch); return 0; } } spin_unlock(&hash_lock); chunk = alloc_chunk(old->count + 1); - if (!chunk) + if (!chunk) { + put_inotify_watch(&old->watch); return -ENOMEM; + } mutex_lock(&inode->inotify_mutex); if (inotify_clone_watch(&old->watch, &chunk->watch) < 0) { @@ -425,7 +427,8 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree) spin_unlock(&hash_lock); inotify_evict_watch(&old->watch); mutex_unlock(&inode->inotify_mutex); - put_inotify_watch(&old->watch); + put_inotify_watch(&old->watch); /* pair to inotify_find_watch */ + put_inotify_watch(&old->watch); /* and kill it */ return 0; } -- cgit v0.10.2 From a6d52d70677e99bdb89b6921c265d0a58c22e597 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sat, 19 Dec 2009 15:36:02 -0700 Subject: ioat2,3: put channel hardware in known state at init Put the ioat2 and ioat3 state machines in the halted state with all errors cleared. The ioat1 init path is not disturbed for stability, there are no reported ioat1 initiaization issues. Cc: Reported-by: Roland Dreier Tested-by: Roland Dreier Acked-by: Simon Horman Signed-off-by: Dan Williams diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c index c524d36..dcc4ab7 100644 --- a/drivers/dma/ioat/dma.c +++ b/drivers/dma/ioat/dma.c @@ -1032,7 +1032,7 @@ int __devinit ioat_probe(struct ioatdma_device *device) dma->dev = &pdev->dev; if (!dma->chancnt) { - dev_err(dev, "zero channels detected\n"); + dev_err(dev, "channel enumeration error\n"); goto err_setup_interrupts; } diff --git a/drivers/dma/ioat/dma.h b/drivers/dma/ioat/dma.h index 45edde9..bbc3e78 100644 --- a/drivers/dma/ioat/dma.h +++ b/drivers/dma/ioat/dma.h @@ -60,6 +60,7 @@ * @dca: direct cache access context * @intr_quirk: interrupt setup quirk (for ioat_v1 devices) * @enumerate_channels: hw version specific channel enumeration + * @reset_hw: hw version specific channel (re)initialization * @cleanup_tasklet: select between the v2 and v3 cleanup routines * @timer_fn: select between the v2 and v3 timer watchdog routines * @self_test: hardware version specific self test for each supported op type @@ -78,6 +79,7 @@ struct ioatdma_device { struct dca_provider *dca; void (*intr_quirk)(struct ioatdma_device *device); int (*enumerate_channels)(struct ioatdma_device *device); + int (*reset_hw)(struct ioat_chan_common *chan); void (*cleanup_tasklet)(unsigned long data); void (*timer_fn)(unsigned long data); int (*self_test)(struct ioatdma_device *device); @@ -264,6 +266,22 @@ static inline void ioat_suspend(struct ioat_chan_common *chan) writeb(IOAT_CHANCMD_SUSPEND, chan->reg_base + IOAT_CHANCMD_OFFSET(ver)); } +static inline void ioat_reset(struct ioat_chan_common *chan) +{ + u8 ver = chan->device->version; + + writeb(IOAT_CHANCMD_RESET, chan->reg_base + IOAT_CHANCMD_OFFSET(ver)); +} + +static inline bool ioat_reset_pending(struct ioat_chan_common *chan) +{ + u8 ver = chan->device->version; + u8 cmd; + + cmd = readb(chan->reg_base + IOAT_CHANCMD_OFFSET(ver)); + return (cmd & IOAT_CHANCMD_RESET) == IOAT_CHANCMD_RESET; +} + static inline void ioat_set_chainaddr(struct ioat_dma_chan *ioat, u64 addr) { struct ioat_chan_common *chan = &ioat->base; diff --git a/drivers/dma/ioat/dma_v2.c b/drivers/dma/ioat/dma_v2.c index 8f1f7f0..5f7a500 100644 --- a/drivers/dma/ioat/dma_v2.c +++ b/drivers/dma/ioat/dma_v2.c @@ -239,20 +239,50 @@ void __ioat2_restart_chan(struct ioat2_dma_chan *ioat) __ioat2_start_null_desc(ioat); } -static void ioat2_restart_channel(struct ioat2_dma_chan *ioat) +int ioat2_quiesce(struct ioat_chan_common *chan, unsigned long tmo) { - struct ioat_chan_common *chan = &ioat->base; - unsigned long phys_complete; + unsigned long end = jiffies + tmo; + int err = 0; u32 status; status = ioat_chansts(chan); if (is_ioat_active(status) || is_ioat_idle(status)) ioat_suspend(chan); while (is_ioat_active(status) || is_ioat_idle(status)) { + if (end && time_after(jiffies, end)) { + err = -ETIMEDOUT; + break; + } status = ioat_chansts(chan); cpu_relax(); } + return err; +} + +int ioat2_reset_sync(struct ioat_chan_common *chan, unsigned long tmo) +{ + unsigned long end = jiffies + tmo; + int err = 0; + + ioat_reset(chan); + while (ioat_reset_pending(chan)) { + if (end && time_after(jiffies, end)) { + err = -ETIMEDOUT; + break; + } + cpu_relax(); + } + + return err; +} + +static void ioat2_restart_channel(struct ioat2_dma_chan *ioat) +{ + struct ioat_chan_common *chan = &ioat->base; + unsigned long phys_complete; + + ioat2_quiesce(chan, 0); if (ioat_cleanup_preamble(chan, &phys_complete)) __cleanup(ioat, phys_complete); @@ -318,6 +348,19 @@ void ioat2_timer_event(unsigned long data) spin_unlock_bh(&chan->cleanup_lock); } +static int ioat2_reset_hw(struct ioat_chan_common *chan) +{ + /* throw away whatever the channel was doing and get it initialized */ + u32 chanerr; + + ioat2_quiesce(chan, msecs_to_jiffies(100)); + + chanerr = readl(chan->reg_base + IOAT_CHANERR_OFFSET); + writel(chanerr, chan->reg_base + IOAT_CHANERR_OFFSET); + + return ioat2_reset_sync(chan, msecs_to_jiffies(200)); +} + /** * ioat2_enumerate_channels - find and initialize the device's channels * @device: the device to be enumerated @@ -360,6 +403,10 @@ int ioat2_enumerate_channels(struct ioatdma_device *device) (unsigned long) ioat); ioat->xfercap_log = xfercap_log; spin_lock_init(&ioat->ring_lock); + if (device->reset_hw(&ioat->base)) { + i = 0; + break; + } } dma->chancnt = i; return i; @@ -467,7 +514,6 @@ int ioat2_alloc_chan_resources(struct dma_chan *c) struct ioat2_dma_chan *ioat = to_ioat2_chan(c); struct ioat_chan_common *chan = &ioat->base; struct ioat_ring_ent **ring; - u32 chanerr; int order; /* have we already been set up? */ @@ -477,12 +523,6 @@ int ioat2_alloc_chan_resources(struct dma_chan *c) /* Setup register to interrupt and write completion status on error */ writew(IOAT_CHANCTRL_RUN, chan->reg_base + IOAT_CHANCTRL_OFFSET); - chanerr = readl(chan->reg_base + IOAT_CHANERR_OFFSET); - if (chanerr) { - dev_err(to_dev(chan), "CHANERR = %x, clearing\n", chanerr); - writel(chanerr, chan->reg_base + IOAT_CHANERR_OFFSET); - } - /* allocate a completion writeback area */ /* doing 2 32bit writes to mmio since 1 64b write doesn't work */ chan->completion = pci_pool_alloc(chan->device->completion_pool, @@ -746,13 +786,7 @@ void ioat2_free_chan_resources(struct dma_chan *c) tasklet_disable(&chan->cleanup_task); del_timer_sync(&chan->timer); device->cleanup_tasklet((unsigned long) ioat); - - /* Delay 100ms after reset to allow internal DMA logic to quiesce - * before removing DMA descriptor resources. - */ - writeb(IOAT_CHANCMD_RESET, - chan->reg_base + IOAT_CHANCMD_OFFSET(chan->device->version)); - mdelay(100); + device->reset_hw(chan); spin_lock_bh(&ioat->ring_lock); descs = ioat2_ring_space(ioat); @@ -839,6 +873,7 @@ int __devinit ioat2_dma_probe(struct ioatdma_device *device, int dca) int err; device->enumerate_channels = ioat2_enumerate_channels; + device->reset_hw = ioat2_reset_hw; device->cleanup_tasklet = ioat2_cleanup_tasklet; device->timer_fn = ioat2_timer_event; device->self_test = ioat_dma_self_test; diff --git a/drivers/dma/ioat/dma_v2.h b/drivers/dma/ioat/dma_v2.h index 1d849ef..3afad8d 100644 --- a/drivers/dma/ioat/dma_v2.h +++ b/drivers/dma/ioat/dma_v2.h @@ -185,6 +185,8 @@ bool reshape_ring(struct ioat2_dma_chan *ioat, int order); void __ioat2_issue_pending(struct ioat2_dma_chan *ioat); void ioat2_cleanup_tasklet(unsigned long data); void ioat2_timer_event(unsigned long data); +int ioat2_quiesce(struct ioat_chan_common *chan, unsigned long tmo); +int ioat2_reset_sync(struct ioat_chan_common *chan, unsigned long tmo); extern struct kobj_type ioat2_ktype; extern struct kmem_cache *ioat2_cache; #endif /* IOATDMA_V2_H */ diff --git a/drivers/dma/ioat/dma_v3.c b/drivers/dma/ioat/dma_v3.c index e58ecb2..9908c9e 100644 --- a/drivers/dma/ioat/dma_v3.c +++ b/drivers/dma/ioat/dma_v3.c @@ -1130,6 +1130,45 @@ static int __devinit ioat3_dma_self_test(struct ioatdma_device *device) return 0; } +static int ioat3_reset_hw(struct ioat_chan_common *chan) +{ + /* throw away whatever the channel was doing and get it + * initialized, with ioat3 specific workarounds + */ + struct ioatdma_device *device = chan->device; + struct pci_dev *pdev = device->pdev; + u32 chanerr; + u16 dev_id; + int err; + + ioat2_quiesce(chan, msecs_to_jiffies(100)); + + chanerr = readl(chan->reg_base + IOAT_CHANERR_OFFSET); + writel(chanerr, chan->reg_base + IOAT_CHANERR_OFFSET); + + /* -= IOAT ver.3 workarounds =- */ + /* Write CHANERRMSK_INT with 3E07h to mask out the errors + * that can cause stability issues for IOAT ver.3, and clear any + * pending errors + */ + pci_write_config_dword(pdev, IOAT_PCI_CHANERRMASK_INT_OFFSET, 0x3e07); + err = pci_read_config_dword(pdev, IOAT_PCI_CHANERR_INT_OFFSET, &chanerr); + if (err) { + dev_err(&pdev->dev, "channel error register unreachable\n"); + return err; + } + pci_write_config_dword(pdev, IOAT_PCI_CHANERR_INT_OFFSET, chanerr); + + /* Clear DMAUNCERRSTS Cfg-Reg Parity Error status bit + * (workaround for spurious config parity error after restart) + */ + pci_read_config_word(pdev, IOAT_PCI_DEVICE_ID_OFFSET, &dev_id); + if (dev_id == PCI_DEVICE_ID_INTEL_IOAT_TBG0) + pci_write_config_dword(pdev, IOAT_PCI_DMAUNCERRSTS_OFFSET, 0x10); + + return ioat2_reset_sync(chan, msecs_to_jiffies(200)); +} + int __devinit ioat3_dma_probe(struct ioatdma_device *device, int dca) { struct pci_dev *pdev = device->pdev; @@ -1139,10 +1178,10 @@ int __devinit ioat3_dma_probe(struct ioatdma_device *device, int dca) struct ioat_chan_common *chan; bool is_raid_device = false; int err; - u16 dev_id; u32 cap; device->enumerate_channels = ioat2_enumerate_channels; + device->reset_hw = ioat3_reset_hw; device->self_test = ioat3_dma_self_test; dma = &device->common; dma->device_prep_dma_memcpy = ioat2_dma_prep_memcpy_lock; @@ -1218,19 +1257,6 @@ int __devinit ioat3_dma_probe(struct ioatdma_device *device, int dca) dma->device_prep_dma_xor_val = NULL; #endif - /* -= IOAT ver.3 workarounds =- */ - /* Write CHANERRMSK_INT with 3E07h to mask out the errors - * that can cause stability issues for IOAT ver.3 - */ - pci_write_config_dword(pdev, IOAT_PCI_CHANERRMASK_INT_OFFSET, 0x3e07); - - /* Clear DMAUNCERRSTS Cfg-Reg Parity Error status bit - * (workaround for spurious config parity error after restart) - */ - pci_read_config_word(pdev, IOAT_PCI_DEVICE_ID_OFFSET, &dev_id); - if (dev_id == PCI_DEVICE_ID_INTEL_IOAT_TBG0) - pci_write_config_dword(pdev, IOAT_PCI_DMAUNCERRSTS_OFFSET, 0x10); - err = ioat_probe(device); if (err) return err; diff --git a/drivers/dma/ioat/registers.h b/drivers/dma/ioat/registers.h index f015ec1..e8ae63b 100644 --- a/drivers/dma/ioat/registers.h +++ b/drivers/dma/ioat/registers.h @@ -27,6 +27,7 @@ #define IOAT_PCI_DEVICE_ID_OFFSET 0x02 #define IOAT_PCI_DMAUNCERRSTS_OFFSET 0x148 +#define IOAT_PCI_CHANERR_INT_OFFSET 0x180 #define IOAT_PCI_CHANERRMASK_INT_OFFSET 0x184 /* MMIO Device Registers */ -- cgit v0.10.2 From cdd90fb575807622e69245d5c3048281f47c77b3 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 19 Dec 2009 23:36:00 +0000 Subject: ARM: add missing include to nwflash.c nwflash needs jiffie definitions. Signed-off-by: Russell King diff --git a/drivers/char/nwflash.c b/drivers/char/nwflash.c index 8c7df5b..f808109 100644 --- a/drivers/char/nwflash.c +++ b/drivers/char/nwflash.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include -- cgit v0.10.2 From 360b6e5cab1cea1d838b0100956ce0d3dbccbb6f Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 18 Dec 2009 15:16:56 -0800 Subject: Documentation: Update mmiotrace.txt Fix typos, spellos, hyphenation, line lengths. BTW: are there some userspace tools? There is a reference to some at the wiki page, but there are no tools listed there. Signed-off-by: Randy Dunlap Acked-by: Pekka Paalanen LKML-Reference: <4B2C0D68.6080401@oracle.com> Signed-off-by: Ingo Molnar diff --git a/Documentation/trace/mmiotrace.txt b/Documentation/trace/mmiotrace.txt index 162effb..664e738 100644 --- a/Documentation/trace/mmiotrace.txt +++ b/Documentation/trace/mmiotrace.txt @@ -44,7 +44,8 @@ Check for lost events. Usage ----- -Make sure debugfs is mounted to /sys/kernel/debug. If not, (requires root privileges) +Make sure debugfs is mounted to /sys/kernel/debug. +If not (requires root privileges): $ mount -t debugfs debugfs /sys/kernel/debug Check that the driver you are about to trace is not loaded. @@ -91,7 +92,7 @@ $ dmesg > dmesg.txt $ tar zcf pciid-nick-mmiotrace.tar.gz mydump.txt lspci.txt dmesg.txt and then send the .tar.gz file. The trace compresses considerably. Replace "pciid" and "nick" with the PCI ID or model name of your piece of hardware -under investigation and your nick name. +under investigation and your nickname. How Mmiotrace Works @@ -100,7 +101,7 @@ How Mmiotrace Works Access to hardware IO-memory is gained by mapping addresses from PCI bus by calling one of the ioremap_*() functions. Mmiotrace is hooked into the __ioremap() function and gets called whenever a mapping is created. Mapping is -an event that is recorded into the trace log. Note, that ISA range mappings +an event that is recorded into the trace log. Note that ISA range mappings are not caught, since the mapping always exists and is returned directly. MMIO accesses are recorded via page faults. Just before __ioremap() returns, @@ -122,11 +123,11 @@ Trace Log Format ---------------- The raw log is text and easily filtered with e.g. grep and awk. One record is -one line in the log. A record starts with a keyword, followed by keyword -dependant arguments. Arguments are separated by a space, or continue until the +one line in the log. A record starts with a keyword, followed by keyword- +dependent arguments. Arguments are separated by a space, or continue until the end of line. The format for version 20070824 is as follows: -Explanation Keyword Space separated arguments +Explanation Keyword Space-separated arguments --------------------------------------------------------------------------- read event R width, timestamp, map id, physical, value, PC, PID @@ -136,7 +137,7 @@ iounmap event UNMAP timestamp, map id, PC, PID marker MARK timestamp, text version VERSION the string "20070824" info for reader LSPCI one line from lspci -v -PCI address map PCIDEV space separated /proc/bus/pci/devices data +PCI address map PCIDEV space-separated /proc/bus/pci/devices data unk. opcode UNKNOWN timestamp, map id, physical, data, PC, PID Timestamp is in seconds with decimals. Physical is a PCI bus address, virtual -- cgit v0.10.2 From b41df645c829d961068aecd30909c2675acbaaea Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 18 Dec 2009 15:17:04 -0800 Subject: Documentation: Update tracepoint-analysis.txt Fix grammar, spelling, punctuation, hyphenation, section numbering. Tell what PCL means. Signed-off-by: Randy Dunlap Cc: Mel Gorman Cc: Steven Rostedt LKML-Reference: <4B2C0D70.4030707@oracle.com> Signed-off-by: Ingo Molnar diff --git a/Documentation/trace/tracepoint-analysis.txt b/Documentation/trace/tracepoint-analysis.txt index 5eb4e487..87bee3c 100644 --- a/Documentation/trace/tracepoint-analysis.txt +++ b/Documentation/trace/tracepoint-analysis.txt @@ -10,8 +10,8 @@ Tracepoints (see Documentation/trace/tracepoints.txt) can be used without creating custom kernel modules to register probe functions using the event tracing infrastructure. -Simplistically, tracepoints will represent an important event that when can -be taken in conjunction with other tracepoints to build a "Big Picture" of +Simplistically, tracepoints represent important events that can be +taken in conjunction with other tracepoints to build a "Big Picture" of what is going on within the system. There are a large number of methods for gathering and interpreting these events. Lacking any current Best Practises, this document describes some of the methods that can be used. @@ -33,12 +33,12 @@ calling will give a fair indication of the number of events available. -2.2 PCL +2.2 PCL (Performance Counters for Linux) ------- -Discovery and enumeration of all counters and events, including tracepoints +Discovery and enumeration of all counters and events, including tracepoints, are available with the perf tool. Getting a list of available events is a -simple case of +simple case of: $ perf list 2>&1 | grep Tracepoint ext4:ext4_free_inode [Tracepoint event] @@ -49,19 +49,19 @@ simple case of [ .... remaining output snipped .... ] -2. Enabling Events +3. Enabling Events ================== -2.1 System-Wide Event Enabling +3.1 System-Wide Event Enabling ------------------------------ See Documentation/trace/events.txt for a proper description on how events can be enabled system-wide. A short example of enabling all events related -to page allocation would look something like +to page allocation would look something like: $ for i in `find /sys/kernel/debug/tracing/events -name "enable" | grep mm_`; do echo 1 > $i; done -2.2 System-Wide Event Enabling with SystemTap +3.2 System-Wide Event Enabling with SystemTap --------------------------------------------- In SystemTap, tracepoints are accessible using the kernel.trace() function @@ -86,7 +86,7 @@ were allocating the pages. print_count() } -2.3 System-Wide Event Enabling with PCL +3.3 System-Wide Event Enabling with PCL --------------------------------------- By specifying the -a switch and analysing sleep, the system-wide events @@ -107,16 +107,16 @@ for a duration of time can be examined. Similarly, one could execute a shell and exit it as desired to get a report at that point. -2.4 Local Event Enabling +3.4 Local Event Enabling ------------------------ Documentation/trace/ftrace.txt describes how to enable events on a per-thread basis using set_ftrace_pid. -2.5 Local Event Enablement with PCL +3.5 Local Event Enablement with PCL ----------------------------------- -Events can be activate and tracked for the duration of a process on a local +Events can be activated and tracked for the duration of a process on a local basis using PCL such as follows. $ perf stat -e kmem:mm_page_alloc -e kmem:mm_page_free_direct \ @@ -131,18 +131,18 @@ basis using PCL such as follows. 0.973913387 seconds time elapsed -3. Event Filtering +4. Event Filtering ================== Documentation/trace/ftrace.txt covers in-depth how to filter events in ftrace. Obviously using grep and awk of trace_pipe is an option as well as any script reading trace_pipe. -4. Analysing Event Variances with PCL +5. Analysing Event Variances with PCL ===================================== Any workload can exhibit variances between runs and it can be important -to know what the standard deviation in. By and large, this is left to the +to know what the standard deviation is. By and large, this is left to the performance analyst to do it by hand. In the event that the discrete event occurrences are useful to the performance analyst, then perf can be used. @@ -166,7 +166,7 @@ In the event that some higher-level event is required that depends on some aggregation of discrete events, then a script would need to be developed. Using --repeat, it is also possible to view how events are fluctuating over -time on a system wide basis using -a and sleep. +time on a system-wide basis using -a and sleep. $ perf stat -e kmem:mm_page_alloc -e kmem:mm_page_free_direct \ -e kmem:mm_pagevec_free \ @@ -180,7 +180,7 @@ time on a system wide basis using -a and sleep. 1.002251757 seconds time elapsed ( +- 0.005% ) -5. Higher-Level Analysis with Helper Scripts +6. Higher-Level Analysis with Helper Scripts ============================================ When events are enabled the events that are triggering can be read from @@ -190,11 +190,11 @@ be gathered on-line as appropriate. Examples of post-processing might include o Reading information from /proc for the PID that triggered the event o Deriving a higher-level event from a series of lower-level events. - o Calculate latencies between two events + o Calculating latencies between two events Documentation/trace/postprocess/trace-pagealloc-postprocess.pl is an example script that can read trace_pipe from STDIN or a copy of a trace. When used -on-line, it can be interrupted once to generate a report without existing +on-line, it can be interrupted once to generate a report without exiting and twice to exit. Simplistically, the script just reads STDIN and counts up events but it @@ -212,12 +212,12 @@ also can do more such as processes, the parent process responsible for creating all the helpers can be identified -6. Lower-Level Analysis with PCL +7. Lower-Level Analysis with PCL ================================ -There may also be a requirement to identify what functions with a program +There may also be a requirement to identify what functions within a program were generating events within the kernel. To begin this sort of analysis, the -data must be recorded. At the time of writing, this required root +data must be recorded. At the time of writing, this required root: $ perf record -c 1 \ -e kmem:mm_page_alloc -e kmem:mm_page_free_direct \ @@ -253,11 +253,11 @@ perf report. # (For more details, try: perf report --sort comm,dso,symbol) # -According to this, the vast majority of events occured triggered on events -within the VDSO. With simple binaries, this will often be the case so lets +According to this, the vast majority of events triggered on events +within the VDSO. With simple binaries, this will often be the case so let's take a slightly different example. In the course of writing this, it was -noticed that X was generating an insane amount of page allocations so lets look -at it +noticed that X was generating an insane amount of page allocations so let's look +at it: $ perf record -c 1 -f \ -e kmem:mm_page_alloc -e kmem:mm_page_free_direct \ @@ -280,8 +280,8 @@ This was interrupted after a few seconds and # (For more details, try: perf report --sort comm,dso,symbol) # -So, almost half of the events are occuring in a library. To get an idea which -symbol. +So, almost half of the events are occurring in a library. To get an idea which +symbol: $ perf report --sort comm,dso,symbol # Samples: 27666 @@ -297,7 +297,7 @@ symbol. 0.01% Xorg /opt/gfx-test/lib/libpixman-1.so.0.13.1 [.] get_fast_path 0.00% Xorg [kernel] [k] ftrace_trace_userstack -To see where within the function pixmanFillsse2 things are going wrong +To see where within the function pixmanFillsse2 things are going wrong: $ perf annotate pixmanFillsse2 [ ... ] -- cgit v0.10.2 From 7e25f44cbf8d95a9748fdfd19c06145f19fd10e3 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 18 Dec 2009 15:17:12 -0800 Subject: Documentation: Update ftrace-design.txt Correct grammos. Spell out words. Add missing words. Consistent use of "mcount()" function name. Signed-off-by: Randy Dunlap Acked-by: Steven Rostedt LKML-Reference: <4B2C0D78.6060707@oracle.com> Signed-off-by: Ingo Molnar diff --git a/Documentation/trace/ftrace-design.txt b/Documentation/trace/ftrace-design.txt index 641a1ef..239f14b 100644 --- a/Documentation/trace/ftrace-design.txt +++ b/Documentation/trace/ftrace-design.txt @@ -53,14 +53,14 @@ size of the mcount call that is embedded in the function). For example, if the function foo() calls bar(), when the bar() function calls mcount(), the arguments mcount() will pass to the tracer are: "frompc" - the address bar() will use to return to foo() - "selfpc" - the address bar() (with _mcount() size adjustment) + "selfpc" - the address bar() (with mcount() size adjustment) Also keep in mind that this mcount function will be called *a lot*, so optimizing for the default case of no tracer will help the smooth running of your system when tracing is disabled. So the start of the mcount function is -typically the bare min with checking things before returning. That also means -the code flow should usually kept linear (i.e. no branching in the nop case). -This is of course an optimization and not a hard requirement. +typically the bare minimum with checking things before returning. That also +means the code flow should usually be kept linear (i.e. no branching in the nop +case). This is of course an optimization and not a hard requirement. Here is some pseudo code that should help (these functions should actually be implemented in assembly): @@ -131,10 +131,10 @@ some functions to save (hijack) and restore the return address. The mcount function should check the function pointers ftrace_graph_return (compare to ftrace_stub) and ftrace_graph_entry (compare to -ftrace_graph_entry_stub). If either of those are not set to the relevant stub +ftrace_graph_entry_stub). If either of those is not set to the relevant stub function, call the arch-specific function ftrace_graph_caller which in turn calls the arch-specific function prepare_ftrace_return. Neither of these -function names are strictly required, but you should use them anyways to stay +function names is strictly required, but you should use them anyway to stay consistent across the architecture ports -- easier to compare & contrast things. @@ -144,7 +144,7 @@ but the first argument should be a pointer to the "frompc". Typically this is located on the stack. This allows the function to hijack the return address temporarily to have it point to the arch-specific function return_to_handler. That function will simply call the common ftrace_return_to_handler function and -that will return the original return address with which, you can return to the +that will return the original return address with which you can return to the original call site. Here is the updated mcount pseudo code: -- cgit v0.10.2 From 440b004cf953bec2bc8cd91c64ae707fd7e25327 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Sun, 20 Dec 2009 12:04:08 +0100 Subject: ALSA: hda/realtek: Remove extra .capsrc_nids initialization for ALC889_INTEL Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 8b37577..2d3f4f8 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -9238,8 +9238,6 @@ static struct alc_config_preset alc882_presets[] = { .dac_nids = alc883_dac_nids, .num_adc_nids = ARRAY_SIZE(alc889_adc_nids), .adc_nids = alc889_adc_nids, - .capsrc_nids = alc889_capsrc_nids, - .capsrc_nids = alc889_capsrc_nids, .dig_out_nid = ALC883_DIGOUT_NID, .dig_in_nid = ALC883_DIGIN_NID, .slave_dig_outs = alc883_slave_dig_outs, -- cgit v0.10.2 From f69ac2f5a36948e1adf071074414c5d1907b89b7 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Fri, 18 Dec 2009 16:31:34 -0500 Subject: nfsd: fix "insecure" export option A typo in 12045a6ee9908b "nfsd: let "insecure" flag vary by pseudoflavor" reversed the sense of the "insecure" flag. Reported-by: Michael Guntsche Signed-off-by: J. Bruce Fields diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index 1c12177..55c8e63 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c @@ -89,7 +89,7 @@ static __be32 nfsd_setuser_and_check_port(struct svc_rqst *rqstp, int flags = nfsexp_flags(rqstp, exp); /* Check if the request originated from a secure port. */ - if (!rqstp->rq_secure && (flags & NFSEXP_INSECURE_PORT)) { + if (!rqstp->rq_secure && !(flags & NFSEXP_INSECURE_PORT)) { RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]); dprintk(KERN_WARNING "nfsd: request from insecure port %s!\n", -- cgit v0.10.2 From 3df0fc5b2e9d8092dcaeb5ae0b6753d85c851d66 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Sun, 20 Dec 2009 14:23:57 +0100 Subject: sched: Restore printk sanity Revert the braindead pr_* crap. (Commit 663997d "sched: Use pr_fmt() and pr_()") It's dumb and causes stupid "sched: " strings all over the place. Signed-off-by: Peter Zijlstra Acked-by: Mike Galbraith Cc: Joe Perches Cc: Linus Torvalds Cc: Andrew Morton LKML-Reference: <1261315437.4314.6.camel@laptop> [ i dont mind the pr_*() patterns that much - but Peter dislikes them with a vengence. ] [ - v2: remove spurious diffstat from changelog :-/ ] Signed-off-by: Ingo Molnar diff --git a/kernel/sched.c b/kernel/sched.c index 720df108..7ffde2a 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -26,8 +26,6 @@ * Thomas Gleixner, Mike Kravetz */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -5375,8 +5373,8 @@ static noinline void __schedule_bug(struct task_struct *prev) { struct pt_regs *regs = get_irq_regs(); - pr_err("BUG: scheduling while atomic: %s/%d/0x%08x\n", - prev->comm, prev->pid, preempt_count()); + printk(KERN_ERR "BUG: scheduling while atomic: %s/%d/0x%08x\n", + prev->comm, prev->pid, preempt_count()); debug_show_held_locks(prev); print_modules(); @@ -6940,23 +6938,23 @@ void sched_show_task(struct task_struct *p) unsigned state; state = p->state ? __ffs(p->state) + 1 : 0; - pr_info("%-13.13s %c", p->comm, + printk(KERN_INFO "%-13.13s %c", p->comm, state < sizeof(stat_nam) - 1 ? stat_nam[state] : '?'); #if BITS_PER_LONG == 32 if (state == TASK_RUNNING) - pr_cont(" running "); + printk(KERN_CONT " running "); else - pr_cont(" %08lx ", thread_saved_pc(p)); + printk(KERN_CONT " %08lx ", thread_saved_pc(p)); #else if (state == TASK_RUNNING) - pr_cont(" running task "); + printk(KERN_CONT " running task "); else - pr_cont(" %016lx ", thread_saved_pc(p)); + printk(KERN_CONT " %016lx ", thread_saved_pc(p)); #endif #ifdef CONFIG_DEBUG_STACK_USAGE free = stack_not_used(p); #endif - pr_cont("%5lu %5d %6d 0x%08lx\n", free, + printk(KERN_CONT "%5lu %5d %6d 0x%08lx\n", free, task_pid_nr(p), task_pid_nr(p->real_parent), (unsigned long)task_thread_info(p)->flags); @@ -6968,9 +6966,11 @@ void show_state_filter(unsigned long state_filter) struct task_struct *g, *p; #if BITS_PER_LONG == 32 - pr_info(" task PC stack pid father\n"); + printk(KERN_INFO + " task PC stack pid father\n"); #else - pr_info(" task PC stack pid father\n"); + printk(KERN_INFO + " task PC stack pid father\n"); #endif read_lock(&tasklist_lock); do_each_thread(g, p) { @@ -7828,44 +7828,48 @@ static int sched_domain_debug_one(struct sched_domain *sd, int cpu, int level, printk(KERN_DEBUG "%*s domain %d: ", level, "", level); if (!(sd->flags & SD_LOAD_BALANCE)) { - pr_cont("does not load-balance\n"); + printk("does not load-balance\n"); if (sd->parent) - pr_err("ERROR: !SD_LOAD_BALANCE domain has parent\n"); + printk(KERN_ERR "ERROR: !SD_LOAD_BALANCE domain" + " has parent"); return -1; } - pr_cont("span %s level %s\n", str, sd->name); + printk(KERN_CONT "span %s level %s\n", str, sd->name); if (!cpumask_test_cpu(cpu, sched_domain_span(sd))) { - pr_err("ERROR: domain->span does not contain CPU%d\n", cpu); + printk(KERN_ERR "ERROR: domain->span does not contain " + "CPU%d\n", cpu); } if (!cpumask_test_cpu(cpu, sched_group_cpus(group))) { - pr_err("ERROR: domain->groups does not contain CPU%d\n", cpu); + printk(KERN_ERR "ERROR: domain->groups does not contain" + " CPU%d\n", cpu); } printk(KERN_DEBUG "%*s groups:", level + 1, ""); do { if (!group) { - pr_cont("\n"); - pr_err("ERROR: group is NULL\n"); + printk("\n"); + printk(KERN_ERR "ERROR: group is NULL\n"); break; } if (!group->cpu_power) { - pr_cont("\n"); - pr_err("ERROR: domain->cpu_power not set\n"); + printk(KERN_CONT "\n"); + printk(KERN_ERR "ERROR: domain->cpu_power not " + "set\n"); break; } if (!cpumask_weight(sched_group_cpus(group))) { - pr_cont("\n"); - pr_err("ERROR: empty group\n"); + printk(KERN_CONT "\n"); + printk(KERN_ERR "ERROR: empty group\n"); break; } if (cpumask_intersects(groupmask, sched_group_cpus(group))) { - pr_cont("\n"); - pr_err("ERROR: repeated CPUs\n"); + printk(KERN_CONT "\n"); + printk(KERN_ERR "ERROR: repeated CPUs\n"); break; } @@ -7873,21 +7877,23 @@ static int sched_domain_debug_one(struct sched_domain *sd, int cpu, int level, cpulist_scnprintf(str, sizeof(str), sched_group_cpus(group)); - pr_cont(" %s", str); + printk(KERN_CONT " %s", str); if (group->cpu_power != SCHED_LOAD_SCALE) { - pr_cont(" (cpu_power = %d)", group->cpu_power); + printk(KERN_CONT " (cpu_power = %d)", + group->cpu_power); } group = group->next; } while (group != sd->groups); - pr_cont("\n"); + printk(KERN_CONT "\n"); if (!cpumask_equal(sched_domain_span(sd), groupmask)) - pr_err("ERROR: groups don't span domain->span\n"); + printk(KERN_ERR "ERROR: groups don't span domain->span\n"); if (sd->parent && !cpumask_subset(groupmask, sched_domain_span(sd->parent))) - pr_err("ERROR: parent span is not a superset of domain->span\n"); + printk(KERN_ERR "ERROR: parent span is not a superset " + "of domain->span\n"); return 0; } @@ -8443,7 +8449,8 @@ static int build_numa_sched_groups(struct s_data *d, sg = kmalloc_node(sizeof(struct sched_group) + cpumask_size(), GFP_KERNEL, num); if (!sg) { - pr_warning("Can not alloc domain group for node %d\n", num); + printk(KERN_WARNING "Can not alloc domain group for node %d\n", + num); return -ENOMEM; } d->sched_group_nodes[num] = sg; @@ -8472,8 +8479,8 @@ static int build_numa_sched_groups(struct s_data *d, sg = kmalloc_node(sizeof(struct sched_group) + cpumask_size(), GFP_KERNEL, num); if (!sg) { - pr_warning("Can not alloc domain group for node %d\n", - j); + printk(KERN_WARNING + "Can not alloc domain group for node %d\n", j); return -ENOMEM; } sg->cpu_power = 0; @@ -8701,7 +8708,7 @@ static enum s_alloc __visit_domain_allocation_hell(struct s_data *d, d->sched_group_nodes = kcalloc(nr_node_ids, sizeof(struct sched_group *), GFP_KERNEL); if (!d->sched_group_nodes) { - pr_warning("Can not alloc sched group node list\n"); + printk(KERN_WARNING "Can not alloc sched group node list\n"); return sa_notcovered; } sched_group_nodes_bycpu[cpumask_first(cpu_map)] = d->sched_group_nodes; @@ -8718,7 +8725,7 @@ static enum s_alloc __visit_domain_allocation_hell(struct s_data *d, return sa_send_covered; d->rd = alloc_rootdomain(); if (!d->rd) { - pr_warning("Cannot alloc root domain\n"); + printk(KERN_WARNING "Cannot alloc root domain\n"); return sa_tmpmask; } return sa_rootdomain; @@ -9700,11 +9707,13 @@ void __might_sleep(char *file, int line, int preempt_offset) return; prev_jiffy = jiffies; - pr_err("BUG: sleeping function called from invalid context at %s:%d\n", - file, line); - pr_err("in_atomic(): %d, irqs_disabled(): %d, pid: %d, name: %s\n", - in_atomic(), irqs_disabled(), - current->pid, current->comm); + printk(KERN_ERR + "BUG: sleeping function called from invalid context at %s:%d\n", + file, line); + printk(KERN_ERR + "in_atomic(): %d, irqs_disabled(): %d, pid: %d, name: %s\n", + in_atomic(), irqs_disabled(), + current->pid, current->comm); debug_show_held_locks(current); if (irqs_disabled()) diff --git a/kernel/sched_idletask.c b/kernel/sched_idletask.c index 21b969a..5f93b57 100644 --- a/kernel/sched_idletask.c +++ b/kernel/sched_idletask.c @@ -35,7 +35,7 @@ static void dequeue_task_idle(struct rq *rq, struct task_struct *p, int sleep) { raw_spin_unlock_irq(&rq->lock); - pr_err("bad: scheduling from the idle thread!\n"); + printk(KERN_ERR "bad: scheduling from the idle thread!\n"); dump_stack(); raw_spin_lock_irq(&rq->lock); } -- cgit v0.10.2 From 06393afde321b0fd7626b2d0966ebcaf6077de93 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Sun, 20 Dec 2009 15:39:55 -0500 Subject: Revert "pata_cmd64x: implement serialization as per notes" This reverts commit d43744390e460dce6626fb8de2c02a24ff650005, because it breaks the boot on several machines (mostly sparc64, at present). Signed-off-by: Jeff Garzik diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c index dadfc35..58c09e22 100644 --- a/drivers/ata/pata_cmd64x.c +++ b/drivers/ata/pata_cmd64x.c @@ -31,7 +31,7 @@ #include #define DRV_NAME "pata_cmd64x" -#define DRV_VERSION "0.3.1" +#define DRV_VERSION "0.2.5" /* * CMD64x specific registers definition. @@ -254,109 +254,17 @@ static void cmd648_bmdma_stop(struct ata_queued_cmd *qc) } /** - * cmd64x_bmdma_stop - DMA stop callback + * cmd646r1_dma_stop - DMA stop callback * @qc: Command in progress * - * Track the completion of live DMA commands and clear the - * host->private_data DMA tracking flag as we do. + * Stub for now while investigating the r1 quirk in the old driver. */ -static void cmd64x_bmdma_stop(struct ata_queued_cmd *qc) +static void cmd646r1_bmdma_stop(struct ata_queued_cmd *qc) { - struct ata_port *ap = qc->ap; ata_bmdma_stop(qc); - WARN_ON(ap->host->private_data != ap); - ap->host->private_data = NULL; -} - -/** - * cmd64x_qc_defer - Defer logic for chip limits - * @qc: queued command - * - * Decide whether we can issue the command. Called under the host lock. - */ - -static int cmd64x_qc_defer(struct ata_queued_cmd *qc) -{ - struct ata_host *host = qc->ap->host; - struct ata_port *alt = host->ports[1 ^ qc->ap->port_no]; - int rc; - int dma = 0; - - /* Apply the ATA rules first */ - rc = ata_std_qc_defer(qc); - if (rc) - return rc; - - if (qc->tf.protocol == ATAPI_PROT_DMA || - qc->tf.protocol == ATA_PROT_DMA) - dma = 1; - - /* If the other port is not live then issue the command */ - if (alt == NULL || !alt->qc_active) { - if (dma) - host->private_data = qc->ap; - return 0; - } - /* If there is a live DMA command then wait */ - if (host->private_data != NULL) - return ATA_DEFER_PORT; - if (dma) - /* Cannot overlap our DMA command */ - return ATA_DEFER_PORT; - return 0; } -/** - * cmd64x_interrupt - ATA host interrupt handler - * @irq: irq line (unused) - * @dev_instance: pointer to our ata_host information structure - * - * Our interrupt handler for PCI IDE devices. Calls - * ata_sff_host_intr() for each port that is flagging an IRQ. We cannot - * use the defaults as we need to avoid touching status/altstatus during - * a DMA. - * - * LOCKING: - * Obtains host lock during operation. - * - * RETURNS: - * IRQ_NONE or IRQ_HANDLED. - */ -irqreturn_t cmd64x_interrupt(int irq, void *dev_instance) -{ - struct ata_host *host = dev_instance; - struct pci_dev *pdev = to_pci_dev(host->dev); - unsigned int i; - unsigned int handled = 0; - unsigned long flags; - static const u8 irq_reg[2] = { CFR, ARTTIM23 }; - static const u8 irq_mask[2] = { 1 << 2, 1 << 4 }; - - /* TODO: make _irqsave conditional on x86 PCI IDE legacy mode */ - spin_lock_irqsave(&host->lock, flags); - - for (i = 0; i < host->n_ports; i++) { - struct ata_port *ap; - u8 reg; - - pci_read_config_byte(pdev, irq_reg[i], ®); - ap = host->ports[i]; - if (ap && (reg & irq_mask[i]) && - !(ap->flags & ATA_FLAG_DISABLED)) { - struct ata_queued_cmd *qc; - - qc = ata_qc_from_tag(ap, ap->link.active_tag); - if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING)) && - (qc->flags & ATA_QCFLAG_ACTIVE)) - handled |= ata_sff_host_intr(ap, qc); - } - } - - spin_unlock_irqrestore(&host->lock, flags); - - return IRQ_RETVAL(handled); -} static struct scsi_host_template cmd64x_sht = { ATA_BMDMA_SHT(DRV_NAME), }; @@ -365,8 +273,6 @@ static const struct ata_port_operations cmd64x_base_ops = { .inherits = &ata_bmdma_port_ops, .set_piomode = cmd64x_set_piomode, .set_dmamode = cmd64x_set_dmamode, - .bmdma_stop = cmd64x_bmdma_stop, - .qc_defer = cmd64x_qc_defer, }; static struct ata_port_operations cmd64x_port_ops = { @@ -376,6 +282,7 @@ static struct ata_port_operations cmd64x_port_ops = { static struct ata_port_operations cmd646r1_port_ops = { .inherits = &cmd64x_base_ops, + .bmdma_stop = cmd646r1_bmdma_stop, .cable_detect = ata_cable_40wire, }; @@ -383,7 +290,6 @@ static struct ata_port_operations cmd648_port_ops = { .inherits = &cmd64x_base_ops, .bmdma_stop = cmd648_bmdma_stop, .cable_detect = cmd648_cable_detect, - .qc_defer = ata_std_qc_defer }; static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) @@ -432,7 +338,6 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) const struct ata_port_info *ppi[] = { &cmd_info[id->driver_data], NULL }; u8 mrdmode; int rc; - struct ata_host *host; rc = pcim_enable_device(pdev); if (rc) @@ -450,25 +355,20 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) ppi[0] = &cmd_info[3]; } - pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64); pci_read_config_byte(pdev, MRDMODE, &mrdmode); mrdmode &= ~ 0x30; /* IRQ set up */ mrdmode |= 0x02; /* Memory read line enable */ pci_write_config_byte(pdev, MRDMODE, mrdmode); + /* Force PIO 0 here.. */ + /* PPC specific fixup copied from old driver */ #ifdef CONFIG_PPC pci_write_config_byte(pdev, UDIDETCR0, 0xF0); #endif - rc = ata_pci_sff_prepare_host(pdev, ppi, &host); - if (rc) - return rc; - /* We use this pointer to track the AP which has DMA running */ - host->private_data = NULL; - pci_set_master(pdev); - return ata_pci_sff_activate_host(host, cmd64x_interrupt, &cmd64x_sht); + return ata_pci_sff_init_one(pdev, ppi, &cmd64x_sht, NULL); } #ifdef CONFIG_PM -- cgit v0.10.2 From 509426bd46ad0903dca409803e0ee3d30f99f1e8 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Sun, 20 Dec 2009 19:22:33 +0100 Subject: pata_cmd64x: fix overclocking of UDMA0-2 modes adev->dma_mode stores the transfer mode value not UDMA mode number so the condition in cmd64x_set_dmamode() is always true and the higher UDMA clock is always selected. This can potentially result in data corruption when UDMA33 device is used, when 40-wire cable is used or when the error recovery code decides to lower the device speed down. The issue was introduced in the commit 6a40da0 ("libata cmd64x: whack into a shape that looks like the documentation") which goes back to kernel 2.6.20. Cc: stable@kernel.org Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jeff Garzik diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c index 58c09e22..0efb1f5 100644 --- a/drivers/ata/pata_cmd64x.c +++ b/drivers/ata/pata_cmd64x.c @@ -219,7 +219,7 @@ static void cmd64x_set_dmamode(struct ata_port *ap, struct ata_device *adev) regU |= udma_data[adev->dma_mode - XFER_UDMA_0] << shift; /* Merge the control bits */ regU |= 1 << adev->devno; /* UDMA on */ - if (adev->dma_mode > 2) /* 15nS timing */ + if (adev->dma_mode > XFER_UDMA_2) /* 15nS timing */ regU |= 4 << adev->devno; } else { regU &= ~ (1 << adev->devno); /* UDMA off */ -- cgit v0.10.2 From 70f1120527797adb31c68bdc6f1b45e182c342c7 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Sun, 20 Dec 2009 17:36:27 +0100 Subject: sched: Fix hotplug hang The hot-unplug kstopmachine usage does a wakeup after deactivating the cpu, hence we cannot use cpu_active() here but must rely on the good olde online. Reported-by: Sachin Sant Reported-by: Jens Axboe Signed-off-by: Peter Zijlstra Tested-by: Jens Axboe Cc: Heiko Carstens Cc: Benjamin Herrenschmidt LKML-Reference: <1261326987.4314.24.camel@laptop> Signed-off-by: Ingo Molnar diff --git a/kernel/sched.c b/kernel/sched.c index 7ffde2a..87f1f47 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -2346,7 +2346,7 @@ int select_task_rq(struct task_struct *p, int sd_flags, int wake_flags) * not worry about this generic constraint ] */ if (unlikely(!cpumask_test_cpu(cpu, &p->cpus_allowed) || - !cpu_active(cpu))) + !cpu_online(cpu))) cpu = select_fallback_rq(task_cpu(p), p); return cpu; -- cgit v0.10.2 From 7ccec3e72693f48957f37949039bf2dfd1c80f22 Mon Sep 17 00:00:00 2001 From: Albert Herranz Date: Fri, 18 Dec 2009 10:04:42 +0000 Subject: powerpc/gc/wii: hlwd-pic: convert irq_desc.lock to raw_spinlock Fix the following build failures: arch/powerpc/platforms/embedded6xx/hlwd-pic.c: In function 'hlwd_pic_irq_cascade': arch/powerpc/platforms/embedded6xx/hlwd-pic.c:135: error: passing argument 1 of 'spin_lock' from incompatible pointer type arch/powerpc/platforms/embedded6xx/hlwd-pic.c:137: error: passing argument 1 of 'spin_unlock' from incompatible pointer type arch/powerpc/platforms/embedded6xx/hlwd-pic.c:145: error: passing argument 1 of 'spin_lock' from incompatible pointer type arch/powerpc/platforms/embedded6xx/hlwd-pic.c:149: error: passing argument 1 of 'spin_unlock' from incompatible pointer type These failures are caused by the changes introduced in commit "genirq: Convert irq_desc.lock to raw_spinlock". The reason this driver was not updated is that it wasn't merged yet. Signed-off-by: Albert Herranz Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c index dd20bff..cba40d0 100644 --- a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c +++ b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c @@ -132,9 +132,9 @@ static void hlwd_pic_irq_cascade(unsigned int cascade_virq, struct irq_host *irq_host = get_irq_data(cascade_virq); unsigned int virq; - spin_lock(&desc->lock); + raw_spin_lock(&desc->lock); desc->chip->mask(cascade_virq); /* IRQ_LEVEL */ - spin_unlock(&desc->lock); + raw_spin_unlock(&desc->lock); virq = __hlwd_pic_get_irq(irq_host); if (virq != NO_IRQ) @@ -142,11 +142,11 @@ static void hlwd_pic_irq_cascade(unsigned int cascade_virq, else pr_err("spurious interrupt!\n"); - spin_lock(&desc->lock); + raw_spin_lock(&desc->lock); desc->chip->ack(cascade_virq); /* IRQ_LEVEL */ if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask) desc->chip->unmask(cascade_virq); - spin_unlock(&desc->lock); + raw_spin_unlock(&desc->lock); } /* -- cgit v0.10.2 From 95cd34b42b43c0ed5a89a764e023189bfe7b1530 Mon Sep 17 00:00:00 2001 From: Albert Herranz Date: Fri, 18 Dec 2009 10:04:05 +0000 Subject: powerpc/gc/wii: Remove get_irq_desc() Fix the following build failures: arch/powerpc/platforms/embedded6xx/flipper-pic.c: In function 'flipper_pic_map': arch/powerpc/platforms/embedded6xx/flipper-pic.c:105: error: implicit declaration of function 'get_irq_desc' arch/powerpc/platforms/embedded6xx/hlwd-pic.c: In function 'hlwd_pic_map': arch/powerpc/platforms/embedded6xx/hlwd-pic.c:98: error: implicit declaration of function 'get_irq_desc' These failures are caused by the changes introduced in commit "powerpc: Remove get_irq_desc()". The reason these drivers were not updated is that they weren't merged yet. Signed-off-by: Albert Herranz Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/platforms/embedded6xx/flipper-pic.c b/arch/powerpc/platforms/embedded6xx/flipper-pic.c index d596328..c278bd3 100644 --- a/arch/powerpc/platforms/embedded6xx/flipper-pic.c +++ b/arch/powerpc/platforms/embedded6xx/flipper-pic.c @@ -102,7 +102,7 @@ static int flipper_pic_map(struct irq_host *h, unsigned int virq, irq_hw_number_t hwirq) { set_irq_chip_data(virq, h->host_data); - get_irq_desc(virq)->status |= IRQ_LEVEL; + irq_to_desc(virq)->status |= IRQ_LEVEL; set_irq_chip_and_handler(virq, &flipper_pic, handle_level_irq); return 0; } diff --git a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c index cba40d0..a771f91 100644 --- a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c +++ b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c @@ -95,7 +95,7 @@ static int hlwd_pic_map(struct irq_host *h, unsigned int virq, irq_hw_number_t hwirq) { set_irq_chip_data(virq, h->host_data); - get_irq_desc(virq)->status |= IRQ_LEVEL; + irq_to_desc(virq)->status |= IRQ_LEVEL; set_irq_chip_and_handler(virq, &hlwd_pic, handle_level_irq); return 0; } -- cgit v0.10.2 From aa0baaef97c89de2ef216fcc017215ee01662a10 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 21 Dec 2009 02:46:11 +0100 Subject: PM: Use pm_runtime_put_sync in system resume This patch (as1317) fixes a bug in the PM core. When a device is resumed following a system sleep, the core decrements the device's runtime PM usage counter but doesn't issue an idle notification if the counter reaches 0. This could prevent an otherwise unused device from being runtime-suspended again after the system sleep. The fix is to call pm_runtime_put_sync() instead of pm_runtime_put_noidle(). Signed-off-by: Alan Stern Signed-off-by: Rafael J. Wysocki diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 8052daf..48adf80 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -607,7 +607,7 @@ static void dpm_complete(pm_message_t state) mutex_unlock(&dpm_list_mtx); device_complete(dev, state); - pm_runtime_put_noidle(dev); + pm_runtime_put_sync(dev); mutex_lock(&dpm_list_mtx); } @@ -880,7 +880,7 @@ static int dpm_prepare(pm_message_t state) pm_runtime_get_noresume(dev); if (pm_runtime_barrier(dev) && device_may_wakeup(dev)) { /* Wake-up requested during system sleep transition. */ - pm_runtime_put_noidle(dev); + pm_runtime_put_sync(dev); error = -EBUSY; } else { error = device_prepare(dev, state); -- cgit v0.10.2 From b74665606962456af7f92b1e448cee30ce70967b Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Sun, 20 Dec 2009 18:40:18 -0800 Subject: bnx2: Fix bnx2_netif_stop() merge error. The error was introduced while merging: commit 4529819c45161e4a119134f56ef504e69420bc98 bnx2: reset_task is crashing the kernel. Fixing it. Signed-off-by: Michael Chan k Signed-off-by: David S. Miller diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index f38764e..65df1de 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -666,6 +666,7 @@ bnx2_netif_stop(struct bnx2 *bp) txq->trans_start = jiffies; } } + bnx2_disable_int_sync(bp); } static void @@ -679,7 +680,6 @@ bnx2_netif_start(struct bnx2 *bp) bnx2_cnic_start(bp); } } - bnx2_disable_int_sync(bp); } static void -- cgit v0.10.2 From 3147093e1de59081e82fb1d815424c3e952caf3e Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 18 Dec 2009 14:19:27 +0900 Subject: sh: Restore bl bit toggling in idle loop. This fixes up some crashes with IRQs racing the need_resched() test under QEMU. Signed-off-by: Paul Mundt diff --git a/arch/sh/kernel/idle.c b/arch/sh/kernel/idle.c index aaff003..8e47565 100644 --- a/arch/sh/kernel/idle.c +++ b/arch/sh/kernel/idle.c @@ -92,6 +92,7 @@ void cpu_idle(void) check_pgt_cache(); rmb(); + set_bl_bit(); local_irq_disable(); /* Don't trace irqs off for idle */ stop_critical_timings(); @@ -102,6 +103,7 @@ void cpu_idle(void) */ WARN_ON(irqs_disabled()); start_critical_timings(); + clear_bl_bit(); } tick_nohz_restart_sched_tick(); -- cgit v0.10.2 From 73a38b839b9295216e8d44dabf54de88270e77b8 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 18 Dec 2009 14:40:56 +0900 Subject: sh: Only use bl bit toggling for sleeping idle. We don't actually require this in the cpu_relax() polling case, so just cuddle these around the sleeping version. Signed-off-by: Paul Mundt diff --git a/arch/sh/kernel/idle.c b/arch/sh/kernel/idle.c index 8e47565..6b3d706 100644 --- a/arch/sh/kernel/idle.c +++ b/arch/sh/kernel/idle.c @@ -62,6 +62,7 @@ void default_idle(void) clear_thread_flag(TIF_POLLING_NRFLAG); smp_mb__after_clear_bit(); + set_bl_bit(); if (!need_resched()) { local_irq_enable(); cpu_sleep(); @@ -69,6 +70,7 @@ void default_idle(void) local_irq_enable(); set_thread_flag(TIF_POLLING_NRFLAG); + clear_bl_bit(); } else poll_idle(); } @@ -92,7 +94,6 @@ void cpu_idle(void) check_pgt_cache(); rmb(); - set_bl_bit(); local_irq_disable(); /* Don't trace irqs off for idle */ stop_critical_timings(); @@ -103,7 +104,6 @@ void cpu_idle(void) */ WARN_ON(irqs_disabled()); start_critical_timings(); - clear_bl_bit(); } tick_nohz_restart_sched_tick(); -- cgit v0.10.2 From 3d354cbc43db36e7e8b27ed78901064b87864ffc Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Sun, 20 Dec 2009 10:43:35 -0500 Subject: nfsd: fix "insecure" export option A typo in 12045a6ee9908b "nfsd: let "insecure" flag vary by pseudoflavor" reversed the sense of the "insecure" flag. Reported-by: Michael Guntsche Signed-off-by: J. Bruce Fields Signed-off-by: Linus Torvalds diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index 1c12177..55c8e63 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c @@ -89,7 +89,7 @@ static __be32 nfsd_setuser_and_check_port(struct svc_rqst *rqstp, int flags = nfsexp_flags(rqstp, exp); /* Check if the request originated from a secure port. */ - if (!rqstp->rq_secure && (flags & NFSEXP_INSECURE_PORT)) { + if (!rqstp->rq_secure && !(flags & NFSEXP_INSECURE_PORT)) { RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]); dprintk(KERN_WARNING "nfsd: request from insecure port %s!\n", -- cgit v0.10.2 From e2595322a3a353a59cecd7f57e7aa421ecb02d12 Mon Sep 17 00:00:00 2001 From: Daniel T Chen Date: Sat, 19 Dec 2009 18:19:02 -0500 Subject: ALSA: hda: Set Front Mic to input vref 50% for Lenovo 3000 Y410 BugLink: https://bugs.launchpad.net/bugs/479373 The OR has verified with hda-verb that the internal microphone needs VREF50 set for audible capture. Signed-off-by: Daniel T Chen Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 84bc2c7..1554c3a 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -10686,6 +10686,13 @@ static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = { {} }; +static struct hda_verb alc262_lenovo_3000_init_verbs[] = { + /* Front Mic pin: input vref at 50% */ + {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, + {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, + {} +}; + static struct hda_input_mux alc262_fujitsu_capture_source = { .num_items = 3, .items = { @@ -11728,7 +11735,8 @@ static struct alc_config_preset alc262_presets[] = { [ALC262_LENOVO_3000] = { .mixers = { alc262_lenovo_3000_mixer }, .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs, - alc262_lenovo_3000_unsol_verbs }, + alc262_lenovo_3000_unsol_verbs, + alc262_lenovo_3000_init_verbs }, .num_dacs = ARRAY_SIZE(alc262_dac_nids), .dac_nids = alc262_dac_nids, .hp_nid = 0x03, -- cgit v0.10.2 From 0f86a228f4a4639b3142ce0dad208433b2db377a Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Sun, 20 Dec 2009 22:51:18 +0100 Subject: ALSA: HDA: simplify Aspire 8930G verb array This patch just simplifies the 8930G verb array a bit. Just use the common ALC889 EAPD verb array to make things more consistent. The file is already huge enough already. Signed-off-by: Hector Martin Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 1554c3a..cb97323 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -1665,9 +1665,6 @@ static struct hda_verb alc889_acer_aspire_8930g_verbs[] = { /* some bit here disables the other DACs. Init=0x4900 */ {0x20, AC_VERB_SET_COEF_INDEX, 0x08}, {0x20, AC_VERB_SET_PROC_COEF, 0x0000}, -/* Enable amplifiers */ - {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, - {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, /* DMIC fix * This laptop has a stereo digital microphone. The mics are only 1cm apart * which makes the stereo useless. However, either the mic or the ALC889 @@ -9386,7 +9383,8 @@ static struct alc_config_preset alc882_presets[] = { .mixers = { alc888_base_mixer, alc883_chmode_mixer }, .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs, - alc889_acer_aspire_8930g_verbs }, + alc889_acer_aspire_8930g_verbs, + alc889_eapd_verbs}, .num_dacs = ARRAY_SIZE(alc883_dac_nids), .dac_nids = alc883_dac_nids, .num_adc_nids = ARRAY_SIZE(alc889_adc_nids), -- cgit v0.10.2 From 556eea9a926bff8f014b4f80522b4de97ae84213 Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Sun, 20 Dec 2009 22:51:23 +0100 Subject: ALSA: HDA: remove useless mixers on Aspire 8930G This patch removes some extra mixers that do nothing on the Acer Aspire 8930G. The CD mixer is useless because the SATA DVD/Blu-Ray drive has no analog audio output, and the Side mixer is useless because we max out at 6ch anyway. Signed-off-by: Hector Martin Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index cb97323..faeb74f 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -1777,6 +1777,25 @@ static struct snd_kcontrol_new alc888_base_mixer[] = { { } /* end */ }; +static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = { + HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), + HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), + HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, + HDA_OUTPUT), + HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), + HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), + HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), + HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), + { } /* end */ +}; + + static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; @@ -9380,7 +9399,7 @@ static struct alc_config_preset alc882_presets[] = { .init_hook = alc_automute_amp, }, [ALC888_ACER_ASPIRE_8930G] = { - .mixers = { alc888_base_mixer, + .mixers = { alc889_acer_aspire_8930g_mixer, alc883_chmode_mixer }, .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs, alc889_acer_aspire_8930g_verbs, -- cgit v0.10.2 From f5de24b06aa46427500d0fdbe8616b73a71d8c28 Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Sun, 20 Dec 2009 22:51:31 +0100 Subject: ALSA: HDA: add powersaving hook for Realtek The current Realtek code makes no specific provision for turning stuff off. The codec chip is placed into low-power mode generically, but this doesn't turn off any external hardware connected to it, in particular external amplifiers. This patch creates a hook function that is called by the codec suspend/resume functions. It ought to disable any external hardware in a device-specific way. I've implemented a generic ALC889 function that sets the EAPD pin properly, and used it for the Acer Aspire 8930G which can benefit from this feature. On my laptop, this results in ~0.5W extra savings. Signed-off-by: Hector Martin Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index faeb74f..b3abe9c 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -337,6 +337,9 @@ struct alc_spec { /* hooks */ void (*init_hook)(struct hda_codec *codec); void (*unsol_event)(struct hda_codec *codec, unsigned int res); +#ifdef CONFIG_SND_HDA_POWER_SAVE + void (*power_hook)(struct hda_codec *codec, int power); +#endif /* for pin sensing */ unsigned int sense_updated: 1; @@ -388,6 +391,7 @@ struct alc_config_preset { void (*init_hook)(struct hda_codec *); #ifdef CONFIG_SND_HDA_POWER_SAVE struct hda_amp_list *loopbacks; + void (*power_hook)(struct hda_codec *codec, int power); #endif }; @@ -900,6 +904,7 @@ static void setup_preset(struct hda_codec *codec, spec->unsol_event = preset->unsol_event; spec->init_hook = preset->init_hook; #ifdef CONFIG_SND_HDA_POWER_SAVE + spec->power_hook = preset->power_hook; spec->loopback.amplist = preset->loopbacks; #endif @@ -1826,6 +1831,16 @@ static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec) spec->autocfg.speaker_pins[2] = 0x1b; } +#ifdef CONFIG_SND_HDA_POWER_SAVE +static void alc889_power_eapd(struct hda_codec *codec, int power) +{ + snd_hda_codec_write(codec, 0x14, 0, + AC_VERB_SET_EAPD_BTLENABLE, power ? 2 : 0); + snd_hda_codec_write(codec, 0x15, 0, + AC_VERB_SET_EAPD_BTLENABLE, power ? 2 : 0); +} +#endif + /* * ALC880 3-stack model * @@ -3619,12 +3634,29 @@ static void alc_free(struct hda_codec *codec) snd_hda_detach_beep_device(codec); } +#ifdef CONFIG_SND_HDA_POWER_SAVE +static int alc_suspend(struct hda_codec *codec, pm_message_t state) +{ + struct alc_spec *spec = codec->spec; + if (spec && spec->power_hook) + spec->power_hook(codec, 0); + return 0; +} +#endif + #ifdef SND_HDA_NEEDS_RESUME static int alc_resume(struct hda_codec *codec) { +#ifdef CONFIG_SND_HDA_POWER_SAVE + struct alc_spec *spec = codec->spec; +#endif codec->patch_ops.init(codec); snd_hda_codec_resume_amp(codec); snd_hda_codec_resume_cache(codec); +#ifdef CONFIG_SND_HDA_POWER_SAVE + if (spec && spec->power_hook) + spec->power_hook(codec, 1); +#endif return 0; } #endif @@ -3641,6 +3673,7 @@ static struct hda_codec_ops alc_patch_ops = { .resume = alc_resume, #endif #ifdef CONFIG_SND_HDA_POWER_SAVE + .suspend = alc_suspend, .check_power_status = alc_check_power_status, #endif }; @@ -9420,6 +9453,9 @@ static struct alc_config_preset alc882_presets[] = { .unsol_event = alc_automute_amp_unsol_event, .setup = alc889_acer_aspire_8930g_setup, .init_hook = alc_automute_amp, +#ifdef CONFIG_SND_HDA_POWER_SAVE + .power_hook = alc889_power_eapd, +#endif }, [ALC888_ACER_ASPIRE_7730G] = { .mixers = { alc883_3ST_6ch_mixer, -- cgit v0.10.2 From 40962d7c741de1c21b6ce8516c1d9f8836fb383e Mon Sep 17 00:00:00 2001 From: Krzysztof Helt Date: Sat, 19 Dec 2009 18:31:04 +0100 Subject: ALSA: fix incorrect rounding direction in snd_interval_ratnum() The direction of rounding is incorrect in the snd_interval_ratnum() It was detected with following parameters (sb8 driver playing 8kHz stereo file): - num is always 1000000 - requested frequency rate is from 7999 to 7999 (single frequency) The first loop calculates div_down(num, freq->min) which is 125. Thus, a frequency range's minimum value is 1000000 / 125 = 8000 Hz. The second loop calculates div_up(num, freq->max) which is 126 The frequency range's maximum value is 1000000 / 126 = 7936 Hz. The range maximum is lower than the range minimum so the function fails due to empty result range. Signed-off-by: Krzysztof Helt Signed-off-by: Takashi Iwai diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index 30f4108..a27545b2 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c @@ -758,7 +758,7 @@ int snd_interval_ratnum(struct snd_interval *i, int diff; if (q == 0) q = 1; - den = div_down(num, q); + den = div_up(num, q); if (den < rats[k].den_min) continue; if (den > rats[k].den_max) @@ -794,7 +794,7 @@ int snd_interval_ratnum(struct snd_interval *i, i->empty = 1; return -EINVAL; } - den = div_up(num, q); + den = div_down(num, q); if (den > rats[k].den_max) continue; if (den < rats[k].den_min) -- cgit v0.10.2 From db8cf334f66bdf1ba2b3d2f7128095fc9b7a6e2b Mon Sep 17 00:00:00 2001 From: Krzysztof Helt Date: Sun, 20 Dec 2009 20:15:19 +0100 Subject: ALSA: sbawe: fix memory detection Memory amount is increased before a successful write-read sequence is done. Thus, 512 kB of onboard memory is detected on memoryless cards like SB32. Move the increasing of memory counter after successful read is done. Signed-off-by: Krzysztof Helt Signed-off-by: Takashi Iwai diff --git a/sound/isa/sb/emu8000.c b/sound/isa/sb/emu8000.c index 96678d5..751762f 100644 --- a/sound/isa/sb/emu8000.c +++ b/sound/isa/sb/emu8000.c @@ -393,8 +393,6 @@ size_dram(struct snd_emu8000 *emu) while (size < EMU8000_MAX_DRAM) { - size += 512 * 1024; /* increment 512kbytes */ - /* Write a unique data on the test address. * if the address is out of range, the data is written on * 0x200000(=EMU8000_DRAM_OFFSET). Then the id word is @@ -414,7 +412,9 @@ size_dram(struct snd_emu8000 *emu) /*snd_emu8000_read_wait(emu);*/ EMU8000_SMLD_READ(emu); /* discard stale data */ if (EMU8000_SMLD_READ(emu) != UNIQUE_ID2) - break; /* we must have wrapped around */ + break; /* no memory at this address */ + + size += 512 * 1024; /* increment 512kbytes */ snd_emu8000_read_wait(emu); -- cgit v0.10.2 From 7d4e9d0962cd0f6a30b01e256756dd10606dab30 Mon Sep 17 00:00:00 2001 From: Emese Revfy Date: Mon, 14 Dec 2009 00:59:30 +0100 Subject: drbd: Constify struct file_operations Signed-off-by: Emese Revfy Signed-off-by: Philipp Reisner diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index 2312d78..c975587 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -1490,7 +1490,7 @@ void drbd_bump_write_ordering(struct drbd_conf *mdev, enum write_ordering_e wo); /* drbd_proc.c */ extern struct proc_dir_entry *drbd_proc; -extern struct file_operations drbd_proc_fops; +extern const struct file_operations drbd_proc_fops; extern const char *drbd_conn_str(enum drbd_conns s); extern const char *drbd_role_str(enum drbd_role s); diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 157d1e4..af30ca9 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -151,7 +151,7 @@ wait_queue_head_t drbd_pp_wait; DEFINE_RATELIMIT_STATE(drbd_ratelimit_state, 5 * HZ, 5); -static struct block_device_operations drbd_ops = { +static const struct block_device_operations drbd_ops = { .owner = THIS_MODULE, .open = drbd_open, .release = drbd_release, diff --git a/drivers/block/drbd/drbd_proc.c b/drivers/block/drbd/drbd_proc.c index bdd0b49..df8ad96 100644 --- a/drivers/block/drbd/drbd_proc.c +++ b/drivers/block/drbd/drbd_proc.c @@ -38,7 +38,7 @@ static int drbd_proc_open(struct inode *inode, struct file *file); struct proc_dir_entry *drbd_proc; -struct file_operations drbd_proc_fops = { +const struct file_operations drbd_proc_fops = { .owner = THIS_MODULE, .open = drbd_proc_open, .read = seq_read, -- cgit v0.10.2 From 49829ea74f790d3be2e803a617e714f5b9a5ed50 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Tue, 15 Dec 2009 22:55:44 +0100 Subject: drbd: Fix test of unsigned in _drbd_fault_random() rsp->count is unsigned so the test does not work. Signed-off-by: Roel Kluin Signed-off-by: Andrew Morton Signed-off-by: Philipp Reisner diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index af30ca9..ecc1612 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -3623,7 +3623,7 @@ _drbd_fault_random(struct fault_random_state *rsp) { long refresh; - if (--rsp->count < 0) { + if (!rsp->count--) { get_random_bytes(&refresh, sizeof(refresh)); rsp->state += refresh; rsp->count = FAULT_RANDOM_REFRESH; -- cgit v0.10.2 From 7b886f4f7a051dc88165684cbcddd98e22bd0203 Mon Sep 17 00:00:00 2001 From: Huang Weiyi Date: Wed, 9 Dec 2009 21:09:12 +0800 Subject: drbd: remove duplicated #include Remove duplicated #include('s) in drivers/block/drbd/drbd_worker.c Signed-off-by: Huang Weiyi Signed-off-by: Philipp Reisner diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c index ed8796f..3e8b6bc 100644 --- a/drivers/block/drbd/drbd_worker.c +++ b/drivers/block/drbd/drbd_worker.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include -- cgit v0.10.2 From 820cd61a28503598f4262c544082ccb33678b9fc Mon Sep 17 00:00:00 2001 From: Huang Weiyi Date: Sun, 13 Dec 2009 22:05:03 +0800 Subject: drbd: remove unused #include Remove unused #include ('s) in drivers/block/drbd/drbd_main.c drivers/block/drbd/drbd_receiver.c drivers/block/drbd/drbd_worker.c Signed-off-by: Huang Weiyi Signed-off-by: Philipp Reisner diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index ecc1612..9348f33 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -27,7 +27,6 @@ */ #include -#include #include #include #include diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index c548f24..259c135 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -28,7 +28,6 @@ #include #include -#include #include #include #include diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c index 3e8b6bc..b453c2b 100644 --- a/drivers/block/drbd/drbd_worker.c +++ b/drivers/block/drbd/drbd_worker.c @@ -24,7 +24,6 @@ */ #include -#include #include #include #include -- cgit v0.10.2 From f797d9881b62c2ddb1d2e7bd80d87141949c84aa Mon Sep 17 00:00:00 2001 From: Shaun Ruffell Date: Thu, 17 Dec 2009 18:00:36 -0600 Subject: dma-debug: Do not add notifier when dma debugging is disabled. If CONFIG_HAVE_DMA_API_DEBUG is defined and "dma_debug=off" is specified on the kernel command line, when you detach a driver from a device you can cause the following NULL pointer dereference: BUG: unable to handle kernel NULL pointer dereference at (null) IP: [] dma_debug_device_change+0x5d/0x117 The problem is that the dma_debug_device_change notifier function is added to the bus notifier chain even though the dma_entry_hash array was never initialized. If dma debugging is disabled, this patch both prevents dma_debug_device_change notifiers from being added to the chain, and additionally ensures that the dma_debug_device_change notifier function is a no-op. Cc: stable@kernel.org Signed-off-by: Shaun Ruffell Signed-off-by: Joerg Roedel diff --git a/lib/dma-debug.c b/lib/dma-debug.c index d9b08e0..7399744 100644 --- a/lib/dma-debug.c +++ b/lib/dma-debug.c @@ -676,6 +676,8 @@ static int dma_debug_device_change(struct notifier_block *nb, struct device *dev = data; int count; + if (global_disable) + return; switch (action) { case BUS_NOTIFY_UNBOUND_DRIVER: @@ -697,6 +699,9 @@ void dma_debug_add_bus(struct bus_type *bus) { struct notifier_block *nb; + if (global_disable) + return; + nb = kzalloc(sizeof(struct notifier_block), GFP_KERNEL); if (nb == NULL) { pr_err("dma_debug_add_bus: out of memory\n"); -- cgit v0.10.2 From 0f764806438d5576ac58898332e5dcf30bb8a679 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Mon, 21 Dec 2009 15:51:23 +0100 Subject: x86/amd-iommu: Fix initialization failure panic The assumption that acpi_table_parse passes the return value of the hanlder function to the caller proved wrong recently. The return value of the handler function is totally ignored. This makes the initialization code for AMD IOMMU buggy in a way that could cause a kernel panic on initialization. This patch fixes the issue in the AMD IOMMU driver. Cc: stable@kernel.org Signed-off-by: Joerg Roedel diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c index 1dca9c3..fb490ce 100644 --- a/arch/x86/kernel/amd_iommu_init.c +++ b/arch/x86/kernel/amd_iommu_init.c @@ -138,6 +138,11 @@ int amd_iommus_present; bool amd_iommu_np_cache __read_mostly; /* + * Set to true if ACPI table parsing and hardware intialization went properly + */ +static bool amd_iommu_initialized; + +/* * List of protection domains - used during resume */ LIST_HEAD(amd_iommu_pd_list); @@ -929,6 +934,8 @@ static int __init init_iommu_all(struct acpi_table_header *table) } WARN_ON(p != end); + amd_iommu_initialized = true; + return 0; } @@ -1263,6 +1270,9 @@ static int __init amd_iommu_init(void) if (acpi_table_parse("IVRS", init_iommu_all) != 0) goto free; + if (!amd_iommu_initialized) + goto free; + if (acpi_table_parse("IVRS", init_memory_definitions) != 0) goto free; -- cgit v0.10.2 From 9504e0864b58b4a304820dcf3755f1da80d5e72f Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Mon, 21 Dec 2009 15:55:51 +0100 Subject: block: Fix topology stacking for data and discard alignment The stacking code incorrectly scaled up the data offset in some cases causing misaligned devices to report alignment. Rewrite the stacking algorithm to remedy this and apply the same alignment principles to the discard handling. Signed-off-by: Martin K. Petersen Signed-off-by: Jens Axboe diff --git a/block/blk-settings.c b/block/blk-settings.c index 6ae118d..e14fcbc 100644 --- a/block/blk-settings.c +++ b/block/blk-settings.c @@ -517,9 +517,8 @@ static unsigned int lcm(unsigned int a, unsigned int b) int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, sector_t offset) { - int ret; - - ret = 0; + sector_t alignment; + unsigned int top, bottom, granularity; t->max_sectors = min_not_zero(t->max_sectors, b->max_sectors); t->max_hw_sectors = min_not_zero(t->max_hw_sectors, b->max_hw_sectors); @@ -537,6 +536,19 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, t->max_segment_size = min_not_zero(t->max_segment_size, b->max_segment_size); + granularity = max(b->physical_block_size, b->io_min); + alignment = b->alignment_offset - (offset & (granularity - 1)); + + if (t->alignment_offset != alignment) { + + top = max(t->physical_block_size, t->io_min) + + t->alignment_offset; + bottom = granularity + alignment; + + if (max(top, bottom) & (min(top, bottom) - 1)) + t->misaligned = 1; + } + t->logical_block_size = max(t->logical_block_size, b->logical_block_size); @@ -544,54 +556,55 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, b->physical_block_size); t->io_min = max(t->io_min, b->io_min); + t->io_opt = lcm(t->io_opt, b->io_opt); + t->no_cluster |= b->no_cluster; t->discard_zeroes_data &= b->discard_zeroes_data; - /* Bottom device offset aligned? */ - if (offset && - (offset & (b->physical_block_size - 1)) != b->alignment_offset) { + if (t->physical_block_size & (t->logical_block_size - 1)) { + t->physical_block_size = t->logical_block_size; t->misaligned = 1; - ret = -1; } - /* - * Temporarily disable discard granularity. It's currently buggy - * since we default to 0 for discard_granularity, hence this - * "failure" will always trigger for non-zero offsets. - */ -#if 0 - if (offset && - (offset & (b->discard_granularity - 1)) != b->discard_alignment) { - t->discard_misaligned = 1; - ret = -1; + if (t->io_min & (t->physical_block_size - 1)) { + t->io_min = t->physical_block_size; + t->misaligned = 1; } -#endif - /* If top has no alignment offset, inherit from bottom */ - if (!t->alignment_offset) - t->alignment_offset = - b->alignment_offset & (b->physical_block_size - 1); + if (t->io_opt & (t->physical_block_size - 1)) { + t->io_opt = 0; + t->misaligned = 1; + } - if (!t->discard_alignment) - t->discard_alignment = - b->discard_alignment & (b->discard_granularity - 1); + t->alignment_offset = lcm(t->alignment_offset, alignment) + & (max(t->physical_block_size, t->io_min) - 1); - /* Top device aligned on logical block boundary? */ - if (t->alignment_offset & (t->logical_block_size - 1)) { + if (t->alignment_offset & (t->logical_block_size - 1)) t->misaligned = 1; - ret = -1; - } - /* Find lcm() of optimal I/O size and granularity */ - t->io_opt = lcm(t->io_opt, b->io_opt); - t->discard_granularity = lcm(t->discard_granularity, - b->discard_granularity); + /* Discard alignment and granularity */ + if (b->discard_granularity) { + + alignment = b->discard_alignment - + (offset & (b->discard_granularity - 1)); + + if (t->discard_granularity != 0 && + t->discard_alignment != alignment) { + top = t->discard_granularity + t->discard_alignment; + bottom = b->discard_granularity + alignment; - /* Verify that optimal I/O size is a multiple of io_min */ - if (t->io_min && t->io_opt % t->io_min) - ret = -1; + /* Verify that top and bottom intervals line up */ + if (max(top, bottom) & (min(top, bottom) - 1)) + t->discard_misaligned = 1; + } + + t->discard_granularity = max(t->discard_granularity, + b->discard_granularity); + t->discard_alignment = lcm(t->discard_alignment, alignment) & + (t->discard_granularity - 1); + } - return ret; + return t->misaligned ? -1 : 0; } EXPORT_SYMBOL(blk_stack_limits); -- cgit v0.10.2 From 64a76b504b04b5da16d1e7658a95dd126594e02f Mon Sep 17 00:00:00 2001 From: Zhu Yi Date: Thu, 10 Dec 2009 14:37:21 -0800 Subject: iwlwifi: allocated rx page accounting cleanup In iwlwifi, priv->alloc_rxb_page is used to keep track of the Rx pages allocated by the driver. This cleans up the page free routines by introducing __iwl_free_pages/iwl_free_pages so that the accounting is more accurate and less error prone. This also fixes two instances where the counter was not updated. Signed-off-by: Zhu Yi Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 7da1dab..4609323 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -1835,8 +1835,7 @@ static int iwl3945_send_rxon_assoc(struct iwl_priv *priv) rc = -EIO; } - priv->alloc_rxb_page--; - free_pages(cmd.reply_page, priv->hw_params.rx_page_order); + iwl_free_pages(priv, cmd.reply_page); return rc; } diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 2673e9a..e1032f2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1353,4 +1353,15 @@ static inline int is_channel_ibss(const struct iwl_channel_info *ch) return ((ch->flags & EEPROM_CHANNEL_IBSS)) ? 1 : 0; } +static inline void __iwl_free_pages(struct iwl_priv *priv, struct page *page) +{ + __free_pages(page, priv->hw_params.rx_page_order); + priv->alloc_rxb_page--; +} + +static inline void iwl_free_pages(struct iwl_priv *priv, unsigned long page) +{ + free_pages(page, priv->hw_params.rx_page_order); + priv->alloc_rxb_page--; +} #endif /* __iwl_dev_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c index a231659..30e9ea6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c @@ -234,7 +234,7 @@ cancel: } fail: if (cmd->reply_page) { - free_pages(cmd->reply_page, priv->hw_params.rx_page_order); + iwl_free_pages(priv, cmd->reply_page); cmd->reply_page = 0; } out: diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index 6090bc1..f5c87e7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -345,10 +345,8 @@ void iwl_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq) pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma, PAGE_SIZE << priv->hw_params.rx_page_order, PCI_DMA_FROMDEVICE); - __free_pages(rxq->pool[i].page, - priv->hw_params.rx_page_order); + __iwl_free_pages(priv, rxq->pool[i].page); rxq->pool[i].page = NULL; - priv->alloc_rxb_page--; } } @@ -416,9 +414,7 @@ void iwl_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq) pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma, PAGE_SIZE << priv->hw_params.rx_page_order, PCI_DMA_FROMDEVICE); - priv->alloc_rxb_page--; - __free_pages(rxq->pool[i].page, - priv->hw_params.rx_page_order); + __iwl_free_pages(priv, rxq->pool[i].page); rxq->pool[i].page = NULL; } list_add_tail(&rxq->pool[i].list, &rxq->rx_used); diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index a2b2b83..fa1c89b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -144,8 +144,7 @@ static int iwl_send_scan_abort(struct iwl_priv *priv) clear_bit(STATUS_SCAN_HW, &priv->status); } - priv->alloc_rxb_page--; - free_pages(cmd.reply_page, priv->hw_params.rx_page_order); + iwl_free_pages(priv, cmd.reply_page); return ret; } diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index cd6a690..cde09a8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -164,9 +164,7 @@ int iwl_send_add_sta(struct iwl_priv *priv, break; } } - - priv->alloc_rxb_page--; - free_pages(cmd.reply_page, priv->hw_params.rx_page_order); + iwl_free_pages(priv, cmd.reply_page); return ret; } @@ -391,9 +389,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr, break; } } - - priv->alloc_rxb_page--; - free_pages(cmd.reply_page, priv->hw_params.rx_page_order); + iwl_free_pages(priv, cmd.reply_page); return ret; } diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 2a28a1f..994db4a 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -812,7 +812,7 @@ static int iwl3945_get_measurement(struct iwl_priv *priv, break; } - free_pages(cmd.reply_page, priv->hw_params.rx_page_order); + iwl_free_pages(priv, cmd.reply_page); return rc; } @@ -1198,9 +1198,7 @@ void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq) pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma, PAGE_SIZE << priv->hw_params.rx_page_order, PCI_DMA_FROMDEVICE); - priv->alloc_rxb_page--; - __free_pages(rxq->pool[i].page, - priv->hw_params.rx_page_order); + __iwl_free_pages(priv, rxq->pool[i].page); rxq->pool[i].page = NULL; } list_add_tail(&rxq->pool[i].list, &rxq->rx_used); @@ -1247,10 +1245,8 @@ static void iwl3945_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rx pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma, PAGE_SIZE << priv->hw_params.rx_page_order, PCI_DMA_FROMDEVICE); - __free_pages(rxq->pool[i].page, - priv->hw_params.rx_page_order); + __iwl_free_pages(priv, rxq->pool[i].page); rxq->pool[i].page = NULL; - priv->alloc_rxb_page--; } } -- cgit v0.10.2 From f8701fe3aec24fcfb0dfa19aab47904611f96daf Mon Sep 17 00:00:00 2001 From: Reinette Chatre Date: Thu, 10 Dec 2009 14:37:22 -0800 Subject: iwlwifi: power up all devices for EEPROM read Recent commits "iwlwifi: remove power-wasting calls to apm_ops.init()" and "iwlagn: power up device before initializing EEPROM" had the goal of reducing device power consumption from the time the module is loaded until the interface is brought up and the device's power saving mechanisms kick in. The idea is that once the module is loaded there is no need for the device to consume power until the interface is brought up. With the current solution the device is only powered up during EEPROM read, and then so also only if the EEPROM type is OTP. We have found that on certain platforms even non-OTP devices require power to be up during EEPROM read. On these platforms the driver never loads and the system log contains the following: iwlagn 0000:03:00.0: MAC is in deep sleep!. CSR_GP_CNTRL = 0x080403D8 We thus now power up all devices during EEPROM read. Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h index a7bfae0..1ec8cb4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/iwlwifi/iwl-csr.h @@ -77,8 +77,7 @@ * The MAC (uCode processor, etc.) does not need to be powered up for accessing * the CSR registers. * - * NOTE: Newer devices using one-time-programmable (OTP) memory - * require device to be awake in order to read this memory + * NOTE: Device does need to be awake in order to read this memory * via CSR_EEPROM and CSR_OTP registers */ #define CSR_BASE (0x000) @@ -111,9 +110,8 @@ /* * EEPROM and OTP (one-time-programmable) memory reads * - * NOTE: For (newer) devices using OTP, device must be awake, initialized via - * apm_ops.init() in order to read. Older devices (3945/4965/5000) - * use EEPROM and do not require this. + * NOTE: Device must be awake, initialized via apm_ops.init(), + * in order to read. */ #define CSR_EEPROM_REG (CSR_BASE+0x02c) #define CSR_EEPROM_GP (CSR_BASE+0x030) diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index 3946e5c..72f0d77 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c @@ -518,10 +518,7 @@ int iwl_eeprom_init(struct iwl_priv *priv) } e = (u16 *)priv->eeprom; - if (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) { - /* OTP reads require powered-up chip */ - priv->cfg->ops->lib->apm_ops.init(priv); - } + priv->cfg->ops->lib->apm_ops.init(priv); ret = priv->cfg->ops->lib->eeprom_ops.verify_signature(priv); if (ret < 0) { @@ -570,13 +567,6 @@ int iwl_eeprom_init(struct iwl_priv *priv) e[cache_addr / 2] = eeprom_data; cache_addr += sizeof(u16); } - - /* - * Now that OTP reads are complete, reset chip to save - * power until we load uCode during "up". - */ - priv->cfg->ops->lib->apm_ops.stop(priv); - } else { /* eeprom is an array of 16bit values */ for (addr = 0; addr < sz; addr += sizeof(u16)) { @@ -603,6 +593,8 @@ done: err: if (ret) iwl_eeprom_free(priv); + /* Reset chip to save power until we load uCode during "up". */ + priv->cfg->ops->lib->apm_ops.stop(priv); alloc_err: return ret; } -- cgit v0.10.2 From 521d9bce86331d8261213b807a9127f7e2ec046b Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Thu, 10 Dec 2009 14:37:23 -0800 Subject: iwlwifi: fix syslog message for event log dump size When trigger event log dumping from debugfs, the entire event log should be dumped and the size should match the number of events being dump. Signed-off-by: Wey-Yi Guy Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index b8377ef..715db219 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1842,7 +1842,7 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log) } #ifdef CONFIG_IWLWIFI_DEBUG - if (!(iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS)) + if (!(iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) && !full_log) size = (size > DEFAULT_DUMP_EVENT_LOG_ENTRIES) ? DEFAULT_DUMP_EVENT_LOG_ENTRIES : size; #else diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 994db4a..4c0e475 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -1684,7 +1684,7 @@ void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log) } #ifdef CONFIG_IWLWIFI_DEBUG - if (!(iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS)) + if (!(iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) && !full_log) size = (size > DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES) ? DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES : size; #else -- cgit v0.10.2 From 4d91f9f3730d6d82a3ba67cae215a1823ba6a191 Mon Sep 17 00:00:00 2001 From: Benoit Papillault Date: Sat, 12 Dec 2009 00:22:35 +0100 Subject: ath9k: Last fix for TX software padding. First, we copy/paste the padding stuff from ath9k_tx to ath_tx_cabq since it needs to same kind of padding, but for internally generated beacons. Next, software padding done on TX needs to be removed before calling ieee80211_tx_status. The code was already there in ath_tx_complete but it was wrong. Fix it by using ath9k_cmn_padpos. This later code has been tested by sending packets to a monitor interface and reading packets from the same interface. Signed-off-by: Benoit PAPILLAULT Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 2a11cc5..6770620 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1780,7 +1780,8 @@ void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb) struct ath_wiphy *aphy = hw->priv; struct ath_softc *sc = aphy->sc; struct ath_common *common = ath9k_hw_common(sc->sc_ah); - int hdrlen, padsize; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; + int padpos, padsize; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ath_tx_control txctl; @@ -1792,7 +1793,6 @@ void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb) * BSSes. */ if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) sc->tx.seq_no += 0x10; hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); @@ -1800,9 +1800,9 @@ void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb) } /* Add the padding after the header if this is not already done */ - hdrlen = ieee80211_get_hdrlen_from_skb(skb); - if (hdrlen & 3) { - padsize = hdrlen % 4; + padpos = ath9k_cmn_padpos(hdr->frame_control); + padsize = padpos & 3; + if (padsize && skb->len>padpos) { if (skb_headroom(skb) < padsize) { ath_print(common, ATH_DBG_XMIT, "TX CABQ padding failed\n"); @@ -1810,7 +1810,7 @@ void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb) return; } skb_push(skb, padsize); - memmove(skb->data, skb->data + padsize, hdrlen); + memmove(skb->data, skb->data + padsize, padpos); } txctl.txq = sc->beacon.cabq; @@ -1838,7 +1838,8 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, struct ieee80211_hw *hw = sc->hw; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); struct ath_common *common = ath9k_hw_common(sc->sc_ah); - int hdrlen, padsize; + struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data; + int padpos, padsize; ath_print(common, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb); @@ -1853,14 +1854,14 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, tx_info->flags |= IEEE80211_TX_STAT_ACK; } - hdrlen = ieee80211_get_hdrlen_from_skb(skb); - padsize = hdrlen & 3; - if (padsize && hdrlen >= 24) { + padpos = ath9k_cmn_padpos(hdr->frame_control); + padsize = padpos & 3; + if (padsize && skb->len>padpos+padsize) { /* * Remove MAC header padding before giving the frame back to * mac80211. */ - memmove(skb->data + padsize, skb->data, hdrlen); + memmove(skb->data + padsize, skb->data, padpos); skb_pull(skb, padsize); } -- cgit v0.10.2 From 855da5e07ef4dba5f23d8f6f31004116ba16c52a Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 13 Dec 2009 17:07:45 +0100 Subject: drivers/net/wireless: Correct code taking the size of a pointer sizeof(iv16) and sizeof(iv32) are the sizes of pointers. Change them to the size of the copied data. Furthermore, iveiv_entry is a local structure that has just been initialized and is not visible outside this function. Thus, there would seem to be no point to copy data into it. The order of the arguments is thus changed to copy the data into the parameters, which are provided as pointers, suggesting in this case that they should be used to return values. A simplified version of the semantic patch that finds the first problem is as follows: (http://coccinelle.lip6.fr/) // @@ expression *x; expression f; type T; @@ *f(...,(T)x,...) // Signed-off-by: Julia Lawall Acked-by: Gertjan van Wingerde Acked-by: Ivo van Doorn Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 6e13650..a199f85 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -2140,8 +2140,8 @@ static void rt2800_get_tkip_seq(struct ieee80211_hw *hw, u8 hw_key_idx, rt2800_register_multiread(rt2x00dev, offset, &iveiv_entry, sizeof(iveiv_entry)); - memcpy(&iveiv_entry.iv[0], iv16, sizeof(iv16)); - memcpy(&iveiv_entry.iv[4], iv32, sizeof(iv32)); + memcpy(iv16, &iveiv_entry.iv[0], sizeof(*iv16)); + memcpy(iv32, &iveiv_entry.iv[4], sizeof(*iv32)); } static int rt2800_set_rts_threshold(struct ieee80211_hw *hw, u32 value) -- cgit v0.10.2 From 93b6bd26b74efe46b4579592560f9f1cb7b61994 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Mon, 14 Dec 2009 20:33:55 +0100 Subject: rt2x00: Disable powersaving for rt61pci and rt2800pci. We've had many reports of rt61pci failures with powersaving enabled. Therefore, as a stop-gap measure, disable powersaving of the rt61pci until we have found a proper solution. Also disable powersaving on rt2800pci as it most probably will show the same problem. Cc: stable@kernel.org Signed-off-by: Gertjan van Wingerde Acked-by: Ivo van Doorn Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index a199f85..6bf6c0f 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -2022,6 +2022,12 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) u16 eeprom; /* + * Disable powersaving as default on PCI devices. + */ + if (rt2x00_intf_is_pci(rt2x00dev)) + rt2x00dev->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; + + /* * Initialize all hw fields. */ rt2x00dev->hw->flags = diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 687e17d..0ca5893 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -2539,6 +2539,11 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) unsigned int i; /* + * Disable powersaving as default. + */ + rt2x00dev->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; + + /* * Initialize all hw fields. */ rt2x00dev->hw->flags = -- cgit v0.10.2 From af6b8ee38833b39f70946f767740565ceb126961 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 14 Dec 2009 14:12:08 -0800 Subject: iwlwifi: fix EEPROM/OTP reading endian annotations and a bug The construct "le16_to_cpu((__force __le16)(r >> 16))" has always bothered me when looking through the iwlwifi code, it shouldn't be necessary to __force anything, and before this code, "r" was obtained with an ioread32, which swaps each of the two u16 values in it properly when swapping the entire u32 value. I've had arguments about this code with people before, but always conceded they were right because removing it only made things not work at all on big endian platforms. However, analysing a failure of the OTP reading code, I now finally figured out what is going on, and why my intuition about that code being wrong was right all along. It turns out that the 'priv->eeprom' u8 array really wants to have the data in it in little endian. So the force code above and all really converts *to* little endian, not from it. Cf., for instance, the function iwl_eeprom_query16() -- it reads two u8 values and combines them into a u16, in a little-endian way. And considering it more, it makes sense to have the eeprom array as on the device, after all not all values really are 16-bit values, the MAC address for instance is not. Now, what this really means is that all the annotations are completely wrong. The eeprom reading code should fill the priv->eeprom array as a __le16 array, with __le16 values. This also means that iwl_read_otp_word() should really have a __le16 pointer as the data argument, since it should be filling that in a format suitable for priv->eeprom. Propagating these changes throughout, iwl_find_otp_image() is found to be, now obviously visible, defective -- it uses the data returned by iwl_read_otp_word() directly as if it was CPU endianness. Fixing that, which is this hunk of the patch: - next_link_addr = link_value * sizeof(u16); + next_link_addr = le16_to_cpu(link_value) * sizeof(u16); is the only real change of this patch. Everything else is just fixing the sparse annotations. Also, the bug only shows up on big endian platforms with a 1000 series card. 5000 and previous series do not use OTP, and 6000 series has shadow RAM support which means we don't ever use the defective code on any cards but 1000. Signed-off-by: Johannes Berg Cc: stable@kernel.org Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index e1032f2..165d1f6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1168,7 +1168,7 @@ struct iwl_priv { u32 last_beacon_time; u64 last_tsf; - /* eeprom */ + /* eeprom -- this is in the card's little endian byte order */ u8 *eeprom; int nvm_device_type; struct iwl_eeprom_calib_info *calib_info; diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index 72f0d77..08ad6e4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c @@ -370,7 +370,7 @@ static int iwl_init_otp_access(struct iwl_priv *priv) return ret; } -static int iwl_read_otp_word(struct iwl_priv *priv, u16 addr, u16 *eeprom_data) +static int iwl_read_otp_word(struct iwl_priv *priv, u16 addr, __le16 *eeprom_data) { int ret = 0; u32 r; @@ -404,7 +404,7 @@ static int iwl_read_otp_word(struct iwl_priv *priv, u16 addr, u16 *eeprom_data) CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK); IWL_ERR(priv, "Correctable OTP ECC error, continue read\n"); } - *eeprom_data = le16_to_cpu((__force __le16)(r >> 16)); + *eeprom_data = cpu_to_le16(r >> 16); return 0; } @@ -413,7 +413,8 @@ static int iwl_read_otp_word(struct iwl_priv *priv, u16 addr, u16 *eeprom_data) */ static bool iwl_is_otp_empty(struct iwl_priv *priv) { - u16 next_link_addr = 0, link_value; + u16 next_link_addr = 0; + __le16 link_value; bool is_empty = false; /* locate the beginning of OTP link list */ @@ -443,7 +444,8 @@ static bool iwl_is_otp_empty(struct iwl_priv *priv) static int iwl_find_otp_image(struct iwl_priv *priv, u16 *validblockaddr) { - u16 next_link_addr = 0, link_value = 0, valid_addr; + u16 next_link_addr = 0, valid_addr; + __le16 link_value = 0; int usedblocks = 0; /* set addressing mode to absolute to traverse the link list */ @@ -463,7 +465,7 @@ static int iwl_find_otp_image(struct iwl_priv *priv, * check for more block on the link list */ valid_addr = next_link_addr; - next_link_addr = link_value * sizeof(u16); + next_link_addr = le16_to_cpu(link_value) * sizeof(u16); IWL_DEBUG_INFO(priv, "OTP blocks %d addr 0x%x\n", usedblocks, next_link_addr); if (iwl_read_otp_word(priv, next_link_addr, &link_value)) @@ -497,7 +499,7 @@ static int iwl_find_otp_image(struct iwl_priv *priv, */ int iwl_eeprom_init(struct iwl_priv *priv) { - u16 *e; + __le16 *e; u32 gp = iwl_read32(priv, CSR_EEPROM_GP); int sz; int ret; @@ -516,7 +518,7 @@ int iwl_eeprom_init(struct iwl_priv *priv) ret = -ENOMEM; goto alloc_err; } - e = (u16 *)priv->eeprom; + e = (__le16 *)priv->eeprom; priv->cfg->ops->lib->apm_ops.init(priv); @@ -559,7 +561,7 @@ int iwl_eeprom_init(struct iwl_priv *priv) } for (addr = validblockaddr; addr < validblockaddr + sz; addr += sizeof(u16)) { - u16 eeprom_data; + __le16 eeprom_data; ret = iwl_read_otp_word(priv, addr, &eeprom_data); if (ret) @@ -584,7 +586,7 @@ int iwl_eeprom_init(struct iwl_priv *priv) goto done; } r = _iwl_read_direct32(priv, CSR_EEPROM_REG); - e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16)); + e[addr / 2] = cpu_to_le16(r >> 16); } } ret = 0; -- cgit v0.10.2 From b7bb1756cb6a610cdbac8cfdad9e79bb5670b63b Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 14 Dec 2009 14:12:09 -0800 Subject: iwlwifi: fix more eeprom endian bugs I've also for a long time had a problem with the temperature calculation code, which I had fixed by byte-swapping the values, and now it turns out that was the correct fix after all. Also, any use of iwl_eeprom_query_addr() that is for more than a u8 must be cast to little endian, and some structs as well. Fix all this. Again, no real impact on platforms that already are little endian. Signed-off-by: Johannes Berg Cc: stable@kernel.org Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 386513b..484c5fd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -1204,7 +1204,7 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel, iwl4965_interpolate_chan(priv, channel, &ch_eeprom_info); /* calculate tx gain adjustment based on power supply voltage */ - voltage = priv->calib_info->voltage; + voltage = le16_to_cpu(priv->calib_info->voltage); init_voltage = (s32)le32_to_cpu(priv->card_alive_init.voltage); voltage_compensation = iwl4965_get_voltage_compensation(voltage, init_voltage); diff --git a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h index 4ef6804..bc056e9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h @@ -92,11 +92,15 @@ static inline s32 iwl_temp_calib_to_offset(struct iwl_priv *priv) { - u16 *temp_calib = (u16 *)iwl_eeprom_query_addr(priv, - EEPROM_5000_TEMPERATURE); - /* offset = temperature - voltage / coef */ - s32 offset = (s32)(temp_calib[0] - temp_calib[1] / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF); - return offset; + u16 temperature, voltage; + __le16 *temp_calib = + (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_5000_TEMPERATURE); + + temperature = le16_to_cpu(temp_calib[0]); + voltage = le16_to_cpu(temp_calib[1]); + + /* offset = temp - volt / coeff */ + return (s32)(temperature - voltage / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF); } /* Fixed (non-configurable) rx data from phy */ diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index e2f8615..33a5866 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -333,14 +333,15 @@ static void iwl5000_set_ct_threshold(struct iwl_priv *priv) static int iwl5000_set_Xtal_calib(struct iwl_priv *priv) { struct iwl_calib_xtal_freq_cmd cmd; - u16 *xtal_calib = (u16 *)iwl_eeprom_query_addr(priv, EEPROM_5000_XTAL); + __le16 *xtal_calib = + (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_5000_XTAL); cmd.hdr.op_code = IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD; cmd.hdr.first_group = 0; cmd.hdr.groups_num = 1; cmd.hdr.data_valid = 1; - cmd.cap_pin1 = (u8)xtal_calib[0]; - cmd.cap_pin2 = (u8)xtal_calib[1]; + cmd.cap_pin1 = le16_to_cpu(xtal_calib[0]); + cmd.cap_pin2 = le16_to_cpu(xtal_calib[1]); return iwl_calib_set(&priv->calib_results[IWL_CALIB_XTAL], (u8 *)&cmd, sizeof(cmd)); } diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index 5cd2b66..0cd9c02 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h @@ -137,7 +137,7 @@ struct iwl_eeprom_channel { * */ struct iwl_eeprom_enhanced_txpwr { - u16 common; + __le16 common; s8 chain_a_max; s8 chain_b_max; s8 chain_c_max; @@ -360,7 +360,7 @@ struct iwl_eeprom_calib_subband_info { struct iwl_eeprom_calib_info { u8 saturation_power24; /* half-dBm (e.g. "34" = 17 dBm) */ u8 saturation_power52; /* half-dBm */ - s16 voltage; /* signed */ + __le16 voltage; /* signed */ struct iwl_eeprom_calib_subband_info band_info[EEPROM_TX_POWER_BANDS]; } __attribute__ ((packed)); -- cgit v0.10.2 From bc45a67079c916a9bd0a95b0b879cc0f259bac6e Mon Sep 17 00:00:00 2001 From: Reinette Chatre Date: Mon, 14 Dec 2009 14:12:10 -0800 Subject: iwl3945: disable power save we see from http://bugzilla.intellinuxwireless.org/show_bug.cgi?id=2125 that power saving does not work well on 3945. Since then power saving has also been connected with association problems where an AP deathenticates a 3945 after it is unable to transmit data to it - this happens when 3945 enters power savings mode. Disable power save support until issues are resolved. Signed-off-by: Reinette Chatre CC: stable@kernel.org Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 4609323..e413bd3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -2835,6 +2835,7 @@ static struct iwl_cfg iwl3945_bg_cfg = { .use_isr_legacy = true, .ht_greenfield_support = false, .led_compensation = 64, + .broken_powersave = true, }; static struct iwl_cfg iwl3945_abg_cfg = { @@ -2851,6 +2852,7 @@ static struct iwl_cfg iwl3945_abg_cfg = { .use_isr_legacy = true, .ht_greenfield_support = false, .led_compensation = 64, + .broken_powersave = true, }; struct pci_device_id iwl3945_hw_card_ids[] = { diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 4c0e475..c322d6c 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -3932,9 +3932,11 @@ static int iwl3945_setup_mac(struct iwl_priv *priv) /* Tell mac80211 our characteristics */ hw->flags = IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_NOISE_DBM | - IEEE80211_HW_SPECTRUM_MGMT | - IEEE80211_HW_SUPPORTS_PS | - IEEE80211_HW_SUPPORTS_DYNAMIC_PS; + IEEE80211_HW_SPECTRUM_MGMT; + + if (!priv->cfg->broken_powersave) + hw->flags |= IEEE80211_HW_SUPPORTS_PS | + IEEE80211_HW_SUPPORTS_DYNAMIC_PS; hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | -- cgit v0.10.2 From 731a29b74aa823e09a6547befce3f721bef32f86 Mon Sep 17 00:00:00 2001 From: Reinette Chatre Date: Mon, 14 Dec 2009 14:12:11 -0800 Subject: iwlwifi: initialize spinlock before use Recent powersaving work resulted in power management ops being called during EEPROM initialization. The lock used by these functions is not initialized at this time. Ensure lock is initialized before it is used. Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 715db219..1c9866d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3173,7 +3173,6 @@ static int iwl_init_drv(struct iwl_priv *priv) priv->ibss_beacon = NULL; - spin_lock_init(&priv->lock); spin_lock_init(&priv->sta_lock); spin_lock_init(&priv->hcmd_lock); @@ -3361,10 +3360,11 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) (unsigned long long) pci_resource_len(pdev, 0)); IWL_DEBUG_INFO(priv, "pci_resource_base = %p\n", priv->hw_base); - /* this spin lock will be used in apm_ops.init and EEPROM access + /* these spin locks will be used in apm_ops.init and EEPROM access * we should init now */ spin_lock_init(&priv->reg_lock); + spin_lock_init(&priv->lock); iwl_hw_detect(priv); IWL_INFO(priv, "Detected Intel Wireless WiFi Link %s REV=0x%X\n", priv->cfg->name, priv->hw_rev); diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index c322d6c..96b23f4 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -3863,7 +3863,6 @@ static int iwl3945_init_drv(struct iwl_priv *priv) priv->retry_rate = 1; priv->ibss_beacon = NULL; - spin_lock_init(&priv->lock); spin_lock_init(&priv->sta_lock); spin_lock_init(&priv->hcmd_lock); @@ -4055,10 +4054,11 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e * PCI Tx retries from interfering with C3 CPU state */ pci_write_config_byte(pdev, 0x41, 0x00); - /* this spin lock will be used in apm_ops.init and EEPROM access + /* these spin locks will be used in apm_ops.init and EEPROM access * we should init now */ spin_lock_init(&priv->reg_lock); + spin_lock_init(&priv->lock); /*********************** * 4. Read EEPROM -- cgit v0.10.2 From dc57a303faab8562b92e85df0d79c4a05d7e2a61 Mon Sep 17 00:00:00 2001 From: Zhu Yi Date: Mon, 14 Dec 2009 14:12:12 -0800 Subject: iwl3945: fix panic in iwl3945 driver 3945 updated write_ptr without regard to read_ptr on the Tx path. This messes up our TFD on high load and result in the following: <1>[ 7290.414172] IP: [] iwl3945_rx_reply_tx+0xc1/0x450 [iwl3945] <4>[ 7290.414205] PGD 0 <1>[ 7290.414214] Thread overran stack, or stack corrupted <0>[ 7290.414229] Oops: 0002 [#1] PREEMPT SMP <0>[ 7290.414246] last sysfs file: /sys/devices/platform/coretemp.1/temp1_input <4>[ 7290.414265] CPU 0 <4>[ 7290.414274] Modules linked in: af_packet nfsd usb_storage usb_libusual cpufreq_powersave exportfs cpufreq_conservative iwl3945 nfs cpufreq_userspace snd_hda_codec_realtek acpi_cpufreq uvcvideo lockd iwlcore snd_hda_intel joydev coretemp nfs_acl videodev snd_hda_codec mac80211 v4l1_compat snd_hwdep sbp2 v4l2_compat_ioctl32 uhci_hcd psmouse auth_rpcgss ohci1394 cfg80211 ehci_hcd video ieee1394 snd_pcm serio_raw battery ac nvidia(P) usbcore output sunrpc evdev lirc_ene0100 snd_page_alloc rfkill tg3 libphy fuse lzo lzo_decompress lzo_compress <6>[ 7290.414486] Pid: 0, comm: swapper Tainted: P 2.6.32-rc8-wl #213 Aspire 5720 <6>[ 7290.414507] RIP: 0010:[] [] iwl3945_rx_reply_tx+0xc1/0x450 [iwl3945] <6>[ 7290.414541] RSP: 0018:ffff880002203d60 EFLAGS: 00010246 <6>[ 7290.414557] RAX: 000000000000004f RBX: ffff880064c11600 RCX: 0000000000000013 <6>[ 7290.414576] RDX: ffffffffa0ddcf20 RSI: ffff8800512b7008 RDI: 0000000000000038 <6>[ 7290.414596] RBP: ffff880002203dd0 R08: 0000000000000000 R09: 0000000000000100 <6>[ 7290.414616] R10: 0000000000000001 R11: 0000000000000000 R12: 00000000000000a0 <6>[ 7290.414635] R13: 0000000000000002 R14: 0000000000000013 R15: 0000000000020201 <6>[ 7290.414655] FS: 0000000000000000(0000) GS:ffff880002200000(0000) knlGS:0000000000000000 <6>[ 7290.414677] CS: 0010 DS: 0018 ES: 0018 CR0: 000000008005003b <6>[ 7290.414693] CR2: 0000000000000041 CR3: 0000000001001000 CR4: 00000000000006f0 <6>[ 7290.414712] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 <6>[ 7290.414732] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 <4>[ 7290.414752] Process swapper (pid: 0, threadinfo ffffffff81524000, task ffffffff81528b60) <0>[ 7290.414772] Stack: <4>[ 7290.414780] ffff880002203da0 0000000000000046 0000000000000000 0000000000000046 <4>[ 7290.414804] <0> 0000000000000282 0000000000000282 0000000000000282 ffff880064c12010 <4>[ 7290.414830] <0> ffff880002203db0 ffff880064c11600 ffff880064c12e50 ffff8800512b7000 <0>[ 7290.414858] Call Trace: <0>[ 7290.414867] <4>[ 7290.414884] [] iwl3945_irq_tasklet+0x657/0x1740 [iwl3945] <4>[ 7290.414910] [] ? _spin_unlock+0x30/0x60 <4>[ 7290.414931] [] tasklet_action+0x101/0x110 <4>[ 7290.414950] [] __do_softirq+0xc0/0x160 <4>[ 7290.414968] [] call_softirq+0x1c/0x30 <4>[ 7290.414986] [] do_softirq+0x75/0xb0 <4>[ 7290.415003] [] irq_exit+0x95/0xa0 <4>[ 7290.415020] [] do_IRQ+0x77/0xf0 <4>[ 7290.415038] [] ret_from_intr+0x0/0xf <0>[ 7290.415052] <4>[ 7290.415067] [] ? acpi_idle_enter_bm+0x270/0x2a5 <4>[ 7290.415087] [] ? acpi_idle_enter_bm+0x27a/0x2a5 <4>[ 7290.415107] [] ? acpi_idle_enter_bm+0x270/0x2a5 <4>[ 7290.415130] [] ? cpuidle_idle_call+0x93/0xf0 <4>[ 7290.415149] [] ? cpu_idle+0xa7/0x110 <4>[ 7290.415168] [] ? rest_init+0x75/0x80 <4>[ 7290.415187] [] ? start_kernel+0x3a7/0x3b3 <4>[ 7290.415206] [] ? x86_64_start_reservations+0x125/0x129 <4>[ 7290.415227] [] ? x86_64_start_kernel+0xe4/0xeb <0>[ 7290.415243] Code: 00 41 39 ce 0f 8d e8 01 00 00 48 8b 47 40 48 63 d2 48 69 d2 98 00 00 00 4c 8b 04 02 48 c7 c2 20 cf dd a0 49 8d 78 38 49 8d 40 4f 47 09 00 c6 47 0c 00 c6 47 0f 00 c6 47 12 00 c6 47 15 00 49 <1>[ 7290.415382] RIP [] iwl3945_rx_reply_tx+0xc1/0x450 [iwl3945] <4>[ 7290.415410] RSP <0>[ 7290.415421] CR2: 0000000000000041 <4>[ 7290.415436] ---[ end trace ec46807277caa515 ]--- <0>[ 7290.415450] Kernel panic - not syncing: Fatal exception in interrupt <4>[ 7290.415468] Pid: 0, comm: swapper Tainted: P D 2.6.32-rc8-wl #213 <4>[ 7290.415486] Call Trace: <4>[ 7290.415495] [] panic+0x7d/0x13a <4>[ 7290.415519] [] oops_end+0xda/0xe0 <4>[ 7290.415538] [] no_context+0xea/0x250 <4>[ 7290.415557] [] ? select_task_rq_fair+0x511/0x780 <4>[ 7290.415578] [] __bad_area_nosemaphore+0x125/0x1e0 <4>[ 7290.415597] [] ? __enqueue_entity+0x7c/0x80 <4>[ 7290.415616] [] ? enqueue_task_fair+0x111/0x150 <4>[ 7290.415636] [] bad_area_nosemaphore+0xe/0x10 <4>[ 7290.415656] [] do_page_fault+0x26a/0x320 <4>[ 7290.415674] [] page_fault+0x1f/0x30 <4>[ 7290.415697] [] ? iwl3945_rx_reply_tx+0xc1/0x450 [iwl3945] <4>[ 7290.415723] [] iwl3945_irq_tasklet+0x657/0x1740 [iwl3945] <4>[ 7290.415746] [] ? _spin_unlock+0x30/0x60 <4>[ 7290.415764] [] tasklet_action+0x101/0x110 <4>[ 7290.415783] [] __do_softirq+0xc0/0x160 <4>[ 7290.415801] [] call_softirq+0x1c/0x30 <4>[ 7290.415818] [] do_softirq+0x75/0xb0 <4>[ 7290.415835] [] irq_exit+0x95/0xa0 <4>[ 7290.415852] [] do_IRQ+0x77/0xf0 <4>[ 7290.415869] [] ret_from_intr+0x0/0xf <4>[ 7290.415883] [] ? acpi_idle_enter_bm+0x270/0x2a5 <4>[ 7290.415911] [] ? acpi_idle_enter_bm+0x27a/0x2a5 <4>[ 7290.415931] [] ? acpi_idle_enter_bm+0x270/0x2a5 <4>[ 7290.415952] [] ? cpuidle_idle_call+0x93/0xf0 <4>[ 7290.415971] [] ? cpu_idle+0xa7/0x110 <4>[ 7290.415989] [] ? rest_init+0x75/0x80 <4>[ 7290.416007] [] ? start_kernel+0x3a7/0x3b3 <4>[ 7290.416026] [] ? x86_64_start_reservations+0x125/0x129 <4>[ 7290.416047] [] ? x86_64_start_kernel+0xe4/0xeb Reported-by: Maxim Levitsky Tested-by: Maxim Levitsky Signed-off-by: Zhu Yi Signed-off-by: Reinette Chatre CC: stable@kernel.org Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 96b23f4..e5d8fa3 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -548,6 +548,9 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) txq = &priv->txq[txq_id]; q = &txq->q; + if ((iwl_queue_space(q) < q->high_mark)) + goto drop; + spin_lock_irqsave(&priv->lock, flags); idx = get_cmd_index(q, q->write_ptr, 0); -- cgit v0.10.2 From 6c3069b1e7e983e176a5f826e2edffefdd404a08 Mon Sep 17 00:00:00 2001 From: Reinette Chatre Date: Mon, 14 Dec 2009 14:12:13 -0800 Subject: iwlwifi: fix 40MHz operation setting on cards that do not allow it Some devices have 40MHz operation disabled entirely. Ensure that driver do not enable 40MHz operation if a channel does not allow this. This fixes http://bugzilla.intellinuxwireless.org/show_bug.cgi?id=2135 Signed-off-by: Reinette Chatre CC: stable@kernel.org Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index 08ad6e4..4a30969 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c @@ -749,7 +749,8 @@ static int iwl_mod_ht40_chan_info(struct iwl_priv *priv, ch_info->ht40_eeprom = *eeprom_ch; ch_info->ht40_max_power_avg = eeprom_ch->max_power_avg; ch_info->ht40_flags = eeprom_ch->flags; - ch_info->ht40_extension_channel &= ~clear_ht40_extension_channel; + if (eeprom_ch->flags & EEPROM_CHANNEL_VALID) + ch_info->ht40_extension_channel &= ~clear_ht40_extension_channel; return 0; } -- cgit v0.10.2 From 7988436c6330eab98f64b6e799ce2d30fe5ffd55 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Mon, 14 Dec 2009 23:32:31 +0100 Subject: rt2x00: Fix calculation of rt2800 iveiv entry offset. Fix typo. The index should be multiplied by the entry size, not 'and'-ed. Found via code-inspection. Signed-off-by: Gertjan van Wingerde Acked-by: Ivo van Doorn Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index c5fe867..1a7eae3 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -1323,7 +1323,7 @@ #define PAIRWISE_KEY_ENTRY(__idx) \ ( PAIRWISE_KEY_TABLE_BASE + ((__idx) * sizeof(struct hw_key_entry)) ) #define MAC_IVEIV_ENTRY(__idx) \ - ( MAC_IVEIV_TABLE_BASE + ((__idx) & sizeof(struct mac_iveiv_entry)) ) + ( MAC_IVEIV_TABLE_BASE + ((__idx) * sizeof(struct mac_iveiv_entry)) ) #define MAC_WCID_ATTR_ENTRY(__idx) \ ( MAC_WCID_ATTRIBUTE_BASE + ((__idx) * sizeof(u32)) ) #define SHARED_KEY_ENTRY(__idx) \ -- cgit v0.10.2 From 17b182e3db255ab068c2ebb85f34840607a53cc4 Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 14 Dec 2009 14:56:56 +0530 Subject: ath9k: Fix bug in assigning sequence number The internal, driver-specific maintenance of sequence numbers is applicable only for HT frames. Also, remove comments that are not relevant anymore. Signed-off-by: Sujith Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 6770620..fd0cf4d8 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1414,17 +1414,9 @@ static void assign_aggr_tid_seqno(struct sk_buff *skb, * For HT capable stations, we save tidno for later use. * We also override seqno set by upper layer with the one * in tx aggregation state. - * - * If fragmentation is on, the sequence number is - * not overridden, since it has been - * incremented by the fragmentation routine. - * - * FIXME: check if the fragmentation threshold exceeds - * IEEE80211 max. */ tid = ATH_AN_2_TID(an, bf->bf_tidno); - hdr->seq_ctrl = cpu_to_le16(tid->seq_next << - IEEE80211_SEQ_SEQ_SHIFT); + hdr->seq_ctrl = cpu_to_le16(tid->seq_next << IEEE80211_SEQ_SEQ_SHIFT); bf->bf_seqno = tid->seq_next; INCR(tid->seq_next, IEEE80211_SEQ_MAX); } @@ -1636,7 +1628,8 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf, bf->bf_keyix = ATH9K_TXKEYIX_INVALID; } - if (ieee80211_is_data_qos(fc) && (sc->sc_flags & SC_OP_TXAGGR)) + if (ieee80211_is_data_qos(fc) && bf_isht(bf) && + (sc->sc_flags & SC_OP_TXAGGR)) assign_aggr_tid_seqno(skb, bf); bf->bf_mpdu = skb; -- cgit v0.10.2 From e8009e9850d59000d518296af372888911a129bd Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 14 Dec 2009 14:57:08 +0530 Subject: ath9k: Fix TX queue draining When TX DMA termination has failed, the HW has to be reset completely. Doing a fast channel change in this case is insufficient. Also, change the debug level of a couple of messages to FATAL. Cc: stable@kernel.org Signed-off-by: Sujith Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index 71b84d9..efc420c 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c @@ -186,7 +186,7 @@ bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q) wait = wait_time; while (ath9k_hw_numtxpending(ah, q)) { if ((--wait) == 0) { - ath_print(common, ATH_DBG_QUEUE, + ath_print(common, ATH_DBG_FATAL, "Failed to stop TX DMA in 100 " "msec after killing last frame\n"); break; diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index fd0cf4d8..1e813bb 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1108,11 +1108,11 @@ void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) if (npend) { int r; - ath_print(common, ATH_DBG_XMIT, + ath_print(common, ATH_DBG_FATAL, "Unable to stop TxDMA. Reset HAL!\n"); spin_lock_bh(&sc->sc_resetlock); - r = ath9k_hw_reset(ah, sc->sc_ah->curchan, true); + r = ath9k_hw_reset(ah, sc->sc_ah->curchan, false); if (r) ath_print(common, ATH_DBG_FATAL, "Unable to reset hardware; reset status %d\n", -- cgit v0.10.2 From 2ab81d4a9a5ecb13d343269b3cdf5d975c81c570 Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 14 Dec 2009 16:34:56 +0530 Subject: ath9k: Stop ANI when doing a reset The MIB counters are disabled when doing a chip reset. Since ANI depends on the MIB registers for its operation, relying on the contents of said registers during HW reset results in sub-optimal performance. Cc: stable@kernel.org Signed-off-by: Sujith Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index c487434..9e68c1a 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1973,6 +1973,9 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) struct ieee80211_hw *hw = sc->hw; int r; + /* Stop ANI */ + del_timer_sync(&common->ani.timer); + ath9k_hw_set_interrupts(ah, 0); ath_drain_all_txq(sc, retry_tx); ath_stoprecv(sc); @@ -2014,6 +2017,9 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) } } + /* Start ANI */ + ath_start_ani(common); + return r; } -- cgit v0.10.2 From 77ca7d9e2c099b4484bb10075948b4267f37d9fa Mon Sep 17 00:00:00 2001 From: "akpm@linux-foundation.org" Date: Mon, 14 Dec 2009 15:56:54 -0800 Subject: drivers/net/wireless/iwlwifi/iwl-tx.c: fix gcc-3.4.5 warning drivers/net/wireless/iwlwifi/iwl-tx.c: In function `iwl_hw_txq_ctx_free': drivers/net/wireless/iwlwifi/iwl-tx.c:410: warning: suggest explicit braces to avoid ambiguous `else' Cc: Zhu Yi Cc: Reinette Chatre Signed-off-by: Andrew Morton Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 00da5e1..87ce2bd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -407,13 +407,14 @@ void iwl_hw_txq_ctx_free(struct iwl_priv *priv) int txq_id; /* Tx queues */ - if (priv->txq) + if (priv->txq) { for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) if (txq_id == IWL_CMD_QUEUE_NUM) iwl_cmd_queue_free(priv); else iwl_tx_queue_free(priv, txq_id); + } iwl_free_dma_ptr(priv, &priv->kw); iwl_free_dma_ptr(priv, &priv->scd_bc_tbls); -- cgit v0.10.2 From 45b241689179a6065384260242637cf21dabfb2d Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Wed, 16 Dec 2009 05:12:58 +0100 Subject: Libertas: fix buffer overflow in lbs_get_essid() The libertas driver copies the SSID buffer back to the wireless core and appends a trailing NULL character for termination. This is a) unnecessary because the buffer is allocated with kzalloc and is hence already NULLed when this function is called, and b) for priv->curbssparams.ssid_len == 32, it writes back one byte too much which causes memory corruptions. Fix this by removing the extra write. Signed-off-by: Daniel Mack Cc: Stephen Hemminger Cc: Maithili Hinge Cc: Kiran Divekar Cc: Michael Hirsch Cc: netdev@vger.kernel.org Cc: libertas-dev@lists.infradead.org Cc: linux-wireless@lists.infradead.org Cc: stable@kernel.org Acked-by: Holger Schurig Acked-by: Dan Williams Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c index a8eb9e1..4b1aab5 100644 --- a/drivers/net/wireless/libertas/wext.c +++ b/drivers/net/wireless/libertas/wext.c @@ -2025,10 +2025,8 @@ static int lbs_get_essid(struct net_device *dev, struct iw_request_info *info, if (priv->connect_status == LBS_CONNECTED) { memcpy(extra, priv->curbssparams.ssid, priv->curbssparams.ssid_len); - extra[priv->curbssparams.ssid_len] = '\0'; } else { memset(extra, 0, 32); - extra[priv->curbssparams.ssid_len] = '\0'; } /* * If none, we may want to get the one that was set -- cgit v0.10.2 From 8585c2b896861aacd15337c3c7e58ad114e6cf60 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Wed, 16 Dec 2009 17:01:38 +0100 Subject: iwmc3200wifi: Fix test of unsigned in iwm_ntf_stop_resume_tx() `queue' was unsigned so the test did not work. Signed-off-by: Roel Kluin Reviewed-by: Pavel Roskin Acked-by: Zhu Yi Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/iwmc3200wifi/iwm.h b/drivers/net/wireless/iwmc3200wifi/iwm.h index 5a26bb0..79ffa3b 100644 --- a/drivers/net/wireless/iwmc3200wifi/iwm.h +++ b/drivers/net/wireless/iwmc3200wifi/iwm.h @@ -349,7 +349,7 @@ int iwm_up(struct iwm_priv *iwm); int iwm_down(struct iwm_priv *iwm); /* TX API */ -u16 iwm_tid_to_queue(u16 tid); +int iwm_tid_to_queue(u16 tid); void iwm_tx_credit_inc(struct iwm_priv *iwm, int id, int total_freed_pages); void iwm_tx_worker(struct work_struct *work); int iwm_xmit_frame(struct sk_buff *skb, struct net_device *netdev); diff --git a/drivers/net/wireless/iwmc3200wifi/netdev.c b/drivers/net/wireless/iwmc3200wifi/netdev.c index e4f0f87..c4c0d23 100644 --- a/drivers/net/wireless/iwmc3200wifi/netdev.c +++ b/drivers/net/wireless/iwmc3200wifi/netdev.c @@ -76,7 +76,7 @@ static int iwm_stop(struct net_device *ndev) */ static const u16 iwm_1d_to_queue[8] = { 1, 0, 0, 1, 2, 2, 3, 3 }; -u16 iwm_tid_to_queue(u16 tid) +int iwm_tid_to_queue(u16 tid) { if (tid > IWM_UMAC_TID_NR - 2) return -EINVAL; diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c index 72c27a3e..3db3d8b 100644 --- a/drivers/net/wireless/iwmc3200wifi/rx.c +++ b/drivers/net/wireless/iwmc3200wifi/rx.c @@ -1126,7 +1126,7 @@ static int iwm_ntf_stop_resume_tx(struct iwm_priv *iwm, u8 *buf, if (!stop) { struct iwm_tx_queue *txq; - u16 queue = iwm_tid_to_queue(bit); + int queue = iwm_tid_to_queue(bit); if (queue < 0) continue; -- cgit v0.10.2 From 9a418af5df03ad133cd8c8f6742b75e542db6392 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 17 Dec 2009 13:55:48 +0100 Subject: mac80211: fix peer HT capabilities I noticed yesterday, because Jeff had noticed a speed regression, cf. bug http://bugzilla.intellinuxwireless.org/show_bug.cgi?id=2138 that the SM PS settings for peers were wrong. Instead of overwriting the SM PS settings with the local bits, we need to keep the remote bits. The bug was part of the original HT code from over two years ago, but unfortunately nobody noticed that it makes no sense -- we shouldn't be overwriting the peer's setting with our own but rather keep it intact when masking the peer capabilities with our own. While fixing that, I noticed that the masking of capabilities is completely useless for most of the bits, so also fix those other bits. Finally, I also noticed that PSMP_SUPPORT no longer exists in the final 802.11n version, so also remove that. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 6bf6c0f..27bf887 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -2080,8 +2080,7 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_TX_STBC | - IEEE80211_HT_CAP_RX_STBC | - IEEE80211_HT_CAP_PSMP_SUPPORT; + IEEE80211_HT_CAP_RX_STBC; spec->ht.ampdu_factor = 3; spec->ht.ampdu_density = 4; spec->ht.mcs.tx_params = diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index d9724a2..163c840 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -832,7 +832,7 @@ struct ieee80211_ht_cap { #define IEEE80211_HT_CAP_DELAY_BA 0x0400 #define IEEE80211_HT_CAP_MAX_AMSDU 0x0800 #define IEEE80211_HT_CAP_DSSSCCK40 0x1000 -#define IEEE80211_HT_CAP_PSMP_SUPPORT 0x2000 +#define IEEE80211_HT_CAP_RESERVED 0x2000 #define IEEE80211_HT_CAP_40MHZ_INTOLERANT 0x4000 #define IEEE80211_HT_CAP_LSIG_TXOP_PROT 0x8000 diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index 3787455..d7dcee6 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c @@ -34,9 +34,28 @@ void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband, ht_cap->ht_supported = true; - ht_cap->cap = le16_to_cpu(ht_cap_ie->cap_info) & sband->ht_cap.cap; - ht_cap->cap &= ~IEEE80211_HT_CAP_SM_PS; - ht_cap->cap |= sband->ht_cap.cap & IEEE80211_HT_CAP_SM_PS; + /* + * The bits listed in this expression should be + * the same for the peer and us, if the station + * advertises more then we can't use those thus + * we mask them out. + */ + ht_cap->cap = le16_to_cpu(ht_cap_ie->cap_info) & + (sband->ht_cap.cap | + ~(IEEE80211_HT_CAP_LDPC_CODING | + IEEE80211_HT_CAP_SUP_WIDTH_20_40 | + IEEE80211_HT_CAP_GRN_FLD | + IEEE80211_HT_CAP_SGI_20 | + IEEE80211_HT_CAP_SGI_40 | + IEEE80211_HT_CAP_DSSSCCK40)); + /* + * The STBC bits are asymmetric -- if we don't have + * TX then mask out the peer's RX and vice versa. + */ + if (!(sband->ht_cap.cap & IEEE80211_HT_CAP_TX_STBC)) + ht_cap->cap &= ~IEEE80211_HT_CAP_RX_STBC; + if (!(sband->ht_cap.cap & IEEE80211_HT_CAP_RX_STBC)) + ht_cap->cap &= ~IEEE80211_HT_CAP_TX_STBC; ampdu_info = ht_cap_ie->ampdu_params_info; ht_cap->ampdu_factor = -- cgit v0.10.2 From 0183826b58a2712ffe608bc3302447be3e6a3ab8 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 17 Dec 2009 16:16:53 +0100 Subject: mac80211: fix WMM AP settings application My commit 77fdaa12cea26c204cc12c312fe40bc0f3dcdfd8 Author: Johannes Berg Date: Tue Jul 7 03:45:17 2009 +0200 mac80211: rework MLME for multiple authentications inadvertedly broke WMM because it removed, along with a bunch of other now useless initialisations, the line initialising sdata->u.mgd.wmm_last_param_set to -1 which would make it adopt any WMM parameter set. If, as is usually the case, the AP uses WMM parameter set sequence number zero, we'd never update it until the AP changes the sequence number. Add the missing initialisation back to get the WMM settings from the AP applied locally. Signed-off-by: Johannes Berg Cc: stable@kernel.org [2.6.31+] Signed-off-by: John W. Linville diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index d8d50fb..c79e59f 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -915,6 +915,14 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL | IEEE80211_STA_BEACON_POLL); + /* + * Always handle WMM once after association regardless + * of the first value the AP uses. Setting -1 here has + * that effect because the AP values is an unsigned + * 4-bit value. + */ + sdata->u.mgd.wmm_last_param_set = -1; + ieee80211_led_assoc(local, 1); sdata->vif.bss_conf.assoc = 1; -- cgit v0.10.2 From 92c6f8d849178582fc527aaf1e51dd37a74767d3 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Fri, 18 Dec 2009 11:19:32 -0800 Subject: ps3_gelic_wireless: Fix build failure due to missing WEXT_PRIV The option to support the old style PSK interface in the PS3 GELIC wireless drivers requires CONFIG_WEXT_PRIV to be set Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Geoff Levand Signed-off-by: John W. Linville diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 0bbd5ae..18ff622 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2344,6 +2344,7 @@ config GELIC_NET config GELIC_WIRELESS bool "PS3 Wireless support" + depends on WLAN depends on GELIC_NET select WIRELESS_EXT help @@ -2356,6 +2357,7 @@ config GELIC_WIRELESS config GELIC_WIRELESS_OLD_PSK_INTERFACE bool "PS3 Wireless private PSK interface (OBSOLETE)" depends on GELIC_WIRELESS + select WEXT_PRIV help This option retains the obsolete private interface to pass the PSK from user space programs to the driver. The PSK -- cgit v0.10.2 From 0e2c8b8f55072a98b99e7bdad55c912084d6a526 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sun, 20 Dec 2009 10:50:02 +0100 Subject: resources: fix call to alignf() in allocate_resource() The second parameter to alignf() in allocate_resource() must reflect what new resource is attempted to be allocated, else functions like pcibios_align_resource() (at least on x86) or pcmcia_align() can't work correctly. Commit 1e5ad9679016275d422e36b12a98b0927d76f556 broke this by setting the "new" resource until we're about to return success. To keep the resource untouched when allocate_resource() fails, a "tmp" resource is introduced. Signed-off-by: Dominik Brodowski Acked-by: Bjorn Helgaas Cc: Yinghai Lu Cc: Jesse Barnes Signed-off-by: Linus Torvalds diff --git a/kernel/resource.c b/kernel/resource.c index dc15686..af96c1e 100644 --- a/kernel/resource.c +++ b/kernel/resource.c @@ -308,37 +308,37 @@ static int find_resource(struct resource *root, struct resource *new, void *alignf_data) { struct resource *this = root->child; - resource_size_t start, end; + struct resource tmp = *new; - start = root->start; + tmp.start = root->start; /* * Skip past an allocated resource that starts at 0, since the assignment - * of this->start - 1 to new->end below would cause an underflow. + * of this->start - 1 to tmp->end below would cause an underflow. */ if (this && this->start == 0) { - start = this->end + 1; + tmp.start = this->end + 1; this = this->sibling; } for(;;) { if (this) - end = this->start - 1; + tmp.end = this->start - 1; else - end = root->end; - if (start < min) - start = min; - if (end > max) - end = max; - start = ALIGN(start, align); + tmp.end = root->end; + if (tmp.start < min) + tmp.start = min; + if (tmp.end > max) + tmp.end = max; + tmp.start = ALIGN(tmp.start, align); if (alignf) - alignf(alignf_data, new, size, align); - if (start < end && end - start >= size - 1) { - new->start = start; - new->end = start + size - 1; + alignf(alignf_data, &tmp, size, align); + if (tmp.start < tmp.end && tmp.end - tmp.start >= size - 1) { + new->start = tmp.start; + new->end = tmp.start + size - 1; return 0; } if (!this) break; - start = this->end + 1; + tmp.start = this->end + 1; this = this->sibling; } return -EBUSY; -- cgit v0.10.2 From 3439d65062a4af6af0433c8816fd54697d782ff4 Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Tue, 14 Jul 2009 13:39:47 -0400 Subject: pata_bf54x: handle portmuxing of pins through GPIO PORTs By default, the PATA pins are routed to the async address lines in which case, no peripheral muxing needs to be done. However, if the pins get routed through the GPIO PORTs pins, we need to make sure to request them so that the muxing is properly set up. Signed-off-by: Sonic Zhang Signed-off-by: Bryan Wu Signed-off-by: Mike Frysinger Signed-off-by: Jeff Garzik diff --git a/drivers/ata/pata_bf54x.c b/drivers/ata/pata_bf54x.c index c4b47a3..02c81f1 100644 --- a/drivers/ata/pata_bf54x.c +++ b/drivers/ata/pata_bf54x.c @@ -1557,6 +1557,25 @@ static unsigned short atapi_io_port[] = { P_ATAPI_DMARQ, P_ATAPI_INTRQ, P_ATAPI_IORDY, + P_ATAPI_D0A, + P_ATAPI_D1A, + P_ATAPI_D2A, + P_ATAPI_D3A, + P_ATAPI_D4A, + P_ATAPI_D5A, + P_ATAPI_D6A, + P_ATAPI_D7A, + P_ATAPI_D8A, + P_ATAPI_D9A, + P_ATAPI_D10A, + P_ATAPI_D11A, + P_ATAPI_D12A, + P_ATAPI_D13A, + P_ATAPI_D14A, + P_ATAPI_D15A, + P_ATAPI_A0A, + P_ATAPI_A1A, + P_ATAPI_A2A, 0 }; -- cgit v0.10.2 From 27df5068e24f2f88de98e95eb6e8dbc9800bf80e Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Mon, 21 Dec 2009 19:56:42 +0100 Subject: HWPOISON: Add PROC_FS dependency to hwpoison injector v2 The injector filter requires stable_page_flags() which is supplied by procfs. So make it dependent on that. Also add ifdefs around the filter code in memory-failure.c so that when the filter is disabled due to missing dependencies the whole code still builds. Reported-by: Ingo Molnar Signed-off-by: Andi Kleen diff --git a/mm/Kconfig b/mm/Kconfig index ee9f3e0..17b8947 100644 --- a/mm/Kconfig +++ b/mm/Kconfig @@ -253,7 +253,7 @@ config MEMORY_FAILURE config HWPOISON_INJECT tristate "HWPoison pages injector" - depends on MEMORY_FAILURE && DEBUG_KERNEL + depends on MEMORY_FAILURE && DEBUG_KERNEL && PROC_FS select PROC_PAGE_MONITOR config NOMMU_INITIAL_TRIM_EXCESS diff --git a/mm/memory-failure.c b/mm/memory-failure.c index 6a0466e..17299fd 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c @@ -52,6 +52,8 @@ int sysctl_memory_failure_recovery __read_mostly = 1; atomic_long_t mce_bad_pages __read_mostly = ATOMIC_LONG_INIT(0); +#if defined(CONFIG_HWPOISON_INJECT) || defined(CONFIG_HWPOISON_INJECT_MODULE) + u32 hwpoison_filter_enable = 0; u32 hwpoison_filter_dev_major = ~0U; u32 hwpoison_filter_dev_minor = ~0U; @@ -164,6 +166,13 @@ int hwpoison_filter(struct page *p) return 0; } +#else +int hwpoison_filter(struct page *p) +{ + return 0; +} +#endif + EXPORT_SYMBOL_GPL(hwpoison_filter); /* -- cgit v0.10.2 From c757bea93bea4b77ebd181cc6dca60c15e3b1a2c Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 21 Dec 2009 22:35:16 -0500 Subject: tracing: Fix setting tracer specific options The function __set_tracer_option() takes as its last parameter a "neg" value. If set it should negate the value of the option. The trace_options_write() passed the value written to the file which is what the new value needs to be set as. But since this is not the negative, it never sets the value. Reported-by: Peter Zijlstra Cc: Li Zefan Signed-off-by: Steven Rostedt diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index ee61915..d0a4c12 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -3949,7 +3949,7 @@ trace_options_write(struct file *filp, const char __user *ubuf, size_t cnt, if (!!(topt->flags->val & topt->opt->bit) != val) { mutex_lock(&trace_types_lock); ret = __set_tracer_option(current_trace, topt->flags, - topt->opt, val); + topt->opt, !val); mutex_unlock(&trace_types_lock); if (ret) return ret; -- cgit v0.10.2 From d8d881dd2c814e1500558889d800cf78d11cf898 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 22 Dec 2009 07:52:49 +0100 Subject: ALSA: hda - Fix NULL dereference with enable_beep=0 option Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 3d59f83..417fb22 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -3779,15 +3779,16 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out err = snd_hda_attach_beep_device(codec, nid); if (err < 0) return err; - /* IDT/STAC codecs have linear beep tone parameter */ - codec->beep->linear_tone = 1; - /* if no beep switch is available, make its own one */ - caps = query_amp_caps(codec, nid, HDA_OUTPUT); - if (codec->beep && - !((caps & AC_AMPCAP_MUTE) >> AC_AMPCAP_MUTE_SHIFT)) { - err = stac92xx_beep_switch_ctl(codec); - if (err < 0) - return err; + if (codec->beep) { + /* IDT/STAC codecs have linear beep tone parameter */ + codec->beep->linear_tone = 1; + /* if no beep switch is available, make its own one */ + caps = query_amp_caps(codec, nid, HDA_OUTPUT); + if (!(caps & AC_AMPCAP_MUTE)) { + err = stac92xx_beep_switch_ctl(codec); + if (err < 0) + return err; + } } } #endif -- cgit v0.10.2 From 1a5ba2e9fc7999b8de2a71c7e7b9f58d752c05e4 Mon Sep 17 00:00:00 2001 From: Rafael Avila de Espindola Date: Tue, 22 Dec 2009 07:59:37 +0100 Subject: ALSA: hda - Add support for the new 27 inch IMacs With the attached patch I am able to use the sound on a new IMac 27. What works: *) Internal speakers *) Internal microphone *) Headphone I don't have an external mic or a SPDIF device to test the rest. Signed-off-by: Rafael Avila de Espindola Signed-off-by: Takashi Iwai diff --git a/Documentation/sound/alsa/HD-Audio-Models.txt b/Documentation/sound/alsa/HD-Audio-Models.txt index e93afff..e72cee9 100644 --- a/Documentation/sound/alsa/HD-Audio-Models.txt +++ b/Documentation/sound/alsa/HD-Audio-Models.txt @@ -403,4 +403,5 @@ STAC9872 Cirrus Logic CS4206/4207 ======================== mbp55 MacBook Pro 5,5 + imac27 IMac 27 Inch auto BIOS setup (default) diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index 4b200da..fe0423c 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c @@ -66,6 +66,7 @@ struct cs_spec { /* available models */ enum { CS420X_MBP55, + CS420X_IMAC27, CS420X_AUTO, CS420X_MODELS }; @@ -827,7 +828,8 @@ static void cs_automute(struct hda_codec *codec) AC_VERB_SET_PIN_WIDGET_CONTROL, hp_present ? 0 : PIN_OUT); } - if (spec->board_config == CS420X_MBP55) { + if (spec->board_config == CS420X_MBP55 || + spec->board_config == CS420X_IMAC27) { unsigned int gpio = hp_present ? 0x02 : 0x08; snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, gpio); @@ -1069,12 +1071,14 @@ static int cs_parse_auto_config(struct hda_codec *codec) static const char *cs420x_models[CS420X_MODELS] = { [CS420X_MBP55] = "mbp55", + [CS420X_IMAC27] = "imac27", [CS420X_AUTO] = "auto", }; static struct snd_pci_quirk cs420x_cfg_tbl[] = { SND_PCI_QUIRK(0x10de, 0xcb79, "MacBookPro 5,5", CS420X_MBP55), + SND_PCI_QUIRK(0x8086, 0x7270, "IMac 27 Inch", CS420X_IMAC27), {} /* terminator */ }; @@ -1097,8 +1101,23 @@ static struct cs_pincfg mbp55_pincfgs[] = { {} /* terminator */ }; +static struct cs_pincfg imac27_pincfgs[] = { + { 0x09, 0x012b4050 }, + { 0x0a, 0x90100140 }, + { 0x0b, 0x90100142 }, + { 0x0c, 0x018b3020 }, + { 0x0d, 0x90a00110 }, + { 0x0e, 0x400000f0 }, + { 0x0f, 0x01cbe030 }, + { 0x10, 0x014be060 }, + { 0x12, 0x01ab9070 }, + { 0x15, 0x400000f0 }, + {} /* terminator */ +}; + static struct cs_pincfg *cs_pincfgs[CS420X_MODELS] = { [CS420X_MBP55] = mbp55_pincfgs, + [CS420X_IMAC27] = imac27_pincfgs, }; static void fix_pincfg(struct hda_codec *codec, int model) @@ -1128,6 +1147,7 @@ static int patch_cs420x(struct hda_codec *codec) fix_pincfg(codec, spec->board_config); switch (spec->board_config) { + case CS420X_IMAC27: case CS420X_MBP55: /* GPIO1 = headphones */ /* GPIO3 = speakers */ -- cgit v0.10.2 From 9dc8398bab52931435fce403ce2eaf5822f28e58 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 22 Dec 2009 08:15:01 +0100 Subject: ALSA: hda - Add MSI blacklist A machine with AMD CPU with Nvidia board doesn't work with MSI. Reported-by: Robert J. King Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 9b56f93..ff8ad46 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2322,6 +2322,7 @@ static void __devinit check_probe_mask(struct azx *chip, int dev) * white/black-list for enable_msi */ static struct snd_pci_quirk msi_black_list[] __devinitdata = { + SND_PCI_QUIRK(0x1043, 0x81f2, "ASUS", 0), /* Athlon64 X2 + nvidia */ {} }; -- cgit v0.10.2 From a9605391cfab2bf9a73e51faac5147622f73c6d5 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 21 Dec 2009 16:36:10 -0800 Subject: ALSA: sound/core/pcm_timer.c: use lib/gcd.c Make sound/core/pcm_timer.c use lib/gcd.c Signed-off-by: Florian Fainelli Signed-off-by: Andrew Morton Signed-off-by: Takashi Iwai diff --git a/sound/core/Kconfig b/sound/core/Kconfig index c15682a..475455c 100644 --- a/sound/core/Kconfig +++ b/sound/core/Kconfig @@ -5,6 +5,7 @@ config SND_TIMER config SND_PCM tristate select SND_TIMER + select GCD config SND_HWDEP tristate diff --git a/sound/core/pcm_timer.c b/sound/core/pcm_timer.c index ca8068b..b01d948 100644 --- a/sound/core/pcm_timer.c +++ b/sound/core/pcm_timer.c @@ -20,6 +20,7 @@ */ #include +#include #include #include #include @@ -28,22 +29,6 @@ * Timer functions */ -/* Greatest common divisor */ -static unsigned long gcd(unsigned long a, unsigned long b) -{ - unsigned long r; - if (a < b) { - r = a; - a = b; - b = r; - } - while ((r = a % b) != 0) { - a = b; - b = r; - } - return b; -} - void snd_pcm_timer_resolution_change(struct snd_pcm_substream *substream) { unsigned long rate, mult, fsize, l, post; -- cgit v0.10.2 From 81074e90f5c150ca70ab8dfcc77860cbe76f364d Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Mon, 21 Dec 2009 16:13:15 +0800 Subject: ACPI: disable _OSI(Windows 2009) on Asus K50IJ Fix a win7 compability issue on Asus K50IJ. Here is the _BCM method of this laptop: Method (_BCM, 1, NotSerialized) { If (LGreaterEqual (OSFG, OSVT)) { If (LNotEqual (OSFG, OSW7)) { Store (One, BCMD) Store (GCBL (Arg0), Local0) Subtract (0x0F, Local0, LBTN) ^^^SBRG.EC0.STBR () ... } Else { DBGR (0x0B, Zero, Zero, Arg0) Store (Arg0, LBTN) ^^^SBRG.EC0.STBR () ... } } } LBTN is used to store the index of the brightness level in the _BCL. GCBL is a method that convert the percentage value to the index value. If _OSI(Windows 2009) is not disabled, LBTN is stored a percentage value which is surely beyond the end of _BCL package. http://bugzilla.kernel.org/show_bug.cgi?id=14753 Signed-off-by: Zhang Rui Signed-off-by: Len Brown diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index 23e5a05..2815df6 100644 --- a/drivers/acpi/blacklist.c +++ b/drivers/acpi/blacklist.c @@ -185,6 +185,12 @@ static int __init dmi_disable_osi_vista(const struct dmi_system_id *d) acpi_osi_setup("!Windows 2006"); return 0; } +static int __init dmi_disable_osi_win7(const struct dmi_system_id *d) +{ + printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident); + acpi_osi_setup("!Windows 2009"); + return 0; +} static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { { @@ -211,6 +217,14 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { DMI_MATCH(DMI_PRODUCT_NAME, "Sony VGN-SR290J"), }, }, + { + .callback = dmi_disable_osi_win7, + .ident = "ASUS K50IJ", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "K50IJ"), + }, + }, /* * BIOS invocation of _OSI(Linux) is almost always a BIOS bug. -- cgit v0.10.2 From 55b313f249e11b815fd0be51869f166aaf368f44 Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Tue, 22 Dec 2009 02:42:52 -0500 Subject: ACPI: EC: Fix MSI DMI detection MSI strings should be ORed, not ANDed. Reference: http://bugzilla.kernel.org/show_bug.cgi?id=14446 cc: stable@kernel.org Signed-off-by: Alexey Starikovskiy Signed-off-by: Len Brown diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index baef28c..7511029 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -916,6 +916,7 @@ static int ec_validate_ecdt(const struct dmi_system_id *id) /* MSI EC needs special treatment, enable it */ static int ec_flag_msi(const struct dmi_system_id *id) { + printk(KERN_DEBUG PREFIX "Detected MSI hardware, enabling workarounds.\n"); EC_FLAGS_MSI = 1; EC_FLAGS_VALIDATE_ECDT = 1; return 0; @@ -928,8 +929,13 @@ static struct dmi_system_id __initdata ec_dmi_table[] = { DMI_MATCH(DMI_BOARD_NAME, "JFL92") }, NULL}, { ec_flag_msi, "MSI hardware", { - DMI_MATCH(DMI_BIOS_VENDOR, "Micro-Star"), - DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-Star") }, NULL}, + DMI_MATCH(DMI_BIOS_VENDOR, "Micro-Star")}, NULL}, + { + ec_flag_msi, "MSI hardware", { + DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star")}, NULL}, + { + ec_flag_msi, "MSI hardware", { + DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-Star")}, NULL}, { ec_validate_ecdt, "ASUS hardware", { DMI_MATCH(DMI_BIOS_VENDOR, "ASUS") }, NULL}, -- cgit v0.10.2 From df9dc83d193959f990c981787279e8541fe9df8c Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Mon, 21 Dec 2009 16:27:49 -0800 Subject: drivers/block/DAC960.c: use DAC960_V2_Controller DAC960_LP_Controller and DAC960_V2_Controller have the same value, but elsewhere it is DAC960_V1_Controller or DAC960_V2_Controller that is used in the FirmwareType field. Signed-off-by: Julia Lawall Signed-off-by: Andrew Morton Signed-off-by: Jens Axboe diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c index eb4fa19..ce1fa92 100644 --- a/drivers/block/DAC960.c +++ b/drivers/block/DAC960.c @@ -7101,7 +7101,7 @@ static struct DAC960_privdata DAC960_BA_privdata = { static struct DAC960_privdata DAC960_LP_privdata = { .HardwareType = DAC960_LP_Controller, - .FirmwareType = DAC960_LP_Controller, + .FirmwareType = DAC960_V2_Controller, .InterruptHandler = DAC960_LP_InterruptHandler, .MemoryWindowSize = DAC960_LP_RegisterWindowSize, }; -- cgit v0.10.2 From e019ef0c4f11a0acb79b89fb1e09c72197b42bbe Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 21 Dec 2009 16:27:49 -0800 Subject: drivers/block/mg_disk.c: use resource_size() Use resource_size() for ioremap. The ioremap appears to be passing the incorrect size for the platform resource. Unfortunately, I can't locate a user in mainline to verify this. Using resource_size should be the correct fix. Signed-off-by: H Hartley Sweeten Acked-by: unsik Kim Signed-off-by: Andrew Morton Signed-off-by: Jens Axboe diff --git a/drivers/block/mg_disk.c b/drivers/block/mg_disk.c index e0339aa..02b2583 100644 --- a/drivers/block/mg_disk.c +++ b/drivers/block/mg_disk.c @@ -860,7 +860,7 @@ static int mg_probe(struct platform_device *plat_dev) err = -EINVAL; goto probe_err_2; } - host->dev_base = ioremap(rsc->start , rsc->end + 1); + host->dev_base = ioremap(rsc->start, resource_size(rsc)); if (!host->dev_base) { printk(KERN_ERR "%s:%d ioremap fail\n", __func__, __LINE__); -- cgit v0.10.2 From 6ec1480d8539c8e2e6ba7fbbeffe5adc640bfe98 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 21 Dec 2009 16:27:50 -0800 Subject: aoe: switch to the new bio_flush_dcache_pages() interface Cc: "Ed L. Cashin" Cc: David Woodhouse Cc: Ilya Loginov Cc: Ingo Molnar Cc: Peter Horton Signed-off-by: Andrew Morton Signed-off-by: Jens Axboe diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c index 13bb69d..64a223b 100644 --- a/drivers/block/aoe/aoecmd.c +++ b/drivers/block/aoe/aoecmd.c @@ -735,21 +735,6 @@ diskstats(struct gendisk *disk, struct bio *bio, ulong duration, sector_t sector part_stat_unlock(); } -/* - * Ensure we don't create aliases in VI caches - */ -static inline void -killalias(struct bio *bio) -{ - struct bio_vec *bv; - int i; - - if (bio_data_dir(bio) == READ) - __bio_for_each_segment(bv, bio, i, 0) { - flush_dcache_page(bv->bv_page); - } -} - void aoecmd_ata_rsp(struct sk_buff *skb) { @@ -871,7 +856,7 @@ aoecmd_ata_rsp(struct sk_buff *skb) if (buf->flags & BUFFL_FAIL) bio_endio(buf->bio, -EIO); else { - killalias(buf->bio); + bio_flush_dcache_pages(buf->bio); bio_endio(buf->bio, 0); } mempool_free(buf, d->bufpool); -- cgit v0.10.2 From 78f1699659963fff97975df44db6d5dbe7218e55 Mon Sep 17 00:00:00 2001 From: Alex Chiang Date: Sun, 20 Dec 2009 12:19:09 -0700 Subject: ACPI: processor: call _PDC early We discovered that at least one machine (HP Envy), methods in the DSDT attempt to call external methods defined in a dynamically loaded SSDT. Unfortunately, the DSDT methods we are trying to call are part of the EC initialization, which happens very early, and the the dynamic SSDT is only loaded when a processor _PDC method runs much later. This results in namespace lookup errors for the (as of yet) undefined methods. Since Windows doesn't have any issues with this machine, we take it as a hint that they must be evaluating _PDC much earlier than we are. Thus, the proper thing for Linux to do should be to match the Windows implementation more closely. Provide a mechanism to call _PDC before we enable the EC. Doing so loads the dynamic tables, and allows the EC to be enabled correctly. The ACPI processor driver will still evaluate _PDC in its .add() method to cover the hotplug case. Resolves: http://bugzilla.kernel.org/show_bug.cgi?id=14824 Cc: ming.m.lin@intel.com Signed-off-by: Alex Chiang Signed-off-by: Len Brown diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index c7b10b4..66cc3f3 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -32,6 +32,7 @@ acpi-$(CONFIG_ACPI_SLEEP) += proc.o # acpi-y += bus.o glue.o acpi-y += scan.o +acpi-y += processor_pdc.o acpi-y += ec.o acpi-$(CONFIG_ACPI_DOCK) += dock.o acpi-y += pci_root.o pci_link.o pci_irq.o pci_bind.o diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 65f7e33..0bdf24a 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -888,6 +888,8 @@ static int __init acpi_bus_init(void) goto error1; } + acpi_early_processor_set_pdc(); + /* * Maybe EC region is required at bus_scan/acpi_get_devices. So it * is necessary to enable it as early as possible. diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 074cf86..cb28e05 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -43,6 +43,7 @@ int acpi_power_transition(struct acpi_device *device, int state); extern int acpi_power_nocheck; int acpi_wakeup_device_init(void); +void acpi_early_processor_set_pdc(void); /* -------------------------------------------------------------------------- Embedded Controller diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 4173123..a19a4ff 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -124,29 +124,6 @@ static const struct file_operations acpi_processor_info_fops = { DEFINE_PER_CPU(struct acpi_processor *, processors); struct acpi_processor_errata errata __read_mostly; -static int set_no_mwait(const struct dmi_system_id *id) -{ - printk(KERN_NOTICE PREFIX "%s detected - " - "disabling mwait for CPU C-states\n", id->ident); - idle_nomwait = 1; - return 0; -} - -static struct dmi_system_id __cpuinitdata processor_idle_dmi_table[] = { - { - set_no_mwait, "IFL91 board", { - DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"), - DMI_MATCH(DMI_SYS_VENDOR, "ZEPTO"), - DMI_MATCH(DMI_PRODUCT_VERSION, "3215W"), - DMI_MATCH(DMI_BOARD_NAME, "IFL91") }, NULL}, - { - set_no_mwait, "Extensa 5220", { - DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), - DMI_MATCH(DMI_SYS_VENDOR, "Acer"), - DMI_MATCH(DMI_PRODUCT_VERSION, "0100"), - DMI_MATCH(DMI_BOARD_NAME, "Columbia") }, NULL}, - {}, -}; /* -------------------------------------------------------------------------- Errata Handling @@ -277,45 +254,6 @@ static int acpi_processor_errata(struct acpi_processor *pr) } /* -------------------------------------------------------------------------- - Common ACPI processor functions - -------------------------------------------------------------------------- */ - -/* - * _PDC is required for a BIOS-OS handshake for most of the newer - * ACPI processor features. - */ -static int acpi_processor_set_pdc(struct acpi_processor *pr) -{ - struct acpi_object_list *pdc_in = pr->pdc; - acpi_status status = AE_OK; - - - if (!pdc_in) - return status; - if (idle_nomwait) { - /* - * If mwait is disabled for CPU C-states, the C2C3_FFH access - * mode will be disabled in the parameter of _PDC object. - * Of course C1_FFH access mode will also be disabled. - */ - union acpi_object *obj; - u32 *buffer = NULL; - - obj = pdc_in->pointer; - buffer = (u32 *)(obj->buffer.pointer); - buffer[2] &= ~(ACPI_PDC_C_C2C3_FFH | ACPI_PDC_C_C1_FFH); - - } - status = acpi_evaluate_object(pr->handle, "_PDC", pdc_in, NULL); - - if (ACPI_FAILURE(status)) - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Could not evaluate _PDC, using legacy perf. control...\n")); - - return status; -} - -/* -------------------------------------------------------------------------- FS Interface (/proc) -------------------------------------------------------------------------- */ @@ -825,9 +763,7 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device) } /* _PDC call should be done before doing anything else (if reqd.). */ - arch_acpi_processor_init_pdc(pr); acpi_processor_set_pdc(pr); - arch_acpi_processor_cleanup_pdc(pr); #ifdef CONFIG_CPU_FREQ acpi_processor_ppc_has_changed(pr, 0); @@ -1145,11 +1081,6 @@ static int __init acpi_processor_init(void) if (!acpi_processor_dir) return -ENOMEM; #endif - /* - * Check whether the system is DMI table. If yes, OSPM - * should not use mwait for CPU-states. - */ - dmi_check_system(processor_idle_dmi_table); result = cpuidle_register_driver(&acpi_idle_driver); if (result < 0) goto out_proc; diff --git a/drivers/acpi/processor_pdc.c b/drivers/acpi/processor_pdc.c new file mode 100644 index 0000000..b416c32 --- /dev/null +++ b/drivers/acpi/processor_pdc.c @@ -0,0 +1,108 @@ +#include + +#include +#include + +#include "internal.h" + +#define PREFIX "ACPI: " +#define _COMPONENT ACPI_PROCESSOR_COMPONENT +ACPI_MODULE_NAME("processor_pdc"); + +static int set_no_mwait(const struct dmi_system_id *id) +{ + printk(KERN_NOTICE PREFIX "%s detected - " + "disabling mwait for CPU C-states\n", id->ident); + idle_nomwait = 1; + return 0; +} + +static struct dmi_system_id __cpuinitdata processor_idle_dmi_table[] = { + { + set_no_mwait, "IFL91 board", { + DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"), + DMI_MATCH(DMI_SYS_VENDOR, "ZEPTO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "3215W"), + DMI_MATCH(DMI_BOARD_NAME, "IFL91") }, NULL}, + { + set_no_mwait, "Extensa 5220", { + DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_VERSION, "0100"), + DMI_MATCH(DMI_BOARD_NAME, "Columbia") }, NULL}, + {}, +}; + +/* + * _PDC is required for a BIOS-OS handshake for most of the newer + * ACPI processor features. + */ +static int acpi_processor_eval_pdc(struct acpi_processor *pr) +{ + struct acpi_object_list *pdc_in = pr->pdc; + acpi_status status = AE_OK; + + if (!pdc_in) + return status; + if (idle_nomwait) { + /* + * If mwait is disabled for CPU C-states, the C2C3_FFH access + * mode will be disabled in the parameter of _PDC object. + * Of course C1_FFH access mode will also be disabled. + */ + union acpi_object *obj; + u32 *buffer = NULL; + + obj = pdc_in->pointer; + buffer = (u32 *)(obj->buffer.pointer); + buffer[2] &= ~(ACPI_PDC_C_C2C3_FFH | ACPI_PDC_C_C1_FFH); + + } + status = acpi_evaluate_object(pr->handle, "_PDC", pdc_in, NULL); + + if (ACPI_FAILURE(status)) + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Could not evaluate _PDC, using legacy perf. control.\n")); + + return status; +} + +void acpi_processor_set_pdc(struct acpi_processor *pr) +{ + arch_acpi_processor_init_pdc(pr); + acpi_processor_eval_pdc(pr); + arch_acpi_processor_cleanup_pdc(pr); +} +EXPORT_SYMBOL_GPL(acpi_processor_set_pdc); + +static acpi_status +early_init_pdc(acpi_handle handle, u32 lvl, void *context, void **rv) +{ + struct acpi_processor pr; + + pr.handle = handle; + + /* x86 implementation looks at pr.id to determine some + * CPU capabilites. We can just hard code to 0 since we're + * assuming the CPUs in the system are homogenous and all + * have the same capabilities. + */ + pr.id = 0; + + acpi_processor_set_pdc(&pr); + + return AE_OK; +} + +void acpi_early_processor_set_pdc(void) +{ + /* + * Check whether the system is DMI table. If yes, OSPM + * should not use mwait for CPU-states. + */ + dmi_check_system(processor_idle_dmi_table); + + acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, + ACPI_UINT32_MAX, + early_init_pdc, NULL, NULL, NULL); +} diff --git a/include/acpi/processor.h b/include/acpi/processor.h index 29245c6..a1b748a 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h @@ -325,6 +325,9 @@ static inline int acpi_processor_get_bios_limit(int cpu, unsigned int *limit) #endif /* CONFIG_CPU_FREQ */ +/* in processor_pdc.c */ +void acpi_processor_set_pdc(struct acpi_processor *pr); + /* in processor_throttling.c */ int acpi_processor_tstate_has_changed(struct acpi_processor *pr); int acpi_processor_get_throttling_info(struct acpi_processor *pr); -- cgit v0.10.2 From 1d9cb470a755409ce97c3376174b1e234bd20371 Mon Sep 17 00:00:00 2001 From: Alex Chiang Date: Sun, 20 Dec 2009 12:19:14 -0700 Subject: ACPI: processor: introduce arch_has_acpi_pdc arch dependent helper function that tells us if we should attempt to evaluate _PDC on this machine or not. The x86 implementation assumes that the CPUs in the machine must be homogeneous, and that you cannot mix CPUs of different vendors. Cc: Tony Luck Cc: Thomas Gleixner Cc: Ingo Molnar Cc: "H. Peter Anvin" Signed-off-by: Alex Chiang Signed-off-by: Len Brown diff --git a/arch/ia64/include/asm/acpi.h b/arch/ia64/include/asm/acpi.h index 91df968..3b78882 100644 --- a/arch/ia64/include/asm/acpi.h +++ b/arch/ia64/include/asm/acpi.h @@ -132,6 +132,8 @@ extern int __devinitdata pxm_to_nid_map[MAX_PXM_DOMAINS]; extern int __initdata nid_to_pxm_map[MAX_NUMNODES]; #endif +static inline bool arch_has_acpi_pdc(void) { return true; } + #define acpi_unlazy_tlb(x) #ifdef CONFIG_ACPI_NUMA diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h index 60d2b2d..d787e6e 100644 --- a/arch/x86/include/asm/acpi.h +++ b/arch/x86/include/asm/acpi.h @@ -142,6 +142,13 @@ static inline unsigned int acpi_processor_cstate_check(unsigned int max_cstate) return max_cstate; } +static inline bool arch_has_acpi_pdc(void) +{ + struct cpuinfo_x86 *c = &cpu_data(0); + return (c->x86_vendor == X86_VENDOR_INTEL || + c->x86_vendor == X86_VENDOR_CENTAUR); +} + #else /* !CONFIG_ACPI */ #define acpi_lapic 0 diff --git a/arch/x86/kernel/acpi/processor.c b/arch/x86/kernel/acpi/processor.c index d85d1b2..bcb6efe 100644 --- a/arch/x86/kernel/acpi/processor.c +++ b/arch/x86/kernel/acpi/processor.c @@ -79,9 +79,7 @@ void arch_acpi_processor_init_pdc(struct acpi_processor *pr) struct cpuinfo_x86 *c = &cpu_data(pr->id); pr->pdc = NULL; - if (c->x86_vendor == X86_VENDOR_INTEL || - c->x86_vendor == X86_VENDOR_CENTAUR) - init_intel_pdc(pr, c); + init_intel_pdc(pr, c); return; } diff --git a/drivers/acpi/processor_pdc.c b/drivers/acpi/processor_pdc.c index b416c32..931e735 100644 --- a/drivers/acpi/processor_pdc.c +++ b/drivers/acpi/processor_pdc.c @@ -69,6 +69,9 @@ static int acpi_processor_eval_pdc(struct acpi_processor *pr) void acpi_processor_set_pdc(struct acpi_processor *pr) { + if (arch_has_acpi_pdc() == false) + return; + arch_acpi_processor_init_pdc(pr); acpi_processor_eval_pdc(pr); arch_acpi_processor_cleanup_pdc(pr); -- cgit v0.10.2 From 407cd87c54e76c266245e8faef8dd4a84b7254fe Mon Sep 17 00:00:00 2001 From: Alex Chiang Date: Sun, 20 Dec 2009 12:19:19 -0700 Subject: ACPI: processor: unify arch_acpi_processor_init_pdc The x86 and ia64 implementations of arch_acpi_processor_init_pdc() are almost exactly the same. The only difference is in what bits they set in obj_list buffer. Combine the boilerplate memory management code, and leave the arch-specific bit twiddling in separate implementations. Cc: Tony Luck Cc: Thomas Gleixner Cc: Ingo Molnar Cc: "H. Peter Anvin" Signed-off-by: Alex Chiang Signed-off-by: Len Brown diff --git a/arch/ia64/kernel/acpi-processor.c b/arch/ia64/kernel/acpi-processor.c index dbda7bd..ab72d46 100644 --- a/arch/ia64/kernel/acpi-processor.c +++ b/arch/ia64/kernel/acpi-processor.c @@ -16,31 +16,7 @@ static void init_intel_pdc(struct acpi_processor *pr) { - struct acpi_object_list *obj_list; - union acpi_object *obj; - u32 *buf; - - /* allocate and initialize pdc. It will be used later. */ - obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL); - if (!obj_list) { - printk(KERN_ERR "Memory allocation error\n"); - return; - } - - obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL); - if (!obj) { - printk(KERN_ERR "Memory allocation error\n"); - kfree(obj_list); - return; - } - - buf = kmalloc(12, GFP_KERNEL); - if (!buf) { - printk(KERN_ERR "Memory allocation error\n"); - kfree(obj); - kfree(obj_list); - return; - } + u32 *buf = (u32 *)pr->pdc->pointer->buffer.pointer; buf[0] = ACPI_PDC_REVISION_ID; buf[1] = 1; @@ -52,20 +28,12 @@ static void init_intel_pdc(struct acpi_processor *pr) */ buf[2] |= ACPI_PDC_SMP_T_SWCOORD; - obj->type = ACPI_TYPE_BUFFER; - obj->buffer.length = 12; - obj->buffer.pointer = (u8 *) buf; - obj_list->count = 1; - obj_list->pointer = obj; - pr->pdc = obj_list; - return; } /* Initialize _PDC data based on the CPU vendor */ void arch_acpi_processor_init_pdc(struct acpi_processor *pr) { - pr->pdc = NULL; init_intel_pdc(pr); return; } diff --git a/arch/x86/kernel/acpi/processor.c b/arch/x86/kernel/acpi/processor.c index bcb6efe..967860b 100644 --- a/arch/x86/kernel/acpi/processor.c +++ b/arch/x86/kernel/acpi/processor.c @@ -14,31 +14,7 @@ static void init_intel_pdc(struct acpi_processor *pr, struct cpuinfo_x86 *c) { - struct acpi_object_list *obj_list; - union acpi_object *obj; - u32 *buf; - - /* allocate and initialize pdc. It will be used later. */ - obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL); - if (!obj_list) { - printk(KERN_ERR "Memory allocation error\n"); - return; - } - - obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL); - if (!obj) { - printk(KERN_ERR "Memory allocation error\n"); - kfree(obj_list); - return; - } - - buf = kmalloc(12, GFP_KERNEL); - if (!buf) { - printk(KERN_ERR "Memory allocation error\n"); - kfree(obj); - kfree(obj_list); - return; - } + u32 *buf = (u32 *)pr->pdc->pointer->buffer.pointer; buf[0] = ACPI_PDC_REVISION_ID; buf[1] = 1; @@ -62,13 +38,6 @@ static void init_intel_pdc(struct acpi_processor *pr, struct cpuinfo_x86 *c) if (!cpu_has(c, X86_FEATURE_MWAIT)) buf[2] &= ~(ACPI_PDC_C_C2C3_FFH); - obj->type = ACPI_TYPE_BUFFER; - obj->buffer.length = 12; - obj->buffer.pointer = (u8 *) buf; - obj_list->count = 1; - obj_list->pointer = obj; - pr->pdc = obj_list; - return; } @@ -78,7 +47,6 @@ void arch_acpi_processor_init_pdc(struct acpi_processor *pr) { struct cpuinfo_x86 *c = &cpu_data(pr->id); - pr->pdc = NULL; init_intel_pdc(pr, c); return; diff --git a/drivers/acpi/processor_pdc.c b/drivers/acpi/processor_pdc.c index 931e735..87946b6 100644 --- a/drivers/acpi/processor_pdc.c +++ b/drivers/acpi/processor_pdc.c @@ -33,6 +33,49 @@ static struct dmi_system_id __cpuinitdata processor_idle_dmi_table[] = { {}, }; +static void acpi_processor_init_pdc(struct acpi_processor *pr) +{ + struct acpi_object_list *obj_list; + union acpi_object *obj; + u32 *buf; + + pr->pdc = NULL; + + /* allocate and initialize pdc. It will be used later. */ + obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL); + if (!obj_list) { + printk(KERN_ERR "Memory allocation error\n"); + return; + } + + obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL); + if (!obj) { + printk(KERN_ERR "Memory allocation error\n"); + kfree(obj_list); + return; + } + + buf = kmalloc(12, GFP_KERNEL); + if (!buf) { + printk(KERN_ERR "Memory allocation error\n"); + kfree(obj); + kfree(obj_list); + return; + } + + obj->type = ACPI_TYPE_BUFFER; + obj->buffer.length = 12; + obj->buffer.pointer = (u8 *) buf; + obj_list->count = 1; + obj_list->pointer = obj; + pr->pdc = obj_list; + + /* Now let the arch do the bit-twiddling to buf[] */ + arch_acpi_processor_init_pdc(pr); + + return; +} + /* * _PDC is required for a BIOS-OS handshake for most of the newer * ACPI processor features. @@ -72,7 +115,7 @@ void acpi_processor_set_pdc(struct acpi_processor *pr) if (arch_has_acpi_pdc() == false) return; - arch_acpi_processor_init_pdc(pr); + acpi_processor_init_pdc(pr); acpi_processor_eval_pdc(pr); arch_acpi_processor_cleanup_pdc(pr); } -- cgit v0.10.2 From 08ea48a326d8030ef5b7fb02292faf5a53c95e0a Mon Sep 17 00:00:00 2001 From: Alex Chiang Date: Sun, 20 Dec 2009 12:19:24 -0700 Subject: ACPI: processor: factor out common _PDC settings Both x86 and ia64 initialize _PDC with mostly common bit settings. Factor out the common settings and leave the arch-specific ones alone. Cc: Tony Luck Cc: Thomas Gleixner Cc: Ingo Molnar Cc: "H. Peter Anvin" Signed-off-by: Alex Chiang Signed-off-by: Len Brown diff --git a/arch/ia64/kernel/acpi-processor.c b/arch/ia64/kernel/acpi-processor.c index ab72d46..ebe23f5 100644 --- a/arch/ia64/kernel/acpi-processor.c +++ b/arch/ia64/kernel/acpi-processor.c @@ -18,15 +18,7 @@ static void init_intel_pdc(struct acpi_processor *pr) { u32 *buf = (u32 *)pr->pdc->pointer->buffer.pointer; - buf[0] = ACPI_PDC_REVISION_ID; - buf[1] = 1; - buf[2] = ACPI_PDC_EST_CAPABILITY_SMP; - /* - * The default of PDC_SMP_T_SWCOORD bit is set for IA64 cpu so - * that OSPM is capable of native ACPI throttling software - * coordination using BIOS supplied _TSD info. - */ - buf[2] |= ACPI_PDC_SMP_T_SWCOORD; + buf[2] |= ACPI_PDC_EST_CAPABILITY_SMP; return; } diff --git a/arch/x86/kernel/acpi/processor.c b/arch/x86/kernel/acpi/processor.c index 967860b..d722ca8 100644 --- a/arch/x86/kernel/acpi/processor.c +++ b/arch/x86/kernel/acpi/processor.c @@ -16,16 +16,8 @@ static void init_intel_pdc(struct acpi_processor *pr, struct cpuinfo_x86 *c) { u32 *buf = (u32 *)pr->pdc->pointer->buffer.pointer; - buf[0] = ACPI_PDC_REVISION_ID; - buf[1] = 1; - buf[2] = ACPI_PDC_C_CAPABILITY_SMP; + buf[2] |= ACPI_PDC_C_CAPABILITY_SMP; - /* - * The default of PDC_SMP_T_SWCOORD bit is set for intel x86 cpu so - * that OSPM is capable of native ACPI throttling software - * coordination using BIOS supplied _TSD info. - */ - buf[2] |= ACPI_PDC_SMP_T_SWCOORD; if (cpu_has(c, X86_FEATURE_EST)) buf[2] |= ACPI_PDC_EST_CAPABILITY_SWSMP; diff --git a/drivers/acpi/processor_pdc.c b/drivers/acpi/processor_pdc.c index 87946b6..ccda7c9 100644 --- a/drivers/acpi/processor_pdc.c +++ b/drivers/acpi/processor_pdc.c @@ -33,6 +33,15 @@ static struct dmi_system_id __cpuinitdata processor_idle_dmi_table[] = { {}, }; +static void acpi_set_pdc_bits(u32 *buf) +{ + buf[0] = ACPI_PDC_REVISION_ID; + buf[1] = 1; + + /* Enable coordination with firmware's _TSD info */ + buf[2] = ACPI_PDC_SMP_T_SWCOORD; +} + static void acpi_processor_init_pdc(struct acpi_processor *pr) { struct acpi_object_list *obj_list; @@ -63,6 +72,8 @@ static void acpi_processor_init_pdc(struct acpi_processor *pr) return; } + acpi_set_pdc_bits(buf); + obj->type = ACPI_TYPE_BUFFER; obj->buffer.length = 12; obj->buffer.pointer = (u8 *) buf; -- cgit v0.10.2 From 6c5807d7bc7d051fce00863ffb98d36325501eb2 Mon Sep 17 00:00:00 2001 From: Alex Chiang Date: Sun, 20 Dec 2009 12:19:29 -0700 Subject: ACPI: processor: finish unifying arch_acpi_processor_init_pdc() The only thing arch-specific about calling _PDC is what bits get set in the input obj_list buffer. There's no need for several levels of indirection to twiddle those bits. Additionally, since we're just messing around with a buffer, we can simplify the interface; no need to pass around the entire struct acpi_processor * just to get at the buffer. Cc: Tony Luck Cc: Thomas Gleixner Cc: Ingo Molnar Cc: "H. Peter Anvin" Signed-off-by: Alex Chiang Signed-off-by: Len Brown diff --git a/arch/ia64/include/asm/acpi.h b/arch/ia64/include/asm/acpi.h index 3b78882..7ae5889 100644 --- a/arch/ia64/include/asm/acpi.h +++ b/arch/ia64/include/asm/acpi.h @@ -133,6 +133,10 @@ extern int __initdata nid_to_pxm_map[MAX_NUMNODES]; #endif static inline bool arch_has_acpi_pdc(void) { return true; } +static inline void arch_acpi_set_pdc_bits(u32 *buf) +{ + buf[2] |= ACPI_PDC_EST_CAPABILITY_SMP; +} #define acpi_unlazy_tlb(x) diff --git a/arch/ia64/kernel/acpi-processor.c b/arch/ia64/kernel/acpi-processor.c index ebe23f5..7ba5acc 100644 --- a/arch/ia64/kernel/acpi-processor.c +++ b/arch/ia64/kernel/acpi-processor.c @@ -14,24 +14,6 @@ #include #include -static void init_intel_pdc(struct acpi_processor *pr) -{ - u32 *buf = (u32 *)pr->pdc->pointer->buffer.pointer; - - buf[2] |= ACPI_PDC_EST_CAPABILITY_SMP; - - return; -} - -/* Initialize _PDC data based on the CPU vendor */ -void arch_acpi_processor_init_pdc(struct acpi_processor *pr) -{ - init_intel_pdc(pr); - return; -} - -EXPORT_SYMBOL(arch_acpi_processor_init_pdc); - void arch_acpi_processor_cleanup_pdc(struct acpi_processor *pr) { if (pr->pdc) { diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h index d787e6e..56f462c 100644 --- a/arch/x86/include/asm/acpi.h +++ b/arch/x86/include/asm/acpi.h @@ -149,6 +149,25 @@ static inline bool arch_has_acpi_pdc(void) c->x86_vendor == X86_VENDOR_CENTAUR); } +static inline void arch_acpi_set_pdc_bits(u32 *buf) +{ + struct cpuinfo_x86 *c = &cpu_data(0); + + buf[2] |= ACPI_PDC_C_CAPABILITY_SMP; + + if (cpu_has(c, X86_FEATURE_EST)) + buf[2] |= ACPI_PDC_EST_CAPABILITY_SWSMP; + + if (cpu_has(c, X86_FEATURE_ACPI)) + buf[2] |= ACPI_PDC_T_FFH; + + /* + * If mwait/monitor is unsupported, C2/C3_FFH will be disabled + */ + if (!cpu_has(c, X86_FEATURE_MWAIT)) + buf[2] &= ~(ACPI_PDC_C_C2C3_FFH); +} + #else /* !CONFIG_ACPI */ #define acpi_lapic 0 diff --git a/arch/x86/kernel/acpi/processor.c b/arch/x86/kernel/acpi/processor.c index d722ca8..0f57307 100644 --- a/arch/x86/kernel/acpi/processor.c +++ b/arch/x86/kernel/acpi/processor.c @@ -12,40 +12,6 @@ #include #include -static void init_intel_pdc(struct acpi_processor *pr, struct cpuinfo_x86 *c) -{ - u32 *buf = (u32 *)pr->pdc->pointer->buffer.pointer; - - buf[2] |= ACPI_PDC_C_CAPABILITY_SMP; - - if (cpu_has(c, X86_FEATURE_EST)) - buf[2] |= ACPI_PDC_EST_CAPABILITY_SWSMP; - - if (cpu_has(c, X86_FEATURE_ACPI)) - buf[2] |= ACPI_PDC_T_FFH; - - /* - * If mwait/monitor is unsupported, C2/C3_FFH will be disabled - */ - if (!cpu_has(c, X86_FEATURE_MWAIT)) - buf[2] &= ~(ACPI_PDC_C_C2C3_FFH); - - return; -} - - -/* Initialize _PDC data based on the CPU vendor */ -void arch_acpi_processor_init_pdc(struct acpi_processor *pr) -{ - struct cpuinfo_x86 *c = &cpu_data(pr->id); - - init_intel_pdc(pr, c); - - return; -} - -EXPORT_SYMBOL(arch_acpi_processor_init_pdc); - void arch_acpi_processor_cleanup_pdc(struct acpi_processor *pr) { if (pr->pdc) { diff --git a/drivers/acpi/processor_pdc.c b/drivers/acpi/processor_pdc.c index ccda7c9..48df08e 100644 --- a/drivers/acpi/processor_pdc.c +++ b/drivers/acpi/processor_pdc.c @@ -40,6 +40,9 @@ static void acpi_set_pdc_bits(u32 *buf) /* Enable coordination with firmware's _TSD info */ buf[2] = ACPI_PDC_SMP_T_SWCOORD; + + /* Twiddle arch-specific bits needed for _PDC */ + arch_acpi_set_pdc_bits(buf); } static void acpi_processor_init_pdc(struct acpi_processor *pr) @@ -81,9 +84,6 @@ static void acpi_processor_init_pdc(struct acpi_processor *pr) obj_list->pointer = obj; pr->pdc = obj_list; - /* Now let the arch do the bit-twiddling to buf[] */ - arch_acpi_processor_init_pdc(pr); - return; } diff --git a/include/acpi/processor.h b/include/acpi/processor.h index a1b748a..50edd73 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h @@ -257,7 +257,6 @@ int acpi_processor_notify_smm(struct module *calling_module); DECLARE_PER_CPU(struct acpi_processor *, processors); extern struct acpi_processor_errata errata; -void arch_acpi_processor_init_pdc(struct acpi_processor *pr); void arch_acpi_processor_cleanup_pdc(struct acpi_processor *pr); #ifdef ARCH_HAS_POWER_INIT -- cgit v0.10.2 From 47817254b8637b56730aec26eed2c337d3938bb5 Mon Sep 17 00:00:00 2001 From: Alex Chiang Date: Sun, 20 Dec 2009 12:19:34 -0700 Subject: ACPI: processor: unify arch_acpi_processor_cleanup_pdc The x86 and ia64 implementations of the function in $subject are exactly the same. Also, since the arch-specific implementations of setting _PDC have been completely hollowed out, remove the empty shells. Cc: Tony Luck Cc: Thomas Gleixner Cc: Ingo Molnar Cc: "H. Peter Anvin" Signed-off-by: Alex Chiang Signed-off-by: Len Brown diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile index 2a75e93..e123634 100644 --- a/arch/ia64/kernel/Makefile +++ b/arch/ia64/kernel/Makefile @@ -18,10 +18,6 @@ obj-$(CONFIG_IA64_GENERIC) += acpi-ext.o obj-$(CONFIG_IA64_HP_ZX1) += acpi-ext.o obj-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += acpi-ext.o -ifneq ($(CONFIG_ACPI_PROCESSOR),) -obj-y += acpi-processor.o -endif - obj-$(CONFIG_IA64_PALINFO) += palinfo.o obj-$(CONFIG_IOSAPIC) += iosapic.o obj-$(CONFIG_MODULES) += module.o diff --git a/arch/ia64/kernel/acpi-processor.c b/arch/ia64/kernel/acpi-processor.c deleted file mode 100644 index 7ba5acc..0000000 --- a/arch/ia64/kernel/acpi-processor.c +++ /dev/null @@ -1,27 +0,0 @@ -/* - * arch/ia64/kernel/acpi-processor.c - * - * Copyright (C) 2005 Intel Corporation - * Venkatesh Pallipadi - * - Added _PDC for platforms with Intel CPUs - */ - -#include -#include -#include -#include - -#include -#include - -void arch_acpi_processor_cleanup_pdc(struct acpi_processor *pr) -{ - if (pr->pdc) { - kfree(pr->pdc->pointer->buffer.pointer); - kfree(pr->pdc->pointer); - kfree(pr->pdc); - pr->pdc = NULL; - } -} - -EXPORT_SYMBOL(arch_acpi_processor_cleanup_pdc); diff --git a/arch/x86/kernel/acpi/Makefile b/arch/x86/kernel/acpi/Makefile index fd5ca97..6f35260 100644 --- a/arch/x86/kernel/acpi/Makefile +++ b/arch/x86/kernel/acpi/Makefile @@ -4,7 +4,7 @@ obj-$(CONFIG_ACPI) += boot.o obj-$(CONFIG_ACPI_SLEEP) += sleep.o wakeup_rm.o wakeup_$(BITS).o ifneq ($(CONFIG_ACPI_PROCESSOR),) -obj-y += cstate.o processor.o +obj-y += cstate.o endif $(obj)/wakeup_rm.o: $(obj)/realmode/wakeup.bin diff --git a/arch/x86/kernel/acpi/processor.c b/arch/x86/kernel/acpi/processor.c deleted file mode 100644 index 0f57307..0000000 --- a/arch/x86/kernel/acpi/processor.c +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 2005 Intel Corporation - * Venkatesh Pallipadi - * - Added _PDC for platforms with Intel CPUs - */ - -#include -#include -#include -#include - -#include -#include - -void arch_acpi_processor_cleanup_pdc(struct acpi_processor *pr) -{ - if (pr->pdc) { - kfree(pr->pdc->pointer->buffer.pointer); - kfree(pr->pdc->pointer); - kfree(pr->pdc); - pr->pdc = NULL; - } -} - -EXPORT_SYMBOL(arch_acpi_processor_cleanup_pdc); diff --git a/drivers/acpi/processor_pdc.c b/drivers/acpi/processor_pdc.c index 48df08e..e786e2c 100644 --- a/drivers/acpi/processor_pdc.c +++ b/drivers/acpi/processor_pdc.c @@ -1,3 +1,12 @@ +/* + * Copyright (C) 2005 Intel Corporation + * Copyright (C) 2009 Hewlett-Packard Development Company, L.P. + * + * Alex Chiang + * - Unified x86/ia64 implementations + * Venkatesh Pallipadi + * - Added _PDC for platforms with Intel CPUs + */ #include #include @@ -121,6 +130,16 @@ static int acpi_processor_eval_pdc(struct acpi_processor *pr) return status; } +static void acpi_processor_cleanup_pdc(struct acpi_processor *pr) +{ + if (pr->pdc) { + kfree(pr->pdc->pointer->buffer.pointer); + kfree(pr->pdc->pointer); + kfree(pr->pdc); + pr->pdc = NULL; + } +} + void acpi_processor_set_pdc(struct acpi_processor *pr) { if (arch_has_acpi_pdc() == false) @@ -128,7 +147,7 @@ void acpi_processor_set_pdc(struct acpi_processor *pr) acpi_processor_init_pdc(pr); acpi_processor_eval_pdc(pr); - arch_acpi_processor_cleanup_pdc(pr); + acpi_processor_cleanup_pdc(pr); } EXPORT_SYMBOL_GPL(acpi_processor_set_pdc); diff --git a/include/acpi/processor.h b/include/acpi/processor.h index 50edd73..0873cd5 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h @@ -257,8 +257,6 @@ int acpi_processor_notify_smm(struct module *calling_module); DECLARE_PER_CPU(struct acpi_processor *, processors); extern struct acpi_processor_errata errata; -void arch_acpi_processor_cleanup_pdc(struct acpi_processor *pr); - #ifdef ARCH_HAS_POWER_INIT void acpi_processor_power_init_bm_check(struct acpi_processor_flags *flags, unsigned int cpu); -- cgit v0.10.2 From 3b407aef573b82139c3bc4dcaad2731fad56c054 Mon Sep 17 00:00:00 2001 From: Alex Chiang Date: Sun, 20 Dec 2009 12:19:39 -0700 Subject: ACPI: processor: introduce acpi_processor_alloc_pdc() acpi_processor_init_pdc() isn't really doing anything interesting with the struct acpi_processor * parameter. Its real job is to allocate the buffer for the _PDC bits. So rename the function to acpi_processor_alloc_pdc(), and just return the struct acpi_object_list * it's supposed to allocate. Signed-off-by: Alex Chiang Signed-off-by: Len Brown diff --git a/drivers/acpi/processor_pdc.c b/drivers/acpi/processor_pdc.c index e786e2c..23d2828 100644 --- a/drivers/acpi/processor_pdc.c +++ b/drivers/acpi/processor_pdc.c @@ -54,26 +54,24 @@ static void acpi_set_pdc_bits(u32 *buf) arch_acpi_set_pdc_bits(buf); } -static void acpi_processor_init_pdc(struct acpi_processor *pr) +static struct acpi_object_list *acpi_processor_alloc_pdc(void) { struct acpi_object_list *obj_list; union acpi_object *obj; u32 *buf; - pr->pdc = NULL; - /* allocate and initialize pdc. It will be used later. */ obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL); if (!obj_list) { printk(KERN_ERR "Memory allocation error\n"); - return; + return NULL; } obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL); if (!obj) { printk(KERN_ERR "Memory allocation error\n"); kfree(obj_list); - return; + return NULL; } buf = kmalloc(12, GFP_KERNEL); @@ -81,7 +79,7 @@ static void acpi_processor_init_pdc(struct acpi_processor *pr) printk(KERN_ERR "Memory allocation error\n"); kfree(obj); kfree(obj_list); - return; + return NULL; } acpi_set_pdc_bits(buf); @@ -91,9 +89,8 @@ static void acpi_processor_init_pdc(struct acpi_processor *pr) obj->buffer.pointer = (u8 *) buf; obj_list->count = 1; obj_list->pointer = obj; - pr->pdc = obj_list; - return; + return obj_list; } /* @@ -142,10 +139,17 @@ static void acpi_processor_cleanup_pdc(struct acpi_processor *pr) void acpi_processor_set_pdc(struct acpi_processor *pr) { + struct acpi_object_list *obj_list; + if (arch_has_acpi_pdc() == false) return; - acpi_processor_init_pdc(pr); + obj_list = acpi_processor_alloc_pdc(); + if (!obj_list) + return; + + pr->pdc = obj_list; + acpi_processor_eval_pdc(pr); acpi_processor_cleanup_pdc(pr); } -- cgit v0.10.2 From fa118564ed66f785f957d8230745b62e9244700d Mon Sep 17 00:00:00 2001 From: Alex Chiang Date: Sun, 20 Dec 2009 12:19:45 -0700 Subject: ACPI: processor: change acpi_processor_eval_pdc interface acpi_processor_eval_pdc() really only needs a handle and an acpi_object_list * to do its work. No need to pass in a struct acpi_processor *, so let's be more specific about what we want. Signed-off-by: Alex Chiang Signed-off-by: Len Brown diff --git a/drivers/acpi/processor_pdc.c b/drivers/acpi/processor_pdc.c index 23d2828..974de4e 100644 --- a/drivers/acpi/processor_pdc.c +++ b/drivers/acpi/processor_pdc.c @@ -97,13 +97,11 @@ static struct acpi_object_list *acpi_processor_alloc_pdc(void) * _PDC is required for a BIOS-OS handshake for most of the newer * ACPI processor features. */ -static int acpi_processor_eval_pdc(struct acpi_processor *pr) +static int +acpi_processor_eval_pdc(acpi_handle handle, struct acpi_object_list *pdc_in) { - struct acpi_object_list *pdc_in = pr->pdc; acpi_status status = AE_OK; - if (!pdc_in) - return status; if (idle_nomwait) { /* * If mwait is disabled for CPU C-states, the C2C3_FFH access @@ -118,7 +116,7 @@ static int acpi_processor_eval_pdc(struct acpi_processor *pr) buffer[2] &= ~(ACPI_PDC_C_C2C3_FFH | ACPI_PDC_C_C1_FFH); } - status = acpi_evaluate_object(pr->handle, "_PDC", pdc_in, NULL); + status = acpi_evaluate_object(handle, "_PDC", pdc_in, NULL); if (ACPI_FAILURE(status)) ACPI_DEBUG_PRINT((ACPI_DB_INFO, @@ -148,9 +146,7 @@ void acpi_processor_set_pdc(struct acpi_processor *pr) if (!obj_list) return; - pr->pdc = obj_list; - - acpi_processor_eval_pdc(pr); + acpi_processor_eval_pdc(pr->handle, obj_list); acpi_processor_cleanup_pdc(pr); } EXPORT_SYMBOL_GPL(acpi_processor_set_pdc); -- cgit v0.10.2 From b9c2db783456bcbce31e2482214cd337528db295 Mon Sep 17 00:00:00 2001 From: Alex Chiang Date: Sun, 20 Dec 2009 12:23:11 -0700 Subject: ACPI: processor: open code acpi_processor_cleanup_pdc We have the acpi_object_list * right there in acpi_processor_set_pdc() so it doesn't seem necessary for an entire helper function just to free it. Signed-off-by: Alex Chiang Signed-off-by: Len Brown diff --git a/drivers/acpi/processor_pdc.c b/drivers/acpi/processor_pdc.c index 974de4e..deeba22 100644 --- a/drivers/acpi/processor_pdc.c +++ b/drivers/acpi/processor_pdc.c @@ -125,16 +125,6 @@ acpi_processor_eval_pdc(acpi_handle handle, struct acpi_object_list *pdc_in) return status; } -static void acpi_processor_cleanup_pdc(struct acpi_processor *pr) -{ - if (pr->pdc) { - kfree(pr->pdc->pointer->buffer.pointer); - kfree(pr->pdc->pointer); - kfree(pr->pdc); - pr->pdc = NULL; - } -} - void acpi_processor_set_pdc(struct acpi_processor *pr) { struct acpi_object_list *obj_list; @@ -147,7 +137,10 @@ void acpi_processor_set_pdc(struct acpi_processor *pr) return; acpi_processor_eval_pdc(pr->handle, obj_list); - acpi_processor_cleanup_pdc(pr); + + kfree(obj_list->pointer->buffer.pointer); + kfree(obj_list->pointer); + kfree(obj_list); } EXPORT_SYMBOL_GPL(acpi_processor_set_pdc); -- cgit v0.10.2 From 43bab25ced218385f7e6a076c2459ea008cfd2e1 Mon Sep 17 00:00:00 2001 From: Alex Chiang Date: Sun, 20 Dec 2009 12:23:16 -0700 Subject: ACPI: processor: change acpi_processor_set_pdc() interface When calling _PDC, we really only need the handle to the processor to call the method; we don't look at any other parts of the struct acpi_processor * given to us. In the early path, when we walk the namespace, we are given the handle directly, so just pass it through to acpi_processor_set_pdc() without stuffing it into a wasteful struct acpi_processor allocated on the stack each time This saves 2834 bytes of stack. Update the interface accordingly. Signed-off-by: Alex Chiang Signed-off-by: Len Brown diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index a19a4ff..9863c98 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -763,7 +763,7 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device) } /* _PDC call should be done before doing anything else (if reqd.). */ - acpi_processor_set_pdc(pr); + acpi_processor_set_pdc(pr->handle); #ifdef CONFIG_CPU_FREQ acpi_processor_ppc_has_changed(pr, 0); diff --git a/drivers/acpi/processor_pdc.c b/drivers/acpi/processor_pdc.c index deeba22..30e4dc0 100644 --- a/drivers/acpi/processor_pdc.c +++ b/drivers/acpi/processor_pdc.c @@ -125,7 +125,7 @@ acpi_processor_eval_pdc(acpi_handle handle, struct acpi_object_list *pdc_in) return status; } -void acpi_processor_set_pdc(struct acpi_processor *pr) +void acpi_processor_set_pdc(acpi_handle handle) { struct acpi_object_list *obj_list; @@ -136,7 +136,7 @@ void acpi_processor_set_pdc(struct acpi_processor *pr) if (!obj_list) return; - acpi_processor_eval_pdc(pr->handle, obj_list); + acpi_processor_eval_pdc(handle, obj_list); kfree(obj_list->pointer->buffer.pointer); kfree(obj_list->pointer); @@ -147,19 +147,7 @@ EXPORT_SYMBOL_GPL(acpi_processor_set_pdc); static acpi_status early_init_pdc(acpi_handle handle, u32 lvl, void *context, void **rv) { - struct acpi_processor pr; - - pr.handle = handle; - - /* x86 implementation looks at pr.id to determine some - * CPU capabilites. We can just hard code to 0 since we're - * assuming the CPUs in the system are homogenous and all - * have the same capabilities. - */ - pr.id = 0; - - acpi_processor_set_pdc(&pr); - + acpi_processor_set_pdc(handle); return AE_OK; } diff --git a/include/acpi/processor.h b/include/acpi/processor.h index 0873cd5..7cc433d 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h @@ -323,7 +323,7 @@ static inline int acpi_processor_get_bios_limit(int cpu, unsigned int *limit) #endif /* CONFIG_CPU_FREQ */ /* in processor_pdc.c */ -void acpi_processor_set_pdc(struct acpi_processor *pr); +void acpi_processor_set_pdc(acpi_handle handle); /* in processor_throttling.c */ int acpi_processor_tstate_has_changed(struct acpi_processor *pr); -- cgit v0.10.2 From e59897fe443b5b0a71e135ef4020d1937c9f8901 Mon Sep 17 00:00:00 2001 From: Alex Chiang Date: Sun, 20 Dec 2009 12:23:21 -0700 Subject: ACPI: processor: remove _PDC object list from struct acpi_processor When we call _PDC, we get a handle to the processor, allocate the object list buffer as needed, and free it immediately after calling _PDC. There's no need to drag around this object list with us everywhere else, so let's just get rid of it. Signed-off-by: Alex Chiang Signed-off-by: Len Brown diff --git a/include/acpi/processor.h b/include/acpi/processor.h index 7cc433d..0ea5ef4 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h @@ -224,8 +224,6 @@ struct acpi_processor { struct acpi_processor_throttling throttling; struct acpi_processor_limit limit; struct thermal_cooling_device *cdev; - /* the _PDC objects for this processor, if any */ - struct acpi_object_list *pdc; }; struct acpi_processor_errata { -- cgit v0.10.2 From ae24e578de02b87cce3dc59248c29b2ecb071e9e Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Tue, 22 Dec 2009 09:42:06 +0100 Subject: ipvs: ip_vs_wrr.c: use lib/gcd.c Remove the private version of the greatest common divider to use lib/gcd.c, the latter also implementing the a < b case. [akpm@linux-foundation.org: repair neighboring whitespace because the diff looked odd] Signed-off-by: Florian Fainelli Cc: Sergei Shtylyov Cc: Takashi Iwai Acked-by: Simon Horman Cc: Julius Volz Cc: David S. Miller Cc: Patrick McHardy Signed-off-by: Andrew Morton Signed-off-by: Patrick McHardy diff --git a/net/netfilter/ipvs/Kconfig b/net/netfilter/ipvs/Kconfig index 79a6980..f2d7623 100644 --- a/net/netfilter/ipvs/Kconfig +++ b/net/netfilter/ipvs/Kconfig @@ -112,7 +112,8 @@ config IP_VS_RR module, choose M here. If unsure, say N. config IP_VS_WRR - tristate "weighted round-robin scheduling" + tristate "weighted round-robin scheduling" + select GCD ---help--- The weighted robin-robin scheduling algorithm directs network connections to different real servers based on server weights diff --git a/net/netfilter/ipvs/ip_vs_wrr.c b/net/netfilter/ipvs/ip_vs_wrr.c index 6182e8e..3c115fc 100644 --- a/net/netfilter/ipvs/ip_vs_wrr.c +++ b/net/netfilter/ipvs/ip_vs_wrr.c @@ -24,6 +24,7 @@ #include #include #include +#include #include @@ -38,20 +39,6 @@ struct ip_vs_wrr_mark { }; -/* - * Get the gcd of server weights - */ -static int gcd(int a, int b) -{ - int c; - - while ((c = a % b)) { - a = b; - b = c; - } - return b; -} - static int ip_vs_wrr_gcd_weight(struct ip_vs_service *svc) { struct ip_vs_dest *dest; -- cgit v0.10.2 From b6aa179334743c6152bd63f1fa368d6db3720db9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Wed, 16 Dec 2009 17:10:09 +0100 Subject: ASoC: sh: FSI:: don't check platform_get_irq's return value against zero MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit platform_get_irq returns -ENXIO on failure, so !irq was probably always true. Better use (int)irq <= 0. Note that a return value of zero is still handled as error even though this could mean irq0. This is a followup to 305b3228f9ff4d59f49e6d34a7034d44ee8ce2f0 that changed the return value of platform_get_irq from 0 to -ENXIO on error. Signed-off-by: Uwe Kleine-König Acked-by: Liam Girdwood Signed-off-by: Mark Brown diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index 9c49c11..42813b8 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c @@ -876,7 +876,7 @@ static int fsi_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_MEM, 0); irq = platform_get_irq(pdev, 0); - if (!res || !irq) { + if (!res || (int)irq <= 0) { dev_err(&pdev->dev, "Not enough FSI platform resources.\n"); ret = -ENODEV; goto exit; -- cgit v0.10.2 From 1628af5adf64cc2960bce81009f119de822f876e Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Tue, 22 Dec 2009 09:26:10 +0100 Subject: ASoC: add missing parameter to mx27vis_hifi_hw_free() Commit 2ccafed4 added an extra parameter to the DAI .set_pll() method, but it missed this call in sound/soc/imx/mx27vis_wm8974.c. Signed-off-by: Guennadi Liakhovetski Acked-by: Liam Girdwood Signed-off-by: Mark Brown diff --git a/sound/soc/imx/mx27vis_wm8974.c b/sound/soc/imx/mx27vis_wm8974.c index 0267d2d..07d2a24 100644 --- a/sound/soc/imx/mx27vis_wm8974.c +++ b/sound/soc/imx/mx27vis_wm8974.c @@ -180,7 +180,8 @@ static int mx27vis_hifi_hw_free(struct snd_pcm_substream *substream) struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; /* disable the PLL */ - return codec_dai->ops->set_pll(codec_dai, IGNORED_ARG, 0, 0); + return codec_dai->ops->set_pll(codec_dai, IGNORED_ARG, IGNORED_ARG, + 0, 0); } /* -- cgit v0.10.2 From 355ffe69cb329bb9ab9eca3ebef369268162220d Mon Sep 17 00:00:00 2001 From: David Vrabel Date: Tue, 22 Dec 2009 13:13:28 +0000 Subject: MAINTAINERS: update entries for WUSB, UWB and WLP subsystems Update the file patterns for the WUSB, UWB and WLP subsystems and add netdev@vger as the list for the WLP subsystem. Signed-off-by: David Vrabel diff --git a/MAINTAINERS b/MAINTAINERS index efd2ef2..d5244f1 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1402,6 +1402,8 @@ L: linux-usb@vger.kernel.org S: Supported F: Documentation/usb/WUSB-Design-overview.txt F: Documentation/usb/wusb-cbaf +F: drivers/usb/host/hwa-hc.c +F: drivers/usb/host/whci/ F: drivers/usb/wusbcore/ F: include/linux/usb/wusb* @@ -5430,7 +5432,10 @@ ULTRA-WIDEBAND (UWB) SUBSYSTEM: M: David Vrabel L: linux-usb@vger.kernel.org S: Supported -F: drivers/uwb/* +F: drivers/uwb/ +X: drivers/uwb/wlp/ +X: drivers/uwb/i1480/i1480u-wlp/ +X: drivers/uwb/i1480/i1480-wlp.h F: include/linux/uwb.h F: include/linux/uwb/ @@ -5943,9 +5948,12 @@ W: http://linuxwimax.org WIMEDIA LLC PROTOCOL (WLP) SUBSYSTEM M: David Vrabel +L: netdev@vger.kernel.org S: Maintained F: include/linux/wlp.h F: drivers/uwb/wlp/ +F: drivers/uwb/i1480/i1480u-wlp/ +F: drivers/uwb/i1480/i1480-wlp.h WISTRON LAPTOP BUTTON DRIVER M: Miloslav Trmac -- cgit v0.10.2 From 3321c2bceab3ae6efdb2dc119c41d78e85d4b661 Mon Sep 17 00:00:00 2001 From: Jean PIHET Date: Tue, 15 Dec 2009 12:36:10 +0100 Subject: ARM: 5849/1: ARMv7: fix Oprofile events count On Oprofile ARMv7 the PMNC_D bit was set to lower the PMU IRQs and so to decrease the risk of errata #628216 from appearing. The effect of setting the PMNC_D bit is that the CCNT counter is divided by 64, making the program counter events count inaccurate. The new OMAP3 r4 cores should have that errata fixed. The PMNC_D bit should not be set, this patch fixes it. Signed-off-by: Jean Pihet Signed-off-by: Russell King diff --git a/arch/arm/oprofile/op_model_v7.c b/arch/arm/oprofile/op_model_v7.c index f20295f..2088a6c 100644 --- a/arch/arm/oprofile/op_model_v7.c +++ b/arch/arm/oprofile/op_model_v7.c @@ -191,12 +191,8 @@ int armv7_setup_pmnc(void) return -EBUSY; } - /* - * Initialize & Reset PMNC: C bit, D bit and P bit. - * Note: Using a slower count for CCNT (D bit: divide by 64) results - * in a more stable system - */ - armv7_pmnc_write(PMNC_P | PMNC_C | PMNC_D); + /* Initialize & Reset PMNC: C bit and P bit */ + armv7_pmnc_write(PMNC_P | PMNC_C); for (cnt = CCNT; cnt < CNTMAX; cnt++) { -- cgit v0.10.2 From d76cdf2394df98383a21cbd0777234956aac2a18 Mon Sep 17 00:00:00 2001 From: wanzongshun Date: Fri, 18 Dec 2009 17:58:58 +0100 Subject: ARM: 5854/1: fix compiling error for NUC900 fix compiling error for NUC900 Signed-off-by: lijie Signed-off-by: Wan ZongShun Signed-off-by: Russell King diff --git a/arch/arm/mach-w90x900/dev.c b/arch/arm/mach-w90x900/dev.c index 51f17b7..ec711f4 100644 --- a/arch/arm/mach-w90x900/dev.c +++ b/arch/arm/mach-w90x900/dev.c @@ -197,7 +197,7 @@ static struct platform_device nuc900_device_emc = { /* SPI device */ -static struct w90p910_spi_info nuc900_spiflash_data = { +static struct nuc900_spi_info nuc900_spiflash_data = { .num_cs = 1, .lsb = 0, .txneg = 1, -- cgit v0.10.2 From 040f04598c6f494796815a4fc203379ff9fb847e Mon Sep 17 00:00:00 2001 From: wanzongshun Date: Fri, 18 Dec 2009 18:00:37 +0100 Subject: ARM: 5855/1: putc support for nuc900 putc support for nuc900 Signed-off-by: lijie Signed-off-by: Wan ZongShun Signed-off-by: Russell King diff --git a/arch/arm/mach-w90x900/include/mach/uncompress.h b/arch/arm/mach-w90x900/include/mach/uncompress.h index 050d9fe..56f1a74 100644 --- a/arch/arm/mach-w90x900/include/mach/uncompress.h +++ b/arch/arm/mach-w90x900/include/mach/uncompress.h @@ -22,11 +22,21 @@ #include #include +#include #define arch_decomp_wdog() +#define TX_DONE (UART_LSR_TEMT | UART_LSR_THRE) +static volatile u32 * uart_base = (u32 *)UART0_PA; + static void putc(int ch) { + /* Check THRE and TEMT bits before we transmit the character. + */ + while ((uart_base[UART_LSR] & TX_DONE) != TX_DONE) + barrier(); + + *uart_base = ch; } static inline void flush(void) -- cgit v0.10.2 From db93dd1ad65172867a9f50a1c36874a7393b8c53 Mon Sep 17 00:00:00 2001 From: wanzongshun Date: Fri, 18 Dec 2009 18:02:46 +0100 Subject: ARM: 5856/1: Fix bug of uart0 platfrom data for nuc900 Fix bug of uart0 platfrom data for nuc900 Signed-off-by: lijie Signed-off-by: Wan ZongShun Signed-off-by: Russell King diff --git a/arch/arm/mach-w90x900/cpu.c b/arch/arm/mach-w90x900/cpu.c index 921cef9..20dc0c9 100644 --- a/arch/arm/mach-w90x900/cpu.c +++ b/arch/arm/mach-w90x900/cpu.c @@ -96,6 +96,7 @@ static struct clk_lookup nuc900_clkregs[] = { struct plat_serial8250_port nuc900_uart_data[] = { NUC900_8250PORT(UART0), + {}, }; struct platform_device nuc900_serial_device = { -- cgit v0.10.2 From d9fd3ab89ff58ca70c8cc0eadc87cd4a96950f95 Mon Sep 17 00:00:00 2001 From: Mike Rapoport Date: Tue, 22 Dec 2009 07:31:04 +0100 Subject: ARM: 5857/1: ARM: dmabounce: fix build Commit f74f7e57ae9fa12b2951ae62ce3557799b318399 (ARM: use flush_kernel_dcache_area() for dmabounce) has broken dmabounce build: CC arch/arm/common/dmabounce.o arch/arm/common/dmabounce.c: In function 'unmap_single': arch/arm/common/dmabounce.c:315: error: implicit declaration of function '__cpuc_flush_kernel_dcache_area' make[2]: *** [arch/arm/common/dmabounce.o] Error 1 Fix it. Signed-off-by: Mike Rapoport Signed-off-by: Russell King diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c index bc90364..cc32c1e 100644 --- a/arch/arm/common/dmabounce.c +++ b/arch/arm/common/dmabounce.c @@ -312,7 +312,7 @@ static inline void unmap_single(struct device *dev, dma_addr_t dma_addr, * we need to ensure that the data will be coherent * with user mappings. */ - __cpuc_flush_kernel_dcache_area(ptr, size); + __cpuc_flush_dcache_area(ptr, size); } free_safe_buffer(dev->archdata.dmabounce, buf); } -- cgit v0.10.2 From 385e3ed4f0b81dd0b0b214050a30d352a71b95f7 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Wed, 16 Dec 2009 12:48:44 -0800 Subject: alloc_file(): simplify handling of mnt_clone_write() errors When alloc_file() and init_file() were combined, the error handling of mnt_clone_write() was taken into alloc_file() in a somewhat obfuscated way. Since we don't use the error code for anything except warning, we might as well warn directly without an extra variable. Signed-off-by: Roland Dreier Signed-off-by: Al Viro diff --git a/fs/file_table.c b/fs/file_table.c index 0afacf6..69652c5 100644 --- a/fs/file_table.c +++ b/fs/file_table.c @@ -186,10 +186,8 @@ struct file *alloc_file(struct path *path, fmode_t mode, * that we can do debugging checks at __fput() */ if ((mode & FMODE_WRITE) && !special_file(path->dentry->d_inode->i_mode)) { - int error = 0; file_take_write(file); - error = mnt_clone_write(path->mnt); - WARN_ON(error); + WARN_ON(mnt_clone_write(path->mnt)); } ima_counts_get(file); return file; -- cgit v0.10.2 From 05f94c9b74b0bed5469d97edffae350ec9c1f205 Mon Sep 17 00:00:00 2001 From: Evgeniy Polyakov Date: Fri, 18 Dec 2009 15:40:44 +0300 Subject: pohmelfs needs I_LOCK Kill debugging printk in question Signed-off-by: Evgeniy Polyakov Signed-off-by: Al Viro diff --git a/drivers/staging/pohmelfs/dir.c b/drivers/staging/pohmelfs/dir.c index 6c5b261..aacd25b 100644 --- a/drivers/staging/pohmelfs/dir.c +++ b/drivers/staging/pohmelfs/dir.c @@ -722,8 +722,6 @@ static int pohmelfs_remove_entry(struct inode *dir, struct dentry *dentry) if (inode->i_nlink) inode_dec_link_count(inode); } - dprintk("%s: inode: %p, lock: %ld, unhashed: %d.\n", - __func__, pi, inode->i_state & I_LOCK, hlist_unhashed(&inode->i_hash)); return err; } -- cgit v0.10.2 From ed2617585f39dd12fae38c657bba68b9779ea10d Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 21 Dec 2009 17:53:53 +0100 Subject: fs/compat_ioctl.c: fix build error when !BLOCK No driver uses SG_SET_TRANSFORM any more in Linux, since the ide-scsi driver was removed in 2.6.29. The compat-ioctl cleanup series moved the handling for this around, which broke building without CONFIG_BLOCK. Just remove the code handling it for compat mode. Signed-off-by: Al Viro diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index 14cbc83..332dd00 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -1600,8 +1600,6 @@ static long do_ioctl_trans(int fd, unsigned int cmd, case KDSKBMETA: case KDSKBLED: case KDSETLED: - /* SG stuff */ - case SG_SET_TRANSFORM: /* AUTOFS */ case AUTOFS_IOC_READY: case AUTOFS_IOC_FAIL: -- cgit v0.10.2 From 628ff7c1d8d8466a5ad8078bd0206a130f8b8a51 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Fri, 18 Dec 2009 09:41:24 -0800 Subject: anonfd: Allow making anon files read-only It seems a couple places such as arch/ia64/kernel/perfmon.c and drivers/infiniband/core/uverbs_main.c could use anon_inode_getfile() instead of a private pseudo-fs + alloc_file(), if only there were a way to get a read-only file. So provide this by having anon_inode_getfile() create a read-only file if we pass O_RDONLY in flags. Signed-off-by: Roland Dreier Signed-off-by: Al Viro diff --git a/fs/anon_inodes.c b/fs/anon_inodes.c index 2c99459..598237e 100644 --- a/fs/anon_inodes.c +++ b/fs/anon_inodes.c @@ -89,11 +89,19 @@ struct file *anon_inode_getfile(const char *name, struct qstr this; struct path path; struct file *file; + fmode_t mode; int error; if (IS_ERR(anon_inode_inode)) return ERR_PTR(-ENODEV); + switch (flags & O_ACCMODE) { + case O_RDONLY: mode = FMODE_READ; break; + case O_WRONLY: mode = FMODE_WRITE; break; + case O_RDWR: mode = FMODE_READ | FMODE_WRITE; break; + default: return ERR_PTR(-EINVAL); + } + if (fops->owner && !try_module_get(fops->owner)) return ERR_PTR(-ENOENT); @@ -121,13 +129,13 @@ struct file *anon_inode_getfile(const char *name, d_instantiate(path.dentry, anon_inode_inode); error = -ENFILE; - file = alloc_file(&path, FMODE_READ | FMODE_WRITE, fops); + file = alloc_file(&path, mode, fops); if (!file) goto err_dput; file->f_mapping = anon_inode_inode->i_mapping; file->f_pos = 0; - file->f_flags = O_RDWR | (flags & O_NONBLOCK); + file->f_flags = flags & (O_ACCMODE | O_NONBLOCK); file->f_version = 0; file->private_data = priv; diff --git a/fs/eventfd.c b/fs/eventfd.c index 8b47e42..d26402f 100644 --- a/fs/eventfd.c +++ b/fs/eventfd.c @@ -339,7 +339,7 @@ struct file *eventfd_file_create(unsigned int count, int flags) ctx->flags = flags; file = anon_inode_getfile("[eventfd]", &eventfd_fops, ctx, - flags & EFD_SHARED_FCNTL_FLAGS); + O_RDWR | (flags & EFD_SHARED_FCNTL_FLAGS)); if (IS_ERR(file)) eventfd_free_ctx(ctx); diff --git a/fs/eventpoll.c b/fs/eventpoll.c index 366c503..bd056a5 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c @@ -1206,7 +1206,7 @@ SYSCALL_DEFINE1(epoll_create1, int, flags) * a file structure and a free file descriptor. */ error = anon_inode_getfd("[eventpoll]", &eventpoll_fops, ep, - flags & O_CLOEXEC); + O_RDWR | (flags & O_CLOEXEC)); if (error < 0) ep_free(ep); diff --git a/fs/signalfd.c b/fs/signalfd.c index b07565c..1dabe4e 100644 --- a/fs/signalfd.c +++ b/fs/signalfd.c @@ -236,7 +236,7 @@ SYSCALL_DEFINE4(signalfd4, int, ufd, sigset_t __user *, user_mask, * anon_inode_getfd() will install the fd. */ ufd = anon_inode_getfd("[signalfd]", &signalfd_fops, ctx, - flags & (O_CLOEXEC | O_NONBLOCK)); + O_RDWR | (flags & (O_CLOEXEC | O_NONBLOCK))); if (ufd < 0) kfree(ctx); } else { diff --git a/fs/timerfd.c b/fs/timerfd.c index b042bd7..1bfc95a 100644 --- a/fs/timerfd.c +++ b/fs/timerfd.c @@ -200,7 +200,7 @@ SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags) hrtimer_init(&ctx->tmr, clockid, HRTIMER_MODE_ABS); ufd = anon_inode_getfd("[timerfd]", &timerfd_fops, ctx, - flags & TFD_SHARED_FCNTL_FLAGS); + O_RDWR | (flags & TFD_SHARED_FCNTL_FLAGS)); if (ufd < 0) kfree(ctx); diff --git a/kernel/perf_event.c b/kernel/perf_event.c index e0eb4a2..1f38270 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c @@ -4724,7 +4724,7 @@ SYSCALL_DEFINE5(perf_event_open, if (IS_ERR(event)) goto err_put_context; - err = anon_inode_getfd("[perf_event]", &perf_fops, event, 0); + err = anon_inode_getfd("[perf_event]", &perf_fops, event, O_RDWR); if (err < 0) goto err_free_put_context; diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index e1f2bf8..b5af881 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -1177,7 +1177,7 @@ static struct file_operations kvm_vcpu_fops = { */ static int create_vcpu_fd(struct kvm_vcpu *vcpu) { - return anon_inode_getfd("kvm-vcpu", &kvm_vcpu_fops, vcpu, 0); + return anon_inode_getfd("kvm-vcpu", &kvm_vcpu_fops, vcpu, O_RDWR); } /* @@ -1638,7 +1638,7 @@ static int kvm_dev_ioctl_create_vm(void) kvm = kvm_create_vm(); if (IS_ERR(kvm)) return PTR_ERR(kvm); - fd = anon_inode_getfd("kvm-vm", &kvm_vm_fops, kvm, 0); + fd = anon_inode_getfd("kvm-vm", &kvm_vm_fops, kvm, O_RDWR); if (fd < 0) kvm_put_kvm(kvm); -- cgit v0.10.2 From 482928d59db668b8d82a48717f78986d8cea72e9 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 19 Dec 2009 10:10:39 -0500 Subject: Fix f_flags/f_mode in case of lookup_instantiate_filp() from open(pathname, 3) Just set f_flags when shoving struct file into nameidata; don't postpone that until __dentry_open(). do_filp_open() has correct value; lookup_instantiate_filp() doesn't - we lose the difference between O_RDWR and 3 by that point. We still set .intent.open.flags, so no fs code needs to be changed. Signed-off-by: Al Viro diff --git a/fs/internal.h b/fs/internal.h index f67cd14..e96a166 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -85,3 +85,10 @@ extern struct file *get_empty_filp(void); * super.c */ extern int do_remount_sb(struct super_block *, int, void *, int); + +/* + * open.c + */ +struct nameidata; +extern struct file *nameidata_to_filp(struct nameidata *); +extern void release_open_intent(struct nameidata *); diff --git a/fs/namei.c b/fs/namei.c index dad4b80..d517f73 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -1640,6 +1640,7 @@ struct file *do_filp_open(int dfd, const char *pathname, if (filp == NULL) return ERR_PTR(-ENFILE); nd.intent.open.file = filp; + filp->f_flags = open_flag; nd.intent.open.flags = flag; nd.intent.open.create_mode = 0; error = do_path_lookup(dfd, pathname, @@ -1685,6 +1686,7 @@ struct file *do_filp_open(int dfd, const char *pathname, if (filp == NULL) goto exit_parent; nd.intent.open.file = filp; + filp->f_flags = open_flag; nd.intent.open.flags = flag; nd.intent.open.create_mode = mode; dir = nd.path.dentry; @@ -1725,7 +1727,7 @@ do_last: mnt_drop_write(nd.path.mnt); goto exit; } - filp = nameidata_to_filp(&nd, open_flag); + filp = nameidata_to_filp(&nd); mnt_drop_write(nd.path.mnt); if (nd.root.mnt) path_put(&nd.root); @@ -1789,7 +1791,7 @@ ok: mnt_drop_write(nd.path.mnt); goto exit; } - filp = nameidata_to_filp(&nd, open_flag); + filp = nameidata_to_filp(&nd); if (!IS_ERR(filp)) { error = ima_path_check(&filp->f_path, filp->f_mode & (MAY_READ | MAY_WRITE | MAY_EXEC)); diff --git a/fs/open.c b/fs/open.c index ca69241..6daee28 100644 --- a/fs/open.c +++ b/fs/open.c @@ -821,15 +821,14 @@ static inline int __get_file_write_access(struct inode *inode, } static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt, - int flags, struct file *f, + struct file *f, int (*open)(struct inode *, struct file *), const struct cred *cred) { struct inode *inode; int error; - f->f_flags = flags; - f->f_mode = (__force fmode_t)((flags+1) & O_ACCMODE) | FMODE_LSEEK | + f->f_mode = (__force fmode_t)((f->f_flags+1) & O_ACCMODE) | FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE; inode = dentry->d_inode; if (f->f_mode & FMODE_WRITE) { @@ -930,7 +929,6 @@ struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry if (IS_ERR(dentry)) goto out_err; nd->intent.open.file = __dentry_open(dget(dentry), mntget(nd->path.mnt), - nd->intent.open.flags - 1, nd->intent.open.file, open, cred); out: @@ -949,7 +947,7 @@ EXPORT_SYMBOL_GPL(lookup_instantiate_filp); * * Note that this function destroys the original nameidata */ -struct file *nameidata_to_filp(struct nameidata *nd, int flags) +struct file *nameidata_to_filp(struct nameidata *nd) { const struct cred *cred = current_cred(); struct file *filp; @@ -958,7 +956,7 @@ struct file *nameidata_to_filp(struct nameidata *nd, int flags) filp = nd->intent.open.file; /* Has the filesystem initialised the file for us? */ if (filp->f_path.dentry == NULL) - filp = __dentry_open(nd->path.dentry, nd->path.mnt, flags, filp, + filp = __dentry_open(nd->path.dentry, nd->path.mnt, filp, NULL, cred); else path_put(&nd->path); @@ -997,7 +995,8 @@ struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags, return ERR_PTR(error); } - return __dentry_open(dentry, mnt, flags, f, NULL, cred); + f->f_flags = flags; + return __dentry_open(dentry, mnt, f, NULL, cred); } EXPORT_SYMBOL(dentry_open); diff --git a/include/linux/namei.h b/include/linux/namei.h index 0289467..05b441d 100644 --- a/include/linux/namei.h +++ b/include/linux/namei.h @@ -72,8 +72,6 @@ extern int vfs_path_lookup(struct dentry *, struct vfsmount *, extern struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry, int (*open)(struct inode *, struct file *)); -extern struct file *nameidata_to_filp(struct nameidata *nd, int flags); -extern void release_open_intent(struct nameidata *); extern struct dentry *lookup_one_len(const char *, struct dentry *, int); -- cgit v0.10.2 From 5300990c0370e804e49d9a59d928c5d53fb73487 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 19 Dec 2009 10:15:07 -0500 Subject: Sanitize f_flags helpers * pull ACC_MODE to fs.h; we have several copies all over the place * nightmarish expression calculating f_mode by f_flags deserves a helper too (OPEN_FMODE(flags)) Signed-off-by: Al Viro diff --git a/fs/anon_inodes.c b/fs/anon_inodes.c index 598237e..9f0bf13 100644 --- a/fs/anon_inodes.c +++ b/fs/anon_inodes.c @@ -89,19 +89,11 @@ struct file *anon_inode_getfile(const char *name, struct qstr this; struct path path; struct file *file; - fmode_t mode; int error; if (IS_ERR(anon_inode_inode)) return ERR_PTR(-ENODEV); - switch (flags & O_ACCMODE) { - case O_RDONLY: mode = FMODE_READ; break; - case O_WRONLY: mode = FMODE_WRITE; break; - case O_RDWR: mode = FMODE_READ | FMODE_WRITE; break; - default: return ERR_PTR(-EINVAL); - } - if (fops->owner && !try_module_get(fops->owner)) return ERR_PTR(-ENOENT); @@ -129,7 +121,7 @@ struct file *anon_inode_getfile(const char *name, d_instantiate(path.dentry, anon_inode_inode); error = -ENFILE; - file = alloc_file(&path, mode, fops); + file = alloc_file(&path, OPEN_FMODE(flags), fops); if (!file) goto err_dput; file->f_mapping = anon_inode_inode->i_mapping; diff --git a/fs/namei.c b/fs/namei.c index d517f73..68921d9 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -37,8 +37,6 @@ #include "internal.h" -#define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE]) - /* [Feb-1997 T. Schoebel-Theuer] * Fundamental changes in the pathname lookup mechanisms (namei) * were necessary because of omirr. The reason is that omirr needs diff --git a/fs/open.c b/fs/open.c index 6daee28..040cef7 100644 --- a/fs/open.c +++ b/fs/open.c @@ -828,7 +828,7 @@ static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt, struct inode *inode; int error; - f->f_mode = (__force fmode_t)((f->f_flags+1) & O_ACCMODE) | FMODE_LSEEK | + f->f_mode = OPEN_FMODE(f->f_flags) | FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE; inode = dentry->d_inode; if (f->f_mode & FMODE_WRITE) { diff --git a/include/linux/fs.h b/include/linux/fs.h index cca1919..9e13b53 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2464,5 +2464,8 @@ int proc_nr_files(struct ctl_table *table, int write, int __init get_filesystem_list(char *buf); +#define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE]) +#define OPEN_FMODE(flag) ((__force fmode_t)((flag + 1) & O_ACCMODE)) + #endif /* __KERNEL__ */ #endif /* _LINUX_FS_H */ diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 267e484..fc0f928 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -250,7 +250,6 @@ struct audit_context { #endif }; -#define ACC_MODE(x) ("\004\002\006\006"[(x)&O_ACCMODE]) static inline int open_arg(int flags, int mask) { int n = ACC_MODE(flags); diff --git a/security/tomoyo/file.c b/security/tomoyo/file.c index 8346938..9a6c588 100644 --- a/security/tomoyo/file.c +++ b/security/tomoyo/file.c @@ -12,7 +12,6 @@ #include "common.h" #include "tomoyo.h" #include "realpath.h" -#define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE]) /* * tomoyo_globally_readable_file_entry is a structure which is used for holding -- cgit v0.10.2 From 95ebc3a7930d5965b00bbedbf36bfd3eb9124d65 Mon Sep 17 00:00:00 2001 From: Andreas Gruenbacher Date: Wed, 28 Oct 2009 01:46:33 +0100 Subject: Remove obsolete comment in fs.h This question was determined to be a bug which was fixed in commit 4a3b0a49. Signed-off-by: Andreas Gruenbacher Cc: Jan Blunck Signed-off-by: Al Viro diff --git a/include/linux/fs.h b/include/linux/fs.h index 9e13b53..7e3012e 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1624,8 +1624,6 @@ struct super_operations { * on the bit address once it is done. * * Q: What is the difference between I_WILL_FREE and I_FREEING? - * Q: igrab() only checks on (I_FREEING|I_WILL_FREE). Should it also check on - * I_CLEAR? If not, why? */ #define I_DIRTY_SYNC 1 #define I_DIRTY_DATASYNC 2 -- cgit v0.10.2 From 28ba0ec64ca0f6ad2b0338ccec0b00a4e64e7a69 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 6 Nov 2009 11:31:06 +0000 Subject: jfs: Fix 32bit build warning loff_t is a type that isn't entirely dependant upon 32 v 64bit choice Signed-off-by: Alan Cox Signed-off-by: Al Viro diff --git a/fs/jfs/super.c b/fs/jfs/super.c index 2234c73..d929a82 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c @@ -524,7 +524,7 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent) * Page cache is indexed by long. * I would use MAX_LFS_FILESIZE, but it's only half as big */ - sb->s_maxbytes = min(((u64) PAGE_CACHE_SIZE << 32) - 1, sb->s_maxbytes); + sb->s_maxbytes = min(((u64) PAGE_CACHE_SIZE << 32) - 1, (u64)sb->s_maxbytes); #endif sb->s_time_gran = 1; return 0; -- cgit v0.10.2 From a6ab7aa9f432f722808c6fea5a8b7f5f229de031 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 22 Dec 2009 20:43:17 +0100 Subject: PM / Runtime: Use device type and device class callbacks The power management of some devices is handled through device types and device classes rather than through bus types. Since these devices may also benefit from using the run-time power management core, extend it so that the device type and device class run-time PM callbacks can be taken into consideration by it if the bus type callback is not defined. Update the run-time PM core documentation to reflect this change. Signed-off-by: Rafael J. Wysocki diff --git a/Documentation/power/runtime_pm.txt b/Documentation/power/runtime_pm.txt index 4a3109b..7b5ab27 100644 --- a/Documentation/power/runtime_pm.txt +++ b/Documentation/power/runtime_pm.txt @@ -42,80 +42,81 @@ struct dev_pm_ops { ... }; -The ->runtime_suspend() callback is executed by the PM core for the bus type of -the device being suspended. The bus type's callback is then _entirely_ -_responsible_ for handling the device as appropriate, which may, but need not -include executing the device driver's own ->runtime_suspend() callback (from the +The ->runtime_suspend(), ->runtime_resume() and ->runtime_idle() callbacks are +executed by the PM core for either the bus type, or device type (if the bus +type's callback is not defined), or device class (if the bus type's and device +type's callbacks are not defined) of given device. The bus type, device type +and device class callbacks are referred to as subsystem-level callbacks in what +follows. + +The subsystem-level suspend callback is _entirely_ _responsible_ for handling +the suspend of the device as appropriate, which may, but need not include +executing the device driver's own ->runtime_suspend() callback (from the PM core's point of view it is not necessary to implement a ->runtime_suspend() -callback in a device driver as long as the bus type's ->runtime_suspend() knows -what to do to handle the device). +callback in a device driver as long as the subsystem-level suspend callback +knows what to do to handle the device). - * Once the bus type's ->runtime_suspend() callback has completed successfully + * Once the subsystem-level suspend callback has completed successfully for given device, the PM core regards the device as suspended, which need not mean that the device has been put into a low power state. It is supposed to mean, however, that the device will not process data and will - not communicate with the CPU(s) and RAM until its bus type's - ->runtime_resume() callback is executed for it. The run-time PM status of - a device after successful execution of its bus type's ->runtime_suspend() - callback is 'suspended'. - - * If the bus type's ->runtime_suspend() callback returns -EBUSY or -EAGAIN, - the device's run-time PM status is supposed to be 'active', which means that - the device _must_ be fully operational afterwards. - - * If the bus type's ->runtime_suspend() callback returns an error code - different from -EBUSY or -EAGAIN, the PM core regards this as a fatal - error and will refuse to run the helper functions described in Section 4 - for the device, until the status of it is directly set either to 'active' - or to 'suspended' (the PM core provides special helper functions for this - purpose). - -In particular, if the driver requires remote wakeup capability for proper -functioning and device_run_wake() returns 'false' for the device, then -->runtime_suspend() should return -EBUSY. On the other hand, if -device_run_wake() returns 'true' for the device and the device is put -into a low power state during the execution of its bus type's -->runtime_suspend(), it is expected that remote wake-up (i.e. hardware mechanism -allowing the device to request a change of its power state, such as PCI PME) -will be enabled for the device. Generally, remote wake-up should be enabled -for all input devices put into a low power state at run time. - -The ->runtime_resume() callback is executed by the PM core for the bus type of -the device being woken up. The bus type's callback is then _entirely_ -_responsible_ for handling the device as appropriate, which may, but need not -include executing the device driver's own ->runtime_resume() callback (from the -PM core's point of view it is not necessary to implement a ->runtime_resume() -callback in a device driver as long as the bus type's ->runtime_resume() knows -what to do to handle the device). - - * Once the bus type's ->runtime_resume() callback has completed successfully, - the PM core regards the device as fully operational, which means that the - device _must_ be able to complete I/O operations as needed. The run-time - PM status of the device is then 'active'. - - * If the bus type's ->runtime_resume() callback returns an error code, the PM - core regards this as a fatal error and will refuse to run the helper - functions described in Section 4 for the device, until its status is - directly set either to 'active' or to 'suspended' (the PM core provides - special helper functions for this purpose). - -The ->runtime_idle() callback is executed by the PM core for the bus type of -given device whenever the device appears to be idle, which is indicated to the -PM core by two counters, the device's usage counter and the counter of 'active' -children of the device. + not communicate with the CPU(s) and RAM until the subsystem-level resume + callback is executed for it. The run-time PM status of a device after + successful execution of the subsystem-level suspend callback is 'suspended'. + + * If the subsystem-level suspend callback returns -EBUSY or -EAGAIN, + the device's run-time PM status is 'active', which means that the device + _must_ be fully operational afterwards. + + * If the subsystem-level suspend callback returns an error code different + from -EBUSY or -EAGAIN, the PM core regards this as a fatal error and will + refuse to run the helper functions described in Section 4 for the device, + until the status of it is directly set either to 'active', or to 'suspended' + (the PM core provides special helper functions for this purpose). + +In particular, if the driver requires remote wake-up capability (i.e. hardware +mechanism allowing the device to request a change of its power state, such as +PCI PME) for proper functioning and device_run_wake() returns 'false' for the +device, then ->runtime_suspend() should return -EBUSY. On the other hand, if +device_run_wake() returns 'true' for the device and the device is put into a low +power state during the execution of the subsystem-level suspend callback, it is +expected that remote wake-up will be enabled for the device. Generally, remote +wake-up should be enabled for all input devices put into a low power state at +run time. + +The subsystem-level resume callback is _entirely_ _responsible_ for handling the +resume of the device as appropriate, which may, but need not include executing +the device driver's own ->runtime_resume() callback (from the PM core's point of +view it is not necessary to implement a ->runtime_resume() callback in a device +driver as long as the subsystem-level resume callback knows what to do to handle +the device). + + * Once the subsystem-level resume callback has completed successfully, the PM + core regards the device as fully operational, which means that the device + _must_ be able to complete I/O operations as needed. The run-time PM status + of the device is then 'active'. + + * If the subsystem-level resume callback returns an error code, the PM core + regards this as a fatal error and will refuse to run the helper functions + described in Section 4 for the device, until its status is directly set + either to 'active' or to 'suspended' (the PM core provides special helper + functions for this purpose). + +The subsystem-level idle callback is executed by the PM core whenever the device +appears to be idle, which is indicated to the PM core by two counters, the +device's usage counter and the counter of 'active' children of the device. * If any of these counters is decreased using a helper function provided by the PM core and it turns out to be equal to zero, the other counter is checked. If that counter also is equal to zero, the PM core executes the - device bus type's ->runtime_idle() callback (with the device as an - argument). + subsystem-level idle callback with the device as an argument. -The action performed by a bus type's ->runtime_idle() callback is totally -dependent on the bus type in question, but the expected and recommended action -is to check if the device can be suspended (i.e. if all of the conditions -necessary for suspending the device are satisfied) and to queue up a suspend -request for the device in that case. The value returned by this callback is -ignored by the PM core. +The action performed by a subsystem-level idle callback is totally dependent on +the subsystem in question, but the expected and recommended action is to check +if the device can be suspended (i.e. if all of the conditions necessary for +suspending the device are satisfied) and to queue up a suspend request for the +device in that case. The value returned by this callback is ignored by the PM +core. The helper functions provided by the PM core, described in Section 4, guarantee that the following constraints are met with respect to the bus type's run-time @@ -238,41 +239,41 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h: removing the device from device hierarchy int pm_runtime_idle(struct device *dev); - - execute ->runtime_idle() for the device's bus type; returns 0 on success - or error code on failure, where -EINPROGRESS means that ->runtime_idle() - is already being executed + - execute the subsystem-level idle callback for the device; returns 0 on + success or error code on failure, where -EINPROGRESS means that + ->runtime_idle() is already being executed int pm_runtime_suspend(struct device *dev); - - execute ->runtime_suspend() for the device's bus type; returns 0 on + - execute the subsystem-level suspend callback for the device; returns 0 on success, 1 if the device's run-time PM status was already 'suspended', or error code on failure, where -EAGAIN or -EBUSY means it is safe to attempt to suspend the device again in future int pm_runtime_resume(struct device *dev); - - execute ->runtime_resume() for the device's bus type; returns 0 on + - execute the subsystem-leve resume callback for the device; returns 0 on success, 1 if the device's run-time PM status was already 'active' or error code on failure, where -EAGAIN means it may be safe to attempt to resume the device again in future, but 'power.runtime_error' should be checked additionally int pm_request_idle(struct device *dev); - - submit a request to execute ->runtime_idle() for the device's bus type - (the request is represented by a work item in pm_wq); returns 0 on success - or error code if the request has not been queued up + - submit a request to execute the subsystem-level idle callback for the + device (the request is represented by a work item in pm_wq); returns 0 on + success or error code if the request has not been queued up int pm_schedule_suspend(struct device *dev, unsigned int delay); - - schedule the execution of ->runtime_suspend() for the device's bus type - in future, where 'delay' is the time to wait before queuing up a suspend - work item in pm_wq, in milliseconds (if 'delay' is zero, the work item is - queued up immediately); returns 0 on success, 1 if the device's PM + - schedule the execution of the subsystem-level suspend callback for the + device in future, where 'delay' is the time to wait before queuing up a + suspend work item in pm_wq, in milliseconds (if 'delay' is zero, the work + item is queued up immediately); returns 0 on success, 1 if the device's PM run-time status was already 'suspended', or error code if the request hasn't been scheduled (or queued up if 'delay' is 0); if the execution of ->runtime_suspend() is already scheduled and not yet expired, the new value of 'delay' will be used as the time to wait int pm_request_resume(struct device *dev); - - submit a request to execute ->runtime_resume() for the device's bus type - (the request is represented by a work item in pm_wq); returns 0 on + - submit a request to execute the subsystem-level resume callback for the + device (the request is represented by a work item in pm_wq); returns 0 on success, 1 if the device's run-time PM status was already 'active', or error code if the request hasn't been queued up @@ -303,12 +304,12 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h: run-time PM callbacks described in Section 2 int pm_runtime_disable(struct device *dev); - - prevent the run-time PM helper functions from running the device bus - type's run-time PM callbacks, make sure that all of the pending run-time - PM operations on the device are either completed or canceled; returns - 1 if there was a resume request pending and it was necessary to execute - ->runtime_resume() for the device's bus type to satisfy that request, - otherwise 0 is returned + - prevent the run-time PM helper functions from running subsystem-level + run-time PM callbacks for the device, make sure that all of the pending + run-time PM operations on the device are either completed or canceled; + returns 1 if there was a resume request pending and it was necessary to + execute the subsystem-level resume callback for the device to satisfy that + request, otherwise 0 is returned void pm_suspend_ignore_children(struct device *dev, bool enable); - set/unset the power.ignore_children flag of the device @@ -378,5 +379,5 @@ pm_runtime_suspend() or pm_runtime_idle() or their asynchronous counterparts, they will fail returning -EAGAIN, because the device's usage counter is incremented by the core before executing ->probe() and ->remove(). Still, it may be desirable to suspend the device as soon as ->probe() or ->remove() has -finished, so the PM core uses pm_runtime_idle_sync() to invoke the device bus -type's ->runtime_idle() callback at that time. +finished, so the PM core uses pm_runtime_idle_sync() to invoke the +subsystem-level idle callback for the device at that time. diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 40d7720..f8b044e 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c @@ -85,6 +85,19 @@ static int __pm_runtime_idle(struct device *dev) dev->bus->pm->runtime_idle(dev); spin_lock_irq(&dev->power.lock); + } else if (dev->type && dev->type->pm && dev->type->pm->runtime_idle) { + spin_unlock_irq(&dev->power.lock); + + dev->type->pm->runtime_idle(dev); + + spin_lock_irq(&dev->power.lock); + } else if (dev->class && dev->class->pm + && dev->class->pm->runtime_idle) { + spin_unlock_irq(&dev->power.lock); + + dev->class->pm->runtime_idle(dev); + + spin_lock_irq(&dev->power.lock); } dev->power.idle_notification = false; @@ -194,6 +207,22 @@ int __pm_runtime_suspend(struct device *dev, bool from_wq) spin_lock_irq(&dev->power.lock); dev->power.runtime_error = retval; + } else if (dev->type && dev->type->pm + && dev->type->pm->runtime_suspend) { + spin_unlock_irq(&dev->power.lock); + + retval = dev->type->pm->runtime_suspend(dev); + + spin_lock_irq(&dev->power.lock); + dev->power.runtime_error = retval; + } else if (dev->class && dev->class->pm + && dev->class->pm->runtime_suspend) { + spin_unlock_irq(&dev->power.lock); + + retval = dev->class->pm->runtime_suspend(dev); + + spin_lock_irq(&dev->power.lock); + dev->power.runtime_error = retval; } else { retval = -ENOSYS; } @@ -359,6 +388,22 @@ int __pm_runtime_resume(struct device *dev, bool from_wq) spin_lock_irq(&dev->power.lock); dev->power.runtime_error = retval; + } else if (dev->type && dev->type->pm + && dev->type->pm->runtime_resume) { + spin_unlock_irq(&dev->power.lock); + + retval = dev->type->pm->runtime_resume(dev); + + spin_lock_irq(&dev->power.lock); + dev->power.runtime_error = retval; + } else if (dev->class && dev->class->pm + && dev->class->pm->runtime_resume) { + spin_unlock_irq(&dev->power.lock); + + retval = dev->class->pm->runtime_resume(dev); + + spin_lock_irq(&dev->power.lock); + dev->power.runtime_error = retval; } else { retval = -ENOSYS; } -- cgit v0.10.2 From f1212ae1332b95fe3bafa7b5c063dd8e473247cf Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 22 Dec 2009 20:43:40 +0100 Subject: PM: Runtime PM documentation update This patch (as1318) updates the runtime PM documentation, adding a section discussing the interaction between runtime PM and system sleep. [rjw: Rebased and made it agree with the other updates better.] Signed-off-by: Alan Stern Signed-off-by: Rafael J. Wysocki diff --git a/Documentation/power/runtime_pm.txt b/Documentation/power/runtime_pm.txt index 7b5ab27..356fd86 100644 --- a/Documentation/power/runtime_pm.txt +++ b/Documentation/power/runtime_pm.txt @@ -381,3 +381,53 @@ incremented by the core before executing ->probe() and ->remove(). Still, it may be desirable to suspend the device as soon as ->probe() or ->remove() has finished, so the PM core uses pm_runtime_idle_sync() to invoke the subsystem-level idle callback for the device at that time. + +6. Run-time PM and System Sleep + +Run-time PM and system sleep (i.e., system suspend and hibernation, also known +as suspend-to-RAM and suspend-to-disk) interact with each other in a couple of +ways. If a device is active when a system sleep starts, everything is +straightforward. But what should happen if the device is already suspended? + +The device may have different wake-up settings for run-time PM and system sleep. +For example, remote wake-up may be enabled for run-time suspend but disallowed +for system sleep (device_may_wakeup(dev) returns 'false'). When this happens, +the subsystem-level system suspend callback is responsible for changing the +device's wake-up setting (it may leave that to the device driver's system +suspend routine). It may be necessary to resume the device and suspend it again +in order to do so. The same is true if the driver uses different power levels +or other settings for run-time suspend and system sleep. + +During system resume, devices generally should be brought back to full power, +even if they were suspended before the system sleep began. There are several +reasons for this, including: + + * The device might need to switch power levels, wake-up settings, etc. + + * Remote wake-up events might have been lost by the firmware. + + * The device's children may need the device to be at full power in order + to resume themselves. + + * The driver's idea of the device state may not agree with the device's + physical state. This can happen during resume from hibernation. + + * The device might need to be reset. + + * Even though the device was suspended, if its usage counter was > 0 then most + likely it would need a run-time resume in the near future anyway. + + * Always going back to full power is simplest. + +If the device was suspended before the sleep began, then its run-time PM status +will have to be updated to reflect the actual post-system sleep status. The way +to do this is: + + pm_runtime_disable(dev); + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + +The PM core always increments the run-time usage counter before calling the +->prepare() callback and decrements it after calling the ->complete() callback. +Hence disabling run-time PM temporarily like this will not cause any run-time +suspend callbacks to be lost. -- cgit v0.10.2 From 4a28395d72a956f2dad24e343d06bc08c9afb89a Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 21 Dec 2009 16:19:58 -0800 Subject: arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c: avoid cross-CPU interrupts by using smp_call_function_any() Presently acpi-cpufreq will perform the MSR read on the first CPU in the mask. That's inefficient if that CPU differs from the current CPU. Because we have to perform a cross-CPU call, but we could have run the rdmsr on the current CPU. So switch to using the new smp_call_function_any(), which will perform the call on the current CPU if that CPU is present in the mask (it is). Cc: "Zhang, Yanmin" Cc: Dave Jones Cc: Ingo Molnar Cc: Jaswinder Singh Rajput Cc: Len Brown Cc: Mike Galbraith Cc: Rusty Russell Cc: Thomas Gleixner Cc: Venkatesh Pallipadi Cc: Zhao Yakui Signed-off-by: Andrew Morton Signed-off-by: Len Brown diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c index f28decf..1b1920f 100644 --- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c @@ -190,9 +190,11 @@ static void do_drv_write(void *_cmd) static void drv_read(struct drv_cmd *cmd) { + int err; cmd->val = 0; - smp_call_function_single(cpumask_any(cmd->mask), do_drv_read, cmd, 1); + err = smp_call_function_any(cmd->mask, do_drv_read, cmd, 1); + WARN_ON_ONCE(err); /* smp_call_function_any() was buggy? */ } static void drv_write(struct drv_cmd *cmd) -- cgit v0.10.2 From 83f57a11d84460dfe2afdb5a8bc759953428e38b Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 22 Dec 2009 14:10:37 -0800 Subject: Revert "time: Remove xtime_cache" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 7bc7d637452383d56ba4368d4336b0dde1bb476d, as requested by John Stultz. Quoting John: "Petr Titěra reported an issue where he saw odd atime regressions with 2.6.33 where there were a full second worth of nanoseconds in the nanoseconds field. He also reviewed the time code and narrowed down the problem: unhandled overflow of the nanosecond field caused by rounding up the sub-nanosecond accumulated time. Details: * At the end of update_wall_time(), we currently round up the sub-nanosecond portion of accumulated time when storing it into xtime. This was added to avoid time inconsistencies caused when the sub-nanosecond portion was truncated when storing into xtime. Unfortunately we don't handle the possible second overflow caused by that rounding. * Previously the xtime_cache code hid this overflow by normalizing the xtime value when storing into the xtime_cache. * We could try to handle the second overflow after the rounding up, but since this affects the timekeeping's internal state, this would further complicate the next accumulation cycle, causing small errors in ntp steering. As much as I'd like to get rid of it, the xtime_cache code is known to work. * The correct fix is really to include the sub-nanosecond portion in the timekeeping accessor function, so we don't need to round up at during accumulation. This would greatly simplify the accumulation code. Unfortunately, we can't do this safely until the last three non-GENERIC_TIME arches (sparc32, arm, cris) are converted (those patches are in -mm) and we kill off the spots where arches set xtime directly. This is all 2.6.34 material, so I think reverting the xtime_cache change is the best approach for now. Many thanks to Petr for both reporting and finding the issue!" Reported-by: Petr Titěra Requested-by: john stultz Cc: Ingo Molnar Signed-off-by: Linus Torvalds diff --git a/kernel/time.c b/kernel/time.c index c6324d9..8047980 100644 --- a/kernel/time.c +++ b/kernel/time.c @@ -136,6 +136,7 @@ static inline void warp_clock(void) write_seqlock_irq(&xtime_lock); wall_to_monotonic.tv_sec -= sys_tz.tz_minuteswest * 60; xtime.tv_sec += sys_tz.tz_minuteswest * 60; + update_xtime_cache(0); write_sequnlock_irq(&xtime_lock); clock_was_set(); } diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index af4135f..7faaa32 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -165,6 +165,13 @@ struct timespec raw_time; /* flag for if timekeeping is suspended */ int __read_mostly timekeeping_suspended; +static struct timespec xtime_cache __attribute__ ((aligned (16))); +void update_xtime_cache(u64 nsec) +{ + xtime_cache = xtime; + timespec_add_ns(&xtime_cache, nsec); +} + /* must hold xtime_lock */ void timekeeping_leap_insert(int leapsecond) { @@ -325,6 +332,8 @@ int do_settimeofday(struct timespec *tv) xtime = *tv; + update_xtime_cache(0); + timekeeper.ntp_error = 0; ntp_clear(); @@ -550,6 +559,7 @@ void __init timekeeping_init(void) } set_normalized_timespec(&wall_to_monotonic, -boot.tv_sec, -boot.tv_nsec); + update_xtime_cache(0); total_sleep_time.tv_sec = 0; total_sleep_time.tv_nsec = 0; write_sequnlock_irqrestore(&xtime_lock, flags); @@ -583,6 +593,7 @@ static int timekeeping_resume(struct sys_device *dev) wall_to_monotonic = timespec_sub(wall_to_monotonic, ts); total_sleep_time = timespec_add_safe(total_sleep_time, ts); } + update_xtime_cache(0); /* re-base the last cycle value */ timekeeper.clock->cycle_last = timekeeper.clock->read(timekeeper.clock); timekeeper.ntp_error = 0; @@ -722,6 +733,7 @@ static void timekeeping_adjust(s64 offset) timekeeper.ntp_error_shift; } + /** * logarithmic_accumulation - shifted accumulation of cycles * @@ -765,6 +777,7 @@ static cycle_t logarithmic_accumulation(cycle_t offset, int shift) return offset; } + /** * update_wall_time - Uses the current clocksource to increment the wall time * @@ -774,6 +787,7 @@ void update_wall_time(void) { struct clocksource *clock; cycle_t offset; + u64 nsecs; int shift = 0, maxshift; /* Make sure we're fully resumed: */ @@ -839,6 +853,9 @@ void update_wall_time(void) timekeeper.ntp_error += timekeeper.xtime_nsec << timekeeper.ntp_error_shift; + nsecs = clocksource_cyc2ns(offset, timekeeper.mult, timekeeper.shift); + update_xtime_cache(nsecs); + /* check to see if there is a new clocksource to use */ update_vsyscall(&xtime, timekeeper.clock, timekeeper.mult); } @@ -875,13 +892,13 @@ void monotonic_to_bootbased(struct timespec *ts) unsigned long get_seconds(void) { - return xtime.tv_sec; + return xtime_cache.tv_sec; } EXPORT_SYMBOL(get_seconds); struct timespec __current_kernel_time(void) { - return xtime; + return xtime_cache; } struct timespec current_kernel_time(void) @@ -891,7 +908,8 @@ struct timespec current_kernel_time(void) do { seq = read_seqbegin(&xtime_lock); - now = xtime; + + now = xtime_cache; } while (read_seqretry(&xtime_lock, seq)); return now; @@ -905,7 +923,8 @@ struct timespec get_monotonic_coarse(void) do { seq = read_seqbegin(&xtime_lock); - now = xtime; + + now = xtime_cache; mono = wall_to_monotonic; } while (read_seqretry(&xtime_lock, seq)); -- cgit v0.10.2 From a6cd13f3c98d1d16213e3b61054b9c209d93f877 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 21 Dec 2009 14:37:22 -0800 Subject: lib/string.c: fix kernel-doc warnings Fix kernel-doc warnings (@arg name) in string.c::skip_spaces(). Warning(lib/string.c:347): No description found for parameter 'str' Warning(lib/string.c:347): Excess function parameter 's' description in 'skip_spaces' Signed-off-by: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/lib/string.c b/lib/string.c index afce96a..9f75b4e 100644 --- a/lib/string.c +++ b/lib/string.c @@ -338,10 +338,10 @@ EXPORT_SYMBOL(strnchr); #endif /** - * skip_spaces - Removes leading whitespace from @s. - * @s: The string to be stripped. + * skip_spaces - Removes leading whitespace from @str. + * @str: The string to be stripped. * - * Returns a pointer to the first non-whitespace character in @s. + * Returns a pointer to the first non-whitespace character in @str. */ char *skip_spaces(const char *str) { -- cgit v0.10.2 From 2ec91eec47f713e3d158ba5b28a24a85a2cf3650 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 21 Dec 2009 14:37:23 -0800 Subject: mm tracing: cleanup Documentation/trace/events-kmem.txt Clean up typos/grammos/spellos in events-kmem.txt. Signed-off-by: Randy Dunlap Cc: Mel Gorman Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/Documentation/trace/events-kmem.txt b/Documentation/trace/events-kmem.txt index 6ef2a86..aa82ee4 100644 --- a/Documentation/trace/events-kmem.txt +++ b/Documentation/trace/events-kmem.txt @@ -1,7 +1,7 @@ Subsystem Trace Points: kmem -The tracing system kmem captures events related to object and page allocation -within the kernel. Broadly speaking there are four major subheadings. +The kmem tracing system captures events related to object and page allocation +within the kernel. Broadly speaking there are five major subheadings. o Slab allocation of small objects of unknown type (kmalloc) o Slab allocation of small objects of known type @@ -9,7 +9,7 @@ within the kernel. Broadly speaking there are four major subheadings. o Per-CPU Allocator Activity o External Fragmentation -This document will describe what each of the tracepoints are and why they +This document describes what each of the tracepoints is and why they might be useful. 1. Slab allocation of small objects of unknown type @@ -34,7 +34,7 @@ kmem_cache_free call_site=%lx ptr=%p These events are similar in usage to the kmalloc-related events except that it is likely easier to pin the event down to a specific cache. At the time of writing, no information is available on what slab is being allocated from, -but the call_site can usually be used to extrapolate that information +but the call_site can usually be used to extrapolate that information. 3. Page allocation ================== @@ -80,9 +80,9 @@ event indicating whether it is for a percpu_refill or not. When the per-CPU list is too full, a number of pages are freed, each one which triggers a mm_page_pcpu_drain event. -The individual nature of the events are so that pages can be tracked +The individual nature of the events is so that pages can be tracked between allocation and freeing. A number of drain or refill pages that occur -consecutively imply the zone->lock being taken once. Large amounts of PCP +consecutively imply the zone->lock being taken once. Large amounts of per-CPU refills and drains could imply an imbalance between CPUs where too much work is being concentrated in one place. It could also indicate that the per-CPU lists should be a larger size. Finally, large amounts of refills on one CPU @@ -102,6 +102,6 @@ is important. Large numbers of this event implies that memory is fragmenting and high-order allocations will start failing at some time in the future. One -means of reducing the occurange of this event is to increase the size of +means of reducing the occurrence of this event is to increase the size of min_free_kbytes in increments of 3*pageblock_size*nr_online_nodes where pageblock_size is usually the size of the default hugepage size. -- cgit v0.10.2 From 45465487897a1c6d508b14b904dc5777f7ec7e04 Mon Sep 17 00:00:00 2001 From: Stefani Seibold Date: Mon, 21 Dec 2009 14:37:26 -0800 Subject: kfifo: move struct kfifo in place This is a new generic kernel FIFO implementation. The current kernel fifo API is not very widely used, because it has to many constrains. Only 17 files in the current 2.6.31-rc5 used it. FIFO's are like list's a very basic thing and a kfifo API which handles the most use case would save a lot of development time and memory resources. I think this are the reasons why kfifo is not in use: - The API is to simple, important functions are missing - A fifo can be only allocated dynamically - There is a requirement of a spinlock whether you need it or not - There is no support for data records inside a fifo So I decided to extend the kfifo in a more generic way without blowing up the API to much. The new API has the following benefits: - Generic usage: For kernel internal use and/or device driver. - Provide an API for the most use case. - Slim API: The whole API provides 25 functions. - Linux style habit. - DECLARE_KFIFO, DEFINE_KFIFO and INIT_KFIFO Macros - Direct copy_to_user from the fifo and copy_from_user into the fifo. - The kfifo itself is an in place member of the using data structure, this save an indirection access and does not waste the kernel allocator. - Lockless access: if only one reader and one writer is active on the fifo, which is the common use case, no additional locking is necessary. - Remove spinlock - give the user the freedom of choice what kind of locking to use if one is required. - Ability to handle records. Three type of records are supported: - Variable length records between 0-255 bytes, with a record size field of 1 bytes. - Variable length records between 0-65535 bytes, with a record size field of 2 bytes. - Fixed size records, which no record size field. - Preserve memory resource. - Performance! - Easy to use! This patch: Since most users want to have the kfifo as part of another object, reorganize the code to allow including struct kfifo in another data structure. This requires changing the kfifo_alloc and kfifo_init prototypes so that we pass an existing kfifo pointer into them. This patch changes the implementation and all existing users. [akpm@linux-foundation.org: fix warning] Signed-off-by: Stefani Seibold Acked-by: Greg Kroah-Hartman Acked-by: Mauro Carvalho Chehab Acked-by: Andi Kleen Acked-by: Arnd Bergmann Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/char/nozomi.c b/drivers/char/nozomi.c index d3400b2..0f39bec 100644 --- a/drivers/char/nozomi.c +++ b/drivers/char/nozomi.c @@ -358,7 +358,7 @@ struct port { u8 update_flow_control; struct ctrl_ul ctrl_ul; struct ctrl_dl ctrl_dl; - struct kfifo *fifo_ul; + struct kfifo fifo_ul; void __iomem *dl_addr[2]; u32 dl_size[2]; u8 toggle_dl; @@ -685,8 +685,8 @@ static int nozomi_read_config_table(struct nozomi *dc) dump_table(dc); for (i = PORT_MDM; i < MAX_PORT; i++) { - dc->port[i].fifo_ul = - kfifo_alloc(FIFO_BUFFER_SIZE_UL, GFP_ATOMIC, NULL); + kfifo_alloc(&dc->port[i].fifo_ul, + FIFO_BUFFER_SIZE_UL, GFP_ATOMIC, NULL); memset(&dc->port[i].ctrl_dl, 0, sizeof(struct ctrl_dl)); memset(&dc->port[i].ctrl_ul, 0, sizeof(struct ctrl_ul)); } @@ -798,7 +798,7 @@ static int send_data(enum port_type index, struct nozomi *dc) struct tty_struct *tty = tty_port_tty_get(&port->port); /* Get data from tty and place in buf for now */ - size = __kfifo_get(port->fifo_ul, dc->send_buf, + size = __kfifo_get(&port->fifo_ul, dc->send_buf, ul_size < SEND_BUF_MAX ? ul_size : SEND_BUF_MAX); if (size == 0) { @@ -988,11 +988,11 @@ static int receive_flow_control(struct nozomi *dc) } else if (old_ctrl.CTS == 0 && ctrl_dl.CTS == 1) { - if (__kfifo_len(dc->port[port].fifo_ul)) { + if (__kfifo_len(&dc->port[port].fifo_ul)) { DBG1("Enable interrupt (0x%04X) on port: %d", enable_ier, port); DBG1("Data in buffer [%d], enable transmit! ", - __kfifo_len(dc->port[port].fifo_ul)); + __kfifo_len(&dc->port[port].fifo_ul)); enable_transmit_ul(port, dc); } else { DBG1("No data in buffer..."); @@ -1536,8 +1536,7 @@ static void __devexit nozomi_card_exit(struct pci_dev *pdev) free_irq(pdev->irq, dc); for (i = 0; i < MAX_PORT; i++) - if (dc->port[i].fifo_ul) - kfifo_free(dc->port[i].fifo_ul); + kfifo_free(&dc->port[i].fifo_ul); kfree(dc->send_buf); @@ -1673,7 +1672,7 @@ static int ntty_write(struct tty_struct *tty, const unsigned char *buffer, goto exit; } - rval = __kfifo_put(port->fifo_ul, (unsigned char *)buffer, count); + rval = __kfifo_put(&port->fifo_ul, (unsigned char *)buffer, count); /* notify card */ if (unlikely(dc == NULL)) { @@ -1721,7 +1720,7 @@ static int ntty_write_room(struct tty_struct *tty) if (!port->port.count) goto exit; - room = port->fifo_ul->size - __kfifo_len(port->fifo_ul); + room = port->fifo_ul.size - __kfifo_len(&port->fifo_ul); exit: mutex_unlock(&port->tty_sem); @@ -1878,7 +1877,7 @@ static s32 ntty_chars_in_buffer(struct tty_struct *tty) goto exit_in_buffer; } - rval = __kfifo_len(port->fifo_ul); + rval = __kfifo_len(&port->fifo_ul); exit_in_buffer: return rval; diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index 8c262aaf7..9e6efb1 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c @@ -487,7 +487,7 @@ static struct sonypi_device { int camera_power; int bluetooth_power; struct mutex lock; - struct kfifo *fifo; + struct kfifo fifo; spinlock_t fifo_lock; wait_queue_head_t fifo_proc_list; struct fasync_struct *fifo_async; @@ -496,7 +496,7 @@ static struct sonypi_device { struct input_dev *input_jog_dev; struct input_dev *input_key_dev; struct work_struct input_work; - struct kfifo *input_fifo; + struct kfifo input_fifo; spinlock_t input_fifo_lock; } sonypi_device; @@ -777,7 +777,7 @@ static void input_keyrelease(struct work_struct *work) { struct sonypi_keypress kp; - while (kfifo_get(sonypi_device.input_fifo, (unsigned char *)&kp, + while (kfifo_get(&sonypi_device.input_fifo, (unsigned char *)&kp, sizeof(kp)) == sizeof(kp)) { msleep(10); input_report_key(kp.dev, kp.key, 0); @@ -827,7 +827,7 @@ static void sonypi_report_input_event(u8 event) if (kp.dev) { input_report_key(kp.dev, kp.key, 1); input_sync(kp.dev); - kfifo_put(sonypi_device.input_fifo, + kfifo_put(&sonypi_device.input_fifo, (unsigned char *)&kp, sizeof(kp)); schedule_work(&sonypi_device.input_work); } @@ -880,7 +880,7 @@ found: acpi_bus_generate_proc_event(sonypi_acpi_device, 1, event); #endif - kfifo_put(sonypi_device.fifo, (unsigned char *)&event, sizeof(event)); + kfifo_put(&sonypi_device.fifo, (unsigned char *)&event, sizeof(event)); kill_fasync(&sonypi_device.fifo_async, SIGIO, POLL_IN); wake_up_interruptible(&sonypi_device.fifo_proc_list); @@ -906,7 +906,7 @@ static int sonypi_misc_open(struct inode *inode, struct file *file) mutex_lock(&sonypi_device.lock); /* Flush input queue on first open */ if (!sonypi_device.open_count) - kfifo_reset(sonypi_device.fifo); + kfifo_reset(&sonypi_device.fifo); sonypi_device.open_count++; mutex_unlock(&sonypi_device.lock); unlock_kernel(); @@ -919,17 +919,17 @@ static ssize_t sonypi_misc_read(struct file *file, char __user *buf, ssize_t ret; unsigned char c; - if ((kfifo_len(sonypi_device.fifo) == 0) && + if ((kfifo_len(&sonypi_device.fifo) == 0) && (file->f_flags & O_NONBLOCK)) return -EAGAIN; ret = wait_event_interruptible(sonypi_device.fifo_proc_list, - kfifo_len(sonypi_device.fifo) != 0); + kfifo_len(&sonypi_device.fifo) != 0); if (ret) return ret; while (ret < count && - (kfifo_get(sonypi_device.fifo, &c, sizeof(c)) == sizeof(c))) { + (kfifo_get(&sonypi_device.fifo, &c, sizeof(c)) == sizeof(c))) { if (put_user(c, buf++)) return -EFAULT; ret++; @@ -946,7 +946,7 @@ static ssize_t sonypi_misc_read(struct file *file, char __user *buf, static unsigned int sonypi_misc_poll(struct file *file, poll_table *wait) { poll_wait(file, &sonypi_device.fifo_proc_list, wait); - if (kfifo_len(sonypi_device.fifo)) + if (kfifo_len(&sonypi_device.fifo)) return POLLIN | POLLRDNORM; return 0; } @@ -1313,11 +1313,11 @@ static int __devinit sonypi_probe(struct platform_device *dev) "http://www.linux.it/~malattia/wiki/index.php/Sony_drivers\n"); spin_lock_init(&sonypi_device.fifo_lock); - sonypi_device.fifo = kfifo_alloc(SONYPI_BUF_SIZE, GFP_KERNEL, + error = kfifo_alloc(&sonypi_device.fifo, SONYPI_BUF_SIZE, GFP_KERNEL, &sonypi_device.fifo_lock); - if (IS_ERR(sonypi_device.fifo)) { + if (error) { printk(KERN_ERR "sonypi: kfifo_alloc failed\n"); - return PTR_ERR(sonypi_device.fifo); + return error; } init_waitqueue_head(&sonypi_device.fifo_proc_list); @@ -1393,12 +1393,10 @@ static int __devinit sonypi_probe(struct platform_device *dev) } spin_lock_init(&sonypi_device.input_fifo_lock); - sonypi_device.input_fifo = - kfifo_alloc(SONYPI_BUF_SIZE, GFP_KERNEL, - &sonypi_device.input_fifo_lock); - if (IS_ERR(sonypi_device.input_fifo)) { + error = kfifo_alloc(&sonypi_device.input_fifo, SONYPI_BUF_SIZE, + GFP_KERNEL, &sonypi_device.input_fifo_lock); + if (error) { printk(KERN_ERR "sonypi: kfifo_alloc failed\n"); - error = PTR_ERR(sonypi_device.input_fifo); goto err_inpdev_unregister; } @@ -1423,7 +1421,7 @@ static int __devinit sonypi_probe(struct platform_device *dev) pci_disable_device(pcidev); err_put_pcidev: pci_dev_put(pcidev); - kfifo_free(sonypi_device.fifo); + kfifo_free(&sonypi_device.fifo); return error; } @@ -1438,7 +1436,7 @@ static int __devexit sonypi_remove(struct platform_device *dev) if (useinput) { input_unregister_device(sonypi_device.input_key_dev); input_unregister_device(sonypi_device.input_jog_dev); - kfifo_free(sonypi_device.input_fifo); + kfifo_free(&sonypi_device.input_fifo); } misc_deregister(&sonypi_misc_device); @@ -1451,7 +1449,7 @@ static int __devexit sonypi_remove(struct platform_device *dev) pci_dev_put(sonypi_device.dev); } - kfifo_free(sonypi_device.fifo); + kfifo_free(&sonypi_device.fifo); return 0; } diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.h b/drivers/infiniband/hw/cxgb3/cxio_hal.h index bfd03bf..f3d440c 100644 --- a/drivers/infiniband/hw/cxgb3/cxio_hal.h +++ b/drivers/infiniband/hw/cxgb3/cxio_hal.h @@ -34,6 +34,7 @@ #include #include +#include #include "t3_cpl.h" #include "t3cdev.h" @@ -75,13 +76,13 @@ struct cxio_hal_ctrl_qp { }; struct cxio_hal_resource { - struct kfifo *tpt_fifo; + struct kfifo tpt_fifo; spinlock_t tpt_fifo_lock; - struct kfifo *qpid_fifo; + struct kfifo qpid_fifo; spinlock_t qpid_fifo_lock; - struct kfifo *cqid_fifo; + struct kfifo cqid_fifo; spinlock_t cqid_fifo_lock; - struct kfifo *pdid_fifo; + struct kfifo pdid_fifo; spinlock_t pdid_fifo_lock; }; diff --git a/drivers/infiniband/hw/cxgb3/cxio_resource.c b/drivers/infiniband/hw/cxgb3/cxio_resource.c index bd233c0..65072bd 100644 --- a/drivers/infiniband/hw/cxgb3/cxio_resource.c +++ b/drivers/infiniband/hw/cxgb3/cxio_resource.c @@ -39,12 +39,12 @@ #include "cxio_resource.h" #include "cxio_hal.h" -static struct kfifo *rhdl_fifo; +static struct kfifo rhdl_fifo; static spinlock_t rhdl_fifo_lock; #define RANDOM_SIZE 16 -static int __cxio_init_resource_fifo(struct kfifo **fifo, +static int __cxio_init_resource_fifo(struct kfifo *fifo, spinlock_t *fifo_lock, u32 nr, u32 skip_low, u32 skip_high, @@ -55,12 +55,11 @@ static int __cxio_init_resource_fifo(struct kfifo **fifo, u32 rarray[16]; spin_lock_init(fifo_lock); - *fifo = kfifo_alloc(nr * sizeof(u32), GFP_KERNEL, fifo_lock); - if (IS_ERR(*fifo)) + if (kfifo_alloc(fifo, nr * sizeof(u32), GFP_KERNEL, fifo_lock)) return -ENOMEM; for (i = 0; i < skip_low + skip_high; i++) - __kfifo_put(*fifo, (unsigned char *) &entry, sizeof(u32)); + __kfifo_put(fifo, (unsigned char *) &entry, sizeof(u32)); if (random) { j = 0; random_bytes = random32(); @@ -72,33 +71,33 @@ static int __cxio_init_resource_fifo(struct kfifo **fifo, random_bytes = random32(); } idx = (random_bytes >> (j * 2)) & 0xF; - __kfifo_put(*fifo, + __kfifo_put(fifo, (unsigned char *) &rarray[idx], sizeof(u32)); rarray[idx] = i; j++; } for (i = 0; i < RANDOM_SIZE; i++) - __kfifo_put(*fifo, + __kfifo_put(fifo, (unsigned char *) &rarray[i], sizeof(u32)); } else for (i = skip_low; i < nr - skip_high; i++) - __kfifo_put(*fifo, (unsigned char *) &i, sizeof(u32)); + __kfifo_put(fifo, (unsigned char *) &i, sizeof(u32)); for (i = 0; i < skip_low + skip_high; i++) - kfifo_get(*fifo, (unsigned char *) &entry, sizeof(u32)); + kfifo_get(fifo, (unsigned char *) &entry, sizeof(u32)); return 0; } -static int cxio_init_resource_fifo(struct kfifo **fifo, spinlock_t * fifo_lock, +static int cxio_init_resource_fifo(struct kfifo *fifo, spinlock_t * fifo_lock, u32 nr, u32 skip_low, u32 skip_high) { return (__cxio_init_resource_fifo(fifo, fifo_lock, nr, skip_low, skip_high, 0)); } -static int cxio_init_resource_fifo_random(struct kfifo **fifo, +static int cxio_init_resource_fifo_random(struct kfifo *fifo, spinlock_t * fifo_lock, u32 nr, u32 skip_low, u32 skip_high) { @@ -113,15 +112,14 @@ static int cxio_init_qpid_fifo(struct cxio_rdev *rdev_p) spin_lock_init(&rdev_p->rscp->qpid_fifo_lock); - rdev_p->rscp->qpid_fifo = kfifo_alloc(T3_MAX_NUM_QP * sizeof(u32), + if (kfifo_alloc(&rdev_p->rscp->qpid_fifo, T3_MAX_NUM_QP * sizeof(u32), GFP_KERNEL, - &rdev_p->rscp->qpid_fifo_lock); - if (IS_ERR(rdev_p->rscp->qpid_fifo)) + &rdev_p->rscp->qpid_fifo_lock)) return -ENOMEM; for (i = 16; i < T3_MAX_NUM_QP; i++) if (!(i & rdev_p->qpmask)) - __kfifo_put(rdev_p->rscp->qpid_fifo, + __kfifo_put(&rdev_p->rscp->qpid_fifo, (unsigned char *) &i, sizeof(u32)); return 0; } @@ -134,7 +132,7 @@ int cxio_hal_init_rhdl_resource(u32 nr_rhdl) void cxio_hal_destroy_rhdl_resource(void) { - kfifo_free(rhdl_fifo); + kfifo_free(&rhdl_fifo); } /* nr_* must be power of 2 */ @@ -167,11 +165,11 @@ int cxio_hal_init_resource(struct cxio_rdev *rdev_p, goto pdid_err; return 0; pdid_err: - kfifo_free(rscp->cqid_fifo); + kfifo_free(&rscp->cqid_fifo); cqid_err: - kfifo_free(rscp->qpid_fifo); + kfifo_free(&rscp->qpid_fifo); qpid_err: - kfifo_free(rscp->tpt_fifo); + kfifo_free(&rscp->tpt_fifo); tpt_err: return -ENOMEM; } @@ -195,17 +193,17 @@ static void cxio_hal_put_resource(struct kfifo *fifo, u32 entry) u32 cxio_hal_get_stag(struct cxio_hal_resource *rscp) { - return cxio_hal_get_resource(rscp->tpt_fifo); + return cxio_hal_get_resource(&rscp->tpt_fifo); } void cxio_hal_put_stag(struct cxio_hal_resource *rscp, u32 stag) { - cxio_hal_put_resource(rscp->tpt_fifo, stag); + cxio_hal_put_resource(&rscp->tpt_fifo, stag); } u32 cxio_hal_get_qpid(struct cxio_hal_resource *rscp) { - u32 qpid = cxio_hal_get_resource(rscp->qpid_fifo); + u32 qpid = cxio_hal_get_resource(&rscp->qpid_fifo); PDBG("%s qpid 0x%x\n", __func__, qpid); return qpid; } @@ -213,35 +211,35 @@ u32 cxio_hal_get_qpid(struct cxio_hal_resource *rscp) void cxio_hal_put_qpid(struct cxio_hal_resource *rscp, u32 qpid) { PDBG("%s qpid 0x%x\n", __func__, qpid); - cxio_hal_put_resource(rscp->qpid_fifo, qpid); + cxio_hal_put_resource(&rscp->qpid_fifo, qpid); } u32 cxio_hal_get_cqid(struct cxio_hal_resource *rscp) { - return cxio_hal_get_resource(rscp->cqid_fifo); + return cxio_hal_get_resource(&rscp->cqid_fifo); } void cxio_hal_put_cqid(struct cxio_hal_resource *rscp, u32 cqid) { - cxio_hal_put_resource(rscp->cqid_fifo, cqid); + cxio_hal_put_resource(&rscp->cqid_fifo, cqid); } u32 cxio_hal_get_pdid(struct cxio_hal_resource *rscp) { - return cxio_hal_get_resource(rscp->pdid_fifo); + return cxio_hal_get_resource(&rscp->pdid_fifo); } void cxio_hal_put_pdid(struct cxio_hal_resource *rscp, u32 pdid) { - cxio_hal_put_resource(rscp->pdid_fifo, pdid); + cxio_hal_put_resource(&rscp->pdid_fifo, pdid); } void cxio_hal_destroy_resource(struct cxio_hal_resource *rscp) { - kfifo_free(rscp->tpt_fifo); - kfifo_free(rscp->cqid_fifo); - kfifo_free(rscp->qpid_fifo); - kfifo_free(rscp->pdid_fifo); + kfifo_free(&rscp->tpt_fifo); + kfifo_free(&rscp->cqid_fifo); + kfifo_free(&rscp->qpid_fifo); + kfifo_free(&rscp->pdid_fifo); kfree(rscp); } diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c index 6ffa64c..dacbbb8 100644 --- a/drivers/media/video/meye.c +++ b/drivers/media/video/meye.c @@ -800,7 +800,7 @@ again: return IRQ_HANDLED; if (meye.mchip_mode == MCHIP_HIC_MODE_CONT_OUT) { - if (kfifo_get(meye.grabq, (unsigned char *)&reqnr, + if (kfifo_get(&meye.grabq, (unsigned char *)&reqnr, sizeof(int)) != sizeof(int)) { mchip_free_frame(); return IRQ_HANDLED; @@ -811,7 +811,7 @@ again: meye.grab_buffer[reqnr].state = MEYE_BUF_DONE; do_gettimeofday(&meye.grab_buffer[reqnr].timestamp); meye.grab_buffer[reqnr].sequence = sequence++; - kfifo_put(meye.doneq, (unsigned char *)&reqnr, sizeof(int)); + kfifo_put(&meye.doneq, (unsigned char *)&reqnr, sizeof(int)); wake_up_interruptible(&meye.proc_list); } else { int size; @@ -820,7 +820,7 @@ again: mchip_free_frame(); goto again; } - if (kfifo_get(meye.grabq, (unsigned char *)&reqnr, + if (kfifo_get(&meye.grabq, (unsigned char *)&reqnr, sizeof(int)) != sizeof(int)) { mchip_free_frame(); goto again; @@ -831,7 +831,7 @@ again: meye.grab_buffer[reqnr].state = MEYE_BUF_DONE; do_gettimeofday(&meye.grab_buffer[reqnr].timestamp); meye.grab_buffer[reqnr].sequence = sequence++; - kfifo_put(meye.doneq, (unsigned char *)&reqnr, sizeof(int)); + kfifo_put(&meye.doneq, (unsigned char *)&reqnr, sizeof(int)); wake_up_interruptible(&meye.proc_list); } mchip_free_frame(); @@ -859,8 +859,8 @@ static int meye_open(struct file *file) for (i = 0; i < MEYE_MAX_BUFNBRS; i++) meye.grab_buffer[i].state = MEYE_BUF_UNUSED; - kfifo_reset(meye.grabq); - kfifo_reset(meye.doneq); + kfifo_reset(&meye.grabq); + kfifo_reset(&meye.doneq); return 0; } @@ -933,7 +933,7 @@ static int meyeioc_qbuf_capt(int *nb) mchip_cont_compression_start(); meye.grab_buffer[*nb].state = MEYE_BUF_USING; - kfifo_put(meye.grabq, (unsigned char *)nb, sizeof(int)); + kfifo_put(&meye.grabq, (unsigned char *)nb, sizeof(int)); mutex_unlock(&meye.lock); return 0; @@ -965,7 +965,7 @@ static int meyeioc_sync(struct file *file, void *fh, int *i) /* fall through */ case MEYE_BUF_DONE: meye.grab_buffer[*i].state = MEYE_BUF_UNUSED; - kfifo_get(meye.doneq, (unsigned char *)&unused, sizeof(int)); + kfifo_get(&meye.doneq, (unsigned char *)&unused, sizeof(int)); } *i = meye.grab_buffer[*i].size; mutex_unlock(&meye.lock); @@ -1452,7 +1452,7 @@ static int vidioc_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf) buf->flags |= V4L2_BUF_FLAG_QUEUED; buf->flags &= ~V4L2_BUF_FLAG_DONE; meye.grab_buffer[buf->index].state = MEYE_BUF_USING; - kfifo_put(meye.grabq, (unsigned char *)&buf->index, sizeof(int)); + kfifo_put(&meye.grabq, (unsigned char *)&buf->index, sizeof(int)); mutex_unlock(&meye.lock); return 0; @@ -1467,18 +1467,18 @@ static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf) mutex_lock(&meye.lock); - if (kfifo_len(meye.doneq) == 0 && file->f_flags & O_NONBLOCK) { + if (kfifo_len(&meye.doneq) == 0 && file->f_flags & O_NONBLOCK) { mutex_unlock(&meye.lock); return -EAGAIN; } if (wait_event_interruptible(meye.proc_list, - kfifo_len(meye.doneq) != 0) < 0) { + kfifo_len(&meye.doneq) != 0) < 0) { mutex_unlock(&meye.lock); return -EINTR; } - if (!kfifo_get(meye.doneq, (unsigned char *)&reqnr, + if (!kfifo_get(&meye.doneq, (unsigned char *)&reqnr, sizeof(int))) { mutex_unlock(&meye.lock); return -EBUSY; @@ -1529,8 +1529,8 @@ static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i) { mutex_lock(&meye.lock); mchip_hic_stop(); - kfifo_reset(meye.grabq); - kfifo_reset(meye.doneq); + kfifo_reset(&meye.grabq); + kfifo_reset(&meye.doneq); for (i = 0; i < MEYE_MAX_BUFNBRS; i++) meye.grab_buffer[i].state = MEYE_BUF_UNUSED; @@ -1572,7 +1572,7 @@ static unsigned int meye_poll(struct file *file, poll_table *wait) mutex_lock(&meye.lock); poll_wait(file, &meye.proc_list, wait); - if (kfifo_len(meye.doneq)) + if (kfifo_len(&meye.doneq)) res = POLLIN | POLLRDNORM; mutex_unlock(&meye.lock); return res; @@ -1745,16 +1745,14 @@ static int __devinit meye_probe(struct pci_dev *pcidev, } spin_lock_init(&meye.grabq_lock); - meye.grabq = kfifo_alloc(sizeof(int) * MEYE_MAX_BUFNBRS, GFP_KERNEL, - &meye.grabq_lock); - if (IS_ERR(meye.grabq)) { + if (kfifo_alloc(&meye.grabq, sizeof(int) * MEYE_MAX_BUFNBRS, GFP_KERNEL, + &meye.grabq_lock)) { printk(KERN_ERR "meye: fifo allocation failed\n"); goto outkfifoalloc1; } spin_lock_init(&meye.doneq_lock); - meye.doneq = kfifo_alloc(sizeof(int) * MEYE_MAX_BUFNBRS, GFP_KERNEL, - &meye.doneq_lock); - if (IS_ERR(meye.doneq)) { + if (kfifo_alloc(&meye.doneq, sizeof(int) * MEYE_MAX_BUFNBRS, GFP_KERNEL, + &meye.doneq_lock)) { printk(KERN_ERR "meye: fifo allocation failed\n"); goto outkfifoalloc2; } @@ -1868,9 +1866,9 @@ outregions: outenabledev: sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERA, 0); outsonypienable: - kfifo_free(meye.doneq); + kfifo_free(&meye.doneq); outkfifoalloc2: - kfifo_free(meye.grabq); + kfifo_free(&meye.grabq); outkfifoalloc1: vfree(meye.grab_temp); outvmalloc: @@ -1901,8 +1899,8 @@ static void __devexit meye_remove(struct pci_dev *pcidev) sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERA, 0); - kfifo_free(meye.doneq); - kfifo_free(meye.grabq); + kfifo_free(&meye.doneq); + kfifo_free(&meye.grabq); vfree(meye.grab_temp); diff --git a/drivers/media/video/meye.h b/drivers/media/video/meye.h index 5f70a10..1321ad5 100644 --- a/drivers/media/video/meye.h +++ b/drivers/media/video/meye.h @@ -303,9 +303,9 @@ struct meye { struct meye_grab_buffer grab_buffer[MEYE_MAX_BUFNBRS]; int vma_use_count[MEYE_MAX_BUFNBRS]; /* mmap count */ struct mutex lock; /* mutex for open/mmap... */ - struct kfifo *grabq; /* queue for buffers to be grabbed */ + struct kfifo grabq; /* queue for buffers to be grabbed */ spinlock_t grabq_lock; /* lock protecting the queue */ - struct kfifo *doneq; /* queue for grabbed buffers */ + struct kfifo doneq; /* queue for grabbed buffers */ spinlock_t doneq_lock; /* lock protecting the queue */ wait_queue_head_t proc_list; /* wait queue */ struct video_device *video_dev; /* video device parameters */ diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index b9b371b..ffed17f 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c @@ -1365,7 +1365,7 @@ static void lbs_send_confirmsleep(struct lbs_private *priv) priv->dnld_sent = DNLD_RES_RECEIVED; /* If nothing to do, go back to sleep (?) */ - if (!__kfifo_len(priv->event_fifo) && !priv->resp_len[priv->resp_idx]) + if (!__kfifo_len(&priv->event_fifo) && !priv->resp_len[priv->resp_idx]) priv->psstate = PS_STATE_SLEEP; spin_unlock_irqrestore(&priv->driver_lock, flags); @@ -1439,7 +1439,7 @@ void lbs_ps_confirm_sleep(struct lbs_private *priv) } /* Pending events or command responses? */ - if (__kfifo_len(priv->event_fifo) || priv->resp_len[priv->resp_idx]) { + if (__kfifo_len(&priv->event_fifo) || priv->resp_len[priv->resp_idx]) { allowed = 0; lbs_deb_host("pending events or command responses\n"); } diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h index 6a8d2b2..05bb298 100644 --- a/drivers/net/wireless/libertas/dev.h +++ b/drivers/net/wireless/libertas/dev.h @@ -10,7 +10,7 @@ #include "scan.h" #include "assoc.h" - +#include /** sleep_params */ struct sleep_params { @@ -120,7 +120,7 @@ struct lbs_private { u32 resp_len[2]; /* Events sent from hardware to driver */ - struct kfifo *event_fifo; + struct kfifo event_fifo; /** thread to service interrupts */ struct task_struct *main_thread; diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index db38a5a..4039092 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c @@ -459,7 +459,7 @@ static int lbs_thread(void *data) else if (!list_empty(&priv->cmdpendingq) && !(priv->wakeup_dev_required)) shouldsleep = 0; /* We have a command to send */ - else if (__kfifo_len(priv->event_fifo)) + else if (__kfifo_len(&priv->event_fifo)) shouldsleep = 0; /* We have an event to process */ else shouldsleep = 1; /* No command */ @@ -511,9 +511,9 @@ static int lbs_thread(void *data) /* Process hardware events, e.g. card removed, link lost */ spin_lock_irq(&priv->driver_lock); - while (__kfifo_len(priv->event_fifo)) { + while (__kfifo_len(&priv->event_fifo)) { u32 event; - __kfifo_get(priv->event_fifo, (unsigned char *) &event, + __kfifo_get(&priv->event_fifo, (unsigned char *) &event, sizeof(event)); spin_unlock_irq(&priv->driver_lock); lbs_process_event(priv, event); @@ -883,10 +883,9 @@ static int lbs_init_adapter(struct lbs_private *priv) priv->resp_len[0] = priv->resp_len[1] = 0; /* Create the event FIFO */ - priv->event_fifo = kfifo_alloc(sizeof(u32) * 16, GFP_KERNEL, NULL); - if (IS_ERR(priv->event_fifo)) { + ret = kfifo_alloc(&priv->event_fifo, sizeof(u32) * 16, GFP_KERNEL, NULL); + if (ret) { lbs_pr_err("Out of memory allocating event FIFO buffer\n"); - ret = -ENOMEM; goto out; } @@ -901,8 +900,7 @@ static void lbs_free_adapter(struct lbs_private *priv) lbs_deb_enter(LBS_DEB_MAIN); lbs_free_cmd_buffer(priv); - if (priv->event_fifo) - kfifo_free(priv->event_fifo); + kfifo_free(&priv->event_fifo); del_timer(&priv->command_timer); del_timer(&priv->auto_deepsleep_timer); kfree(priv->networks); @@ -1177,7 +1175,7 @@ void lbs_queue_event(struct lbs_private *priv, u32 event) if (priv->psstate == PS_STATE_SLEEP) priv->psstate = PS_STATE_AWAKE; - __kfifo_put(priv->event_fifo, (unsigned char *) &event, sizeof(u32)); + __kfifo_put(&priv->event_fifo, (unsigned char *) &event, sizeof(u32)); wake_up_interruptible(&priv->waitq); diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c index bcd4ba8..f999fba 100644 --- a/drivers/platform/x86/fujitsu-laptop.c +++ b/drivers/platform/x86/fujitsu-laptop.c @@ -164,7 +164,7 @@ struct fujitsu_hotkey_t { struct input_dev *input; char phys[32]; struct platform_device *pf_device; - struct kfifo *fifo; + struct kfifo fifo; spinlock_t fifo_lock; int rfkill_supported; int rfkill_state; @@ -824,12 +824,10 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device) /* kfifo */ spin_lock_init(&fujitsu_hotkey->fifo_lock); - fujitsu_hotkey->fifo = - kfifo_alloc(RINGBUFFERSIZE * sizeof(int), GFP_KERNEL, - &fujitsu_hotkey->fifo_lock); - if (IS_ERR(fujitsu_hotkey->fifo)) { + error = kfifo_alloc(&fujitsu_hotkey->fifo, RINGBUFFERSIZE * sizeof(int), + GFP_KERNEL, &fujitsu_hotkey->fifo_lock); + if (error) { printk(KERN_ERR "kfifo_alloc failed\n"); - error = PTR_ERR(fujitsu_hotkey->fifo); goto err_stop; } @@ -934,7 +932,7 @@ err_unregister_input_dev: err_free_input_dev: input_free_device(input); err_free_fifo: - kfifo_free(fujitsu_hotkey->fifo); + kfifo_free(&fujitsu_hotkey->fifo); err_stop: return result; } @@ -956,7 +954,7 @@ static int acpi_fujitsu_hotkey_remove(struct acpi_device *device, int type) input_free_device(input); - kfifo_free(fujitsu_hotkey->fifo); + kfifo_free(&fujitsu_hotkey->fifo); fujitsu_hotkey->acpi_handle = NULL; @@ -1008,7 +1006,7 @@ static void acpi_fujitsu_hotkey_notify(struct acpi_device *device, u32 event) vdbg_printk(FUJLAPTOP_DBG_TRACE, "Push keycode into ringbuffer [%d]\n", keycode); - status = kfifo_put(fujitsu_hotkey->fifo, + status = kfifo_put(&fujitsu_hotkey->fifo, (unsigned char *)&keycode, sizeof(keycode)); if (status != sizeof(keycode)) { @@ -1022,7 +1020,7 @@ static void acpi_fujitsu_hotkey_notify(struct acpi_device *device, u32 event) } else if (keycode == 0) { while ((status = kfifo_get - (fujitsu_hotkey->fifo, (unsigned char *) + (&fujitsu_hotkey->fifo, (unsigned char *) &keycode_r, sizeof (keycode_r))) == sizeof(keycode_r)) { diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index 7a2cc8a..04625a0 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c @@ -142,7 +142,7 @@ struct sony_laptop_input_s { atomic_t users; struct input_dev *jog_dev; struct input_dev *key_dev; - struct kfifo *fifo; + struct kfifo fifo; spinlock_t fifo_lock; struct workqueue_struct *wq; }; @@ -300,7 +300,7 @@ static void do_sony_laptop_release_key(struct work_struct *work) { struct sony_laptop_keypress kp; - while (kfifo_get(sony_laptop_input.fifo, (unsigned char *)&kp, + while (kfifo_get(&sony_laptop_input.fifo, (unsigned char *)&kp, sizeof(kp)) == sizeof(kp)) { msleep(10); input_report_key(kp.dev, kp.key, 0); @@ -362,7 +362,7 @@ static void sony_laptop_report_input_event(u8 event) /* we emit the scancode so we can always remap the key */ input_event(kp.dev, EV_MSC, MSC_SCAN, event); input_sync(kp.dev); - kfifo_put(sony_laptop_input.fifo, + kfifo_put(&sony_laptop_input.fifo, (unsigned char *)&kp, sizeof(kp)); if (!work_pending(&sony_laptop_release_key_work)) @@ -385,12 +385,11 @@ static int sony_laptop_setup_input(struct acpi_device *acpi_device) /* kfifo */ spin_lock_init(&sony_laptop_input.fifo_lock); - sony_laptop_input.fifo = - kfifo_alloc(SONY_LAPTOP_BUF_SIZE, GFP_KERNEL, + error = + kfifo_alloc(&sony_laptop_input.fifo, SONY_LAPTOP_BUF_SIZE, GFP_KERNEL, &sony_laptop_input.fifo_lock); - if (IS_ERR(sony_laptop_input.fifo)) { + if (error) { printk(KERN_ERR DRV_PFX "kfifo_alloc failed\n"); - error = PTR_ERR(sony_laptop_input.fifo); goto err_dec_users; } @@ -474,7 +473,7 @@ err_destroy_wq: destroy_workqueue(sony_laptop_input.wq); err_free_kfifo: - kfifo_free(sony_laptop_input.fifo); + kfifo_free(&sony_laptop_input.fifo); err_dec_users: atomic_dec(&sony_laptop_input.users); @@ -500,7 +499,7 @@ static void sony_laptop_remove_input(void) } destroy_workqueue(sony_laptop_input.wq); - kfifo_free(sony_laptop_input.fifo); + kfifo_free(&sony_laptop_input.fifo); } /*********** Platform Device ***********/ @@ -2079,7 +2078,7 @@ static struct attribute_group spic_attribute_group = { struct sonypi_compat_s { struct fasync_struct *fifo_async; - struct kfifo *fifo; + struct kfifo fifo; spinlock_t fifo_lock; wait_queue_head_t fifo_proc_list; atomic_t open_count; @@ -2104,12 +2103,12 @@ static int sonypi_misc_open(struct inode *inode, struct file *file) /* Flush input queue on first open */ unsigned long flags; - spin_lock_irqsave(sonypi_compat.fifo->lock, flags); + spin_lock_irqsave(&sonypi_compat.fifo_lock, flags); if (atomic_inc_return(&sonypi_compat.open_count) == 1) - __kfifo_reset(sonypi_compat.fifo); + __kfifo_reset(&sonypi_compat.fifo); - spin_unlock_irqrestore(sonypi_compat.fifo->lock, flags); + spin_unlock_irqrestore(&sonypi_compat.fifo_lock, flags); return 0; } @@ -2120,17 +2119,17 @@ static ssize_t sonypi_misc_read(struct file *file, char __user *buf, ssize_t ret; unsigned char c; - if ((kfifo_len(sonypi_compat.fifo) == 0) && + if ((kfifo_len(&sonypi_compat.fifo) == 0) && (file->f_flags & O_NONBLOCK)) return -EAGAIN; ret = wait_event_interruptible(sonypi_compat.fifo_proc_list, - kfifo_len(sonypi_compat.fifo) != 0); + kfifo_len(&sonypi_compat.fifo) != 0); if (ret) return ret; while (ret < count && - (kfifo_get(sonypi_compat.fifo, &c, sizeof(c)) == sizeof(c))) { + (kfifo_get(&sonypi_compat.fifo, &c, sizeof(c)) == sizeof(c))) { if (put_user(c, buf++)) return -EFAULT; ret++; @@ -2147,7 +2146,7 @@ static ssize_t sonypi_misc_read(struct file *file, char __user *buf, static unsigned int sonypi_misc_poll(struct file *file, poll_table *wait) { poll_wait(file, &sonypi_compat.fifo_proc_list, wait); - if (kfifo_len(sonypi_compat.fifo)) + if (kfifo_len(&sonypi_compat.fifo)) return POLLIN | POLLRDNORM; return 0; } @@ -2309,7 +2308,7 @@ static struct miscdevice sonypi_misc_device = { static void sonypi_compat_report_event(u8 event) { - kfifo_put(sonypi_compat.fifo, (unsigned char *)&event, sizeof(event)); + kfifo_put(&sonypi_compat.fifo, (unsigned char *)&event, sizeof(event)); kill_fasync(&sonypi_compat.fifo_async, SIGIO, POLL_IN); wake_up_interruptible(&sonypi_compat.fifo_proc_list); } @@ -2319,11 +2318,12 @@ static int sonypi_compat_init(void) int error; spin_lock_init(&sonypi_compat.fifo_lock); - sonypi_compat.fifo = kfifo_alloc(SONY_LAPTOP_BUF_SIZE, GFP_KERNEL, + error = + kfifo_alloc(&sonypi_compat.fifo, SONY_LAPTOP_BUF_SIZE, GFP_KERNEL, &sonypi_compat.fifo_lock); - if (IS_ERR(sonypi_compat.fifo)) { + if (error) { printk(KERN_ERR DRV_PFX "kfifo_alloc failed\n"); - return PTR_ERR(sonypi_compat.fifo); + return error; } init_waitqueue_head(&sonypi_compat.fifo_proc_list); @@ -2342,14 +2342,14 @@ static int sonypi_compat_init(void) return 0; err_free_kfifo: - kfifo_free(sonypi_compat.fifo); + kfifo_free(&sonypi_compat.fifo); return error; } static void sonypi_compat_exit(void) { misc_deregister(&sonypi_misc_device); - kfifo_free(sonypi_compat.fifo); + kfifo_free(&sonypi_compat.fifo); } #else static int sonypi_compat_init(void) { return 0; } diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index b7689f3..cf0aa7e 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -517,7 +517,7 @@ static void iscsi_free_task(struct iscsi_task *task) if (conn->login_task == task) return; - __kfifo_put(session->cmdpool.queue, (void*)&task, sizeof(void*)); + __kfifo_put(&session->cmdpool.queue, (void*)&task, sizeof(void*)); if (sc) { task->sc = NULL; @@ -737,7 +737,7 @@ __iscsi_conn_send_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, BUG_ON(conn->c_stage == ISCSI_CONN_INITIAL_STAGE); BUG_ON(conn->c_stage == ISCSI_CONN_STOPPED); - if (!__kfifo_get(session->cmdpool.queue, + if (!__kfifo_get(&session->cmdpool.queue, (void*)&task, sizeof(void*))) return NULL; } @@ -1567,7 +1567,7 @@ static inline struct iscsi_task *iscsi_alloc_task(struct iscsi_conn *conn, { struct iscsi_task *task; - if (!__kfifo_get(conn->session->cmdpool.queue, + if (!__kfifo_get(&conn->session->cmdpool.queue, (void *) &task, sizeof(void *))) return NULL; @@ -2461,12 +2461,7 @@ iscsi_pool_init(struct iscsi_pool *q, int max, void ***items, int item_size) if (q->pool == NULL) return -ENOMEM; - q->queue = kfifo_init((void*)q->pool, max * sizeof(void*), - GFP_KERNEL, NULL); - if (IS_ERR(q->queue)) { - q->queue = NULL; - goto enomem; - } + kfifo_init(&q->queue, (void*)q->pool, max * sizeof(void*), NULL); for (i = 0; i < max; i++) { q->pool[i] = kzalloc(item_size, GFP_KERNEL); @@ -2474,7 +2469,7 @@ iscsi_pool_init(struct iscsi_pool *q, int max, void ***items, int item_size) q->max = i; goto enomem; } - __kfifo_put(q->queue, (void*)&q->pool[i], sizeof(void*)); + __kfifo_put(&q->queue, (void*)&q->pool[i], sizeof(void*)); } if (items) { @@ -2497,7 +2492,6 @@ void iscsi_pool_free(struct iscsi_pool *q) for (i = 0; i < q->max; i++) kfree(q->pool[i]); kfree(q->pool); - kfree(q->queue); } EXPORT_SYMBOL_GPL(iscsi_pool_free); @@ -2825,7 +2819,7 @@ iscsi_conn_setup(struct iscsi_cls_session *cls_session, int dd_size, /* allocate login_task used for the login/text sequences */ spin_lock_bh(&session->lock); - if (!__kfifo_get(session->cmdpool.queue, + if (!__kfifo_get(&session->cmdpool.queue, (void*)&conn->login_task, sizeof(void*))) { spin_unlock_bh(&session->lock); @@ -2845,7 +2839,7 @@ iscsi_conn_setup(struct iscsi_cls_session *cls_session, int dd_size, return cls_conn; login_task_data_alloc_fail: - __kfifo_put(session->cmdpool.queue, (void*)&conn->login_task, + __kfifo_put(&session->cmdpool.queue, (void*)&conn->login_task, sizeof(void*)); login_task_alloc_fail: iscsi_destroy_conn(cls_conn); @@ -2908,7 +2902,7 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn) free_pages((unsigned long) conn->data, get_order(ISCSI_DEF_MAX_RECV_SEG_LEN)); kfree(conn->persistent_address); - __kfifo_put(session->cmdpool.queue, (void*)&conn->login_task, + __kfifo_put(&session->cmdpool.queue, (void*)&conn->login_task, sizeof(void*)); if (session->leadconn == conn) session->leadconn = NULL; diff --git a/drivers/scsi/libiscsi_tcp.c b/drivers/scsi/libiscsi_tcp.c index ca25ee5..a83ee56 100644 --- a/drivers/scsi/libiscsi_tcp.c +++ b/drivers/scsi/libiscsi_tcp.c @@ -445,15 +445,15 @@ void iscsi_tcp_cleanup_task(struct iscsi_task *task) return; /* flush task's r2t queues */ - while (__kfifo_get(tcp_task->r2tqueue, (void*)&r2t, sizeof(void*))) { - __kfifo_put(tcp_task->r2tpool.queue, (void*)&r2t, + while (__kfifo_get(&tcp_task->r2tqueue, (void*)&r2t, sizeof(void*))) { + __kfifo_put(&tcp_task->r2tpool.queue, (void*)&r2t, sizeof(void*)); ISCSI_DBG_TCP(task->conn, "pending r2t dropped\n"); } r2t = tcp_task->r2t; if (r2t != NULL) { - __kfifo_put(tcp_task->r2tpool.queue, (void*)&r2t, + __kfifo_put(&tcp_task->r2tpool.queue, (void*)&r2t, sizeof(void*)); tcp_task->r2t = NULL; } @@ -541,7 +541,7 @@ static int iscsi_tcp_r2t_rsp(struct iscsi_conn *conn, struct iscsi_task *task) return 0; } - rc = __kfifo_get(tcp_task->r2tpool.queue, (void*)&r2t, sizeof(void*)); + rc = __kfifo_get(&tcp_task->r2tpool.queue, (void*)&r2t, sizeof(void*)); if (!rc) { iscsi_conn_printk(KERN_ERR, conn, "Could not allocate R2T. " "Target has sent more R2Ts than it " @@ -554,7 +554,7 @@ static int iscsi_tcp_r2t_rsp(struct iscsi_conn *conn, struct iscsi_task *task) if (r2t->data_length == 0) { iscsi_conn_printk(KERN_ERR, conn, "invalid R2T with zero data len\n"); - __kfifo_put(tcp_task->r2tpool.queue, (void*)&r2t, + __kfifo_put(&tcp_task->r2tpool.queue, (void*)&r2t, sizeof(void*)); return ISCSI_ERR_DATALEN; } @@ -570,7 +570,7 @@ static int iscsi_tcp_r2t_rsp(struct iscsi_conn *conn, struct iscsi_task *task) "invalid R2T with data len %u at offset %u " "and total length %d\n", r2t->data_length, r2t->data_offset, scsi_out(task->sc)->length); - __kfifo_put(tcp_task->r2tpool.queue, (void*)&r2t, + __kfifo_put(&tcp_task->r2tpool.queue, (void*)&r2t, sizeof(void*)); return ISCSI_ERR_DATALEN; } @@ -580,7 +580,7 @@ static int iscsi_tcp_r2t_rsp(struct iscsi_conn *conn, struct iscsi_task *task) r2t->sent = 0; tcp_task->exp_datasn = r2tsn + 1; - __kfifo_put(tcp_task->r2tqueue, (void*)&r2t, sizeof(void*)); + __kfifo_put(&tcp_task->r2tqueue, (void*)&r2t, sizeof(void*)); conn->r2t_pdus_cnt++; iscsi_requeue_task(task); @@ -951,7 +951,7 @@ int iscsi_tcp_task_init(struct iscsi_task *task) return conn->session->tt->init_pdu(task, 0, task->data_count); } - BUG_ON(__kfifo_len(tcp_task->r2tqueue)); + BUG_ON(__kfifo_len(&tcp_task->r2tqueue)); tcp_task->exp_datasn = 0; /* Prepare PDU, optionally w/ immediate data */ @@ -982,7 +982,7 @@ static struct iscsi_r2t_info *iscsi_tcp_get_curr_r2t(struct iscsi_task *task) if (r2t->data_length <= r2t->sent) { ISCSI_DBG_TCP(task->conn, " done with r2t %p\n", r2t); - __kfifo_put(tcp_task->r2tpool.queue, + __kfifo_put(&tcp_task->r2tpool.queue, (void *)&tcp_task->r2t, sizeof(void *)); tcp_task->r2t = r2t = NULL; @@ -990,7 +990,7 @@ static struct iscsi_r2t_info *iscsi_tcp_get_curr_r2t(struct iscsi_task *task) } if (r2t == NULL) { - __kfifo_get(tcp_task->r2tqueue, + __kfifo_get(&tcp_task->r2tqueue, (void *)&tcp_task->r2t, sizeof(void *)); r2t = tcp_task->r2t; } @@ -1127,9 +1127,8 @@ int iscsi_tcp_r2tpool_alloc(struct iscsi_session *session) } /* R2T xmit queue */ - tcp_task->r2tqueue = kfifo_alloc( - session->max_r2t * 4 * sizeof(void*), GFP_KERNEL, NULL); - if (tcp_task->r2tqueue == ERR_PTR(-ENOMEM)) { + if (kfifo_alloc(&tcp_task->r2tqueue, + session->max_r2t * 4 * sizeof(void*), GFP_KERNEL, NULL)) { iscsi_pool_free(&tcp_task->r2tpool); goto r2t_alloc_fail; } @@ -1142,7 +1141,7 @@ r2t_alloc_fail: struct iscsi_task *task = session->cmds[i]; struct iscsi_tcp_task *tcp_task = task->dd_data; - kfifo_free(tcp_task->r2tqueue); + kfifo_free(&tcp_task->r2tqueue); iscsi_pool_free(&tcp_task->r2tpool); } return -ENOMEM; @@ -1157,7 +1156,7 @@ void iscsi_tcp_r2tpool_free(struct iscsi_session *session) struct iscsi_task *task = session->cmds[i]; struct iscsi_tcp_task *tcp_task = task->dd_data; - kfifo_free(tcp_task->r2tqueue); + kfifo_free(&tcp_task->r2tqueue); iscsi_pool_free(&tcp_task->r2tpool); } } diff --git a/drivers/scsi/libsrp.c b/drivers/scsi/libsrp.c index 9ad38e8..b1b5e51 100644 --- a/drivers/scsi/libsrp.c +++ b/drivers/scsi/libsrp.c @@ -58,19 +58,16 @@ static int srp_iu_pool_alloc(struct srp_queue *q, size_t max, goto free_pool; spin_lock_init(&q->lock); - q->queue = kfifo_init((void *) q->pool, max * sizeof(void *), - GFP_KERNEL, &q->lock); - if (IS_ERR(q->queue)) - goto free_item; + kfifo_init(&q->queue, (void *) q->pool, max * sizeof(void *), + &q->lock); for (i = 0, iue = q->items; i < max; i++) { - __kfifo_put(q->queue, (void *) &iue, sizeof(void *)); + __kfifo_put(&q->queue, (void *) &iue, sizeof(void *)); iue->sbuf = ring[i]; iue++; } return 0; -free_item: kfree(q->items); free_pool: kfree(q->pool); @@ -167,7 +164,7 @@ struct iu_entry *srp_iu_get(struct srp_target *target) { struct iu_entry *iue = NULL; - kfifo_get(target->iu_queue.queue, (void *) &iue, sizeof(void *)); + kfifo_get(&target->iu_queue.queue, (void *) &iue, sizeof(void *)); if (!iue) return iue; iue->target = target; @@ -179,7 +176,7 @@ EXPORT_SYMBOL_GPL(srp_iu_get); void srp_iu_put(struct iu_entry *iue) { - kfifo_put(iue->target->iu_queue.queue, (void *) &iue, sizeof(void *)); + kfifo_put(&iue->target->iu_queue.queue, (void *) &iue, sizeof(void *)); } EXPORT_SYMBOL_GPL(srp_iu_put); diff --git a/drivers/usb/host/fhci-sched.c b/drivers/usb/host/fhci-sched.c index 00a2985..ff43747 100644 --- a/drivers/usb/host/fhci-sched.c +++ b/drivers/usb/host/fhci-sched.c @@ -37,7 +37,7 @@ static void recycle_frame(struct fhci_usb *usb, struct packet *pkt) pkt->info = 0; pkt->priv_data = NULL; - cq_put(usb->ep0->empty_frame_Q, pkt); + cq_put(&usb->ep0->empty_frame_Q, pkt); } /* confirm submitted packet */ @@ -57,7 +57,7 @@ void fhci_transaction_confirm(struct fhci_usb *usb, struct packet *pkt) if ((td->data + td->actual_len) && trans_len) memcpy(td->data + td->actual_len, pkt->data, trans_len); - cq_put(usb->ep0->dummy_packets_Q, pkt->data); + cq_put(&usb->ep0->dummy_packets_Q, pkt->data); } recycle_frame(usb, pkt); @@ -213,7 +213,7 @@ static int add_packet(struct fhci_usb *usb, struct ed *ed, struct td *td) } /* update frame object fields before transmitting */ - pkt = cq_get(usb->ep0->empty_frame_Q); + pkt = cq_get(&usb->ep0->empty_frame_Q); if (!pkt) { fhci_dbg(usb->fhci, "there is no empty frame\n"); return -1; @@ -222,7 +222,7 @@ static int add_packet(struct fhci_usb *usb, struct ed *ed, struct td *td) pkt->info = 0; if (data == NULL) { - data = cq_get(usb->ep0->dummy_packets_Q); + data = cq_get(&usb->ep0->dummy_packets_Q); BUG_ON(!data); pkt->info = PKT_DUMMY_PACKET; } @@ -246,7 +246,7 @@ static int add_packet(struct fhci_usb *usb, struct ed *ed, struct td *td) list_del_init(&td->frame_lh); td->status = USB_TD_OK; if (pkt->info & PKT_DUMMY_PACKET) - cq_put(usb->ep0->dummy_packets_Q, pkt->data); + cq_put(&usb->ep0->dummy_packets_Q, pkt->data); recycle_frame(usb, pkt); usb->actual_frame->total_bytes -= (len + PROTOCOL_OVERHEAD); fhci_err(usb->fhci, "host transaction failed\n"); diff --git a/drivers/usb/host/fhci-tds.c b/drivers/usb/host/fhci-tds.c index b403322..d224ab4 100644 --- a/drivers/usb/host/fhci-tds.c +++ b/drivers/usb/host/fhci-tds.c @@ -106,33 +106,33 @@ void fhci_ep0_free(struct fhci_usb *usb) cpm_muram_free(cpm_muram_offset(ep->td_base)); if (ep->conf_frame_Q) { - size = cq_howmany(ep->conf_frame_Q); + size = cq_howmany(&ep->conf_frame_Q); for (; size; size--) { - struct packet *pkt = cq_get(ep->conf_frame_Q); + struct packet *pkt = cq_get(&ep->conf_frame_Q); kfree(pkt); } - cq_delete(ep->conf_frame_Q); + cq_delete(&ep->conf_frame_Q); } if (ep->empty_frame_Q) { - size = cq_howmany(ep->empty_frame_Q); + size = cq_howmany(&ep->empty_frame_Q); for (; size; size--) { - struct packet *pkt = cq_get(ep->empty_frame_Q); + struct packet *pkt = cq_get(&ep->empty_frame_Q); kfree(pkt); } - cq_delete(ep->empty_frame_Q); + cq_delete(&ep->empty_frame_Q); } if (ep->dummy_packets_Q) { - size = cq_howmany(ep->dummy_packets_Q); + size = cq_howmany(&ep->dummy_packets_Q); for (; size; size--) { - u8 *buff = cq_get(ep->dummy_packets_Q); + u8 *buff = cq_get(&ep->dummy_packets_Q); kfree(buff); } - cq_delete(ep->dummy_packets_Q); + cq_delete(&ep->dummy_packets_Q); } kfree(ep); @@ -175,10 +175,9 @@ u32 fhci_create_ep(struct fhci_usb *usb, enum fhci_mem_alloc data_mem, ep->td_base = cpm_muram_addr(ep_offset); /* zero all queue pointers */ - ep->conf_frame_Q = cq_new(ring_len + 2); - ep->empty_frame_Q = cq_new(ring_len + 2); - ep->dummy_packets_Q = cq_new(ring_len + 2); - if (!ep->conf_frame_Q || !ep->empty_frame_Q || !ep->dummy_packets_Q) { + if (cq_new(&ep->conf_frame_Q, ring_len + 2) || + cq_new(&ep->empty_frame_Q, ring_len + 2) || + cq_new(&ep->dummy_packets_Q, ring_len + 2)) { err_for = "frame_queues"; goto err; } @@ -199,8 +198,8 @@ u32 fhci_create_ep(struct fhci_usb *usb, enum fhci_mem_alloc data_mem, err_for = "buffer"; goto err; } - cq_put(ep->empty_frame_Q, pkt); - cq_put(ep->dummy_packets_Q, buff); + cq_put(&ep->empty_frame_Q, pkt); + cq_put(&ep->dummy_packets_Q, buff); } /* we put the endpoint parameter RAM right behind the TD ring */ @@ -319,7 +318,7 @@ static void fhci_td_transaction_confirm(struct fhci_usb *usb) if ((buf == DUMMY2_BD_BUFFER) && !(td_status & ~TD_W)) continue; - pkt = cq_get(ep->conf_frame_Q); + pkt = cq_get(&ep->conf_frame_Q); if (!pkt) fhci_err(usb->fhci, "no frame to confirm\n"); @@ -460,9 +459,9 @@ u32 fhci_host_transaction(struct fhci_usb *usb, out_be16(&td->length, pkt->len); /* put the frame to the confirmation queue */ - cq_put(ep->conf_frame_Q, pkt); + cq_put(&ep->conf_frame_Q, pkt); - if (cq_howmany(ep->conf_frame_Q) == 1) + if (cq_howmany(&ep->conf_frame_Q) == 1) out_8(&usb->fhci->regs->usb_comm, USB_CMD_STR_FIFO); return 0; diff --git a/drivers/usb/host/fhci.h b/drivers/usb/host/fhci.h index 7116284..2277428 100644 --- a/drivers/usb/host/fhci.h +++ b/drivers/usb/host/fhci.h @@ -423,9 +423,9 @@ struct endpoint { struct usb_td __iomem *td_base; /* first TD in the ring */ struct usb_td __iomem *conf_td; /* next TD for confirm after transac */ struct usb_td __iomem *empty_td;/* next TD for new transaction req. */ - struct kfifo *empty_frame_Q; /* Empty frames list to use */ - struct kfifo *conf_frame_Q; /* frames passed to TDs,waiting for tx */ - struct kfifo *dummy_packets_Q;/* dummy packets for the CRC overun */ + struct kfifo empty_frame_Q; /* Empty frames list to use */ + struct kfifo conf_frame_Q; /* frames passed to TDs,waiting for tx */ + struct kfifo dummy_packets_Q;/* dummy packets for the CRC overun */ bool already_pushed_dummy_bd; }; @@ -493,9 +493,9 @@ static inline struct usb_hcd *fhci_to_hcd(struct fhci_hcd *fhci) } /* fifo of pointers */ -static inline struct kfifo *cq_new(int size) +static inline int cq_new(struct kfifo *fifo, int size) { - return kfifo_alloc(size * sizeof(void *), GFP_KERNEL, NULL); + return kfifo_alloc(fifo, size * sizeof(void *), GFP_KERNEL, NULL); } static inline void cq_delete(struct kfifo *kfifo) diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 4543f35..44b72d4 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -939,9 +939,8 @@ int usb_serial_probe(struct usb_interface *interface, dev_err(&interface->dev, "No free urbs available\n"); goto probe_error; } - port->write_fifo = kfifo_alloc(PAGE_SIZE, GFP_KERNEL, - &port->lock); - if (IS_ERR(port->write_fifo)) + if (kfifo_alloc(&port->write_fifo, PAGE_SIZE, GFP_KERNEL, + &port->lock)) goto probe_error; buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); port->bulk_out_size = buffer_size; diff --git a/include/linux/kfifo.h b/include/linux/kfifo.h index ad6bdf5..c3f8d82 100644 --- a/include/linux/kfifo.h +++ b/include/linux/kfifo.h @@ -1,6 +1,7 @@ /* - * A simple kernel FIFO implementation. + * A generic kernel FIFO implementation. * + * Copyright (C) 2009 Stefani Seibold * Copyright (C) 2004 Stelian Pop * * This program is free software; you can redistribute it and/or modify @@ -32,10 +33,10 @@ struct kfifo { spinlock_t *lock; /* protects concurrent modifications */ }; -extern struct kfifo *kfifo_init(unsigned char *buffer, unsigned int size, - gfp_t gfp_mask, spinlock_t *lock); -extern struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask, - spinlock_t *lock); +extern void kfifo_init(struct kfifo *fifo, unsigned char *buffer, + unsigned int size, spinlock_t *lock); +extern __must_check int kfifo_alloc(struct kfifo *fifo, unsigned int size, + gfp_t gfp_mask, spinlock_t *lock); extern void kfifo_free(struct kfifo *fifo); extern unsigned int __kfifo_put(struct kfifo *fifo, const unsigned char *buffer, unsigned int len); diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index 7394e3b..ff92b46 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -231,7 +232,7 @@ struct iscsi_conn { }; struct iscsi_pool { - struct kfifo *queue; /* FIFO Queue */ + struct kfifo queue; /* FIFO Queue */ void **pool; /* Pool of elements */ int max; /* Max number of elements */ }; diff --git a/include/scsi/libiscsi_tcp.h b/include/scsi/libiscsi_tcp.h index 9e3182e..741ae7e 100644 --- a/include/scsi/libiscsi_tcp.h +++ b/include/scsi/libiscsi_tcp.h @@ -80,7 +80,7 @@ struct iscsi_tcp_task { int data_offset; struct iscsi_r2t_info *r2t; /* in progress solict R2T */ struct iscsi_pool r2tpool; - struct kfifo *r2tqueue; + struct kfifo r2tqueue; void *dd_data; }; diff --git a/include/scsi/libsrp.h b/include/scsi/libsrp.h index ba615e4..07e3add 100644 --- a/include/scsi/libsrp.h +++ b/include/scsi/libsrp.h @@ -21,7 +21,7 @@ struct srp_buf { struct srp_queue { void *pool; void *items; - struct kfifo *queue; + struct kfifo queue; spinlock_t lock; }; diff --git a/kernel/kfifo.c b/kernel/kfifo.c index 3765ff3..8da6bb9 100644 --- a/kernel/kfifo.c +++ b/kernel/kfifo.c @@ -1,6 +1,7 @@ /* - * A simple kernel FIFO implementation. + * A generic kernel FIFO implementation. * + * Copyright (C) 2009 Stefani Seibold * Copyright (C) 2004 Stelian Pop * * This program is free software; you can redistribute it and/or modify @@ -26,49 +27,51 @@ #include #include +static void _kfifo_init(struct kfifo *fifo, unsigned char *buffer, + unsigned int size, spinlock_t *lock) +{ + fifo->buffer = buffer; + fifo->size = size; + fifo->lock = lock; + + kfifo_reset(fifo); +} + /** - * kfifo_init - allocates a new FIFO using a preallocated buffer + * kfifo_init - initialize a FIFO using a preallocated buffer + * @fifo: the fifo to assign the buffer * @buffer: the preallocated buffer to be used. * @size: the size of the internal buffer, this have to be a power of 2. - * @gfp_mask: get_free_pages mask, passed to kmalloc() * @lock: the lock to be used to protect the fifo buffer * - * Do NOT pass the kfifo to kfifo_free() after use! Simply free the - * &struct kfifo with kfree(). */ -struct kfifo *kfifo_init(unsigned char *buffer, unsigned int size, - gfp_t gfp_mask, spinlock_t *lock) +void kfifo_init(struct kfifo *fifo, unsigned char *buffer, unsigned int size, + spinlock_t *lock) { - struct kfifo *fifo; - /* size must be a power of 2 */ BUG_ON(!is_power_of_2(size)); - fifo = kmalloc(sizeof(struct kfifo), gfp_mask); - if (!fifo) - return ERR_PTR(-ENOMEM); - - fifo->buffer = buffer; - fifo->size = size; - fifo->in = fifo->out = 0; - fifo->lock = lock; - - return fifo; + _kfifo_init(fifo, buffer, size, lock); } EXPORT_SYMBOL(kfifo_init); /** - * kfifo_alloc - allocates a new FIFO and its internal buffer - * @size: the size of the internal buffer to be allocated. + * kfifo_alloc - allocates a new FIFO internal buffer + * @fifo: the fifo to assign then new buffer + * @size: the size of the buffer to be allocated, this have to be a power of 2. * @gfp_mask: get_free_pages mask, passed to kmalloc() * @lock: the lock to be used to protect the fifo buffer * + * This function dynamically allocates a new fifo internal buffer + * * The size will be rounded-up to a power of 2. + * The buffer will be release with kfifo_free(). + * Return 0 if no error, otherwise the an error code */ -struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask, spinlock_t *lock) +int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask, + spinlock_t *lock) { unsigned char *buffer; - struct kfifo *ret; /* * round up to the next power of 2, since our 'let the indices @@ -80,26 +83,24 @@ struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask, spinlock_t *lock) } buffer = kmalloc(size, gfp_mask); - if (!buffer) - return ERR_PTR(-ENOMEM); - - ret = kfifo_init(buffer, size, gfp_mask, lock); + if (!buffer) { + _kfifo_init(fifo, 0, 0, NULL); + return -ENOMEM; + } - if (IS_ERR(ret)) - kfree(buffer); + _kfifo_init(fifo, buffer, size, lock); - return ret; + return 0; } EXPORT_SYMBOL(kfifo_alloc); /** - * kfifo_free - frees the FIFO + * kfifo_free - frees the FIFO internal buffer * @fifo: the fifo to be freed. */ void kfifo_free(struct kfifo *fifo) { kfree(fifo->buffer); - kfree(fifo); } EXPORT_SYMBOL(kfifo_free); diff --git a/net/dccp/probe.c b/net/dccp/probe.c index dc32842..6230ceb 100644 --- a/net/dccp/probe.c +++ b/net/dccp/probe.c @@ -43,7 +43,7 @@ static int bufsize = 64 * 1024; static const char procname[] = "dccpprobe"; static struct { - struct kfifo *fifo; + struct kfifo fifo; spinlock_t lock; wait_queue_head_t wait; struct timespec tstart; @@ -67,7 +67,7 @@ static void printl(const char *fmt, ...) len += vscnprintf(tbuf+len, sizeof(tbuf)-len, fmt, args); va_end(args); - kfifo_put(dccpw.fifo, tbuf, len); + kfifo_put(&dccpw.fifo, tbuf, len); wake_up(&dccpw.wait); } @@ -109,7 +109,7 @@ static struct jprobe dccp_send_probe = { static int dccpprobe_open(struct inode *inode, struct file *file) { - kfifo_reset(dccpw.fifo); + kfifo_reset(&dccpw.fifo); getnstimeofday(&dccpw.tstart); return 0; } @@ -131,11 +131,11 @@ static ssize_t dccpprobe_read(struct file *file, char __user *buf, return -ENOMEM; error = wait_event_interruptible(dccpw.wait, - __kfifo_len(dccpw.fifo) != 0); + __kfifo_len(&dccpw.fifo) != 0); if (error) goto out_free; - cnt = kfifo_get(dccpw.fifo, tbuf, len); + cnt = kfifo_get(&dccpw.fifo, tbuf, len); error = copy_to_user(buf, tbuf, cnt) ? -EFAULT : 0; out_free: @@ -156,10 +156,8 @@ static __init int dccpprobe_init(void) init_waitqueue_head(&dccpw.wait); spin_lock_init(&dccpw.lock); - dccpw.fifo = kfifo_alloc(bufsize, GFP_KERNEL, &dccpw.lock); - if (IS_ERR(dccpw.fifo)) - return PTR_ERR(dccpw.fifo); - + if (kfifo_alloc(&dccpw.fifo, bufsize, GFP_KERNEL, &dccpw.lock)) + return ret; if (!proc_net_fops_create(&init_net, procname, S_IRUSR, &dccpprobe_fops)) goto err0; @@ -172,14 +170,14 @@ static __init int dccpprobe_init(void) err1: proc_net_remove(&init_net, procname); err0: - kfifo_free(dccpw.fifo); + kfifo_free(&dccpw.fifo); return ret; } module_init(dccpprobe_init); static __exit void dccpprobe_exit(void) { - kfifo_free(dccpw.fifo); + kfifo_free(&dccpw.fifo); proc_net_remove(&init_net, procname); unregister_jprobe(&dccp_send_probe); -- cgit v0.10.2 From c1e13f25674ed564948ecb7dfe5f83e578892896 Mon Sep 17 00:00:00 2001 From: Stefani Seibold Date: Mon, 21 Dec 2009 14:37:27 -0800 Subject: kfifo: move out spinlock Move the pointer to the spinlock out of struct kfifo. Most users in tree do not actually use a spinlock, so the few exceptions now have to call kfifo_{get,put}_locked, which takes an extra argument to a spinlock. Signed-off-by: Stefani Seibold Acked-by: Greg Kroah-Hartman Acked-by: Mauro Carvalho Chehab Acked-by: Andi Kleen Acked-by: Arnd Bergmann Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/char/nozomi.c b/drivers/char/nozomi.c index 0f39bec..935b30d 100644 --- a/drivers/char/nozomi.c +++ b/drivers/char/nozomi.c @@ -686,7 +686,7 @@ static int nozomi_read_config_table(struct nozomi *dc) for (i = PORT_MDM; i < MAX_PORT; i++) { kfifo_alloc(&dc->port[i].fifo_ul, - FIFO_BUFFER_SIZE_UL, GFP_ATOMIC, NULL); + FIFO_BUFFER_SIZE_UL, GFP_ATOMIC); memset(&dc->port[i].ctrl_dl, 0, sizeof(struct ctrl_dl)); memset(&dc->port[i].ctrl_ul, 0, sizeof(struct ctrl_ul)); } diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index 9e6efb1..dbcb3bd 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c @@ -777,8 +777,9 @@ static void input_keyrelease(struct work_struct *work) { struct sonypi_keypress kp; - while (kfifo_get(&sonypi_device.input_fifo, (unsigned char *)&kp, - sizeof(kp)) == sizeof(kp)) { + while (kfifo_get_locked(&sonypi_device.input_fifo, (unsigned char *)&kp, + sizeof(kp), &sonypi_device.input_fifo_lock) + == sizeof(kp)) { msleep(10); input_report_key(kp.dev, kp.key, 0); input_sync(kp.dev); @@ -827,8 +828,9 @@ static void sonypi_report_input_event(u8 event) if (kp.dev) { input_report_key(kp.dev, kp.key, 1); input_sync(kp.dev); - kfifo_put(&sonypi_device.input_fifo, - (unsigned char *)&kp, sizeof(kp)); + kfifo_put_locked(&sonypi_device.input_fifo, + (unsigned char *)&kp, sizeof(kp), + &sonypi_device.input_fifo_lock); schedule_work(&sonypi_device.input_work); } } @@ -880,7 +882,8 @@ found: acpi_bus_generate_proc_event(sonypi_acpi_device, 1, event); #endif - kfifo_put(&sonypi_device.fifo, (unsigned char *)&event, sizeof(event)); + kfifo_put_locked(&sonypi_device.fifo, (unsigned char *)&event, + sizeof(event), &sonypi_device.fifo_lock); kill_fasync(&sonypi_device.fifo_async, SIGIO, POLL_IN); wake_up_interruptible(&sonypi_device.fifo_proc_list); @@ -929,7 +932,8 @@ static ssize_t sonypi_misc_read(struct file *file, char __user *buf, return ret; while (ret < count && - (kfifo_get(&sonypi_device.fifo, &c, sizeof(c)) == sizeof(c))) { + (kfifo_get_locked(&sonypi_device.fifo, &c, sizeof(c), + &sonypi_device.fifo_lock) == sizeof(c))) { if (put_user(c, buf++)) return -EFAULT; ret++; @@ -1313,8 +1317,7 @@ static int __devinit sonypi_probe(struct platform_device *dev) "http://www.linux.it/~malattia/wiki/index.php/Sony_drivers\n"); spin_lock_init(&sonypi_device.fifo_lock); - error = kfifo_alloc(&sonypi_device.fifo, SONYPI_BUF_SIZE, GFP_KERNEL, - &sonypi_device.fifo_lock); + error = kfifo_alloc(&sonypi_device.fifo, SONYPI_BUF_SIZE, GFP_KERNEL); if (error) { printk(KERN_ERR "sonypi: kfifo_alloc failed\n"); return error; @@ -1394,7 +1397,7 @@ static int __devinit sonypi_probe(struct platform_device *dev) spin_lock_init(&sonypi_device.input_fifo_lock); error = kfifo_alloc(&sonypi_device.input_fifo, SONYPI_BUF_SIZE, - GFP_KERNEL, &sonypi_device.input_fifo_lock); + GFP_KERNEL); if (error) { printk(KERN_ERR "sonypi: kfifo_alloc failed\n"); goto err_inpdev_unregister; diff --git a/drivers/infiniband/hw/cxgb3/cxio_resource.c b/drivers/infiniband/hw/cxgb3/cxio_resource.c index 65072bd..98f24e6 100644 --- a/drivers/infiniband/hw/cxgb3/cxio_resource.c +++ b/drivers/infiniband/hw/cxgb3/cxio_resource.c @@ -55,7 +55,7 @@ static int __cxio_init_resource_fifo(struct kfifo *fifo, u32 rarray[16]; spin_lock_init(fifo_lock); - if (kfifo_alloc(fifo, nr * sizeof(u32), GFP_KERNEL, fifo_lock)) + if (kfifo_alloc(fifo, nr * sizeof(u32), GFP_KERNEL)) return -ENOMEM; for (i = 0; i < skip_low + skip_high; i++) @@ -86,7 +86,8 @@ static int __cxio_init_resource_fifo(struct kfifo *fifo, __kfifo_put(fifo, (unsigned char *) &i, sizeof(u32)); for (i = 0; i < skip_low + skip_high; i++) - kfifo_get(fifo, (unsigned char *) &entry, sizeof(u32)); + kfifo_get_locked(fifo, (unsigned char *) &entry, + sizeof(u32), fifo_lock); return 0; } @@ -113,8 +114,7 @@ static int cxio_init_qpid_fifo(struct cxio_rdev *rdev_p) spin_lock_init(&rdev_p->rscp->qpid_fifo_lock); if (kfifo_alloc(&rdev_p->rscp->qpid_fifo, T3_MAX_NUM_QP * sizeof(u32), - GFP_KERNEL, - &rdev_p->rscp->qpid_fifo_lock)) + GFP_KERNEL)) return -ENOMEM; for (i = 16; i < T3_MAX_NUM_QP; i++) @@ -177,33 +177,37 @@ tpt_err: /* * returns 0 if no resource available */ -static u32 cxio_hal_get_resource(struct kfifo *fifo) +static u32 cxio_hal_get_resource(struct kfifo *fifo, spinlock_t * lock) { u32 entry; - if (kfifo_get(fifo, (unsigned char *) &entry, sizeof(u32))) + if (kfifo_get_locked(fifo, (unsigned char *) &entry, sizeof(u32), lock)) return entry; else return 0; /* fifo emptry */ } -static void cxio_hal_put_resource(struct kfifo *fifo, u32 entry) +static void cxio_hal_put_resource(struct kfifo *fifo, spinlock_t * lock, + u32 entry) { - BUG_ON(kfifo_put(fifo, (unsigned char *) &entry, sizeof(u32)) == 0); + BUG_ON( + kfifo_put_locked(fifo, (unsigned char *) &entry, sizeof(u32), lock) + == 0); } u32 cxio_hal_get_stag(struct cxio_hal_resource *rscp) { - return cxio_hal_get_resource(&rscp->tpt_fifo); + return cxio_hal_get_resource(&rscp->tpt_fifo, &rscp->tpt_fifo_lock); } void cxio_hal_put_stag(struct cxio_hal_resource *rscp, u32 stag) { - cxio_hal_put_resource(&rscp->tpt_fifo, stag); + cxio_hal_put_resource(&rscp->tpt_fifo, &rscp->tpt_fifo_lock, stag); } u32 cxio_hal_get_qpid(struct cxio_hal_resource *rscp) { - u32 qpid = cxio_hal_get_resource(&rscp->qpid_fifo); + u32 qpid = cxio_hal_get_resource(&rscp->qpid_fifo, + &rscp->qpid_fifo_lock); PDBG("%s qpid 0x%x\n", __func__, qpid); return qpid; } @@ -211,27 +215,27 @@ u32 cxio_hal_get_qpid(struct cxio_hal_resource *rscp) void cxio_hal_put_qpid(struct cxio_hal_resource *rscp, u32 qpid) { PDBG("%s qpid 0x%x\n", __func__, qpid); - cxio_hal_put_resource(&rscp->qpid_fifo, qpid); + cxio_hal_put_resource(&rscp->qpid_fifo, &rscp->qpid_fifo_lock, qpid); } u32 cxio_hal_get_cqid(struct cxio_hal_resource *rscp) { - return cxio_hal_get_resource(&rscp->cqid_fifo); + return cxio_hal_get_resource(&rscp->cqid_fifo, &rscp->cqid_fifo_lock); } void cxio_hal_put_cqid(struct cxio_hal_resource *rscp, u32 cqid) { - cxio_hal_put_resource(&rscp->cqid_fifo, cqid); + cxio_hal_put_resource(&rscp->cqid_fifo, &rscp->cqid_fifo_lock, cqid); } u32 cxio_hal_get_pdid(struct cxio_hal_resource *rscp) { - return cxio_hal_get_resource(&rscp->pdid_fifo); + return cxio_hal_get_resource(&rscp->pdid_fifo, &rscp->pdid_fifo_lock); } void cxio_hal_put_pdid(struct cxio_hal_resource *rscp, u32 pdid) { - cxio_hal_put_resource(&rscp->pdid_fifo, pdid); + cxio_hal_put_resource(&rscp->pdid_fifo, &rscp->pdid_fifo_lock, pdid); } void cxio_hal_destroy_resource(struct cxio_hal_resource *rscp) diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c index dacbbb8..38bcedf 100644 --- a/drivers/media/video/meye.c +++ b/drivers/media/video/meye.c @@ -800,8 +800,8 @@ again: return IRQ_HANDLED; if (meye.mchip_mode == MCHIP_HIC_MODE_CONT_OUT) { - if (kfifo_get(&meye.grabq, (unsigned char *)&reqnr, - sizeof(int)) != sizeof(int)) { + if (kfifo_get_locked(&meye.grabq, (unsigned char *)&reqnr, + sizeof(int), &meye.grabq_lock) != sizeof(int)) { mchip_free_frame(); return IRQ_HANDLED; } @@ -811,7 +811,8 @@ again: meye.grab_buffer[reqnr].state = MEYE_BUF_DONE; do_gettimeofday(&meye.grab_buffer[reqnr].timestamp); meye.grab_buffer[reqnr].sequence = sequence++; - kfifo_put(&meye.doneq, (unsigned char *)&reqnr, sizeof(int)); + kfifo_put_locked(&meye.doneq, (unsigned char *)&reqnr, + sizeof(int), &meye.doneq_lock); wake_up_interruptible(&meye.proc_list); } else { int size; @@ -820,8 +821,8 @@ again: mchip_free_frame(); goto again; } - if (kfifo_get(&meye.grabq, (unsigned char *)&reqnr, - sizeof(int)) != sizeof(int)) { + if (kfifo_get_locked(&meye.grabq, (unsigned char *)&reqnr, + sizeof(int), &meye.grabq_lock) != sizeof(int)) { mchip_free_frame(); goto again; } @@ -831,7 +832,8 @@ again: meye.grab_buffer[reqnr].state = MEYE_BUF_DONE; do_gettimeofday(&meye.grab_buffer[reqnr].timestamp); meye.grab_buffer[reqnr].sequence = sequence++; - kfifo_put(&meye.doneq, (unsigned char *)&reqnr, sizeof(int)); + kfifo_put_locked(&meye.doneq, (unsigned char *)&reqnr, + sizeof(int), &meye.doneq_lock); wake_up_interruptible(&meye.proc_list); } mchip_free_frame(); @@ -933,7 +935,8 @@ static int meyeioc_qbuf_capt(int *nb) mchip_cont_compression_start(); meye.grab_buffer[*nb].state = MEYE_BUF_USING; - kfifo_put(&meye.grabq, (unsigned char *)nb, sizeof(int)); + kfifo_put_locked(&meye.grabq, (unsigned char *)nb, sizeof(int), + &meye.grabq_lock); mutex_unlock(&meye.lock); return 0; @@ -965,7 +968,8 @@ static int meyeioc_sync(struct file *file, void *fh, int *i) /* fall through */ case MEYE_BUF_DONE: meye.grab_buffer[*i].state = MEYE_BUF_UNUSED; - kfifo_get(&meye.doneq, (unsigned char *)&unused, sizeof(int)); + kfifo_get_locked(&meye.doneq, (unsigned char *)&unused, + sizeof(int), &meye.doneq_lock); } *i = meye.grab_buffer[*i].size; mutex_unlock(&meye.lock); @@ -1452,7 +1456,8 @@ static int vidioc_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf) buf->flags |= V4L2_BUF_FLAG_QUEUED; buf->flags &= ~V4L2_BUF_FLAG_DONE; meye.grab_buffer[buf->index].state = MEYE_BUF_USING; - kfifo_put(&meye.grabq, (unsigned char *)&buf->index, sizeof(int)); + kfifo_put_locked(&meye.grabq, (unsigned char *)&buf->index, + sizeof(int), &meye.grabq_lock); mutex_unlock(&meye.lock); return 0; @@ -1478,8 +1483,8 @@ static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf) return -EINTR; } - if (!kfifo_get(&meye.doneq, (unsigned char *)&reqnr, - sizeof(int))) { + if (!kfifo_get_locked(&meye.doneq, (unsigned char *)&reqnr, + sizeof(int), &meye.doneq_lock)) { mutex_unlock(&meye.lock); return -EBUSY; } @@ -1745,14 +1750,14 @@ static int __devinit meye_probe(struct pci_dev *pcidev, } spin_lock_init(&meye.grabq_lock); - if (kfifo_alloc(&meye.grabq, sizeof(int) * MEYE_MAX_BUFNBRS, GFP_KERNEL, - &meye.grabq_lock)) { + if (kfifo_alloc(&meye.grabq, sizeof(int) * MEYE_MAX_BUFNBRS, + GFP_KERNEL)) { printk(KERN_ERR "meye: fifo allocation failed\n"); goto outkfifoalloc1; } spin_lock_init(&meye.doneq_lock); - if (kfifo_alloc(&meye.doneq, sizeof(int) * MEYE_MAX_BUFNBRS, GFP_KERNEL, - &meye.doneq_lock)) { + if (kfifo_alloc(&meye.doneq, sizeof(int) * MEYE_MAX_BUFNBRS, + GFP_KERNEL)) { printk(KERN_ERR "meye: fifo allocation failed\n"); goto outkfifoalloc2; } diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index 4039092..2cc7ecd 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c @@ -883,7 +883,7 @@ static int lbs_init_adapter(struct lbs_private *priv) priv->resp_len[0] = priv->resp_len[1] = 0; /* Create the event FIFO */ - ret = kfifo_alloc(&priv->event_fifo, sizeof(u32) * 16, GFP_KERNEL, NULL); + ret = kfifo_alloc(&priv->event_fifo, sizeof(u32) * 16, GFP_KERNEL); if (ret) { lbs_pr_err("Out of memory allocating event FIFO buffer\n"); goto out; diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c index f999fba..13dc7be 100644 --- a/drivers/platform/x86/fujitsu-laptop.c +++ b/drivers/platform/x86/fujitsu-laptop.c @@ -825,7 +825,7 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device) /* kfifo */ spin_lock_init(&fujitsu_hotkey->fifo_lock); error = kfifo_alloc(&fujitsu_hotkey->fifo, RINGBUFFERSIZE * sizeof(int), - GFP_KERNEL, &fujitsu_hotkey->fifo_lock); + GFP_KERNEL); if (error) { printk(KERN_ERR "kfifo_alloc failed\n"); goto err_stop; @@ -1006,9 +1006,10 @@ static void acpi_fujitsu_hotkey_notify(struct acpi_device *device, u32 event) vdbg_printk(FUJLAPTOP_DBG_TRACE, "Push keycode into ringbuffer [%d]\n", keycode); - status = kfifo_put(&fujitsu_hotkey->fifo, + status = kfifo_put_locked(&fujitsu_hotkey->fifo, (unsigned char *)&keycode, - sizeof(keycode)); + sizeof(keycode), + &fujitsu_hotkey->fifo_lock); if (status != sizeof(keycode)) { vdbg_printk(FUJLAPTOP_DBG_WARN, "Could not push keycode [0x%x]\n", @@ -1019,11 +1020,12 @@ static void acpi_fujitsu_hotkey_notify(struct acpi_device *device, u32 event) } } else if (keycode == 0) { while ((status = - kfifo_get - (&fujitsu_hotkey->fifo, (unsigned char *) - &keycode_r, - sizeof - (keycode_r))) == sizeof(keycode_r)) { + kfifo_get_locked( + &fujitsu_hotkey->fifo, + (unsigned char *) &keycode_r, + sizeof(keycode_r), + &fujitsu_hotkey->fifo_lock)) + == sizeof(keycode_r)) { input_report_key(input, keycode_r, 0); input_sync(input); vdbg_printk(FUJLAPTOP_DBG_TRACE, diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index 04625a0..1538a0a 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c @@ -300,8 +300,9 @@ static void do_sony_laptop_release_key(struct work_struct *work) { struct sony_laptop_keypress kp; - while (kfifo_get(&sony_laptop_input.fifo, (unsigned char *)&kp, - sizeof(kp)) == sizeof(kp)) { + while (kfifo_get_locked(&sony_laptop_input.fifo, (unsigned char *)&kp, + sizeof(kp), &sony_laptop_input.fifo_lock) + == sizeof(kp)) { msleep(10); input_report_key(kp.dev, kp.key, 0); input_sync(kp.dev); @@ -362,8 +363,9 @@ static void sony_laptop_report_input_event(u8 event) /* we emit the scancode so we can always remap the key */ input_event(kp.dev, EV_MSC, MSC_SCAN, event); input_sync(kp.dev); - kfifo_put(&sony_laptop_input.fifo, - (unsigned char *)&kp, sizeof(kp)); + kfifo_put_locked(&sony_laptop_input.fifo, + (unsigned char *)&kp, sizeof(kp), + &sony_laptop_input.fifo_lock); if (!work_pending(&sony_laptop_release_key_work)) queue_work(sony_laptop_input.wq, @@ -386,8 +388,7 @@ static int sony_laptop_setup_input(struct acpi_device *acpi_device) /* kfifo */ spin_lock_init(&sony_laptop_input.fifo_lock); error = - kfifo_alloc(&sony_laptop_input.fifo, SONY_LAPTOP_BUF_SIZE, GFP_KERNEL, - &sony_laptop_input.fifo_lock); + kfifo_alloc(&sony_laptop_input.fifo, SONY_LAPTOP_BUF_SIZE, GFP_KERNEL); if (error) { printk(KERN_ERR DRV_PFX "kfifo_alloc failed\n"); goto err_dec_users; @@ -2129,7 +2130,8 @@ static ssize_t sonypi_misc_read(struct file *file, char __user *buf, return ret; while (ret < count && - (kfifo_get(&sonypi_compat.fifo, &c, sizeof(c)) == sizeof(c))) { + (kfifo_get_locked(&sonypi_compat.fifo, &c, sizeof(c), + &sonypi_compat.fifo_lock) == sizeof(c))) { if (put_user(c, buf++)) return -EFAULT; ret++; @@ -2308,7 +2310,8 @@ static struct miscdevice sonypi_misc_device = { static void sonypi_compat_report_event(u8 event) { - kfifo_put(&sonypi_compat.fifo, (unsigned char *)&event, sizeof(event)); + kfifo_put_locked(&sonypi_compat.fifo, (unsigned char *)&event, + sizeof(event), &sonypi_compat.fifo_lock); kill_fasync(&sonypi_compat.fifo_async, SIGIO, POLL_IN); wake_up_interruptible(&sonypi_compat.fifo_proc_list); } @@ -2319,8 +2322,7 @@ static int sonypi_compat_init(void) spin_lock_init(&sonypi_compat.fifo_lock); error = - kfifo_alloc(&sonypi_compat.fifo, SONY_LAPTOP_BUF_SIZE, GFP_KERNEL, - &sonypi_compat.fifo_lock); + kfifo_alloc(&sonypi_compat.fifo, SONY_LAPTOP_BUF_SIZE, GFP_KERNEL); if (error) { printk(KERN_ERR DRV_PFX "kfifo_alloc failed\n"); return error; diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index cf0aa7e..1bccbc1 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -2461,7 +2461,7 @@ iscsi_pool_init(struct iscsi_pool *q, int max, void ***items, int item_size) if (q->pool == NULL) return -ENOMEM; - kfifo_init(&q->queue, (void*)q->pool, max * sizeof(void*), NULL); + kfifo_init(&q->queue, (void*)q->pool, max * sizeof(void*)); for (i = 0; i < max; i++) { q->pool[i] = kzalloc(item_size, GFP_KERNEL); diff --git a/drivers/scsi/libiscsi_tcp.c b/drivers/scsi/libiscsi_tcp.c index a83ee56..41643c8 100644 --- a/drivers/scsi/libiscsi_tcp.c +++ b/drivers/scsi/libiscsi_tcp.c @@ -1128,7 +1128,7 @@ int iscsi_tcp_r2tpool_alloc(struct iscsi_session *session) /* R2T xmit queue */ if (kfifo_alloc(&tcp_task->r2tqueue, - session->max_r2t * 4 * sizeof(void*), GFP_KERNEL, NULL)) { + session->max_r2t * 4 * sizeof(void*), GFP_KERNEL)) { iscsi_pool_free(&tcp_task->r2tpool); goto r2t_alloc_fail; } diff --git a/drivers/scsi/libsrp.c b/drivers/scsi/libsrp.c index b1b5e51..db1b41c 100644 --- a/drivers/scsi/libsrp.c +++ b/drivers/scsi/libsrp.c @@ -58,8 +58,7 @@ static int srp_iu_pool_alloc(struct srp_queue *q, size_t max, goto free_pool; spin_lock_init(&q->lock); - kfifo_init(&q->queue, (void *) q->pool, max * sizeof(void *), - &q->lock); + kfifo_init(&q->queue, (void *) q->pool, max * sizeof(void *)); for (i = 0, iue = q->items; i < max; i++) { __kfifo_put(&q->queue, (void *) &iue, sizeof(void *)); @@ -164,7 +163,8 @@ struct iu_entry *srp_iu_get(struct srp_target *target) { struct iu_entry *iue = NULL; - kfifo_get(&target->iu_queue.queue, (void *) &iue, sizeof(void *)); + kfifo_get_locked(&target->iu_queue.queue, (void *) &iue, + sizeof(void *), &target->iu_queue.lock); if (!iue) return iue; iue->target = target; @@ -176,7 +176,8 @@ EXPORT_SYMBOL_GPL(srp_iu_get); void srp_iu_put(struct iu_entry *iue) { - kfifo_put(&iue->target->iu_queue.queue, (void *) &iue, sizeof(void *)); + kfifo_put_locked(&iue->target->iu_queue.queue, (void *) &iue, + sizeof(void *), &iue->target->iu_queue.lock); } EXPORT_SYMBOL_GPL(srp_iu_put); diff --git a/drivers/usb/host/fhci.h b/drivers/usb/host/fhci.h index 2277428..a76da20 100644 --- a/drivers/usb/host/fhci.h +++ b/drivers/usb/host/fhci.h @@ -495,7 +495,7 @@ static inline struct usb_hcd *fhci_to_hcd(struct fhci_hcd *fhci) /* fifo of pointers */ static inline int cq_new(struct kfifo *fifo, int size) { - return kfifo_alloc(fifo, size * sizeof(void *), GFP_KERNEL, NULL); + return kfifo_alloc(fifo, size * sizeof(void *), GFP_KERNEL); } static inline void cq_delete(struct kfifo *kfifo) diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index bbe005c..61eef18 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -285,7 +285,7 @@ static int usb_serial_generic_write_start(struct usb_serial_port *port) return 0; data = port->write_urb->transfer_buffer; - count = kfifo_get(port->write_fifo, data, port->bulk_out_size); + count = kfifo_get_locked(port->write_fifo, data, port->bulk_out_size, &port->lock); usb_serial_debug_data(debug, &port->dev, __func__, count, data); /* set up our urb */ @@ -345,7 +345,7 @@ int usb_serial_generic_write(struct tty_struct *tty, return usb_serial_multi_urb_write(tty, port, buf, count); - count = kfifo_put(port->write_fifo, buf, count); + count = kfifo_put_locked(port->write_fifo, buf, count, &port->lock); result = usb_serial_generic_write_start(port); if (result >= 0) diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 44b72d4..636a4f2 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -939,8 +939,7 @@ int usb_serial_probe(struct usb_interface *interface, dev_err(&interface->dev, "No free urbs available\n"); goto probe_error; } - if (kfifo_alloc(&port->write_fifo, PAGE_SIZE, GFP_KERNEL, - &port->lock)) + if (kfifo_alloc(port->write_fifo, PAGE_SIZE, GFP_KERNEL)) goto probe_error; buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); port->bulk_out_size = buffer_size; diff --git a/include/linux/kfifo.h b/include/linux/kfifo.h index c3f8d82..e0f5c9d 100644 --- a/include/linux/kfifo.h +++ b/include/linux/kfifo.h @@ -30,13 +30,12 @@ struct kfifo { unsigned int size; /* the size of the allocated buffer */ unsigned int in; /* data is added at offset (in % size) */ unsigned int out; /* data is extracted from off. (out % size) */ - spinlock_t *lock; /* protects concurrent modifications */ }; extern void kfifo_init(struct kfifo *fifo, unsigned char *buffer, - unsigned int size, spinlock_t *lock); + unsigned int size); extern __must_check int kfifo_alloc(struct kfifo *fifo, unsigned int size, - gfp_t gfp_mask, spinlock_t *lock); + gfp_t gfp_mask); extern void kfifo_free(struct kfifo *fifo); extern unsigned int __kfifo_put(struct kfifo *fifo, const unsigned char *buffer, unsigned int len); @@ -58,58 +57,67 @@ static inline void __kfifo_reset(struct kfifo *fifo) */ static inline void kfifo_reset(struct kfifo *fifo) { - unsigned long flags; - - spin_lock_irqsave(fifo->lock, flags); - __kfifo_reset(fifo); +} + +/** + * __kfifo_len - returns the number of bytes available in the FIFO + * @fifo: the fifo to be used. + */ +static inline unsigned int __kfifo_len(struct kfifo *fifo) +{ + register unsigned int out; - spin_unlock_irqrestore(fifo->lock, flags); + out = fifo->out; + smp_rmb(); + return fifo->in - out; } /** - * kfifo_put - puts some data into the FIFO + * kfifo_put_locked - puts some data into the FIFO using a spinlock for locking * @fifo: the fifo to be used. - * @buffer: the data to be added. - * @len: the length of the data to be added. + * @from: the data to be added. + * @n: the length of the data to be added. + * @lock: pointer to the spinlock to use for locking. * - * This function copies at most @len bytes from the @buffer into + * This function copies at most @len bytes from the @from buffer into * the FIFO depending on the free space, and returns the number of * bytes copied. */ -static inline unsigned int kfifo_put(struct kfifo *fifo, - const unsigned char *buffer, unsigned int len) +static inline __must_check unsigned int kfifo_put_locked(struct kfifo *fifo, + const unsigned char *from, unsigned int n, spinlock_t *lock) { unsigned long flags; unsigned int ret; - spin_lock_irqsave(fifo->lock, flags); + spin_lock_irqsave(lock, flags); - ret = __kfifo_put(fifo, buffer, len); + ret = __kfifo_put(fifo, from, n); - spin_unlock_irqrestore(fifo->lock, flags); + spin_unlock_irqrestore(lock, flags); return ret; } /** - * kfifo_get - gets some data from the FIFO + * kfifo_get_locked - gets some data from the FIFO using a spinlock for locking * @fifo: the fifo to be used. - * @buffer: where the data must be copied. - * @len: the size of the destination buffer. + * @to: where the data must be copied. + * @n: the size of the destination buffer. + * @lock: pointer to the spinlock to use for locking. * * This function copies at most @len bytes from the FIFO into the - * @buffer and returns the number of copied bytes. + * @to buffer and returns the number of copied bytes. */ -static inline unsigned int kfifo_get(struct kfifo *fifo, - unsigned char *buffer, unsigned int len) +static inline __must_check unsigned int kfifo_get_locked(struct kfifo *fifo, + unsigned char *to, unsigned int n, spinlock_t *lock) { unsigned long flags; unsigned int ret; - spin_lock_irqsave(fifo->lock, flags); + spin_lock_irqsave(lock, flags); - ret = __kfifo_get(fifo, buffer, len); + ret = __kfifo_get(fifo, to, n); /* * optimization: if the FIFO is empty, set the indices to 0 @@ -118,36 +126,18 @@ static inline unsigned int kfifo_get(struct kfifo *fifo, if (fifo->in == fifo->out) fifo->in = fifo->out = 0; - spin_unlock_irqrestore(fifo->lock, flags); + spin_unlock_irqrestore(lock, flags); return ret; } /** - * __kfifo_len - returns the number of bytes available in the FIFO, no locking version - * @fifo: the fifo to be used. - */ -static inline unsigned int __kfifo_len(struct kfifo *fifo) -{ - return fifo->in - fifo->out; -} - -/** * kfifo_len - returns the number of bytes available in the FIFO * @fifo: the fifo to be used. */ static inline unsigned int kfifo_len(struct kfifo *fifo) { - unsigned long flags; - unsigned int ret; - - spin_lock_irqsave(fifo->lock, flags); - - ret = __kfifo_len(fifo); - - spin_unlock_irqrestore(fifo->lock, flags); - - return ret; + return __kfifo_len(fifo); } #endif diff --git a/kernel/kfifo.c b/kernel/kfifo.c index 8da6bb9..4950bdb 100644 --- a/kernel/kfifo.c +++ b/kernel/kfifo.c @@ -28,11 +28,10 @@ #include static void _kfifo_init(struct kfifo *fifo, unsigned char *buffer, - unsigned int size, spinlock_t *lock) + unsigned int size) { fifo->buffer = buffer; fifo->size = size; - fifo->lock = lock; kfifo_reset(fifo); } @@ -42,16 +41,14 @@ static void _kfifo_init(struct kfifo *fifo, unsigned char *buffer, * @fifo: the fifo to assign the buffer * @buffer: the preallocated buffer to be used. * @size: the size of the internal buffer, this have to be a power of 2. - * @lock: the lock to be used to protect the fifo buffer * */ -void kfifo_init(struct kfifo *fifo, unsigned char *buffer, unsigned int size, - spinlock_t *lock) +void kfifo_init(struct kfifo *fifo, unsigned char *buffer, unsigned int size) { /* size must be a power of 2 */ BUG_ON(!is_power_of_2(size)); - _kfifo_init(fifo, buffer, size, lock); + _kfifo_init(fifo, buffer, size); } EXPORT_SYMBOL(kfifo_init); @@ -60,7 +57,6 @@ EXPORT_SYMBOL(kfifo_init); * @fifo: the fifo to assign then new buffer * @size: the size of the buffer to be allocated, this have to be a power of 2. * @gfp_mask: get_free_pages mask, passed to kmalloc() - * @lock: the lock to be used to protect the fifo buffer * * This function dynamically allocates a new fifo internal buffer * @@ -68,8 +64,7 @@ EXPORT_SYMBOL(kfifo_init); * The buffer will be release with kfifo_free(). * Return 0 if no error, otherwise the an error code */ -int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask, - spinlock_t *lock) +int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask) { unsigned char *buffer; @@ -84,11 +79,11 @@ int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask, buffer = kmalloc(size, gfp_mask); if (!buffer) { - _kfifo_init(fifo, 0, 0, NULL); + _kfifo_init(fifo, 0, 0); return -ENOMEM; } - _kfifo_init(fifo, buffer, size, lock); + _kfifo_init(fifo, buffer, size); return 0; } diff --git a/net/dccp/probe.c b/net/dccp/probe.c index 6230ceb..c6b5035 100644 --- a/net/dccp/probe.c +++ b/net/dccp/probe.c @@ -67,7 +67,7 @@ static void printl(const char *fmt, ...) len += vscnprintf(tbuf+len, sizeof(tbuf)-len, fmt, args); va_end(args); - kfifo_put(&dccpw.fifo, tbuf, len); + kfifo_put_locked(&dccpw.fifo, tbuf, len, &dccpw.lock); wake_up(&dccpw.wait); } @@ -135,7 +135,7 @@ static ssize_t dccpprobe_read(struct file *file, char __user *buf, if (error) goto out_free; - cnt = kfifo_get(&dccpw.fifo, tbuf, len); + cnt = kfifo_get_locked(&dccpw.fifo, tbuf, len, &dccpw.lock); error = copy_to_user(buf, tbuf, cnt) ? -EFAULT : 0; out_free: @@ -156,7 +156,7 @@ static __init int dccpprobe_init(void) init_waitqueue_head(&dccpw.wait); spin_lock_init(&dccpw.lock); - if (kfifo_alloc(&dccpw.fifo, bufsize, GFP_KERNEL, &dccpw.lock)) + if (kfifo_alloc(&dccpw.fifo, bufsize, GFP_KERNEL)) return ret; if (!proc_net_fops_create(&init_net, procname, S_IRUSR, &dccpprobe_fops)) goto err0; -- cgit v0.10.2 From e64c026dd09b73faf20707711402fc5ed55a8e70 Mon Sep 17 00:00:00 2001 From: Stefani Seibold Date: Mon, 21 Dec 2009 14:37:28 -0800 Subject: kfifo: cleanup namespace change name of __kfifo_* functions to kfifo_*, because the prefix __kfifo should be reserved for internal functions only. Signed-off-by: Stefani Seibold Acked-by: Greg Kroah-Hartman Acked-by: Mauro Carvalho Chehab Acked-by: Andi Kleen Acked-by: Arnd Bergmann Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/char/nozomi.c b/drivers/char/nozomi.c index 935b30d..61f5bfe 100644 --- a/drivers/char/nozomi.c +++ b/drivers/char/nozomi.c @@ -798,7 +798,7 @@ static int send_data(enum port_type index, struct nozomi *dc) struct tty_struct *tty = tty_port_tty_get(&port->port); /* Get data from tty and place in buf for now */ - size = __kfifo_get(&port->fifo_ul, dc->send_buf, + size = kfifo_get(&port->fifo_ul, dc->send_buf, ul_size < SEND_BUF_MAX ? ul_size : SEND_BUF_MAX); if (size == 0) { @@ -988,11 +988,11 @@ static int receive_flow_control(struct nozomi *dc) } else if (old_ctrl.CTS == 0 && ctrl_dl.CTS == 1) { - if (__kfifo_len(&dc->port[port].fifo_ul)) { + if (kfifo_len(&dc->port[port].fifo_ul)) { DBG1("Enable interrupt (0x%04X) on port: %d", enable_ier, port); DBG1("Data in buffer [%d], enable transmit! ", - __kfifo_len(&dc->port[port].fifo_ul)); + kfifo_len(&dc->port[port].fifo_ul)); enable_transmit_ul(port, dc); } else { DBG1("No data in buffer..."); @@ -1672,7 +1672,7 @@ static int ntty_write(struct tty_struct *tty, const unsigned char *buffer, goto exit; } - rval = __kfifo_put(&port->fifo_ul, (unsigned char *)buffer, count); + rval = kfifo_put(&port->fifo_ul, (unsigned char *)buffer, count); /* notify card */ if (unlikely(dc == NULL)) { @@ -1720,7 +1720,7 @@ static int ntty_write_room(struct tty_struct *tty) if (!port->port.count) goto exit; - room = port->fifo_ul.size - __kfifo_len(&port->fifo_ul); + room = port->fifo_ul.size - kfifo_len(&port->fifo_ul); exit: mutex_unlock(&port->tty_sem); @@ -1877,7 +1877,7 @@ static s32 ntty_chars_in_buffer(struct tty_struct *tty) goto exit_in_buffer; } - rval = __kfifo_len(&port->fifo_ul); + rval = kfifo_len(&port->fifo_ul); exit_in_buffer: return rval; diff --git a/drivers/infiniband/hw/cxgb3/cxio_resource.c b/drivers/infiniband/hw/cxgb3/cxio_resource.c index 98f24e6..d7d18fb0 100644 --- a/drivers/infiniband/hw/cxgb3/cxio_resource.c +++ b/drivers/infiniband/hw/cxgb3/cxio_resource.c @@ -59,7 +59,7 @@ static int __cxio_init_resource_fifo(struct kfifo *fifo, return -ENOMEM; for (i = 0; i < skip_low + skip_high; i++) - __kfifo_put(fifo, (unsigned char *) &entry, sizeof(u32)); + kfifo_put(fifo, (unsigned char *) &entry, sizeof(u32)); if (random) { j = 0; random_bytes = random32(); @@ -71,19 +71,19 @@ static int __cxio_init_resource_fifo(struct kfifo *fifo, random_bytes = random32(); } idx = (random_bytes >> (j * 2)) & 0xF; - __kfifo_put(fifo, + kfifo_put(fifo, (unsigned char *) &rarray[idx], sizeof(u32)); rarray[idx] = i; j++; } for (i = 0; i < RANDOM_SIZE; i++) - __kfifo_put(fifo, + kfifo_put(fifo, (unsigned char *) &rarray[i], sizeof(u32)); } else for (i = skip_low; i < nr - skip_high; i++) - __kfifo_put(fifo, (unsigned char *) &i, sizeof(u32)); + kfifo_put(fifo, (unsigned char *) &i, sizeof(u32)); for (i = 0; i < skip_low + skip_high; i++) kfifo_get_locked(fifo, (unsigned char *) &entry, @@ -119,7 +119,7 @@ static int cxio_init_qpid_fifo(struct cxio_rdev *rdev_p) for (i = 16; i < T3_MAX_NUM_QP; i++) if (!(i & rdev_p->qpmask)) - __kfifo_put(&rdev_p->rscp->qpid_fifo, + kfifo_put(&rdev_p->rscp->qpid_fifo, (unsigned char *) &i, sizeof(u32)); return 0; } diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index ffed17f..42611be 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c @@ -1365,7 +1365,7 @@ static void lbs_send_confirmsleep(struct lbs_private *priv) priv->dnld_sent = DNLD_RES_RECEIVED; /* If nothing to do, go back to sleep (?) */ - if (!__kfifo_len(&priv->event_fifo) && !priv->resp_len[priv->resp_idx]) + if (!kfifo_len(&priv->event_fifo) && !priv->resp_len[priv->resp_idx]) priv->psstate = PS_STATE_SLEEP; spin_unlock_irqrestore(&priv->driver_lock, flags); @@ -1439,7 +1439,7 @@ void lbs_ps_confirm_sleep(struct lbs_private *priv) } /* Pending events or command responses? */ - if (__kfifo_len(&priv->event_fifo) || priv->resp_len[priv->resp_idx]) { + if (kfifo_len(&priv->event_fifo) || priv->resp_len[priv->resp_idx]) { allowed = 0; lbs_deb_host("pending events or command responses\n"); } diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index 2cc7ecd..0622104 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c @@ -459,7 +459,7 @@ static int lbs_thread(void *data) else if (!list_empty(&priv->cmdpendingq) && !(priv->wakeup_dev_required)) shouldsleep = 0; /* We have a command to send */ - else if (__kfifo_len(&priv->event_fifo)) + else if (kfifo_len(&priv->event_fifo)) shouldsleep = 0; /* We have an event to process */ else shouldsleep = 1; /* No command */ @@ -511,9 +511,9 @@ static int lbs_thread(void *data) /* Process hardware events, e.g. card removed, link lost */ spin_lock_irq(&priv->driver_lock); - while (__kfifo_len(&priv->event_fifo)) { + while (kfifo_len(&priv->event_fifo)) { u32 event; - __kfifo_get(&priv->event_fifo, (unsigned char *) &event, + kfifo_get(&priv->event_fifo, (unsigned char *) &event, sizeof(event)); spin_unlock_irq(&priv->driver_lock); lbs_process_event(priv, event); @@ -1175,7 +1175,7 @@ void lbs_queue_event(struct lbs_private *priv, u32 event) if (priv->psstate == PS_STATE_SLEEP) priv->psstate = PS_STATE_AWAKE; - __kfifo_put(&priv->event_fifo, (unsigned char *) &event, sizeof(u32)); + kfifo_put(&priv->event_fifo, (unsigned char *) &event, sizeof(u32)); wake_up_interruptible(&priv->waitq); diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index 1538a0a..36e5dc6 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c @@ -2107,7 +2107,7 @@ static int sonypi_misc_open(struct inode *inode, struct file *file) spin_lock_irqsave(&sonypi_compat.fifo_lock, flags); if (atomic_inc_return(&sonypi_compat.open_count) == 1) - __kfifo_reset(&sonypi_compat.fifo); + kfifo_reset(&sonypi_compat.fifo); spin_unlock_irqrestore(&sonypi_compat.fifo_lock, flags); diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 1bccbc1..5f0c46f 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -517,7 +517,7 @@ static void iscsi_free_task(struct iscsi_task *task) if (conn->login_task == task) return; - __kfifo_put(&session->cmdpool.queue, (void*)&task, sizeof(void*)); + kfifo_put(&session->cmdpool.queue, (void*)&task, sizeof(void*)); if (sc) { task->sc = NULL; @@ -737,7 +737,7 @@ __iscsi_conn_send_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, BUG_ON(conn->c_stage == ISCSI_CONN_INITIAL_STAGE); BUG_ON(conn->c_stage == ISCSI_CONN_STOPPED); - if (!__kfifo_get(&session->cmdpool.queue, + if (!kfifo_get(&session->cmdpool.queue, (void*)&task, sizeof(void*))) return NULL; } @@ -1567,7 +1567,7 @@ static inline struct iscsi_task *iscsi_alloc_task(struct iscsi_conn *conn, { struct iscsi_task *task; - if (!__kfifo_get(&conn->session->cmdpool.queue, + if (!kfifo_get(&conn->session->cmdpool.queue, (void *) &task, sizeof(void *))) return NULL; @@ -2469,7 +2469,7 @@ iscsi_pool_init(struct iscsi_pool *q, int max, void ***items, int item_size) q->max = i; goto enomem; } - __kfifo_put(&q->queue, (void*)&q->pool[i], sizeof(void*)); + kfifo_put(&q->queue, (void*)&q->pool[i], sizeof(void*)); } if (items) { @@ -2819,7 +2819,7 @@ iscsi_conn_setup(struct iscsi_cls_session *cls_session, int dd_size, /* allocate login_task used for the login/text sequences */ spin_lock_bh(&session->lock); - if (!__kfifo_get(&session->cmdpool.queue, + if (!kfifo_get(&session->cmdpool.queue, (void*)&conn->login_task, sizeof(void*))) { spin_unlock_bh(&session->lock); @@ -2839,7 +2839,7 @@ iscsi_conn_setup(struct iscsi_cls_session *cls_session, int dd_size, return cls_conn; login_task_data_alloc_fail: - __kfifo_put(&session->cmdpool.queue, (void*)&conn->login_task, + kfifo_put(&session->cmdpool.queue, (void*)&conn->login_task, sizeof(void*)); login_task_alloc_fail: iscsi_destroy_conn(cls_conn); @@ -2902,7 +2902,7 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn) free_pages((unsigned long) conn->data, get_order(ISCSI_DEF_MAX_RECV_SEG_LEN)); kfree(conn->persistent_address); - __kfifo_put(&session->cmdpool.queue, (void*)&conn->login_task, + kfifo_put(&session->cmdpool.queue, (void*)&conn->login_task, sizeof(void*)); if (session->leadconn == conn) session->leadconn = NULL; diff --git a/drivers/scsi/libiscsi_tcp.c b/drivers/scsi/libiscsi_tcp.c index 41643c8..c0be926 100644 --- a/drivers/scsi/libiscsi_tcp.c +++ b/drivers/scsi/libiscsi_tcp.c @@ -445,15 +445,15 @@ void iscsi_tcp_cleanup_task(struct iscsi_task *task) return; /* flush task's r2t queues */ - while (__kfifo_get(&tcp_task->r2tqueue, (void*)&r2t, sizeof(void*))) { - __kfifo_put(&tcp_task->r2tpool.queue, (void*)&r2t, + while (kfifo_get(&tcp_task->r2tqueue, (void*)&r2t, sizeof(void*))) { + kfifo_put(&tcp_task->r2tpool.queue, (void*)&r2t, sizeof(void*)); ISCSI_DBG_TCP(task->conn, "pending r2t dropped\n"); } r2t = tcp_task->r2t; if (r2t != NULL) { - __kfifo_put(&tcp_task->r2tpool.queue, (void*)&r2t, + kfifo_put(&tcp_task->r2tpool.queue, (void*)&r2t, sizeof(void*)); tcp_task->r2t = NULL; } @@ -541,7 +541,7 @@ static int iscsi_tcp_r2t_rsp(struct iscsi_conn *conn, struct iscsi_task *task) return 0; } - rc = __kfifo_get(&tcp_task->r2tpool.queue, (void*)&r2t, sizeof(void*)); + rc = kfifo_get(&tcp_task->r2tpool.queue, (void*)&r2t, sizeof(void*)); if (!rc) { iscsi_conn_printk(KERN_ERR, conn, "Could not allocate R2T. " "Target has sent more R2Ts than it " @@ -554,7 +554,7 @@ static int iscsi_tcp_r2t_rsp(struct iscsi_conn *conn, struct iscsi_task *task) if (r2t->data_length == 0) { iscsi_conn_printk(KERN_ERR, conn, "invalid R2T with zero data len\n"); - __kfifo_put(&tcp_task->r2tpool.queue, (void*)&r2t, + kfifo_put(&tcp_task->r2tpool.queue, (void*)&r2t, sizeof(void*)); return ISCSI_ERR_DATALEN; } @@ -570,7 +570,7 @@ static int iscsi_tcp_r2t_rsp(struct iscsi_conn *conn, struct iscsi_task *task) "invalid R2T with data len %u at offset %u " "and total length %d\n", r2t->data_length, r2t->data_offset, scsi_out(task->sc)->length); - __kfifo_put(&tcp_task->r2tpool.queue, (void*)&r2t, + kfifo_put(&tcp_task->r2tpool.queue, (void*)&r2t, sizeof(void*)); return ISCSI_ERR_DATALEN; } @@ -580,7 +580,7 @@ static int iscsi_tcp_r2t_rsp(struct iscsi_conn *conn, struct iscsi_task *task) r2t->sent = 0; tcp_task->exp_datasn = r2tsn + 1; - __kfifo_put(&tcp_task->r2tqueue, (void*)&r2t, sizeof(void*)); + kfifo_put(&tcp_task->r2tqueue, (void*)&r2t, sizeof(void*)); conn->r2t_pdus_cnt++; iscsi_requeue_task(task); @@ -951,7 +951,7 @@ int iscsi_tcp_task_init(struct iscsi_task *task) return conn->session->tt->init_pdu(task, 0, task->data_count); } - BUG_ON(__kfifo_len(&tcp_task->r2tqueue)); + BUG_ON(kfifo_len(&tcp_task->r2tqueue)); tcp_task->exp_datasn = 0; /* Prepare PDU, optionally w/ immediate data */ @@ -982,7 +982,7 @@ static struct iscsi_r2t_info *iscsi_tcp_get_curr_r2t(struct iscsi_task *task) if (r2t->data_length <= r2t->sent) { ISCSI_DBG_TCP(task->conn, " done with r2t %p\n", r2t); - __kfifo_put(&tcp_task->r2tpool.queue, + kfifo_put(&tcp_task->r2tpool.queue, (void *)&tcp_task->r2t, sizeof(void *)); tcp_task->r2t = r2t = NULL; @@ -990,7 +990,7 @@ static struct iscsi_r2t_info *iscsi_tcp_get_curr_r2t(struct iscsi_task *task) } if (r2t == NULL) { - __kfifo_get(&tcp_task->r2tqueue, + kfifo_get(&tcp_task->r2tqueue, (void *)&tcp_task->r2t, sizeof(void *)); r2t = tcp_task->r2t; } diff --git a/drivers/scsi/libsrp.c b/drivers/scsi/libsrp.c index db1b41c..975e448 100644 --- a/drivers/scsi/libsrp.c +++ b/drivers/scsi/libsrp.c @@ -61,7 +61,7 @@ static int srp_iu_pool_alloc(struct srp_queue *q, size_t max, kfifo_init(&q->queue, (void *) q->pool, max * sizeof(void *)); for (i = 0, iue = q->items; i < max; i++) { - __kfifo_put(&q->queue, (void *) &iue, sizeof(void *)); + kfifo_put(&q->queue, (void *) &iue, sizeof(void *)); iue->sbuf = ring[i]; iue++; } diff --git a/drivers/usb/host/fhci.h b/drivers/usb/host/fhci.h index a76da20..96aa787 100644 --- a/drivers/usb/host/fhci.h +++ b/drivers/usb/host/fhci.h @@ -505,19 +505,19 @@ static inline void cq_delete(struct kfifo *kfifo) static inline unsigned int cq_howmany(struct kfifo *kfifo) { - return __kfifo_len(kfifo) / sizeof(void *); + return kfifo_len(kfifo) / sizeof(void *); } static inline int cq_put(struct kfifo *kfifo, void *p) { - return __kfifo_put(kfifo, (void *)&p, sizeof(p)); + return kfifo_put(kfifo, (void *)&p, sizeof(p)); } static inline void *cq_get(struct kfifo *kfifo) { void *p = NULL; - __kfifo_get(kfifo, (void *)&p, sizeof(p)); + kfifo_get(kfifo, (void *)&p, sizeof(p)); return p; } diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 61eef18..d0a2e46 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -276,7 +276,7 @@ static int usb_serial_generic_write_start(struct usb_serial_port *port) if (port->write_urb_busy) start_io = false; else { - start_io = (__kfifo_len(port->write_fifo) != 0); + start_io = (kfifo_len(port->write_fifo) != 0); port->write_urb_busy = start_io; } spin_unlock_irqrestore(&port->lock, flags); @@ -370,7 +370,7 @@ int usb_serial_generic_write_room(struct tty_struct *tty) (serial->type->max_in_flight_urbs - port->urbs_in_flight); } else if (serial->num_bulk_out) - room = port->write_fifo->size - __kfifo_len(port->write_fifo); + room = port->write_fifo->size - kfifo_len(port->write_fifo); spin_unlock_irqrestore(&port->lock, flags); dbg("%s - returns %d", __func__, room); diff --git a/include/linux/kfifo.h b/include/linux/kfifo.h index e0f5c9d..a893acd 100644 --- a/include/linux/kfifo.h +++ b/include/linux/kfifo.h @@ -37,34 +37,25 @@ extern void kfifo_init(struct kfifo *fifo, unsigned char *buffer, extern __must_check int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask); extern void kfifo_free(struct kfifo *fifo); -extern unsigned int __kfifo_put(struct kfifo *fifo, +extern unsigned int kfifo_put(struct kfifo *fifo, const unsigned char *buffer, unsigned int len); -extern unsigned int __kfifo_get(struct kfifo *fifo, +extern unsigned int kfifo_get(struct kfifo *fifo, unsigned char *buffer, unsigned int len); /** - * __kfifo_reset - removes the entire FIFO contents, no locking version - * @fifo: the fifo to be emptied. - */ -static inline void __kfifo_reset(struct kfifo *fifo) -{ - fifo->in = fifo->out = 0; -} - -/** * kfifo_reset - removes the entire FIFO contents * @fifo: the fifo to be emptied. */ static inline void kfifo_reset(struct kfifo *fifo) { - __kfifo_reset(fifo); + fifo->in = fifo->out = 0; } /** - * __kfifo_len - returns the number of bytes available in the FIFO + * kfifo_len - returns the number of used bytes in the FIFO * @fifo: the fifo to be used. */ -static inline unsigned int __kfifo_len(struct kfifo *fifo) +static inline unsigned int kfifo_len(struct kfifo *fifo) { register unsigned int out; @@ -92,7 +83,7 @@ static inline __must_check unsigned int kfifo_put_locked(struct kfifo *fifo, spin_lock_irqsave(lock, flags); - ret = __kfifo_put(fifo, from, n); + ret = kfifo_put(fifo, from, n); spin_unlock_irqrestore(lock, flags); @@ -117,7 +108,7 @@ static inline __must_check unsigned int kfifo_get_locked(struct kfifo *fifo, spin_lock_irqsave(lock, flags); - ret = __kfifo_get(fifo, to, n); + ret = kfifo_get(fifo, to, n); /* * optimization: if the FIFO is empty, set the indices to 0 @@ -131,13 +122,4 @@ static inline __must_check unsigned int kfifo_get_locked(struct kfifo *fifo, return ret; } -/** - * kfifo_len - returns the number of bytes available in the FIFO - * @fifo: the fifo to be used. - */ -static inline unsigned int kfifo_len(struct kfifo *fifo) -{ - return __kfifo_len(fifo); -} - #endif diff --git a/kernel/kfifo.c b/kernel/kfifo.c index 4950bdb..963ffde 100644 --- a/kernel/kfifo.c +++ b/kernel/kfifo.c @@ -100,7 +100,7 @@ void kfifo_free(struct kfifo *fifo) EXPORT_SYMBOL(kfifo_free); /** - * __kfifo_put - puts some data into the FIFO, no locking version + * kfifo_put - puts some data into the FIFO, no locking version * @fifo: the fifo to be used. * @buffer: the data to be added. * @len: the length of the data to be added. @@ -112,7 +112,7 @@ EXPORT_SYMBOL(kfifo_free); * Note that with only one concurrent reader and one concurrent * writer, you don't need extra locking to use these functions. */ -unsigned int __kfifo_put(struct kfifo *fifo, +unsigned int kfifo_put(struct kfifo *fifo, const unsigned char *buffer, unsigned int len) { unsigned int l; @@ -144,10 +144,10 @@ unsigned int __kfifo_put(struct kfifo *fifo, return len; } -EXPORT_SYMBOL(__kfifo_put); +EXPORT_SYMBOL(kfifo_put); /** - * __kfifo_get - gets some data from the FIFO, no locking version + * kfifo_get - gets some data from the FIFO, no locking version * @fifo: the fifo to be used. * @buffer: where the data must be copied. * @len: the size of the destination buffer. @@ -158,7 +158,7 @@ EXPORT_SYMBOL(__kfifo_put); * Note that with only one concurrent reader and one concurrent * writer, you don't need extra locking to use these functions. */ -unsigned int __kfifo_get(struct kfifo *fifo, +unsigned int kfifo_get(struct kfifo *fifo, unsigned char *buffer, unsigned int len) { unsigned int l; @@ -190,4 +190,4 @@ unsigned int __kfifo_get(struct kfifo *fifo, return len; } -EXPORT_SYMBOL(__kfifo_get); +EXPORT_SYMBOL(kfifo_get); diff --git a/net/dccp/probe.c b/net/dccp/probe.c index c6b5035..9ef3684 100644 --- a/net/dccp/probe.c +++ b/net/dccp/probe.c @@ -131,7 +131,7 @@ static ssize_t dccpprobe_read(struct file *file, char __user *buf, return -ENOMEM; error = wait_event_interruptible(dccpw.wait, - __kfifo_len(&dccpw.fifo) != 0); + kfifo_len(&dccpw.fifo) != 0); if (error) goto out_free; -- cgit v0.10.2 From 7acd72eb85f1c7a15e8b5eb554994949241737f1 Mon Sep 17 00:00:00 2001 From: Stefani Seibold Date: Mon, 21 Dec 2009 14:37:28 -0800 Subject: kfifo: rename kfifo_put... into kfifo_in... and kfifo_get... into kfifo_out... rename kfifo_put... into kfifo_in... to prevent miss use of old non in kernel-tree drivers ditto for kfifo_get... -> kfifo_out... Improve the prototypes of kfifo_in and kfifo_out to make the kerneldoc annotations more readable. Add mini "howto porting to the new API" in kfifo.h Signed-off-by: Stefani Seibold Acked-by: Greg Kroah-Hartman Acked-by: Mauro Carvalho Chehab Acked-by: Andi Kleen Acked-by: Arnd Bergmann Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/char/nozomi.c b/drivers/char/nozomi.c index 61f5bfe..9ef2434 100644 --- a/drivers/char/nozomi.c +++ b/drivers/char/nozomi.c @@ -798,7 +798,7 @@ static int send_data(enum port_type index, struct nozomi *dc) struct tty_struct *tty = tty_port_tty_get(&port->port); /* Get data from tty and place in buf for now */ - size = kfifo_get(&port->fifo_ul, dc->send_buf, + size = kfifo_out(&port->fifo_ul, dc->send_buf, ul_size < SEND_BUF_MAX ? ul_size : SEND_BUF_MAX); if (size == 0) { @@ -1672,7 +1672,7 @@ static int ntty_write(struct tty_struct *tty, const unsigned char *buffer, goto exit; } - rval = kfifo_put(&port->fifo_ul, (unsigned char *)buffer, count); + rval = kfifo_in(&port->fifo_ul, (unsigned char *)buffer, count); /* notify card */ if (unlikely(dc == NULL)) { diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index dbcb3bd..0798754 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c @@ -777,7 +777,7 @@ static void input_keyrelease(struct work_struct *work) { struct sonypi_keypress kp; - while (kfifo_get_locked(&sonypi_device.input_fifo, (unsigned char *)&kp, + while (kfifo_out_locked(&sonypi_device.input_fifo, (unsigned char *)&kp, sizeof(kp), &sonypi_device.input_fifo_lock) == sizeof(kp)) { msleep(10); @@ -828,7 +828,7 @@ static void sonypi_report_input_event(u8 event) if (kp.dev) { input_report_key(kp.dev, kp.key, 1); input_sync(kp.dev); - kfifo_put_locked(&sonypi_device.input_fifo, + kfifo_in_locked(&sonypi_device.input_fifo, (unsigned char *)&kp, sizeof(kp), &sonypi_device.input_fifo_lock); schedule_work(&sonypi_device.input_work); @@ -882,7 +882,7 @@ found: acpi_bus_generate_proc_event(sonypi_acpi_device, 1, event); #endif - kfifo_put_locked(&sonypi_device.fifo, (unsigned char *)&event, + kfifo_in_locked(&sonypi_device.fifo, (unsigned char *)&event, sizeof(event), &sonypi_device.fifo_lock); kill_fasync(&sonypi_device.fifo_async, SIGIO, POLL_IN); wake_up_interruptible(&sonypi_device.fifo_proc_list); @@ -932,7 +932,7 @@ static ssize_t sonypi_misc_read(struct file *file, char __user *buf, return ret; while (ret < count && - (kfifo_get_locked(&sonypi_device.fifo, &c, sizeof(c), + (kfifo_out_locked(&sonypi_device.fifo, &c, sizeof(c), &sonypi_device.fifo_lock) == sizeof(c))) { if (put_user(c, buf++)) return -EFAULT; diff --git a/drivers/infiniband/hw/cxgb3/cxio_resource.c b/drivers/infiniband/hw/cxgb3/cxio_resource.c index d7d18fb0..dcbf260 100644 --- a/drivers/infiniband/hw/cxgb3/cxio_resource.c +++ b/drivers/infiniband/hw/cxgb3/cxio_resource.c @@ -59,7 +59,7 @@ static int __cxio_init_resource_fifo(struct kfifo *fifo, return -ENOMEM; for (i = 0; i < skip_low + skip_high; i++) - kfifo_put(fifo, (unsigned char *) &entry, sizeof(u32)); + kfifo_in(fifo, (unsigned char *) &entry, sizeof(u32)); if (random) { j = 0; random_bytes = random32(); @@ -71,22 +71,22 @@ static int __cxio_init_resource_fifo(struct kfifo *fifo, random_bytes = random32(); } idx = (random_bytes >> (j * 2)) & 0xF; - kfifo_put(fifo, + kfifo_in(fifo, (unsigned char *) &rarray[idx], sizeof(u32)); rarray[idx] = i; j++; } for (i = 0; i < RANDOM_SIZE; i++) - kfifo_put(fifo, + kfifo_in(fifo, (unsigned char *) &rarray[i], sizeof(u32)); } else for (i = skip_low; i < nr - skip_high; i++) - kfifo_put(fifo, (unsigned char *) &i, sizeof(u32)); + kfifo_in(fifo, (unsigned char *) &i, sizeof(u32)); for (i = 0; i < skip_low + skip_high; i++) - kfifo_get_locked(fifo, (unsigned char *) &entry, + kfifo_out_locked(fifo, (unsigned char *) &entry, sizeof(u32), fifo_lock); return 0; } @@ -119,7 +119,7 @@ static int cxio_init_qpid_fifo(struct cxio_rdev *rdev_p) for (i = 16; i < T3_MAX_NUM_QP; i++) if (!(i & rdev_p->qpmask)) - kfifo_put(&rdev_p->rscp->qpid_fifo, + kfifo_in(&rdev_p->rscp->qpid_fifo, (unsigned char *) &i, sizeof(u32)); return 0; } @@ -180,7 +180,7 @@ tpt_err: static u32 cxio_hal_get_resource(struct kfifo *fifo, spinlock_t * lock) { u32 entry; - if (kfifo_get_locked(fifo, (unsigned char *) &entry, sizeof(u32), lock)) + if (kfifo_out_locked(fifo, (unsigned char *) &entry, sizeof(u32), lock)) return entry; else return 0; /* fifo emptry */ @@ -190,7 +190,7 @@ static void cxio_hal_put_resource(struct kfifo *fifo, spinlock_t * lock, u32 entry) { BUG_ON( - kfifo_put_locked(fifo, (unsigned char *) &entry, sizeof(u32), lock) + kfifo_in_locked(fifo, (unsigned char *) &entry, sizeof(u32), lock) == 0); } diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c index 38bcedf..884a569 100644 --- a/drivers/media/video/meye.c +++ b/drivers/media/video/meye.c @@ -800,7 +800,7 @@ again: return IRQ_HANDLED; if (meye.mchip_mode == MCHIP_HIC_MODE_CONT_OUT) { - if (kfifo_get_locked(&meye.grabq, (unsigned char *)&reqnr, + if (kfifo_out_locked(&meye.grabq, (unsigned char *)&reqnr, sizeof(int), &meye.grabq_lock) != sizeof(int)) { mchip_free_frame(); return IRQ_HANDLED; @@ -811,7 +811,7 @@ again: meye.grab_buffer[reqnr].state = MEYE_BUF_DONE; do_gettimeofday(&meye.grab_buffer[reqnr].timestamp); meye.grab_buffer[reqnr].sequence = sequence++; - kfifo_put_locked(&meye.doneq, (unsigned char *)&reqnr, + kfifo_in_locked(&meye.doneq, (unsigned char *)&reqnr, sizeof(int), &meye.doneq_lock); wake_up_interruptible(&meye.proc_list); } else { @@ -821,7 +821,7 @@ again: mchip_free_frame(); goto again; } - if (kfifo_get_locked(&meye.grabq, (unsigned char *)&reqnr, + if (kfifo_out_locked(&meye.grabq, (unsigned char *)&reqnr, sizeof(int), &meye.grabq_lock) != sizeof(int)) { mchip_free_frame(); goto again; @@ -832,7 +832,7 @@ again: meye.grab_buffer[reqnr].state = MEYE_BUF_DONE; do_gettimeofday(&meye.grab_buffer[reqnr].timestamp); meye.grab_buffer[reqnr].sequence = sequence++; - kfifo_put_locked(&meye.doneq, (unsigned char *)&reqnr, + kfifo_in_locked(&meye.doneq, (unsigned char *)&reqnr, sizeof(int), &meye.doneq_lock); wake_up_interruptible(&meye.proc_list); } @@ -935,7 +935,7 @@ static int meyeioc_qbuf_capt(int *nb) mchip_cont_compression_start(); meye.grab_buffer[*nb].state = MEYE_BUF_USING; - kfifo_put_locked(&meye.grabq, (unsigned char *)nb, sizeof(int), + kfifo_in_locked(&meye.grabq, (unsigned char *)nb, sizeof(int), &meye.grabq_lock); mutex_unlock(&meye.lock); @@ -968,7 +968,7 @@ static int meyeioc_sync(struct file *file, void *fh, int *i) /* fall through */ case MEYE_BUF_DONE: meye.grab_buffer[*i].state = MEYE_BUF_UNUSED; - kfifo_get_locked(&meye.doneq, (unsigned char *)&unused, + kfifo_out_locked(&meye.doneq, (unsigned char *)&unused, sizeof(int), &meye.doneq_lock); } *i = meye.grab_buffer[*i].size; @@ -1456,7 +1456,7 @@ static int vidioc_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf) buf->flags |= V4L2_BUF_FLAG_QUEUED; buf->flags &= ~V4L2_BUF_FLAG_DONE; meye.grab_buffer[buf->index].state = MEYE_BUF_USING; - kfifo_put_locked(&meye.grabq, (unsigned char *)&buf->index, + kfifo_in_locked(&meye.grabq, (unsigned char *)&buf->index, sizeof(int), &meye.grabq_lock); mutex_unlock(&meye.lock); @@ -1483,7 +1483,7 @@ static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf) return -EINTR; } - if (!kfifo_get_locked(&meye.doneq, (unsigned char *)&reqnr, + if (!kfifo_out_locked(&meye.doneq, (unsigned char *)&reqnr, sizeof(int), &meye.doneq_lock)) { mutex_unlock(&meye.lock); return -EBUSY; diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index 0622104..2bcfa74 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c @@ -513,7 +513,8 @@ static int lbs_thread(void *data) spin_lock_irq(&priv->driver_lock); while (kfifo_len(&priv->event_fifo)) { u32 event; - kfifo_get(&priv->event_fifo, (unsigned char *) &event, + + kfifo_out(&priv->event_fifo, (unsigned char *) &event, sizeof(event)); spin_unlock_irq(&priv->driver_lock); lbs_process_event(priv, event); @@ -1175,7 +1176,7 @@ void lbs_queue_event(struct lbs_private *priv, u32 event) if (priv->psstate == PS_STATE_SLEEP) priv->psstate = PS_STATE_AWAKE; - kfifo_put(&priv->event_fifo, (unsigned char *) &event, sizeof(u32)); + kfifo_in(&priv->event_fifo, (unsigned char *) &event, sizeof(u32)); wake_up_interruptible(&priv->waitq); diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c index 13dc7be..b66029b 100644 --- a/drivers/platform/x86/fujitsu-laptop.c +++ b/drivers/platform/x86/fujitsu-laptop.c @@ -1006,7 +1006,7 @@ static void acpi_fujitsu_hotkey_notify(struct acpi_device *device, u32 event) vdbg_printk(FUJLAPTOP_DBG_TRACE, "Push keycode into ringbuffer [%d]\n", keycode); - status = kfifo_put_locked(&fujitsu_hotkey->fifo, + status = kfifo_in_locked(&fujitsu_hotkey->fifo, (unsigned char *)&keycode, sizeof(keycode), &fujitsu_hotkey->fifo_lock); @@ -1020,7 +1020,7 @@ static void acpi_fujitsu_hotkey_notify(struct acpi_device *device, u32 event) } } else if (keycode == 0) { while ((status = - kfifo_get_locked( + kfifo_out_locked( &fujitsu_hotkey->fifo, (unsigned char *) &keycode_r, sizeof(keycode_r), diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index 36e5dc6..2896ca4 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c @@ -300,7 +300,7 @@ static void do_sony_laptop_release_key(struct work_struct *work) { struct sony_laptop_keypress kp; - while (kfifo_get_locked(&sony_laptop_input.fifo, (unsigned char *)&kp, + while (kfifo_out_locked(&sony_laptop_input.fifo, (unsigned char *)&kp, sizeof(kp), &sony_laptop_input.fifo_lock) == sizeof(kp)) { msleep(10); @@ -363,7 +363,7 @@ static void sony_laptop_report_input_event(u8 event) /* we emit the scancode so we can always remap the key */ input_event(kp.dev, EV_MSC, MSC_SCAN, event); input_sync(kp.dev); - kfifo_put_locked(&sony_laptop_input.fifo, + kfifo_in_locked(&sony_laptop_input.fifo, (unsigned char *)&kp, sizeof(kp), &sony_laptop_input.fifo_lock); @@ -2130,7 +2130,7 @@ static ssize_t sonypi_misc_read(struct file *file, char __user *buf, return ret; while (ret < count && - (kfifo_get_locked(&sonypi_compat.fifo, &c, sizeof(c), + (kfifo_out_locked(&sonypi_compat.fifo, &c, sizeof(c), &sonypi_compat.fifo_lock) == sizeof(c))) { if (put_user(c, buf++)) return -EFAULT; @@ -2310,7 +2310,7 @@ static struct miscdevice sonypi_misc_device = { static void sonypi_compat_report_event(u8 event) { - kfifo_put_locked(&sonypi_compat.fifo, (unsigned char *)&event, + kfifo_in_locked(&sonypi_compat.fifo, (unsigned char *)&event, sizeof(event), &sonypi_compat.fifo_lock); kill_fasync(&sonypi_compat.fifo_async, SIGIO, POLL_IN); wake_up_interruptible(&sonypi_compat.fifo_proc_list); diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 5f0c46f..c28a712 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -517,7 +517,7 @@ static void iscsi_free_task(struct iscsi_task *task) if (conn->login_task == task) return; - kfifo_put(&session->cmdpool.queue, (void*)&task, sizeof(void*)); + kfifo_in(&session->cmdpool.queue, (void*)&task, sizeof(void*)); if (sc) { task->sc = NULL; @@ -737,7 +737,7 @@ __iscsi_conn_send_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, BUG_ON(conn->c_stage == ISCSI_CONN_INITIAL_STAGE); BUG_ON(conn->c_stage == ISCSI_CONN_STOPPED); - if (!kfifo_get(&session->cmdpool.queue, + if (!kfifo_out(&session->cmdpool.queue, (void*)&task, sizeof(void*))) return NULL; } @@ -1567,7 +1567,7 @@ static inline struct iscsi_task *iscsi_alloc_task(struct iscsi_conn *conn, { struct iscsi_task *task; - if (!kfifo_get(&conn->session->cmdpool.queue, + if (!kfifo_out(&conn->session->cmdpool.queue, (void *) &task, sizeof(void *))) return NULL; @@ -2469,7 +2469,7 @@ iscsi_pool_init(struct iscsi_pool *q, int max, void ***items, int item_size) q->max = i; goto enomem; } - kfifo_put(&q->queue, (void*)&q->pool[i], sizeof(void*)); + kfifo_in(&q->queue, (void*)&q->pool[i], sizeof(void*)); } if (items) { @@ -2819,7 +2819,7 @@ iscsi_conn_setup(struct iscsi_cls_session *cls_session, int dd_size, /* allocate login_task used for the login/text sequences */ spin_lock_bh(&session->lock); - if (!kfifo_get(&session->cmdpool.queue, + if (!kfifo_out(&session->cmdpool.queue, (void*)&conn->login_task, sizeof(void*))) { spin_unlock_bh(&session->lock); @@ -2839,7 +2839,7 @@ iscsi_conn_setup(struct iscsi_cls_session *cls_session, int dd_size, return cls_conn; login_task_data_alloc_fail: - kfifo_put(&session->cmdpool.queue, (void*)&conn->login_task, + kfifo_in(&session->cmdpool.queue, (void*)&conn->login_task, sizeof(void*)); login_task_alloc_fail: iscsi_destroy_conn(cls_conn); @@ -2902,7 +2902,7 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn) free_pages((unsigned long) conn->data, get_order(ISCSI_DEF_MAX_RECV_SEG_LEN)); kfree(conn->persistent_address); - kfifo_put(&session->cmdpool.queue, (void*)&conn->login_task, + kfifo_in(&session->cmdpool.queue, (void*)&conn->login_task, sizeof(void*)); if (session->leadconn == conn) session->leadconn = NULL; diff --git a/drivers/scsi/libiscsi_tcp.c b/drivers/scsi/libiscsi_tcp.c index c0be926..d51ffec 100644 --- a/drivers/scsi/libiscsi_tcp.c +++ b/drivers/scsi/libiscsi_tcp.c @@ -445,15 +445,15 @@ void iscsi_tcp_cleanup_task(struct iscsi_task *task) return; /* flush task's r2t queues */ - while (kfifo_get(&tcp_task->r2tqueue, (void*)&r2t, sizeof(void*))) { - kfifo_put(&tcp_task->r2tpool.queue, (void*)&r2t, + while (kfifo_out(&tcp_task->r2tqueue, (void*)&r2t, sizeof(void*))) { + kfifo_in(&tcp_task->r2tpool.queue, (void*)&r2t, sizeof(void*)); ISCSI_DBG_TCP(task->conn, "pending r2t dropped\n"); } r2t = tcp_task->r2t; if (r2t != NULL) { - kfifo_put(&tcp_task->r2tpool.queue, (void*)&r2t, + kfifo_in(&tcp_task->r2tpool.queue, (void*)&r2t, sizeof(void*)); tcp_task->r2t = NULL; } @@ -541,7 +541,7 @@ static int iscsi_tcp_r2t_rsp(struct iscsi_conn *conn, struct iscsi_task *task) return 0; } - rc = kfifo_get(&tcp_task->r2tpool.queue, (void*)&r2t, sizeof(void*)); + rc = kfifo_out(&tcp_task->r2tpool.queue, (void*)&r2t, sizeof(void*)); if (!rc) { iscsi_conn_printk(KERN_ERR, conn, "Could not allocate R2T. " "Target has sent more R2Ts than it " @@ -554,7 +554,7 @@ static int iscsi_tcp_r2t_rsp(struct iscsi_conn *conn, struct iscsi_task *task) if (r2t->data_length == 0) { iscsi_conn_printk(KERN_ERR, conn, "invalid R2T with zero data len\n"); - kfifo_put(&tcp_task->r2tpool.queue, (void*)&r2t, + kfifo_in(&tcp_task->r2tpool.queue, (void*)&r2t, sizeof(void*)); return ISCSI_ERR_DATALEN; } @@ -570,7 +570,7 @@ static int iscsi_tcp_r2t_rsp(struct iscsi_conn *conn, struct iscsi_task *task) "invalid R2T with data len %u at offset %u " "and total length %d\n", r2t->data_length, r2t->data_offset, scsi_out(task->sc)->length); - kfifo_put(&tcp_task->r2tpool.queue, (void*)&r2t, + kfifo_in(&tcp_task->r2tpool.queue, (void*)&r2t, sizeof(void*)); return ISCSI_ERR_DATALEN; } @@ -580,7 +580,7 @@ static int iscsi_tcp_r2t_rsp(struct iscsi_conn *conn, struct iscsi_task *task) r2t->sent = 0; tcp_task->exp_datasn = r2tsn + 1; - kfifo_put(&tcp_task->r2tqueue, (void*)&r2t, sizeof(void*)); + kfifo_in(&tcp_task->r2tqueue, (void*)&r2t, sizeof(void*)); conn->r2t_pdus_cnt++; iscsi_requeue_task(task); @@ -982,7 +982,7 @@ static struct iscsi_r2t_info *iscsi_tcp_get_curr_r2t(struct iscsi_task *task) if (r2t->data_length <= r2t->sent) { ISCSI_DBG_TCP(task->conn, " done with r2t %p\n", r2t); - kfifo_put(&tcp_task->r2tpool.queue, + kfifo_in(&tcp_task->r2tpool.queue, (void *)&tcp_task->r2t, sizeof(void *)); tcp_task->r2t = r2t = NULL; @@ -990,7 +990,7 @@ static struct iscsi_r2t_info *iscsi_tcp_get_curr_r2t(struct iscsi_task *task) } if (r2t == NULL) { - kfifo_get(&tcp_task->r2tqueue, + kfifo_out(&tcp_task->r2tqueue, (void *)&tcp_task->r2t, sizeof(void *)); r2t = tcp_task->r2t; } diff --git a/drivers/scsi/libsrp.c b/drivers/scsi/libsrp.c index 975e448..8424b86 100644 --- a/drivers/scsi/libsrp.c +++ b/drivers/scsi/libsrp.c @@ -61,7 +61,7 @@ static int srp_iu_pool_alloc(struct srp_queue *q, size_t max, kfifo_init(&q->queue, (void *) q->pool, max * sizeof(void *)); for (i = 0, iue = q->items; i < max; i++) { - kfifo_put(&q->queue, (void *) &iue, sizeof(void *)); + kfifo_in(&q->queue, (void *) &iue, sizeof(void *)); iue->sbuf = ring[i]; iue++; } @@ -163,7 +163,7 @@ struct iu_entry *srp_iu_get(struct srp_target *target) { struct iu_entry *iue = NULL; - kfifo_get_locked(&target->iu_queue.queue, (void *) &iue, + kfifo_out_locked(&target->iu_queue.queue, (void *) &iue, sizeof(void *), &target->iu_queue.lock); if (!iue) return iue; @@ -176,7 +176,7 @@ EXPORT_SYMBOL_GPL(srp_iu_get); void srp_iu_put(struct iu_entry *iue) { - kfifo_put_locked(&iue->target->iu_queue.queue, (void *) &iue, + kfifo_in_locked(&iue->target->iu_queue.queue, (void *) &iue, sizeof(void *), &iue->target->iu_queue.lock); } EXPORT_SYMBOL_GPL(srp_iu_put); diff --git a/drivers/usb/host/fhci.h b/drivers/usb/host/fhci.h index 96aa787..72dae1c 100644 --- a/drivers/usb/host/fhci.h +++ b/drivers/usb/host/fhci.h @@ -510,14 +510,14 @@ static inline unsigned int cq_howmany(struct kfifo *kfifo) static inline int cq_put(struct kfifo *kfifo, void *p) { - return kfifo_put(kfifo, (void *)&p, sizeof(p)); + return kfifo_in(kfifo, (void *)&p, sizeof(p)); } static inline void *cq_get(struct kfifo *kfifo) { void *p = NULL; - kfifo_get(kfifo, (void *)&p, sizeof(p)); + kfifo_out(kfifo, (void *)&p, sizeof(p)); return p; } diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index d0a2e46..b0f1183 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -285,7 +285,7 @@ static int usb_serial_generic_write_start(struct usb_serial_port *port) return 0; data = port->write_urb->transfer_buffer; - count = kfifo_get_locked(port->write_fifo, data, port->bulk_out_size, &port->lock); + count = kfifo_out_locked(port->write_fifo, data, port->bulk_out_size, &port->lock); usb_serial_debug_data(debug, &port->dev, __func__, count, data); /* set up our urb */ @@ -345,7 +345,7 @@ int usb_serial_generic_write(struct tty_struct *tty, return usb_serial_multi_urb_write(tty, port, buf, count); - count = kfifo_put_locked(port->write_fifo, buf, count, &port->lock); + count = kfifo_in_locked(port->write_fifo, buf, count, &port->lock); result = usb_serial_generic_write_start(port); if (result >= 0) diff --git a/include/linux/kfifo.h b/include/linux/kfifo.h index a893acd..1b59c4a 100644 --- a/include/linux/kfifo.h +++ b/include/linux/kfifo.h @@ -19,6 +19,25 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ + +/* + * Howto porting drivers to the new generic fifo API: + * + * - Modify the declaration of the "struct kfifo *" object into a + * in-place "struct kfifo" object + * - Init the in-place object with kfifo_alloc() or kfifo_init() + * Note: The address of the in-place "struct kfifo" object must be + * passed as the first argument to this functions + * - Replace the use of __kfifo_put into kfifo_in and __kfifo_get + * into kfifo_out + * - Replace the use of kfifo_put into kfifo_in_locked and kfifo_get + * into kfifo_out_locked + * Note: the spinlock pointer formerly passed to kfifo_init/kfifo_alloc + * must be passed now to the kfifo_in_locked and kfifo_out_locked + * as the last parameter. + * - All formerly name __kfifo_* functions has been renamed into kfifo_* + */ + #ifndef _LINUX_KFIFO_H #define _LINUX_KFIFO_H @@ -37,10 +56,10 @@ extern void kfifo_init(struct kfifo *fifo, unsigned char *buffer, extern __must_check int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask); extern void kfifo_free(struct kfifo *fifo); -extern unsigned int kfifo_put(struct kfifo *fifo, - const unsigned char *buffer, unsigned int len); -extern unsigned int kfifo_get(struct kfifo *fifo, - unsigned char *buffer, unsigned int len); +extern __must_check unsigned int kfifo_in(struct kfifo *fifo, + const unsigned char *from, unsigned int len); +extern __must_check unsigned int kfifo_out(struct kfifo *fifo, + unsigned char *to, unsigned int len); /** * kfifo_reset - removes the entire FIFO contents @@ -65,7 +84,7 @@ static inline unsigned int kfifo_len(struct kfifo *fifo) } /** - * kfifo_put_locked - puts some data into the FIFO using a spinlock for locking + * kfifo_in_locked - puts some data into the FIFO using a spinlock for locking * @fifo: the fifo to be used. * @from: the data to be added. * @n: the length of the data to be added. @@ -75,7 +94,7 @@ static inline unsigned int kfifo_len(struct kfifo *fifo) * the FIFO depending on the free space, and returns the number of * bytes copied. */ -static inline __must_check unsigned int kfifo_put_locked(struct kfifo *fifo, +static inline __must_check unsigned int kfifo_in_locked(struct kfifo *fifo, const unsigned char *from, unsigned int n, spinlock_t *lock) { unsigned long flags; @@ -83,7 +102,7 @@ static inline __must_check unsigned int kfifo_put_locked(struct kfifo *fifo, spin_lock_irqsave(lock, flags); - ret = kfifo_put(fifo, from, n); + ret = kfifo_in(fifo, from, n); spin_unlock_irqrestore(lock, flags); @@ -91,7 +110,7 @@ static inline __must_check unsigned int kfifo_put_locked(struct kfifo *fifo, } /** - * kfifo_get_locked - gets some data from the FIFO using a spinlock for locking + * kfifo_out_locked - gets some data from the FIFO using a spinlock for locking * @fifo: the fifo to be used. * @to: where the data must be copied. * @n: the size of the destination buffer. @@ -100,7 +119,7 @@ static inline __must_check unsigned int kfifo_put_locked(struct kfifo *fifo, * This function copies at most @len bytes from the FIFO into the * @to buffer and returns the number of copied bytes. */ -static inline __must_check unsigned int kfifo_get_locked(struct kfifo *fifo, +static inline __must_check unsigned int kfifo_out_locked(struct kfifo *fifo, unsigned char *to, unsigned int n, spinlock_t *lock) { unsigned long flags; @@ -108,7 +127,7 @@ static inline __must_check unsigned int kfifo_get_locked(struct kfifo *fifo, spin_lock_irqsave(lock, flags); - ret = kfifo_get(fifo, to, n); + ret = kfifo_out(fifo, to, n); /* * optimization: if the FIFO is empty, set the indices to 0 diff --git a/kernel/kfifo.c b/kernel/kfifo.c index 963ffde..d659442 100644 --- a/kernel/kfifo.c +++ b/kernel/kfifo.c @@ -100,20 +100,20 @@ void kfifo_free(struct kfifo *fifo) EXPORT_SYMBOL(kfifo_free); /** - * kfifo_put - puts some data into the FIFO, no locking version + * kfifo_in - puts some data into the FIFO * @fifo: the fifo to be used. - * @buffer: the data to be added. + * @from: the data to be added. * @len: the length of the data to be added. * - * This function copies at most @len bytes from the @buffer into + * This function copies at most @len bytes from the @from buffer into * the FIFO depending on the free space, and returns the number of * bytes copied. * * Note that with only one concurrent reader and one concurrent * writer, you don't need extra locking to use these functions. */ -unsigned int kfifo_put(struct kfifo *fifo, - const unsigned char *buffer, unsigned int len) +unsigned int kfifo_in(struct kfifo *fifo, + const unsigned char *from, unsigned int len) { unsigned int l; @@ -128,10 +128,10 @@ unsigned int kfifo_put(struct kfifo *fifo, /* first put the data starting from fifo->in to buffer end */ l = min(len, fifo->size - (fifo->in & (fifo->size - 1))); - memcpy(fifo->buffer + (fifo->in & (fifo->size - 1)), buffer, l); + memcpy(fifo->buffer + (fifo->in & (fifo->size - 1)), from, l); /* then put the rest (if any) at the beginning of the buffer */ - memcpy(fifo->buffer, buffer + l, len - l); + memcpy(fifo->buffer, from + l, len - l); /* * Ensure that we add the bytes to the kfifo -before- @@ -144,22 +144,22 @@ unsigned int kfifo_put(struct kfifo *fifo, return len; } -EXPORT_SYMBOL(kfifo_put); +EXPORT_SYMBOL(kfifo_in); /** - * kfifo_get - gets some data from the FIFO, no locking version + * kfifo_out - gets some data from the FIFO * @fifo: the fifo to be used. - * @buffer: where the data must be copied. + * @to: where the data must be copied. * @len: the size of the destination buffer. * * This function copies at most @len bytes from the FIFO into the - * @buffer and returns the number of copied bytes. + * @to buffer and returns the number of copied bytes. * * Note that with only one concurrent reader and one concurrent * writer, you don't need extra locking to use these functions. */ -unsigned int kfifo_get(struct kfifo *fifo, - unsigned char *buffer, unsigned int len) +unsigned int kfifo_out(struct kfifo *fifo, + unsigned char *to, unsigned int len) { unsigned int l; @@ -174,10 +174,10 @@ unsigned int kfifo_get(struct kfifo *fifo, /* first get the data from fifo->out until the end of the buffer */ l = min(len, fifo->size - (fifo->out & (fifo->size - 1))); - memcpy(buffer, fifo->buffer + (fifo->out & (fifo->size - 1)), l); + memcpy(to, fifo->buffer + (fifo->out & (fifo->size - 1)), l); /* then get the rest (if any) from the beginning of the buffer */ - memcpy(buffer + l, fifo->buffer, len - l); + memcpy(to + l, fifo->buffer, len - l); /* * Ensure that we remove the bytes from the kfifo -before- @@ -190,4 +190,4 @@ unsigned int kfifo_get(struct kfifo *fifo, return len; } -EXPORT_SYMBOL(kfifo_get); +EXPORT_SYMBOL(kfifo_out); diff --git a/net/dccp/probe.c b/net/dccp/probe.c index 9ef3684..a1362dc 100644 --- a/net/dccp/probe.c +++ b/net/dccp/probe.c @@ -67,7 +67,7 @@ static void printl(const char *fmt, ...) len += vscnprintf(tbuf+len, sizeof(tbuf)-len, fmt, args); va_end(args); - kfifo_put_locked(&dccpw.fifo, tbuf, len, &dccpw.lock); + kfifo_in_locked(&dccpw.fifo, tbuf, len, &dccpw.lock); wake_up(&dccpw.wait); } @@ -135,7 +135,7 @@ static ssize_t dccpprobe_read(struct file *file, char __user *buf, if (error) goto out_free; - cnt = kfifo_get_locked(&dccpw.fifo, tbuf, len, &dccpw.lock); + cnt = kfifo_out_locked(&dccpw.fifo, tbuf, len, &dccpw.lock); error = copy_to_user(buf, tbuf, cnt) ? -EFAULT : 0; out_free: -- cgit v0.10.2 From 9842c38e917636fa7dc6b88aff17a8f1fd7f0cc0 Mon Sep 17 00:00:00 2001 From: Stefani Seibold Date: Mon, 21 Dec 2009 14:37:29 -0800 Subject: kfifo: fix warn_unused_result Fix the "ignoring return value of '...', declared with attribute warn_unused_result" compiler warning in several users of the new kfifo API. It removes the __must_check attribute from kfifo_in() and kfifo_in_locked() which must not necessary performed. Fix the allocation bug in the nozomi driver file, by moving out the kfifo_alloc from the interrupt handler into the probe function. Fix the kfifo_out() and kfifo_out_locked() users to handle a unexpected end of fifo. Signed-off-by: Stefani Seibold Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/char/nozomi.c b/drivers/char/nozomi.c index 9ef2434..7d73cd4 100644 --- a/drivers/char/nozomi.c +++ b/drivers/char/nozomi.c @@ -685,8 +685,6 @@ static int nozomi_read_config_table(struct nozomi *dc) dump_table(dc); for (i = PORT_MDM; i < MAX_PORT; i++) { - kfifo_alloc(&dc->port[i].fifo_ul, - FIFO_BUFFER_SIZE_UL, GFP_ATOMIC); memset(&dc->port[i].ctrl_dl, 0, sizeof(struct ctrl_dl)); memset(&dc->port[i].ctrl_ul, 0, sizeof(struct ctrl_ul)); } @@ -1433,6 +1431,16 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev, goto err_free_sbuf; } + for (i = PORT_MDM; i < MAX_PORT; i++) { + if (kfifo_alloc(&dc->port[i].fifo_ul, + FIFO_BUFFER_SIZE_UL, GFP_ATOMIC)) { + dev_err(&pdev->dev, + "Could not allocate kfifo buffer\n"); + ret = -ENOMEM; + goto err_free_kfifo; + } + } + spin_lock_init(&dc->spin_mutex); nozomi_setup_private_data(dc); @@ -1445,7 +1453,7 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev, NOZOMI_NAME, dc); if (unlikely(ret)) { dev_err(&pdev->dev, "can't request irq %d\n", pdev->irq); - goto err_free_sbuf; + goto err_free_kfifo; } DBG1("base_addr: %p", dc->base_addr); @@ -1464,13 +1472,28 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev, dc->state = NOZOMI_STATE_ENABLED; for (i = 0; i < MAX_PORT; i++) { + struct device *tty_dev; + mutex_init(&dc->port[i].tty_sem); tty_port_init(&dc->port[i].port); - tty_register_device(ntty_driver, dc->index_start + i, + tty_dev = tty_register_device(ntty_driver, dc->index_start + i, &pdev->dev); + + if (IS_ERR(tty_dev)) { + ret = PTR_ERR(tty_dev); + dev_err(&pdev->dev, "Could not allocate tty?\n"); + goto err_free_tty; + } } + return 0; +err_free_tty: + for (i = dc->index_start; i < dc->index_start + MAX_PORT; ++i) + tty_unregister_device(ntty_driver, i); +err_free_kfifo: + for (i = 0; i < MAX_PORT; i++) + kfifo_free(&dc->port[i].fifo_ul); err_free_sbuf: kfree(dc->send_buf); iounmap(dc->base_addr); diff --git a/drivers/infiniband/hw/cxgb3/cxio_resource.c b/drivers/infiniband/hw/cxgb3/cxio_resource.c index dcbf260..31f9201 100644 --- a/drivers/infiniband/hw/cxgb3/cxio_resource.c +++ b/drivers/infiniband/hw/cxgb3/cxio_resource.c @@ -86,8 +86,9 @@ static int __cxio_init_resource_fifo(struct kfifo *fifo, kfifo_in(fifo, (unsigned char *) &i, sizeof(u32)); for (i = 0; i < skip_low + skip_high; i++) - kfifo_out_locked(fifo, (unsigned char *) &entry, - sizeof(u32), fifo_lock); + if (kfifo_out_locked(fifo, (unsigned char *) &entry, + sizeof(u32), fifo_lock) != sizeof(u32)) + break; return 0; } diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c index 884a569..b421858 100644 --- a/drivers/media/video/meye.c +++ b/drivers/media/video/meye.c @@ -968,8 +968,9 @@ static int meyeioc_sync(struct file *file, void *fh, int *i) /* fall through */ case MEYE_BUF_DONE: meye.grab_buffer[*i].state = MEYE_BUF_UNUSED; - kfifo_out_locked(&meye.doneq, (unsigned char *)&unused, - sizeof(int), &meye.doneq_lock); + if (kfifo_out_locked(&meye.doneq, (unsigned char *)&unused, + sizeof(int), &meye.doneq_lock) != sizeof(int)) + break; } *i = meye.grab_buffer[*i].size; mutex_unlock(&meye.lock); diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index 2bcfa74..c2975c8 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c @@ -514,8 +514,10 @@ static int lbs_thread(void *data) while (kfifo_len(&priv->event_fifo)) { u32 event; - kfifo_out(&priv->event_fifo, (unsigned char *) &event, - sizeof(event)); + if (kfifo_out(&priv->event_fifo, + (unsigned char *) &event, sizeof(event)) != + sizeof(event)) + break; spin_unlock_irq(&priv->driver_lock); lbs_process_event(priv, event); spin_lock_irq(&priv->driver_lock); diff --git a/drivers/scsi/libiscsi_tcp.c b/drivers/scsi/libiscsi_tcp.c index d51ffec..db6856c 100644 --- a/drivers/scsi/libiscsi_tcp.c +++ b/drivers/scsi/libiscsi_tcp.c @@ -990,8 +990,13 @@ static struct iscsi_r2t_info *iscsi_tcp_get_curr_r2t(struct iscsi_task *task) } if (r2t == NULL) { - kfifo_out(&tcp_task->r2tqueue, - (void *)&tcp_task->r2t, sizeof(void *)); + if (kfifo_out(&tcp_task->r2tqueue, + (void *)&tcp_task->r2t, sizeof(void *)) != + sizeof(void *)) { + WARN_ONCE(1, "unexpected fifo state"); + r2t = NULL; + } + r2t = tcp_task->r2t; } spin_unlock_bh(&session->lock); diff --git a/drivers/scsi/libsrp.c b/drivers/scsi/libsrp.c index 8424b86..ab19b3b 100644 --- a/drivers/scsi/libsrp.c +++ b/drivers/scsi/libsrp.c @@ -163,8 +163,11 @@ struct iu_entry *srp_iu_get(struct srp_target *target) { struct iu_entry *iue = NULL; - kfifo_out_locked(&target->iu_queue.queue, (void *) &iue, - sizeof(void *), &target->iu_queue.lock); + if (kfifo_out_locked(&target->iu_queue.queue, (void *) &iue, + sizeof(void *), &target->iu_queue.lock) != sizeof(void *)) { + WARN_ONCE(1, "unexpected fifo state"); + return NULL; + } if (!iue) return iue; iue->target = target; diff --git a/include/linux/kfifo.h b/include/linux/kfifo.h index 1b59c4a..5ed2565 100644 --- a/include/linux/kfifo.h +++ b/include/linux/kfifo.h @@ -56,7 +56,7 @@ extern void kfifo_init(struct kfifo *fifo, unsigned char *buffer, extern __must_check int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask); extern void kfifo_free(struct kfifo *fifo); -extern __must_check unsigned int kfifo_in(struct kfifo *fifo, +extern unsigned int kfifo_in(struct kfifo *fifo, const unsigned char *from, unsigned int len); extern __must_check unsigned int kfifo_out(struct kfifo *fifo, unsigned char *to, unsigned int len); @@ -94,7 +94,7 @@ static inline unsigned int kfifo_len(struct kfifo *fifo) * the FIFO depending on the free space, and returns the number of * bytes copied. */ -static inline __must_check unsigned int kfifo_in_locked(struct kfifo *fifo, +static inline unsigned int kfifo_in_locked(struct kfifo *fifo, const unsigned char *from, unsigned int n, spinlock_t *lock) { unsigned long flags; -- cgit v0.10.2 From 37bdfbbfaab47811fcec84dff23c4e8da1a09f9e Mon Sep 17 00:00:00 2001 From: Stefani Seibold Date: Mon, 21 Dec 2009 14:37:30 -0800 Subject: kfifo: add DEFINE_KFIFO and friends, add very tiny functions Add DECLARE_KFIFO - macro to declare a kfifo and the associated buffer inside a struct Add INIT_KFIFO - Initialize a kfifo declared by DECLARED_KFIFO Add DEFINE_KFIFO - macro to define and initialize a kfifo as a global or local object Add kfifo_size() - returns the size of the fifo in bytes Add kfifo_is_empty() - returns true if the fifo is empty Add kfifo_is_full() - returns true if the fifo is full Add kfifo_avail() - returns the number of bytes available in the FIFO Do some code cleanup Signed-off-by: Stefani Seibold Acked-by: Greg Kroah-Hartman Acked-by: Mauro Carvalho Chehab Acked-by: Andi Kleen Acked-by: Arnd Bergmann Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/include/linux/kfifo.h b/include/linux/kfifo.h index 5ed2565..dd53eed 100644 --- a/include/linux/kfifo.h +++ b/include/linux/kfifo.h @@ -51,6 +51,60 @@ struct kfifo { unsigned int out; /* data is extracted from off. (out % size) */ }; +/* + * Macros for declaration and initialization of the kfifo datatype + */ + +/* helper macro */ +#define __kfifo_initializer(s, b) \ + (struct kfifo) { \ + .size = s, \ + .in = 0, \ + .out = 0, \ + .buffer = b \ + } + +/** + * DECLARE_KFIFO - macro to declare a kfifo and the associated buffer + * @name: name of the declared kfifo datatype + * @size: size of the fifo buffer + * + * Note: the macro can be used inside struct or union declaration + * Note: the macro creates two objects: + * A kfifo object with the given name and a buffer for the kfifo + * object named name##kfifo_buffer + */ +#define DECLARE_KFIFO(name, size) \ +union { \ + struct kfifo name; \ + unsigned char name##kfifo_buffer[size + sizeof(struct kfifo)]; \ +} + +/** + * INIT_KFIFO - Initialize a kfifo declared by DECLARED_KFIFO + * @name: name of the declared kfifo datatype + * @size: size of the fifo buffer + */ +#define INIT_KFIFO(name) \ + name = __kfifo_initializer(sizeof(name##kfifo_buffer) - \ + sizeof(struct kfifo), name##kfifo_buffer) + +/** + * DEFINE_KFIFO - macro to define and initialize a kfifo + * @name: name of the declared kfifo datatype + * @size: size of the fifo buffer + * + * Note: the macro can be used for global and local kfifo data type variables + * Note: the macro creates two objects: + * A kfifo object with the given name and a buffer for the kfifo + * object named name##kfifo_buffer + */ +#define DEFINE_KFIFO(name, size) \ + unsigned char name##kfifo_buffer[size]; \ + struct kfifo name = __kfifo_initializer(size, name##kfifo_buffer) + +#undef __kfifo_initializer + extern void kfifo_init(struct kfifo *fifo, unsigned char *buffer, unsigned int size); extern __must_check int kfifo_alloc(struct kfifo *fifo, unsigned int size, @@ -71,6 +125,15 @@ static inline void kfifo_reset(struct kfifo *fifo) } /** + * kfifo_size - returns the size of the fifo in bytes + * @fifo: the fifo to be used. + */ +static inline __must_check unsigned int kfifo_size(struct kfifo *fifo) +{ + return fifo->size; +} + +/** * kfifo_len - returns the number of used bytes in the FIFO * @fifo: the fifo to be used. */ @@ -84,6 +147,33 @@ static inline unsigned int kfifo_len(struct kfifo *fifo) } /** + * kfifo_is_empty - returns true if the fifo is empty + * @fifo: the fifo to be used. + */ +static inline __must_check int kfifo_is_empty(struct kfifo *fifo) +{ + return fifo->in == fifo->out; +} + +/** + * kfifo_is_full - returns true if the fifo is full + * @fifo: the fifo to be used. + */ +static inline __must_check int kfifo_is_full(struct kfifo *fifo) +{ + return kfifo_len(fifo) == kfifo_size(fifo); +} + +/** + * kfifo_avail - returns the number of bytes available in the FIFO + * @fifo: the fifo to be used. + */ +static inline __must_check unsigned int kfifo_avail(struct kfifo *fifo) +{ + return kfifo_size(fifo) - kfifo_len(fifo); +} + +/** * kfifo_in_locked - puts some data into the FIFO using a spinlock for locking * @fifo: the fifo to be used. * @from: the data to be added. @@ -133,8 +223,8 @@ static inline __must_check unsigned int kfifo_out_locked(struct kfifo *fifo, * optimization: if the FIFO is empty, set the indices to 0 * so we don't wrap the next time */ - if (fifo->in == fifo->out) - fifo->in = fifo->out = 0; + if (kfifo_is_empty(fifo)) + kfifo_reset(fifo); spin_unlock_irqrestore(lock, flags); -- cgit v0.10.2 From a121f24accac1600bf5b6fb1e12eeabdfed7cb1a Mon Sep 17 00:00:00 2001 From: Stefani Seibold Date: Mon, 21 Dec 2009 14:37:31 -0800 Subject: kfifo: add kfifo_skip, kfifo_from_user and kfifo_to_user Add kfifo_reset_out() for save lockless discard the fifo output Add kfifo_skip() to skip a number of output bytes Add kfifo_from_user() to copy user space data into the fifo Add kfifo_to_user() to copy fifo data to user space Signed-off-by: Stefani Seibold Acked-by: Greg Kroah-Hartman Acked-by: Mauro Carvalho Chehab Acked-by: Andi Kleen Acked-by: Arnd Bergmann Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/include/linux/kfifo.h b/include/linux/kfifo.h index dd53eed..d3230fb 100644 --- a/include/linux/kfifo.h +++ b/include/linux/kfifo.h @@ -125,6 +125,16 @@ static inline void kfifo_reset(struct kfifo *fifo) } /** + * kfifo_reset_out - skip FIFO contents + * @fifo: the fifo to be emptied. + */ +static inline void kfifo_reset_out(struct kfifo *fifo) +{ + smp_mb(); + fifo->out = fifo->in; +} + +/** * kfifo_size - returns the size of the fifo in bytes * @fifo: the fifo to be used. */ @@ -231,4 +241,41 @@ static inline __must_check unsigned int kfifo_out_locked(struct kfifo *fifo, return ret; } +extern void kfifo_skip(struct kfifo *fifo, unsigned int len); + +extern __must_check unsigned int kfifo_from_user(struct kfifo *fifo, + const void __user *from, unsigned int n); + +extern __must_check unsigned int kfifo_to_user(struct kfifo *fifo, + void __user *to, unsigned int n); + +/** + * __kfifo_add_out internal helper function for updating the out offset + */ +static inline void __kfifo_add_out(struct kfifo *fifo, + unsigned int off) +{ + smp_mb(); + fifo->out += off; +} + +/** + * __kfifo_add_in internal helper function for updating the in offset + */ +static inline void __kfifo_add_in(struct kfifo *fifo, + unsigned int off) +{ + smp_wmb(); + fifo->in += off; +} + +/** + * __kfifo_off internal helper function for calculating the index of a + * given offeset + */ +static inline unsigned int __kfifo_off(struct kfifo *fifo, unsigned int off) +{ + return off & (fifo->size - 1); +} + #endif diff --git a/kernel/kfifo.c b/kernel/kfifo.c index d659442..2a78425 100644 --- a/kernel/kfifo.c +++ b/kernel/kfifo.c @@ -26,6 +26,7 @@ #include #include #include +#include static void _kfifo_init(struct kfifo *fifo, unsigned char *buffer, unsigned int size) @@ -100,6 +101,21 @@ void kfifo_free(struct kfifo *fifo) EXPORT_SYMBOL(kfifo_free); /** + * kfifo_skip - skip output data + * @fifo: the fifo to be used. + * @len: number of bytes to skip + */ +void kfifo_skip(struct kfifo *fifo, unsigned int len) +{ + if (len < kfifo_len(fifo)) { + __kfifo_add_out(fifo, len); + return; + } + kfifo_reset_out(fifo); +} +EXPORT_SYMBOL(kfifo_skip); + +/** * kfifo_in - puts some data into the FIFO * @fifo: the fifo to be used. * @from: the data to be added. @@ -115,6 +131,7 @@ EXPORT_SYMBOL(kfifo_free); unsigned int kfifo_in(struct kfifo *fifo, const unsigned char *from, unsigned int len) { + unsigned int off; unsigned int l; len = min(len, fifo->size - fifo->in + fifo->out); @@ -126,21 +143,16 @@ unsigned int kfifo_in(struct kfifo *fifo, smp_mb(); + off = __kfifo_off(fifo, fifo->in); + /* first put the data starting from fifo->in to buffer end */ - l = min(len, fifo->size - (fifo->in & (fifo->size - 1))); - memcpy(fifo->buffer + (fifo->in & (fifo->size - 1)), from, l); + l = min(len, fifo->size - off); + memcpy(fifo->buffer + off, from, l); /* then put the rest (if any) at the beginning of the buffer */ memcpy(fifo->buffer, from + l, len - l); - /* - * Ensure that we add the bytes to the kfifo -before- - * we update the fifo->in index. - */ - - smp_wmb(); - - fifo->in += len; + __kfifo_add_in(fifo, len); return len; } @@ -161,6 +173,7 @@ EXPORT_SYMBOL(kfifo_in); unsigned int kfifo_out(struct kfifo *fifo, unsigned char *to, unsigned int len) { + unsigned int off; unsigned int l; len = min(len, fifo->in - fifo->out); @@ -172,22 +185,116 @@ unsigned int kfifo_out(struct kfifo *fifo, smp_rmb(); + off = __kfifo_off(fifo, fifo->out); + /* first get the data from fifo->out until the end of the buffer */ - l = min(len, fifo->size - (fifo->out & (fifo->size - 1))); - memcpy(to, fifo->buffer + (fifo->out & (fifo->size - 1)), l); + l = min(len, fifo->size - off); + memcpy(to, fifo->buffer + off, l); /* then get the rest (if any) from the beginning of the buffer */ memcpy(to + l, fifo->buffer, len - l); + __kfifo_add_out(fifo, len); + + return len; +} +EXPORT_SYMBOL(kfifo_out); + +/** + * kfifo_from_user - puts some data from user space into the FIFO + * @fifo: the fifo to be used. + * @from: pointer to the data to be added. + * @len: the length of the data to be added. + * + * This function copies at most @len bytes from the @from into the + * FIFO depending and returns the number of copied bytes. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these functions. + */ +unsigned int kfifo_from_user(struct kfifo *fifo, + const void __user *from, unsigned int len) +{ + unsigned int off; + unsigned int l; + int ret; + + len = min(len, fifo->size - fifo->in + fifo->out); + /* - * Ensure that we remove the bytes from the kfifo -before- - * we update the fifo->out index. + * Ensure that we sample the fifo->out index -before- we + * start putting bytes into the kfifo. */ smp_mb(); - fifo->out += len; + off = __kfifo_off(fifo, fifo->in); + + /* first put the data starting from fifo->in to buffer end */ + l = min(len, fifo->size - off); + ret = copy_from_user(fifo->buffer + off, from, l); + + if (unlikely(ret)) + return l - ret; + + /* then put the rest (if any) at the beginning of the buffer */ + ret = copy_from_user(fifo->buffer, from + l, len - l); + + if (unlikely(ret)) + return len - ret; + + __kfifo_add_in(fifo, len); return len; } -EXPORT_SYMBOL(kfifo_out); +EXPORT_SYMBOL(kfifo_from_user); + +/** + * kfifo_to_user - gets data from the FIFO and write it to user space + * @fifo: the fifo to be used. + * @to: where the data must be copied. + * @len: the size of the destination buffer. + * + * This function copies at most @len bytes from the FIFO into the + * @to buffer and returns the number of copied bytes. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these functions. + */ +unsigned int kfifo_to_user(struct kfifo *fifo, + void __user *to, unsigned int len) +{ + unsigned int off; + unsigned int l; + int ret; + + len = min(len, fifo->in - fifo->out); + + /* + * Ensure that we sample the fifo->in index -before- we + * start removing bytes from the kfifo. + */ + + smp_rmb(); + + off = __kfifo_off(fifo, fifo->out); + + /* first get the data from fifo->out until the end of the buffer */ + l = min(len, fifo->size - off); + ret = copy_to_user(to, fifo->buffer + off, l); + + if (unlikely(ret)) + return l - ret; + + /* then get the rest (if any) from the beginning of the buffer */ + ret = copy_to_user(to + l, fifo->buffer, len - l); + + if (unlikely(ret)) + return len - ret; + + __kfifo_add_out(fifo, len); + + return len; +} +EXPORT_SYMBOL(kfifo_to_user); + -- cgit v0.10.2 From 86d4880313603810901f639ccb5c88ff13d4ad3c Mon Sep 17 00:00:00 2001 From: Stefani Seibold Date: Mon, 21 Dec 2009 14:37:32 -0800 Subject: kfifo: add record handling functions Add kfifo_in_rec() - puts some record data into the FIFO Add kfifo_out_rec() - gets some record data from the FIFO Add kfifo_from_user_rec() - puts some data from user space into the FIFO Add kfifo_to_user_rec() - gets data from the FIFO and write it to user space Add kfifo_peek_rec() - gets the size of the next FIFO record field Add kfifo_skip_rec() - skip the next fifo out record Add kfifo_avail_rec() - determinate the number of bytes available in a record FIFO Signed-off-by: Stefani Seibold Acked-by: Greg Kroah-Hartman Acked-by: Mauro Carvalho Chehab Acked-by: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/include/linux/kfifo.h b/include/linux/kfifo.h index d3230fb..486e8ad 100644 --- a/include/linux/kfifo.h +++ b/include/linux/kfifo.h @@ -278,4 +278,334 @@ static inline unsigned int __kfifo_off(struct kfifo *fifo, unsigned int off) return off & (fifo->size - 1); } +/** + * __kfifo_peek_n internal helper function for determinate the length of + * the next record in the fifo + */ +static inline unsigned int __kfifo_peek_n(struct kfifo *fifo, + unsigned int recsize) +{ +#define __KFIFO_GET(fifo, off, shift) \ + ((fifo)->buffer[__kfifo_off((fifo), (fifo)->out+(off))] << (shift)) + + unsigned int l; + + l = __KFIFO_GET(fifo, 0, 0); + + if (--recsize) + l |= __KFIFO_GET(fifo, 1, 8); + + return l; +#undef __KFIFO_GET +} + +/** + * __kfifo_poke_n internal helper function for storing the length of + * the next record into the fifo + */ +static inline void __kfifo_poke_n(struct kfifo *fifo, + unsigned int recsize, unsigned int n) +{ +#define __KFIFO_PUT(fifo, off, val, shift) \ + ( \ + (fifo)->buffer[__kfifo_off((fifo), (fifo)->in+(off))] = \ + (unsigned char)((val) >> (shift)) \ + ) + + __KFIFO_PUT(fifo, 0, n, 0); + + if (--recsize) + __KFIFO_PUT(fifo, 1, n, 8); +#undef __KFIFO_PUT +} + +/** + * __kfifo_in_... internal functions for put date into the fifo + * do not call it directly, use kfifo_in_rec() instead + */ +extern unsigned int __kfifo_in_n(struct kfifo *fifo, + const void *from, unsigned int n, unsigned int recsize); + +extern unsigned int __kfifo_in_generic(struct kfifo *fifo, + const void *from, unsigned int n, unsigned int recsize); + +static inline unsigned int __kfifo_in_rec(struct kfifo *fifo, + const void *from, unsigned int n, unsigned int recsize) +{ + unsigned int ret; + + ret = __kfifo_in_n(fifo, from, n, recsize); + + if (likely(ret == 0)) { + if (recsize) + __kfifo_poke_n(fifo, recsize, n); + __kfifo_add_in(fifo, n + recsize); + } + return ret; +} + +/** + * kfifo_in_rec - puts some record data into the FIFO + * @fifo: the fifo to be used. + * @from: the data to be added. + * @n: the length of the data to be added. + * @recsize: size of record field + * + * This function copies @n bytes from the @from into the FIFO and returns + * the number of bytes which cannot be copied. + * A returned value greater than the @n value means that the record doesn't + * fit into the buffer. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these functions. + */ +static inline __must_check unsigned int kfifo_in_rec(struct kfifo *fifo, + void *from, unsigned int n, unsigned int recsize) +{ + if (!__builtin_constant_p(recsize)) + return __kfifo_in_generic(fifo, from, n, recsize); + return __kfifo_in_rec(fifo, from, n, recsize); +} + +/** + * __kfifo_out_... internal functions for get date from the fifo + * do not call it directly, use kfifo_out_rec() instead + */ +extern unsigned int __kfifo_out_n(struct kfifo *fifo, + void *to, unsigned int reclen, unsigned int recsize); + +extern unsigned int __kfifo_out_generic(struct kfifo *fifo, + void *to, unsigned int n, + unsigned int recsize, unsigned int *total); + +static inline unsigned int __kfifo_out_rec(struct kfifo *fifo, + void *to, unsigned int n, unsigned int recsize, + unsigned int *total) +{ + unsigned int l; + + if (!recsize) { + l = n; + if (total) + *total = l; + } else { + l = __kfifo_peek_n(fifo, recsize); + if (total) + *total = l; + if (n < l) + return l; + } + + return __kfifo_out_n(fifo, to, l, recsize); +} + +/** + * kfifo_out_rec - gets some record data from the FIFO + * @fifo: the fifo to be used. + * @to: where the data must be copied. + * @n: the size of the destination buffer. + * @recsize: size of record field + * @total: pointer where the total number of to copied bytes should stored + * + * This function copies at most @n bytes from the FIFO to @to and returns the + * number of bytes which cannot be copied. + * A returned value greater than the @n value means that the record doesn't + * fit into the @to buffer. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these functions. + */ +static inline __must_check unsigned int kfifo_out_rec(struct kfifo *fifo, + void *to, unsigned int n, unsigned int recsize, + unsigned int *total) + +{ + if (!__builtin_constant_p(recsize)) + return __kfifo_out_generic(fifo, to, n, recsize, total); + return __kfifo_out_rec(fifo, to, n, recsize, total); +} + +/** + * __kfifo_from_user_... internal functions for transfer from user space into + * the fifo. do not call it directly, use kfifo_from_user_rec() instead + */ +extern unsigned int __kfifo_from_user_n(struct kfifo *fifo, + const void __user *from, unsigned int n, unsigned int recsize); + +extern unsigned int __kfifo_from_user_generic(struct kfifo *fifo, + const void __user *from, unsigned int n, unsigned int recsize); + +static inline unsigned int __kfifo_from_user_rec(struct kfifo *fifo, + const void __user *from, unsigned int n, unsigned int recsize) +{ + unsigned int ret; + + ret = __kfifo_from_user_n(fifo, from, n, recsize); + + if (likely(ret == 0)) { + if (recsize) + __kfifo_poke_n(fifo, recsize, n); + __kfifo_add_in(fifo, n + recsize); + } + return ret; +} + +/** + * kfifo_from_user_rec - puts some data from user space into the FIFO + * @fifo: the fifo to be used. + * @from: pointer to the data to be added. + * @n: the length of the data to be added. + * @recsize: size of record field + * + * This function copies @n bytes from the @from into the + * FIFO and returns the number of bytes which cannot be copied. + * + * If the returned value is equal or less the @n value, the copy_from_user() + * functions has failed. Otherwise the record doesn't fit into the buffer. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these functions. + */ +static inline __must_check unsigned int kfifo_from_user_rec(struct kfifo *fifo, + const void __user *from, unsigned int n, unsigned int recsize) +{ + if (!__builtin_constant_p(recsize)) + return __kfifo_from_user_generic(fifo, from, n, recsize); + return __kfifo_from_user_rec(fifo, from, n, recsize); +} + +/** + * __kfifo_to_user_... internal functions for transfer fifo data into user space + * do not call it directly, use kfifo_to_user_rec() instead + */ +extern unsigned int __kfifo_to_user_n(struct kfifo *fifo, + void __user *to, unsigned int n, unsigned int reclen, + unsigned int recsize); + +extern unsigned int __kfifo_to_user_generic(struct kfifo *fifo, + void __user *to, unsigned int n, unsigned int recsize, + unsigned int *total); + +static inline unsigned int __kfifo_to_user_rec(struct kfifo *fifo, + void __user *to, unsigned int n, + unsigned int recsize, unsigned int *total) +{ + unsigned int l; + + if (!recsize) { + l = n; + if (total) + *total = l; + } else { + l = __kfifo_peek_n(fifo, recsize); + if (total) + *total = l; + if (n < l) + return l; + } + + return __kfifo_to_user_n(fifo, to, n, l, recsize); +} + +/** + * kfifo_to_user_rec - gets data from the FIFO and write it to user space + * @fifo: the fifo to be used. + * @to: where the data must be copied. + * @n: the size of the destination buffer. + * @recsize: size of record field + * @total: pointer where the total number of to copied bytes should stored + * + * This function copies at most @n bytes from the FIFO to the @to. + * In case of an error, the function returns the number of bytes which cannot + * be copied. + * If the returned value is equal or less the @n value, the copy_to_user() + * functions has failed. Otherwise the record doesn't fit into the @to buffer. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these functions. + */ +static inline __must_check unsigned int kfifo_to_user_rec(struct kfifo *fifo, + void __user *to, unsigned int n, unsigned int recsize, + unsigned int *total) +{ + if (!__builtin_constant_p(recsize)) + return __kfifo_to_user_generic(fifo, to, n, recsize, total); + return __kfifo_to_user_rec(fifo, to, n, recsize, total); +} + +/** + * __kfifo_peek_... internal functions for peek into the next fifo record + * do not call it directly, use kfifo_peek_rec() instead + */ +extern unsigned int __kfifo_peek_generic(struct kfifo *fifo, + unsigned int recsize); + +/** + * kfifo_peek_rec - gets the size of the next FIFO record data + * @fifo: the fifo to be used. + * @recsize: size of record field + * + * This function returns the size of the next FIFO record in number of bytes + */ +static inline __must_check unsigned int kfifo_peek_rec(struct kfifo *fifo, + unsigned int recsize) +{ + if (!__builtin_constant_p(recsize)) + return __kfifo_peek_generic(fifo, recsize); + if (!recsize) + return kfifo_len(fifo); + return __kfifo_peek_n(fifo, recsize); +} + +/** + * __kfifo_skip_... internal functions for skip the next fifo record + * do not call it directly, use kfifo_skip_rec() instead + */ +extern void __kfifo_skip_generic(struct kfifo *fifo, unsigned int recsize); + +static inline void __kfifo_skip_rec(struct kfifo *fifo, + unsigned int recsize) +{ + unsigned int l; + + if (recsize) { + l = __kfifo_peek_n(fifo, recsize); + + if (l + recsize <= kfifo_len(fifo)) { + __kfifo_add_out(fifo, l + recsize); + return; + } + } + kfifo_reset_out(fifo); +} + +/** + * kfifo_skip_rec - skip the next fifo out record + * @fifo: the fifo to be used. + * @recsize: size of record field + * + * This function skips the next FIFO record + */ +static inline void kfifo_skip_rec(struct kfifo *fifo, + unsigned int recsize) +{ + if (!__builtin_constant_p(recsize)) + __kfifo_skip_generic(fifo, recsize); + else + __kfifo_skip_rec(fifo, recsize); +} + +/** + * kfifo_avail_rec - returns the number of bytes available in a record FIFO + * @fifo: the fifo to be used. + * @recsize: size of record field + */ +static inline __must_check unsigned int kfifo_avail_rec(struct kfifo *fifo, + unsigned int recsize) +{ + unsigned int l = kfifo_size(fifo) - kfifo_len(fifo); + + return (l > recsize) ? l - recsize : 0; +} + #endif diff --git a/kernel/kfifo.c b/kernel/kfifo.c index 2a78425..e92d519 100644 --- a/kernel/kfifo.c +++ b/kernel/kfifo.c @@ -115,27 +115,11 @@ void kfifo_skip(struct kfifo *fifo, unsigned int len) } EXPORT_SYMBOL(kfifo_skip); -/** - * kfifo_in - puts some data into the FIFO - * @fifo: the fifo to be used. - * @from: the data to be added. - * @len: the length of the data to be added. - * - * This function copies at most @len bytes from the @from buffer into - * the FIFO depending on the free space, and returns the number of - * bytes copied. - * - * Note that with only one concurrent reader and one concurrent - * writer, you don't need extra locking to use these functions. - */ -unsigned int kfifo_in(struct kfifo *fifo, - const unsigned char *from, unsigned int len) +static inline void __kfifo_in_data(struct kfifo *fifo, + const void *from, unsigned int len, unsigned int off) { - unsigned int off; unsigned int l; - len = min(len, fifo->size - fifo->in + fifo->out); - /* * Ensure that we sample the fifo->out index -before- we * start putting bytes into the kfifo. @@ -143,7 +127,7 @@ unsigned int kfifo_in(struct kfifo *fifo, smp_mb(); - off = __kfifo_off(fifo, fifo->in); + off = __kfifo_off(fifo, fifo->in + off); /* first put the data starting from fifo->in to buffer end */ l = min(len, fifo->size - off); @@ -151,33 +135,13 @@ unsigned int kfifo_in(struct kfifo *fifo, /* then put the rest (if any) at the beginning of the buffer */ memcpy(fifo->buffer, from + l, len - l); - - __kfifo_add_in(fifo, len); - - return len; } -EXPORT_SYMBOL(kfifo_in); -/** - * kfifo_out - gets some data from the FIFO - * @fifo: the fifo to be used. - * @to: where the data must be copied. - * @len: the size of the destination buffer. - * - * This function copies at most @len bytes from the FIFO into the - * @to buffer and returns the number of copied bytes. - * - * Note that with only one concurrent reader and one concurrent - * writer, you don't need extra locking to use these functions. - */ -unsigned int kfifo_out(struct kfifo *fifo, - unsigned char *to, unsigned int len) +static inline void __kfifo_out_data(struct kfifo *fifo, + void *to, unsigned int len, unsigned int off) { - unsigned int off; unsigned int l; - len = min(len, fifo->in - fifo->out); - /* * Ensure that we sample the fifo->in index -before- we * start removing bytes from the kfifo. @@ -185,7 +149,7 @@ unsigned int kfifo_out(struct kfifo *fifo, smp_rmb(); - off = __kfifo_off(fifo, fifo->out); + off = __kfifo_off(fifo, fifo->out + off); /* first get the data from fifo->out until the end of the buffer */ l = min(len, fifo->size - off); @@ -193,34 +157,14 @@ unsigned int kfifo_out(struct kfifo *fifo, /* then get the rest (if any) from the beginning of the buffer */ memcpy(to + l, fifo->buffer, len - l); - - __kfifo_add_out(fifo, len); - - return len; } -EXPORT_SYMBOL(kfifo_out); -/** - * kfifo_from_user - puts some data from user space into the FIFO - * @fifo: the fifo to be used. - * @from: pointer to the data to be added. - * @len: the length of the data to be added. - * - * This function copies at most @len bytes from the @from into the - * FIFO depending and returns the number of copied bytes. - * - * Note that with only one concurrent reader and one concurrent - * writer, you don't need extra locking to use these functions. - */ -unsigned int kfifo_from_user(struct kfifo *fifo, - const void __user *from, unsigned int len) +static inline unsigned int __kfifo_from_user_data(struct kfifo *fifo, + const void __user *from, unsigned int len, unsigned int off) { - unsigned int off; unsigned int l; int ret; - len = min(len, fifo->size - fifo->in + fifo->out); - /* * Ensure that we sample the fifo->out index -before- we * start putting bytes into the kfifo. @@ -228,29 +172,101 @@ unsigned int kfifo_from_user(struct kfifo *fifo, smp_mb(); - off = __kfifo_off(fifo, fifo->in); + off = __kfifo_off(fifo, fifo->in + off); /* first put the data starting from fifo->in to buffer end */ l = min(len, fifo->size - off); ret = copy_from_user(fifo->buffer + off, from, l); if (unlikely(ret)) - return l - ret; + return ret + len - l; /* then put the rest (if any) at the beginning of the buffer */ - ret = copy_from_user(fifo->buffer, from + l, len - l); + return copy_from_user(fifo->buffer, from + l, len - l); +} + +static inline unsigned int __kfifo_to_user_data(struct kfifo *fifo, + void __user *to, unsigned int len, unsigned int off) +{ + unsigned int l; + int ret; + + /* + * Ensure that we sample the fifo->in index -before- we + * start removing bytes from the kfifo. + */ + + smp_rmb(); + + off = __kfifo_off(fifo, fifo->out + off); + + /* first get the data from fifo->out until the end of the buffer */ + l = min(len, fifo->size - off); + ret = copy_to_user(to, fifo->buffer + off, l); if (unlikely(ret)) - return len - ret; + return ret + len - l; - __kfifo_add_in(fifo, len); + /* then get the rest (if any) from the beginning of the buffer */ + return copy_to_user(to + l, fifo->buffer, len - l); +} +unsigned int __kfifo_in_n(struct kfifo *fifo, + const void *from, unsigned int len, unsigned int recsize) +{ + if (kfifo_avail(fifo) < len + recsize) + return len + 1; + + __kfifo_in_data(fifo, from, len, recsize); + return 0; +} +EXPORT_SYMBOL(__kfifo_in_n); + +/** + * kfifo_in - puts some data into the FIFO + * @fifo: the fifo to be used. + * @from: the data to be added. + * @len: the length of the data to be added. + * + * This function copies at most @len bytes from the @from buffer into + * the FIFO depending on the free space, and returns the number of + * bytes copied. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these functions. + */ +unsigned int kfifo_in(struct kfifo *fifo, const unsigned char *from, + unsigned int len) +{ + len = min(kfifo_avail(fifo), len); + + __kfifo_in_data(fifo, from, len, 0); + __kfifo_add_in(fifo, len); return len; } -EXPORT_SYMBOL(kfifo_from_user); +EXPORT_SYMBOL(kfifo_in); + +unsigned int __kfifo_in_generic(struct kfifo *fifo, + const void *from, unsigned int len, unsigned int recsize) +{ + return __kfifo_in_rec(fifo, from, len, recsize); +} +EXPORT_SYMBOL(__kfifo_in_generic); + +unsigned int __kfifo_out_n(struct kfifo *fifo, + void *to, unsigned int len, unsigned int recsize) +{ + if (kfifo_len(fifo) < len + recsize) + return len; + + __kfifo_out_data(fifo, to, len, recsize); + __kfifo_add_out(fifo, len + recsize); + return 0; +} +EXPORT_SYMBOL(__kfifo_out_n); /** - * kfifo_to_user - gets data from the FIFO and write it to user space + * kfifo_out - gets some data from the FIFO * @fifo: the fifo to be used. * @to: where the data must be copied. * @len: the size of the destination buffer. @@ -261,40 +277,124 @@ EXPORT_SYMBOL(kfifo_from_user); * Note that with only one concurrent reader and one concurrent * writer, you don't need extra locking to use these functions. */ -unsigned int kfifo_to_user(struct kfifo *fifo, - void __user *to, unsigned int len) +unsigned int kfifo_out(struct kfifo *fifo, unsigned char *to, unsigned int len) { - unsigned int off; - unsigned int l; - int ret; + len = min(kfifo_len(fifo), len); - len = min(len, fifo->in - fifo->out); + __kfifo_out_data(fifo, to, len, 0); + __kfifo_add_out(fifo, len); - /* - * Ensure that we sample the fifo->in index -before- we - * start removing bytes from the kfifo. - */ + return len; +} +EXPORT_SYMBOL(kfifo_out); - smp_rmb(); +unsigned int __kfifo_out_generic(struct kfifo *fifo, + void *to, unsigned int len, unsigned int recsize, + unsigned int *total) +{ + return __kfifo_out_rec(fifo, to, len, recsize, total); +} +EXPORT_SYMBOL(__kfifo_out_generic); - off = __kfifo_off(fifo, fifo->out); +unsigned int __kfifo_from_user_n(struct kfifo *fifo, + const void __user *from, unsigned int len, unsigned int recsize) +{ + if (kfifo_avail(fifo) < len + recsize) + return len + 1; - /* first get the data from fifo->out until the end of the buffer */ - l = min(len, fifo->size - off); - ret = copy_to_user(to, fifo->buffer + off, l); + return __kfifo_from_user_data(fifo, from, len, recsize); +} +EXPORT_SYMBOL(__kfifo_from_user_n); - if (unlikely(ret)) - return l - ret; +/** + * kfifo_from_user - puts some data from user space into the FIFO + * @fifo: the fifo to be used. + * @from: pointer to the data to be added. + * @len: the length of the data to be added. + * + * This function copies at most @len bytes from the @from into the + * FIFO depending and returns the number of copied bytes. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these functions. + */ +unsigned int kfifo_from_user(struct kfifo *fifo, + const void __user *from, unsigned int len) +{ + len = min(kfifo_avail(fifo), len); + len -= __kfifo_from_user_data(fifo, from, len, 0); + __kfifo_add_in(fifo, len); + return len; +} +EXPORT_SYMBOL(kfifo_from_user); - /* then get the rest (if any) from the beginning of the buffer */ - ret = copy_to_user(to + l, fifo->buffer, len - l); +unsigned int __kfifo_from_user_generic(struct kfifo *fifo, + const void __user *from, unsigned int len, unsigned int recsize) +{ + return __kfifo_from_user_rec(fifo, from, len, recsize); +} +EXPORT_SYMBOL(__kfifo_from_user_generic); - if (unlikely(ret)) - return len - ret; +unsigned int __kfifo_to_user_n(struct kfifo *fifo, + void __user *to, unsigned int len, unsigned int reclen, + unsigned int recsize) +{ + unsigned int ret; - __kfifo_add_out(fifo, len); + if (kfifo_len(fifo) < reclen + recsize) + return len; + ret = __kfifo_to_user_data(fifo, to, reclen, recsize); + + if (likely(ret == 0)) + __kfifo_add_out(fifo, reclen + recsize); + + return ret; +} +EXPORT_SYMBOL(__kfifo_to_user_n); + +/** + * kfifo_to_user - gets data from the FIFO and write it to user space + * @fifo: the fifo to be used. + * @to: where the data must be copied. + * @len: the size of the destination buffer. + * + * This function copies at most @len bytes from the FIFO into the + * @to buffer and returns the number of copied bytes. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these functions. + */ +unsigned int kfifo_to_user(struct kfifo *fifo, + void __user *to, unsigned int len) +{ + len = min(kfifo_len(fifo), len); + len -= __kfifo_to_user_data(fifo, to, len, 0); + __kfifo_add_out(fifo, len); return len; } EXPORT_SYMBOL(kfifo_to_user); +unsigned int __kfifo_to_user_generic(struct kfifo *fifo, + void __user *to, unsigned int len, unsigned int recsize, + unsigned int *total) +{ + return __kfifo_to_user_rec(fifo, to, len, recsize, total); +} +EXPORT_SYMBOL(__kfifo_to_user_generic); + +unsigned int __kfifo_peek_generic(struct kfifo *fifo, unsigned int recsize) +{ + if (recsize == 0) + return kfifo_avail(fifo); + + return __kfifo_peek_n(fifo, recsize); +} +EXPORT_SYMBOL(__kfifo_peek_generic); + +void __kfifo_skip_generic(struct kfifo *fifo, unsigned int recsize) +{ + __kfifo_skip_rec(fifo, recsize); +} +EXPORT_SYMBOL(__kfifo_skip_generic); + -- cgit v0.10.2 From 7801edb0b8b66e83c13623b483bc2e846c007c9d Mon Sep 17 00:00:00 2001 From: Stefani Seibold Date: Mon, 21 Dec 2009 14:37:33 -0800 Subject: media video cx23888 driver: ported to new kfifo API Fix the cx23888 driver to use the new kfifo API. Using kfifo_reset() may result in a possible race conditions. This patch fixes it by using a spinlock around the kfifo_reset() function. Signed-off-by: Stefani Seibold Cc: Mauro Carvalho Chehab Reviewed-by: Andy Walls Acked-by: Andy Walls Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/media/video/cx23885/cx23888-ir.c b/drivers/media/video/cx23885/cx23888-ir.c index 3ccc8af..2bf57a4 100644 --- a/drivers/media/video/cx23885/cx23888-ir.c +++ b/drivers/media/video/cx23885/cx23888-ir.c @@ -124,15 +124,12 @@ struct cx23888_ir_state { atomic_t rxclk_divider; atomic_t rx_invert; - struct kfifo *rx_kfifo; + struct kfifo rx_kfifo; spinlock_t rx_kfifo_lock; struct v4l2_subdev_ir_parameters tx_params; struct mutex tx_params_lock; atomic_t txclk_divider; - - struct kfifo *tx_kfifo; - spinlock_t tx_kfifo_lock; }; static inline struct cx23888_ir_state *to_state(struct v4l2_subdev *sd) @@ -522,6 +519,7 @@ static int cx23888_ir_irq_handler(struct v4l2_subdev *sd, u32 status, { struct cx23888_ir_state *state = to_state(sd); struct cx23885_dev *dev = state->dev; + unsigned long flags; u32 cntrl = cx23888_ir_read4(dev, CX23888_IR_CNTRL_REG); u32 irqen = cx23888_ir_read4(dev, CX23888_IR_IRQEN_REG); @@ -594,8 +592,9 @@ static int cx23888_ir_irq_handler(struct v4l2_subdev *sd, u32 status, if (i == 0) break; j = i * sizeof(u32); - k = kfifo_put(state->rx_kfifo, - (unsigned char *) rx_data, j); + k = kfifo_in_locked(&state->rx_kfifo, + (unsigned char *) rx_data, j, + &state->rx_kfifo_lock); if (k != j) kror++; /* rx_kfifo over run */ } @@ -631,8 +630,11 @@ static int cx23888_ir_irq_handler(struct v4l2_subdev *sd, u32 status, cx23888_ir_write4(dev, CX23888_IR_CNTRL_REG, cntrl); *handled = true; } - if (kfifo_len(state->rx_kfifo) >= CX23888_IR_RX_KFIFO_SIZE / 2) + + spin_lock_irqsave(&state->rx_kfifo_lock, flags); + if (kfifo_len(&state->rx_kfifo) >= CX23888_IR_RX_KFIFO_SIZE / 2) events |= V4L2_SUBDEV_IR_RX_FIFO_SERVICE_REQ; + spin_unlock_irqrestore(&state->rx_kfifo_lock, flags); if (events) v4l2_subdev_notify(sd, V4L2_SUBDEV_IR_RX_NOTIFY, &events); @@ -657,7 +659,7 @@ static int cx23888_ir_rx_read(struct v4l2_subdev *sd, u8 *buf, size_t count, return 0; } - n = kfifo_get(state->rx_kfifo, buf, n); + n = kfifo_out_locked(&state->rx_kfifo, buf, n, &state->rx_kfifo_lock); n /= sizeof(u32); *num = n * sizeof(u32); @@ -785,7 +787,12 @@ static int cx23888_ir_rx_s_parameters(struct v4l2_subdev *sd, o->interrupt_enable = p->interrupt_enable; o->enable = p->enable; if (p->enable) { - kfifo_reset(state->rx_kfifo); + unsigned long flags; + + spin_lock_irqsave(&state->rx_kfifo_lock, flags); + kfifo_reset(&state->rx_kfifo); + /* reset tx_fifo too if there is one... */ + spin_unlock_irqrestore(&state->rx_kfifo_lock, flags); if (p->interrupt_enable) irqenable_rx(dev, IRQEN_RSE | IRQEN_RTE | IRQEN_ROE); control_rx_enable(dev, p->enable); @@ -892,7 +899,6 @@ static int cx23888_ir_tx_s_parameters(struct v4l2_subdev *sd, o->interrupt_enable = p->interrupt_enable; o->enable = p->enable; if (p->enable) { - kfifo_reset(state->tx_kfifo); if (p->interrupt_enable) irqenable_tx(dev, IRQEN_TSE); control_tx_enable(dev, p->enable); @@ -1168,18 +1174,8 @@ int cx23888_ir_probe(struct cx23885_dev *dev) return -ENOMEM; spin_lock_init(&state->rx_kfifo_lock); - state->rx_kfifo = kfifo_alloc(CX23888_IR_RX_KFIFO_SIZE, GFP_KERNEL, - &state->rx_kfifo_lock); - if (state->rx_kfifo == NULL) - return -ENOMEM; - - spin_lock_init(&state->tx_kfifo_lock); - state->tx_kfifo = kfifo_alloc(CX23888_IR_TX_KFIFO_SIZE, GFP_KERNEL, - &state->tx_kfifo_lock); - if (state->tx_kfifo == NULL) { - kfifo_free(state->rx_kfifo); + if (kfifo_alloc(&state->rx_kfifo, CX23888_IR_RX_KFIFO_SIZE, GFP_KERNEL)) return -ENOMEM; - } state->dev = dev; state->id = V4L2_IDENT_CX23888_IR; @@ -1211,8 +1207,7 @@ int cx23888_ir_probe(struct cx23885_dev *dev) sizeof(struct v4l2_subdev_ir_parameters)); v4l2_subdev_call(sd, ir, tx_s_parameters, &default_params); } else { - kfifo_free(state->rx_kfifo); - kfifo_free(state->tx_kfifo); + kfifo_free(&state->rx_kfifo); } return ret; } @@ -1231,8 +1226,7 @@ int cx23888_ir_remove(struct cx23885_dev *dev) state = to_state(sd); v4l2_device_unregister_subdev(sd); - kfifo_free(state->rx_kfifo); - kfifo_free(state->tx_kfifo); + kfifo_free(&state->rx_kfifo); kfree(state); /* Nothing more to free() as state held the actual v4l2_subdev object */ return 0; -- cgit v0.10.2 From 1e9d1b13efae7e0a2705611d47ae5f07e27015f0 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 19 Dec 2009 08:30:30 +0100 Subject: drivers/dma: drop unnecesary memset memset of 0 is not needed after kzalloc The semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ expression x; statement S; @@ x = kzalloc(...); if (x == NULL) S ... when != x -memset(x,0,...);// Signed-off-by: Julia Lawall Signed-off-by: Dan Williams diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c index 2eea823..53bb3ca 100644 --- a/drivers/dma/dw_dmac.c +++ b/drivers/dma/dw_dmac.c @@ -1270,8 +1270,6 @@ static int __init dw_probe(struct platform_device *pdev) goto err_kfree; } - memset(dw, 0, sizeof *dw); - dw->regs = ioremap(io->start, DW_REGLEN); if (!dw->regs) { err = -ENOMEM; -- cgit v0.10.2 From 0794ec8ce327ec74416b569b8fb1951274693700 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Tue, 22 Dec 2009 21:30:59 +0100 Subject: drivers/dma: Correct use after free Move the kfree after the iounmap that refers to the same structure. A simplified version of the semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @@ expression x,e; identifier f; iterator I; statement S; @@ *kfree(x); ... when != &x when != x = e when != I(x,...) S *x->f // Signed-off-by: Julia Lawall Signed-off-by: Dan Williams diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c index 4a99cd9..b5f2ee0 100644 --- a/drivers/dma/coh901318.c +++ b/drivers/dma/coh901318.c @@ -1294,8 +1294,8 @@ static int __exit coh901318_remove(struct platform_device *pdev) dma_async_device_unregister(&base->dma_slave); coh901318_pool_destroy(&base->pool); free_irq(platform_get_irq(pdev, 0), base); - kfree(base); iounmap(base->virtbase); + kfree(base); release_mem_region(pdev->resource->start, resource_size(pdev->resource)); return 0; -- cgit v0.10.2 From 01136acff8cc8251822fbae77f11e8029049c6f1 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Mon, 21 Dec 2009 02:24:47 +0100 Subject: DRM: Rename clamp variable linux/kernel.h has a "clamp" macro, but r300_cmdbuf also uses a variable with the same name. Right now it doesn't seem to include the header, but sooner or later someone will. So better rename the variable now. Signed-off-by: Andi Kleen Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/r300_cmdbuf.c b/drivers/gpu/drm/radeon/r300_cmdbuf.c index cb2e470..34bffa0 100644 --- a/drivers/gpu/drm/radeon/r300_cmdbuf.c +++ b/drivers/gpu/drm/radeon/r300_cmdbuf.c @@ -990,7 +990,7 @@ static inline int r300_emit_r500fp(drm_radeon_private_t *dev_priv, int sz; int addr; int type; - int clamp; + int isclamp; int stride; RING_LOCALS; @@ -999,10 +999,10 @@ static inline int r300_emit_r500fp(drm_radeon_private_t *dev_priv, addr = ((header.r500fp.adrhi_flags & 1) << 8) | header.r500fp.adrlo; type = !!(header.r500fp.adrhi_flags & R500FP_CONSTANT_TYPE); - clamp = !!(header.r500fp.adrhi_flags & R500FP_CONSTANT_CLAMP); + isclamp = !!(header.r500fp.adrhi_flags & R500FP_CONSTANT_CLAMP); addr |= (type << 16); - addr |= (clamp << 17); + addr |= (isclamp << 17); stride = type ? 4 : 6; -- cgit v0.10.2 From e265f39e1ff026dcc787f1953c048f3de5aefd16 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 19 Dec 2009 08:16:33 +0100 Subject: drivers/gpu: Use kzalloc for allocating only one thing Use kzalloc rather than kcalloc(1,...) The use of the allocated memory that looks like an array is &p->relocs[0], but this should be the same as p->relocs. The semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ @@ - kcalloc(1, + kzalloc( ...) // Signed-off-by: Julia Lawall Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index 0d82076..44060b9 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c @@ -170,7 +170,7 @@ static int r600_cs_packet_next_reloc_nomm(struct radeon_cs_parser *p, idx, relocs_chunk->length_dw); return -EINVAL; } - *cs_reloc = &p->relocs[0]; + *cs_reloc = p->relocs; (*cs_reloc)->lobj.gpu_offset = (u64)relocs_chunk->kdata[idx + 3] << 32; (*cs_reloc)->lobj.gpu_offset |= relocs_chunk->kdata[idx + 0]; return 0; @@ -717,7 +717,7 @@ static int r600_cs_parser_relocs_legacy(struct radeon_cs_parser *p) if (p->chunk_relocs_idx == -1) { return 0; } - p->relocs = kcalloc(1, sizeof(struct radeon_cs_reloc), GFP_KERNEL); + p->relocs = kzalloc(sizeof(struct radeon_cs_reloc), GFP_KERNEL); if (p->relocs == NULL) { return -ENOMEM; } -- cgit v0.10.2 From 794f3141a194a4f4c28c1d417b071a901f78d9bb Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sun, 20 Dec 2009 16:08:40 +1000 Subject: drm/radeon: fix build on 64-bit with some compilers. drivers/gpu/drm/radeon/radeon_test.c:45: undefined reference to `__udivdi3' Reported-by: Mr. James W. Laferriere Cc: stable@kernel.org Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/radeon_test.c b/drivers/gpu/drm/radeon/radeon_test.c index 391c973..9f5e2f9 100644 --- a/drivers/gpu/drm/radeon/radeon_test.c +++ b/drivers/gpu/drm/radeon/radeon_test.c @@ -42,8 +42,8 @@ void radeon_test_moves(struct radeon_device *rdev) /* Number of tests = * (Total GTT - IB pool - writeback page - ring buffer) / test size */ - n = (rdev->mc.gtt_size - RADEON_IB_POOL_SIZE*64*1024 - RADEON_GPU_PAGE_SIZE - - rdev->cp.ring_size) / size; + n = ((u32)(rdev->mc.gtt_size - RADEON_IB_POOL_SIZE*64*1024 - RADEON_GPU_PAGE_SIZE - + rdev->cp.ring_size)) / size; gtt_obj = kzalloc(n * sizeof(*gtt_obj), GFP_KERNEL); if (!gtt_obj) { -- cgit v0.10.2 From e1f7800315d78686481b27b113a3317ac687b6bf Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 8 Dec 2009 12:57:51 +0100 Subject: drm/vmwgfx: Fix unlocked ioctl and add proper access control This fixes up vmwgfx for the unlocked ioctl code to avoid doing it in the driver. Also adds ioctl flags. Signed-off-by: Thomas Hellstrom Signed-off-by: Jakob Bornecrantz Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 7b48bb3..1db1ef3 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -103,37 +103,39 @@ */ static struct drm_ioctl_desc vmw_ioctls[] = { - VMW_IOCTL_DEF(DRM_IOCTL_VMW_GET_PARAM, vmw_getparam_ioctl, 0), + VMW_IOCTL_DEF(DRM_IOCTL_VMW_GET_PARAM, vmw_getparam_ioctl, + DRM_AUTH | DRM_UNLOCKED), VMW_IOCTL_DEF(DRM_IOCTL_VMW_ALLOC_DMABUF, vmw_dmabuf_alloc_ioctl, - 0), + DRM_AUTH | DRM_UNLOCKED), VMW_IOCTL_DEF(DRM_IOCTL_VMW_UNREF_DMABUF, vmw_dmabuf_unref_ioctl, - 0), + DRM_AUTH | DRM_UNLOCKED), VMW_IOCTL_DEF(DRM_IOCTL_VMW_CURSOR_BYPASS, - vmw_kms_cursor_bypass_ioctl, 0), + vmw_kms_cursor_bypass_ioctl, + DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED), VMW_IOCTL_DEF(DRM_IOCTL_VMW_CONTROL_STREAM, vmw_overlay_ioctl, - 0), + DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED), VMW_IOCTL_DEF(DRM_IOCTL_VMW_CLAIM_STREAM, vmw_stream_claim_ioctl, - 0), + DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED), VMW_IOCTL_DEF(DRM_IOCTL_VMW_UNREF_STREAM, vmw_stream_unref_ioctl, - 0), + DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED), VMW_IOCTL_DEF(DRM_IOCTL_VMW_CREATE_CONTEXT, vmw_context_define_ioctl, - 0), + DRM_AUTH | DRM_UNLOCKED), VMW_IOCTL_DEF(DRM_IOCTL_VMW_UNREF_CONTEXT, vmw_context_destroy_ioctl, - 0), + DRM_AUTH | DRM_UNLOCKED), VMW_IOCTL_DEF(DRM_IOCTL_VMW_CREATE_SURFACE, vmw_surface_define_ioctl, - 0), + DRM_AUTH | DRM_UNLOCKED), VMW_IOCTL_DEF(DRM_IOCTL_VMW_UNREF_SURFACE, vmw_surface_destroy_ioctl, - 0), + DRM_AUTH | DRM_UNLOCKED), VMW_IOCTL_DEF(DRM_IOCTL_VMW_REF_SURFACE, vmw_surface_reference_ioctl, - 0), + DRM_AUTH | DRM_UNLOCKED), VMW_IOCTL_DEF(DRM_IOCTL_VMW_EXECBUF, vmw_execbuf_ioctl, - 0), + DRM_AUTH | DRM_UNLOCKED), VMW_IOCTL_DEF(DRM_IOCTL_VMW_FIFO_DEBUG, vmw_fifo_debug_ioctl, - 0), + DRM_AUTH | DRM_ROOT_ONLY | DRM_MASTER | DRM_UNLOCKED), VMW_IOCTL_DEF(DRM_IOCTL_VMW_FENCE_WAIT, vmw_fence_wait_ioctl, - 0) + DRM_AUTH | DRM_UNLOCKED) }; static struct pci_device_id vmw_pci_id_list[] = { @@ -460,11 +462,9 @@ static long vmw_unlocked_ioctl(struct file *filp, unsigned int cmd, struct drm_file *file_priv = filp->private_data; struct drm_device *dev = file_priv->minor->dev; unsigned int nr = DRM_IOCTL_NR(cmd); - long ret; /* - * The driver private ioctls and TTM ioctls should be - * thread-safe. + * Do extra checking on driver private ioctls. */ if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END) @@ -477,18 +477,9 @@ static long vmw_unlocked_ioctl(struct file *filp, unsigned int cmd, nr - DRM_COMMAND_BASE); return -EINVAL; } - return drm_ioctl(filp->f_path.dentry->d_inode, - filp, cmd, arg); } - /* - * Not all old drm ioctls are thread-safe. - */ - - lock_kernel(); - ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg); - unlock_kernel(); - return ret; + return drm_ioctl(filp, cmd, arg); } static int vmw_firstopen(struct drm_device *dev) -- cgit v0.10.2 From 3d3a5b3290043618e8409f3fb68a63de6156fdd4 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 8 Dec 2009 12:59:34 +0100 Subject: drm/vmwgfx: Return -ERESTARTSYS when interrupted by a signal. Fixes for TTM API change. Signed-off-by: Thomas Hellstrom Signed-off-by: Jakob Bornecrantz Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 7a39f3e..7e73cf5 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -386,7 +386,7 @@ static int vmw_validate_single_buffer(struct vmw_private *dev_priv, return 0; ret = vmw_gmr_bind(dev_priv, bo); - if (likely(ret == 0 || ret == -ERESTART)) + if (likely(ret == 0 || ret == -ERESTARTSYS)) return ret; @@ -429,7 +429,7 @@ int vmw_execbuf_ioctl(struct drm_device *dev, void *data, ret = mutex_lock_interruptible(&dev_priv->cmdbuf_mutex); if (unlikely(ret != 0)) { - ret = -ERESTART; + ret = -ERESTARTSYS; goto out_no_cmd_mutex; } diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c index 76b0693..01feb48 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c @@ -191,7 +191,7 @@ static int vmw_fifo_wait_noirq(struct vmw_private *dev_priv, } schedule_timeout(1); if (interruptible && signal_pending(current)) { - ret = -ERESTART; + ret = -ERESTARTSYS; break; } } @@ -237,9 +237,7 @@ static int vmw_fifo_wait(struct vmw_private *dev_priv, (dev_priv->fifo_queue, !vmw_fifo_is_full(dev_priv, bytes), timeout); - if (unlikely(ret == -ERESTARTSYS)) - ret = -ERESTART; - else if (unlikely(ret == 0)) + if (unlikely(ret == 0)) ret = -EBUSY; else if (likely(ret > 0)) ret = 0; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c b/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c index 9e0f030..d40086f 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c @@ -155,7 +155,7 @@ int vmw_fallback_wait(struct vmw_private *dev_priv, TASK_UNINTERRUPTIBLE); } if (interruptible && signal_pending(current)) { - ret = -ERESTART; + ret = -ERESTARTSYS; break; } } @@ -218,9 +218,7 @@ int vmw_wait_fence(struct vmw_private *dev_priv, vmw_fence_signaled(dev_priv, sequence), timeout); - if (unlikely(ret == -ERESTARTSYS)) - ret = -ERESTART; - else if (unlikely(ret == 0)) + if (unlikely(ret == 0)) ret = -EBUSY; else if (likely(ret > 0)) ret = 0; -- cgit v0.10.2 From 7a73ba7469cbea631050094fd14f73acebb97cf9 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 22 Dec 2009 16:53:41 +0100 Subject: drm/vmwgfx: Use TTM handles instead of SIDs as user-space surface handles. Improve the command verifier to catch all occurences of surface handles, and translate to SIDs. This way DMA buffers and 3D surfaces share a common handle space, which makes it possible for the kms code to differentiate. Signed-off-by: Thomas Hellstrom Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 43546d0..e61bd85 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -123,6 +123,7 @@ struct vmw_sw_context{ uint32_t last_cid; bool cid_valid; uint32_t last_sid; + uint32_t sid_translation; bool sid_valid; struct ttm_object_file *tfile; struct list_head validate_nodes; @@ -317,9 +318,10 @@ extern void vmw_surface_res_free(struct vmw_resource *res); extern int vmw_surface_init(struct vmw_private *dev_priv, struct vmw_surface *srf, void (*res_free) (struct vmw_resource *res)); -extern int vmw_user_surface_lookup(struct vmw_private *dev_priv, - struct ttm_object_file *tfile, - int sid, struct vmw_surface **out); +extern int vmw_user_surface_lookup_handle(struct vmw_private *dev_priv, + struct ttm_object_file *tfile, + uint32_t handle, + struct vmw_surface **out); extern int vmw_surface_destroy_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int vmw_surface_define_ioctl(struct drm_device *dev, void *data, @@ -328,7 +330,7 @@ extern int vmw_surface_reference_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int vmw_surface_check(struct vmw_private *dev_priv, struct ttm_object_file *tfile, - int id); + uint32_t handle, int *id); extern void vmw_dmabuf_bo_free(struct ttm_buffer_object *bo); extern int vmw_dmabuf_init(struct vmw_private *dev_priv, struct vmw_dma_buffer *vmw_bo, diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 7e73cf5..2e92da5 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -73,21 +73,32 @@ static int vmw_cmd_cid_check(struct vmw_private *dev_priv, static int vmw_cmd_sid_check(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, - uint32_t sid) + uint32_t *sid) { - if (unlikely((!sw_context->sid_valid || sid != sw_context->last_sid) && - sid != SVGA3D_INVALID_ID)) { - int ret = vmw_surface_check(dev_priv, sw_context->tfile, sid); + if (*sid == SVGA3D_INVALID_ID) + return 0; + + if (unlikely((!sw_context->sid_valid || + *sid != sw_context->last_sid))) { + int real_id; + int ret = vmw_surface_check(dev_priv, sw_context->tfile, + *sid, &real_id); if (unlikely(ret != 0)) { - DRM_ERROR("Could ot find or use surface %u\n", - (unsigned) sid); + DRM_ERROR("Could ot find or use surface 0x%08x " + "address 0x%08lx\n", + (unsigned int) *sid, + (unsigned long) sid); return ret; } - sw_context->last_sid = sid; + sw_context->last_sid = *sid; sw_context->sid_valid = true; - } + *sid = real_id; + sw_context->sid_translation = real_id; + } else + *sid = sw_context->sid_translation; + return 0; } @@ -107,7 +118,8 @@ static int vmw_cmd_set_render_target_check(struct vmw_private *dev_priv, return ret; cmd = container_of(header, struct vmw_sid_cmd, header); - return vmw_cmd_sid_check(dev_priv, sw_context, cmd->body.target.sid); + ret = vmw_cmd_sid_check(dev_priv, sw_context, &cmd->body.target.sid); + return ret; } static int vmw_cmd_surface_copy_check(struct vmw_private *dev_priv, @@ -121,10 +133,10 @@ static int vmw_cmd_surface_copy_check(struct vmw_private *dev_priv, int ret; cmd = container_of(header, struct vmw_sid_cmd, header); - ret = vmw_cmd_sid_check(dev_priv, sw_context, cmd->body.src.sid); + ret = vmw_cmd_sid_check(dev_priv, sw_context, &cmd->body.src.sid); if (unlikely(ret != 0)) return ret; - return vmw_cmd_sid_check(dev_priv, sw_context, cmd->body.dest.sid); + return vmw_cmd_sid_check(dev_priv, sw_context, &cmd->body.dest.sid); } static int vmw_cmd_stretch_blt_check(struct vmw_private *dev_priv, @@ -138,10 +150,10 @@ static int vmw_cmd_stretch_blt_check(struct vmw_private *dev_priv, int ret; cmd = container_of(header, struct vmw_sid_cmd, header); - ret = vmw_cmd_sid_check(dev_priv, sw_context, cmd->body.src.sid); + ret = vmw_cmd_sid_check(dev_priv, sw_context, &cmd->body.src.sid); if (unlikely(ret != 0)) return ret; - return vmw_cmd_sid_check(dev_priv, sw_context, cmd->body.dest.sid); + return vmw_cmd_sid_check(dev_priv, sw_context, &cmd->body.dest.sid); } static int vmw_cmd_blt_surf_screen_check(struct vmw_private *dev_priv, @@ -154,7 +166,7 @@ static int vmw_cmd_blt_surf_screen_check(struct vmw_private *dev_priv, } *cmd; cmd = container_of(header, struct vmw_sid_cmd, header); - return vmw_cmd_sid_check(dev_priv, sw_context, cmd->body.srcImage.sid); + return vmw_cmd_sid_check(dev_priv, sw_context, &cmd->body.srcImage.sid); } static int vmw_cmd_present_check(struct vmw_private *dev_priv, @@ -167,7 +179,7 @@ static int vmw_cmd_present_check(struct vmw_private *dev_priv, } *cmd; cmd = container_of(header, struct vmw_sid_cmd, header); - return vmw_cmd_sid_check(dev_priv, sw_context, cmd->body.sid); + return vmw_cmd_sid_check(dev_priv, sw_context, &cmd->body.sid); } static int vmw_cmd_dma(struct vmw_private *dev_priv, @@ -187,12 +199,7 @@ static int vmw_cmd_dma(struct vmw_private *dev_priv, uint32_t cur_validate_node; struct ttm_validate_buffer *val_buf; - cmd = container_of(header, struct vmw_dma_cmd, header); - ret = vmw_cmd_sid_check(dev_priv, sw_context, cmd->dma.host.sid); - if (unlikely(ret != 0)) - return ret; - handle = cmd->dma.guest.ptr.gmrId; ret = vmw_user_dmabuf_lookup(sw_context->tfile, handle, &vmw_bo); if (unlikely(ret != 0)) { @@ -228,14 +235,23 @@ static int vmw_cmd_dma(struct vmw_private *dev_priv, ++sw_context->cur_val_buf; } - ret = vmw_user_surface_lookup(dev_priv, sw_context->tfile, - cmd->dma.host.sid, &srf); + ret = vmw_user_surface_lookup_handle(dev_priv, sw_context->tfile, + cmd->dma.host.sid, &srf); if (ret) { DRM_ERROR("could not find surface\n"); goto out_no_reloc; } + /** + * Patch command stream with device SID. + */ + + cmd->dma.host.sid = srf->res.id; vmw_kms_cursor_snoop(srf, sw_context->tfile, bo, header); + /** + * FIXME: May deadlock here when called from the + * command parsing code. + */ vmw_surface_unreference(&srf); out_no_reloc: @@ -243,6 +259,90 @@ out_no_reloc: return ret; } +static int vmw_cmd_draw(struct vmw_private *dev_priv, + struct vmw_sw_context *sw_context, + SVGA3dCmdHeader *header) +{ + struct vmw_draw_cmd { + SVGA3dCmdHeader header; + SVGA3dCmdDrawPrimitives body; + } *cmd; + SVGA3dVertexDecl *decl = (SVGA3dVertexDecl *)( + (unsigned long)header + sizeof(*cmd)); + SVGA3dPrimitiveRange *range; + uint32_t i; + uint32_t maxnum; + int ret; + + ret = vmw_cmd_cid_check(dev_priv, sw_context, header); + if (unlikely(ret != 0)) + return ret; + + cmd = container_of(header, struct vmw_draw_cmd, header); + maxnum = (header->size - sizeof(cmd->body)) / sizeof(*decl); + + if (unlikely(cmd->body.numVertexDecls > maxnum)) { + DRM_ERROR("Illegal number of vertex declarations.\n"); + return -EINVAL; + } + + for (i = 0; i < cmd->body.numVertexDecls; ++i, ++decl) { + ret = vmw_cmd_sid_check(dev_priv, sw_context, + &decl->array.surfaceId); + if (unlikely(ret != 0)) + return ret; + } + + maxnum = (header->size - sizeof(cmd->body) - + cmd->body.numVertexDecls * sizeof(*decl)) / sizeof(*range); + if (unlikely(cmd->body.numRanges > maxnum)) { + DRM_ERROR("Illegal number of index ranges.\n"); + return -EINVAL; + } + + range = (SVGA3dPrimitiveRange *) decl; + for (i = 0; i < cmd->body.numRanges; ++i, ++range) { + ret = vmw_cmd_sid_check(dev_priv, sw_context, + &range->indexArray.surfaceId); + if (unlikely(ret != 0)) + return ret; + } + return 0; +} + + +static int vmw_cmd_tex_state(struct vmw_private *dev_priv, + struct vmw_sw_context *sw_context, + SVGA3dCmdHeader *header) +{ + struct vmw_tex_state_cmd { + SVGA3dCmdHeader header; + SVGA3dCmdSetTextureState state; + }; + + SVGA3dTextureState *last_state = (SVGA3dTextureState *) + ((unsigned long) header + header->size + sizeof(header)); + SVGA3dTextureState *cur_state = (SVGA3dTextureState *) + ((unsigned long) header + sizeof(struct vmw_tex_state_cmd)); + int ret; + + ret = vmw_cmd_cid_check(dev_priv, sw_context, header); + if (unlikely(ret != 0)) + return ret; + + for (; cur_state < last_state; ++cur_state) { + if (likely(cur_state->name != SVGA3D_TS_BIND_TEXTURE)) + continue; + + ret = vmw_cmd_sid_check(dev_priv, sw_context, + &cur_state->value); + if (unlikely(ret != 0)) + return ret; + } + + return 0; +} + typedef int (*vmw_cmd_func) (struct vmw_private *, struct vmw_sw_context *, @@ -264,7 +364,7 @@ static vmw_cmd_func vmw_cmd_funcs[SVGA_3D_CMD_MAX] = { VMW_CMD_DEF(SVGA_3D_CMD_SETRENDERSTATE, &vmw_cmd_cid_check), VMW_CMD_DEF(SVGA_3D_CMD_SETRENDERTARGET, &vmw_cmd_set_render_target_check), - VMW_CMD_DEF(SVGA_3D_CMD_SETTEXTURESTATE, &vmw_cmd_cid_check), + VMW_CMD_DEF(SVGA_3D_CMD_SETTEXTURESTATE, &vmw_cmd_tex_state), VMW_CMD_DEF(SVGA_3D_CMD_SETMATERIAL, &vmw_cmd_cid_check), VMW_CMD_DEF(SVGA_3D_CMD_SETLIGHTDATA, &vmw_cmd_cid_check), VMW_CMD_DEF(SVGA_3D_CMD_SETLIGHTENABLED, &vmw_cmd_cid_check), @@ -276,7 +376,7 @@ static vmw_cmd_func vmw_cmd_funcs[SVGA_3D_CMD_MAX] = { VMW_CMD_DEF(SVGA_3D_CMD_SHADER_DESTROY, &vmw_cmd_cid_check), VMW_CMD_DEF(SVGA_3D_CMD_SET_SHADER, &vmw_cmd_cid_check), VMW_CMD_DEF(SVGA_3D_CMD_SET_SHADER_CONST, &vmw_cmd_cid_check), - VMW_CMD_DEF(SVGA_3D_CMD_DRAW_PRIMITIVES, &vmw_cmd_cid_check), + VMW_CMD_DEF(SVGA_3D_CMD_DRAW_PRIMITIVES, &vmw_cmd_draw), VMW_CMD_DEF(SVGA_3D_CMD_SETSCISSORRECT, &vmw_cmd_cid_check), VMW_CMD_DEF(SVGA_3D_CMD_BEGIN_QUERY, &vmw_cmd_cid_check), VMW_CMD_DEF(SVGA_3D_CMD_END_QUERY, &vmw_cmd_cid_check), @@ -291,6 +391,7 @@ static int vmw_cmd_check(struct vmw_private *dev_priv, void *buf, uint32_t *size) { uint32_t cmd_id; + uint32_t size_remaining = *size; SVGA3dCmdHeader *header = (SVGA3dCmdHeader *) buf; int ret; @@ -304,6 +405,9 @@ static int vmw_cmd_check(struct vmw_private *dev_priv, *size = le32_to_cpu(header->size) + sizeof(SVGA3dCmdHeader); cmd_id -= SVGA_3D_CMD_BASE; + if (unlikely(*size > size_remaining)) + goto out_err; + if (unlikely(cmd_id >= SVGA_3D_CMD_MAX - SVGA_3D_CMD_BASE)) goto out_err; @@ -326,6 +430,7 @@ static int vmw_cmd_check_all(struct vmw_private *dev_priv, int ret; while (cur_size > 0) { + size = cur_size; ret = vmw_cmd_check(dev_priv, sw_context, buf, &size); if (unlikely(ret != 0)) return ret; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index e9403be..b1af76e 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -106,8 +106,8 @@ int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, int ret; if (handle) { - ret = vmw_user_surface_lookup(dev_priv, tfile, - handle, &surface); + ret = vmw_user_surface_lookup_handle(dev_priv, tfile, + handle, &surface); if (!ret) { if (!surface->snooper.image) { DRM_ERROR("surface not suitable for cursor\n"); @@ -704,8 +704,8 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev, struct vmw_dma_buffer *bo = NULL; int ret; - ret = vmw_user_surface_lookup(dev_priv, tfile, - mode_cmd->handle, &surface); + ret = vmw_user_surface_lookup_handle(dev_priv, tfile, + mode_cmd->handle, &surface); if (ret) goto try_dmabuf; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c index a1ceed0..c012d59 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c @@ -488,28 +488,44 @@ static void vmw_user_surface_free(struct vmw_resource *res) kfree(user_srf); } -int vmw_user_surface_lookup(struct vmw_private *dev_priv, - struct ttm_object_file *tfile, - int sid, struct vmw_surface **out) +int vmw_user_surface_lookup_handle(struct vmw_private *dev_priv, + struct ttm_object_file *tfile, + uint32_t handle, struct vmw_surface **out) { struct vmw_resource *res; struct vmw_surface *srf; struct vmw_user_surface *user_srf; + struct ttm_base_object *base; + int ret = -EINVAL; - res = vmw_resource_lookup(dev_priv, &dev_priv->surface_idr, sid); - if (unlikely(res == NULL)) + base = ttm_base_object_lookup(tfile, handle); + if (unlikely(base == NULL)) return -EINVAL; - if (res->res_free != &vmw_user_surface_free) - return -EINVAL; + if (unlikely(base->object_type != VMW_RES_SURFACE)) + goto out_bad_resource; - srf = container_of(res, struct vmw_surface, res); - user_srf = container_of(srf, struct vmw_user_surface, srf); - if (user_srf->base.tfile != tfile && !user_srf->base.shareable) - return -EPERM; + user_srf = container_of(base, struct vmw_user_surface, base); + srf = &user_srf->srf; + res = &srf->res; + + read_lock(&dev_priv->resource_lock); + + if (!res->avail || res->res_free != &vmw_user_surface_free) { + read_unlock(&dev_priv->resource_lock); + goto out_bad_resource; + } + + kref_get(&res->kref); + read_unlock(&dev_priv->resource_lock); *out = srf; - return 0; + ret = 0; + +out_bad_resource: + ttm_base_object_unref(&base); + + return ret; } static void vmw_user_surface_base_release(struct ttm_base_object **p_base) @@ -526,35 +542,10 @@ static void vmw_user_surface_base_release(struct ttm_base_object **p_base) int vmw_surface_destroy_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { - struct vmw_private *dev_priv = vmw_priv(dev); - struct vmw_resource *res; - struct vmw_surface *srf; - struct vmw_user_surface *user_srf; struct drm_vmw_surface_arg *arg = (struct drm_vmw_surface_arg *)data; struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; - int ret = 0; - - res = vmw_resource_lookup(dev_priv, &dev_priv->surface_idr, arg->sid); - if (unlikely(res == NULL)) - return -EINVAL; - - if (res->res_free != &vmw_user_surface_free) { - ret = -EINVAL; - goto out; - } - srf = container_of(res, struct vmw_surface, res); - user_srf = container_of(srf, struct vmw_user_surface, srf); - if (user_srf->base.tfile != tfile && !user_srf->base.shareable) { - ret = -EPERM; - goto out; - } - - ttm_ref_object_base_unref(tfile, user_srf->base.hash.key, - TTM_REF_USAGE); -out: - vmw_resource_unreference(&res); - return ret; + return ttm_ref_object_base_unref(tfile, arg->sid, TTM_REF_USAGE); } int vmw_surface_define_ioctl(struct drm_device *dev, void *data, @@ -649,7 +640,10 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data, } srf->snooper.crtc = NULL; - rep->sid = res->id; + rep->sid = user_srf->base.hash.key; + if (rep->sid == SVGA3D_INVALID_ID) + DRM_ERROR("Created bad Surface ID.\n"); + vmw_resource_unreference(&res); return 0; out_err1: @@ -662,39 +656,33 @@ out_err0: int vmw_surface_reference_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { - struct vmw_private *dev_priv = vmw_priv(dev); union drm_vmw_surface_reference_arg *arg = (union drm_vmw_surface_reference_arg *)data; struct drm_vmw_surface_arg *req = &arg->req; struct drm_vmw_surface_create_req *rep = &arg->rep; struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; - struct vmw_resource *res; struct vmw_surface *srf; struct vmw_user_surface *user_srf; struct drm_vmw_size __user *user_sizes; - int ret; + struct ttm_base_object *base; + int ret = -EINVAL; - res = vmw_resource_lookup(dev_priv, &dev_priv->surface_idr, req->sid); - if (unlikely(res == NULL)) + base = ttm_base_object_lookup(tfile, req->sid); + if (unlikely(base == NULL)) { + DRM_ERROR("Could not find surface to reference.\n"); return -EINVAL; - - if (res->res_free != &vmw_user_surface_free) { - ret = -EINVAL; - goto out; } - srf = container_of(res, struct vmw_surface, res); - user_srf = container_of(srf, struct vmw_user_surface, srf); - if (user_srf->base.tfile != tfile && !user_srf->base.shareable) { - DRM_ERROR("Tried to reference none shareable surface\n"); - ret = -EPERM; - goto out; - } + if (unlikely(base->object_type != VMW_RES_SURFACE)) + goto out_bad_resource; + + user_srf = container_of(base, struct vmw_user_surface, base); + srf = &user_srf->srf; ret = ttm_ref_object_add(tfile, &user_srf->base, TTM_REF_USAGE, NULL); if (unlikely(ret != 0)) { DRM_ERROR("Could not add a reference to a surface.\n"); - goto out; + goto out_no_reference; } rep->flags = srf->flags; @@ -706,40 +694,43 @@ int vmw_surface_reference_ioctl(struct drm_device *dev, void *data, if (user_sizes) ret = copy_to_user(user_sizes, srf->sizes, srf->num_sizes * sizeof(*srf->sizes)); - if (unlikely(ret != 0)) { + if (unlikely(ret != 0)) DRM_ERROR("copy_to_user failed %p %u\n", user_sizes, srf->num_sizes); - /** - * FIXME: Unreference surface here? - */ - goto out; - } -out: - vmw_resource_unreference(&res); +out_bad_resource: +out_no_reference: + ttm_base_object_unref(&base); + return ret; } int vmw_surface_check(struct vmw_private *dev_priv, struct ttm_object_file *tfile, - int id) + uint32_t handle, int *id) { - struct vmw_resource *res; - int ret = 0; + struct ttm_base_object *base; + struct vmw_user_surface *user_srf; - read_lock(&dev_priv->resource_lock); - res = idr_find(&dev_priv->surface_idr, id); - if (res && res->avail) { - struct vmw_surface *srf = - container_of(res, struct vmw_surface, res); - struct vmw_user_surface *usrf = - container_of(srf, struct vmw_user_surface, srf); + int ret = -EPERM; - if (usrf->base.tfile != tfile && !usrf->base.shareable) - ret = -EPERM; - } else - ret = -EINVAL; - read_unlock(&dev_priv->resource_lock); + base = ttm_base_object_lookup(tfile, handle); + if (unlikely(base == NULL)) + return -EINVAL; + + if (unlikely(base->object_type != VMW_RES_SURFACE)) + goto out_bad_surface; + user_srf = container_of(base, struct vmw_user_surface, base); + *id = user_srf->srf.res.id; + ret = 0; + +out_bad_surface: + /** + * FIXME: May deadlock here when called from the + * command parsing code. + */ + + ttm_base_object_unref(&base); return ret; } -- cgit v0.10.2 From e2108eb1f66d77b4af77caf282cab1d47e3f4831 Mon Sep 17 00:00:00 2001 From: Bob Gleitsmann Date: Mon, 21 Dec 2009 13:52:09 +1000 Subject: drm/mm: fix logic for selection of best fit block This is from bug 25728. [airlied: I'm just forwarding the patch for review, Thomas, ickle?] Acked-by: Jerome Glisse Acked-by: Thomas Hellstrom Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index d7d7eac..cdec329 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c @@ -358,7 +358,7 @@ struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm, if (entry->size >= size + wasted) { if (!best_match) return entry; - if (size < best_size) { + if (entry->size < best_size) { best = entry; best_size = entry->size; } @@ -408,7 +408,7 @@ struct drm_mm_node *drm_mm_search_free_in_range(const struct drm_mm *mm, if (entry->size >= size + wasted) { if (!best_match) return entry; - if (size < best_size) { + if (entry->size < best_size) { best = entry; best_size = entry->size; } -- cgit v0.10.2 From 29ebdf925c2c45f6531a953c6c5c8e4d3b4ac2dc Mon Sep 17 00:00:00 2001 From: Marin Mitov Date: Sun, 20 Dec 2009 09:03:27 +0200 Subject: drm/kms: silencing a false positive warning. warning: 'width' may be used uninitialized in this function drivers/gpu/drm/drm_edid.c Signed-off-by: Marin Mitov Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index c39b26f..5c9f798 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -913,7 +913,7 @@ static int drm_cvt_modes(struct drm_connector *connector, const int rates[] = { 60, 85, 75, 60, 50 }; for (i = 0; i < 4; i++) { - int width, height; + int uninitialized_var(width), height; cvt = &(timing->data.other_data.data.cvt[i]); height = (cvt->code[0] + ((cvt->code[1] & 0xf0) << 8) + 1) * 2; -- cgit v0.10.2 From edc664e314d5dadc326cfc15a536fe906d652204 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 17 Dec 2009 11:22:01 -0500 Subject: drm/radeon/kms/atom: fill in proper defines for digital setup Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index 0d1d908..547fe10 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c @@ -495,9 +495,9 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) args.v1.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE; args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { - if (dig->lvds_misc & (1 << 0)) + if (dig->lvds_misc & ATOM_PANEL_MISC_DUAL) args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL; - if (dig->lvds_misc & (1 << 1)) + if (dig->lvds_misc & ATOM_PANEL_MISC_888RGB) args.v1.ucMisc |= (1 << 1); } else { if (dig_connector->linkb) @@ -524,18 +524,18 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) args.v2.ucTemporal = 0; args.v2.ucFRC = 0; if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { - if (dig->lvds_misc & (1 << 0)) + if (dig->lvds_misc & ATOM_PANEL_MISC_DUAL) args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL; - if (dig->lvds_misc & (1 << 5)) { + if (dig->lvds_misc & ATOM_PANEL_MISC_SPATIAL) { args.v2.ucSpatial = PANEL_ENCODER_SPATIAL_DITHER_EN; - if (dig->lvds_misc & (1 << 1)) + if (dig->lvds_misc & ATOM_PANEL_MISC_888RGB) args.v2.ucSpatial |= PANEL_ENCODER_SPATIAL_DITHER_DEPTH; } - if (dig->lvds_misc & (1 << 6)) { + if (dig->lvds_misc & ATOM_PANEL_MISC_TEMPORAL) { args.v2.ucTemporal = PANEL_ENCODER_TEMPORAL_DITHER_EN; - if (dig->lvds_misc & (1 << 1)) + if (dig->lvds_misc & ATOM_PANEL_MISC_888RGB) args.v2.ucTemporal |= PANEL_ENCODER_TEMPORAL_DITHER_DEPTH; - if (((dig->lvds_misc >> 2) & 0x3) == 2) + if (((dig->lvds_misc >> ATOM_PANEL_MISC_GREY_LEVEL_SHIFT) & 0x3) == 2) args.v2.ucTemporal |= PANEL_ENCODER_TEMPORAL_LEVEL_4; } } else { -- cgit v0.10.2 From 310a82c8c5fc431913fe34a17251118e71c2c876 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 17 Dec 2009 01:24:59 -0500 Subject: drm/radeon/kms: fix legacy rmx This makes 640x480 on my R100 work again, both in aspect and centered mode. Signed-off-by: Alex Deucher Tested-by: Dave Airlie Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index 547fe10..ccba95f 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c @@ -233,6 +233,8 @@ static bool radeon_atom_mode_fixup(struct drm_encoder *encoder, if (!ASIC_IS_AVIVO(rdev)) { adjusted_mode->hdisplay = mode->hdisplay; adjusted_mode->vdisplay = mode->vdisplay; + adjusted_mode->crtc_hdisplay = mode->hdisplay; + adjusted_mode->crtc_vdisplay = mode->vdisplay; } adjusted_mode->base.id = mode_id; } diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index b82ede9..cc27485 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c @@ -43,8 +43,7 @@ static void radeon_overscan_setup(struct drm_crtc *crtc, } static void radeon_legacy_rmx_mode_set(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) + struct drm_display_mode *mode) { struct drm_device *dev = crtc->dev; struct radeon_device *rdev = dev->dev_private; @@ -1059,7 +1058,7 @@ static int radeon_crtc_mode_set(struct drm_crtc *crtc, radeon_set_pll(crtc, adjusted_mode); radeon_overscan_setup(crtc, adjusted_mode); if (radeon_crtc->crtc_id == 0) { - radeon_legacy_rmx_mode_set(crtc, mode, adjusted_mode); + radeon_legacy_rmx_mode_set(crtc, adjusted_mode); } else { if (radeon_crtc->rmx_type != RMX_OFF) { /* FIXME: only first crtc has rmx what should we diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c index df00515..981508f 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c @@ -207,6 +207,8 @@ static bool radeon_legacy_mode_fixup(struct drm_encoder *encoder, *adjusted_mode = *native_mode; adjusted_mode->hdisplay = mode->hdisplay; adjusted_mode->vdisplay = mode->vdisplay; + adjusted_mode->crtc_hdisplay = mode->hdisplay; + adjusted_mode->crtc_vdisplay = mode->vdisplay; adjusted_mode->base.id = mode_id; } -- cgit v0.10.2 From d79766fab9975c6414ebab7d2abf017834a48c35 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 17 Dec 2009 19:00:29 -0500 Subject: drm/radeon/kms: set proper default tv standard we were just using 1 before. reported on irc by soreau Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 12a0c76..b5912c2 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -1234,6 +1234,61 @@ bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index, return true; } +enum radeon_tv_std +radeon_atombios_get_tv_info(struct radeon_device *rdev) +{ + struct radeon_mode_info *mode_info = &rdev->mode_info; + int index = GetIndexIntoMasterTable(DATA, AnalogTV_Info); + uint16_t data_offset; + uint8_t frev, crev; + struct _ATOM_ANALOG_TV_INFO *tv_info; + enum radeon_tv_std tv_std = TV_STD_NTSC; + + atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset); + + tv_info = (struct _ATOM_ANALOG_TV_INFO *)(mode_info->atom_context->bios + data_offset); + + switch (tv_info->ucTV_BootUpDefaultStandard) { + case ATOM_TV_NTSC: + tv_std = TV_STD_NTSC; + DRM_INFO("Default TV standard: NTSC\n"); + break; + case ATOM_TV_NTSCJ: + tv_std = TV_STD_NTSC_J; + DRM_INFO("Default TV standard: NTSC-J\n"); + break; + case ATOM_TV_PAL: + tv_std = TV_STD_PAL; + DRM_INFO("Default TV standard: PAL\n"); + break; + case ATOM_TV_PALM: + tv_std = TV_STD_PAL_M; + DRM_INFO("Default TV standard: PAL-M\n"); + break; + case ATOM_TV_PALN: + tv_std = TV_STD_PAL_N; + DRM_INFO("Default TV standard: PAL-N\n"); + break; + case ATOM_TV_PALCN: + tv_std = TV_STD_PAL_CN; + DRM_INFO("Default TV standard: PAL-CN\n"); + break; + case ATOM_TV_PAL60: + tv_std = TV_STD_PAL_60; + DRM_INFO("Default TV standard: PAL-60\n"); + break; + case ATOM_TV_SECAM: + tv_std = TV_STD_SECAM; + DRM_INFO("Default TV standard: SECAM\n"); + break; + default: + tv_std = TV_STD_NTSC; + DRM_INFO("Unknown TV standard; defaulting to NTSC\n"); + break; + } + return tv_std; +} + struct radeon_encoder_tv_dac * radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder) { @@ -1269,6 +1324,7 @@ radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder) dac = dac_info->ucDAC2_NTSC_DAC_Adjustment; tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20); + tv_dac->tv_std = radeon_atombios_get_tv_info(rdev); } return tv_dac; } diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index c5021a3..fd94dbc 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c @@ -634,11 +634,10 @@ struct radeon_encoder_primary_dac *radeon_combios_get_primary_dac_info(struct return p_dac; } -static enum radeon_tv_std -radeon_combios_get_tv_info(struct radeon_encoder *encoder) +enum radeon_tv_std +radeon_combios_get_tv_info(struct radeon_device *rdev) { - struct drm_device *dev = encoder->base.dev; - struct radeon_device *rdev = dev->dev_private; + struct drm_device *dev = rdev->ddev; uint16_t tv_info; enum radeon_tv_std tv_std = TV_STD_NTSC; @@ -779,7 +778,7 @@ struct radeon_encoder_tv_dac *radeon_combios_get_tv_dac_info(struct tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20); found = 1; } - tv_dac->tv_std = radeon_combios_get_tv_info(encoder); + tv_dac->tv_std = radeon_combios_get_tv_info(rdev); } if (!found) { /* then check CRT table */ diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 5eece18..8da06e1 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -1171,7 +1171,7 @@ radeon_add_atom_connector(struct drm_device *dev, 1); drm_connector_attach_property(&radeon_connector->base, rdev->mode_info.tv_std_property, - 1); + radeon_atombios_get_tv_info(rdev)); } break; case DRM_MODE_CONNECTOR_LVDS: @@ -1315,7 +1315,7 @@ radeon_add_legacy_connector(struct drm_device *dev, 1); drm_connector_attach_property(&radeon_connector->base, rdev->mode_info.tv_std_property, - 1); + radeon_combios_get_tv_info(rdev)); } break; case DRM_MODE_CONNECTOR_LVDS: diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index a133b83..91d72b7 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -739,7 +739,7 @@ static struct drm_prop_enum_list radeon_tv_std_enum_list[] = { TV_STD_SECAM, "secam" }, }; -int radeon_modeset_create_props(struct radeon_device *rdev) +static int radeon_modeset_create_props(struct radeon_device *rdev) { int i, sz; diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 3dcbe13..402369d 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -88,6 +88,7 @@ enum radeon_tv_std { TV_STD_SCART_PAL, TV_STD_SECAM, TV_STD_PAL_CN, + TV_STD_PAL_N, }; /* radeon gpio-based i2c @@ -395,6 +396,11 @@ struct radeon_framebuffer { struct drm_gem_object *obj; }; +extern enum radeon_tv_std +radeon_combios_get_tv_info(struct radeon_device *rdev); +extern enum radeon_tv_std +radeon_atombios_get_tv_info(struct radeon_device *rdev); + extern void radeon_connector_hotplug(struct drm_connector *connector); extern bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector); extern int radeon_dp_mode_valid_helper(struct radeon_connector *radeon_connector, -- cgit v0.10.2 From c31ad97f1886a2ff0f3356dc31d50c57944365da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Thu, 17 Dec 2009 00:00:46 +0100 Subject: drm/radeon/kms: prevent parallel AtomBIOS calls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This just adds a mutex around the atombios table execution so we don't call it from two contexts at once. Signed-off-by: Rafał Miłecki Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c index 6578d19..388140a7 100644 --- a/drivers/gpu/drm/radeon/atom.c +++ b/drivers/gpu/drm/radeon/atom.c @@ -58,6 +58,7 @@ typedef struct { } atom_exec_context; int atom_debug = 0; +static void atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params); void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params); static uint32_t atom_arg_mask[8] = @@ -573,7 +574,7 @@ static void atom_op_calltable(atom_exec_context *ctx, int *ptr, int arg) else SDEBUG(" table: %d\n", idx); if (U16(ctx->ctx->cmd_table + 4 + 2 * idx)) - atom_execute_table(ctx->ctx, idx, ctx->ps + ctx->ps_shift); + atom_execute_table_locked(ctx->ctx, idx, ctx->ps + ctx->ps_shift); } static void atom_op_clear(atom_exec_context *ctx, int *ptr, int arg) @@ -1040,7 +1041,7 @@ static struct { atom_op_shr, ATOM_ARG_MC}, { atom_op_debug, 0},}; -void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params) +static void atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params) { int base = CU16(ctx->cmd_table + 4 + 2 * index); int len, ws, ps, ptr; @@ -1092,6 +1093,13 @@ void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params) kfree(ectx.ws); } +void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params) +{ + mutex_lock(&ctx->mutex); + atom_execute_table_locked(ctx, index, params); + mutex_unlock(&ctx->mutex); +} + static int atom_iio_len[] = { 1, 2, 3, 3, 3, 3, 4, 4, 4, 3 }; static void atom_index_iio(struct atom_context *ctx, int base) diff --git a/drivers/gpu/drm/radeon/atom.h b/drivers/gpu/drm/radeon/atom.h index 6671848..47fd943 100644 --- a/drivers/gpu/drm/radeon/atom.h +++ b/drivers/gpu/drm/radeon/atom.h @@ -120,6 +120,7 @@ struct card_info { struct atom_context { struct card_info *card; + struct mutex mutex; void *bios; uint32_t cmd_table, data_table; uint16_t *iio; diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 02bcdb1..99b95ca 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -481,6 +481,7 @@ int radeon_atombios_init(struct radeon_device *rdev) atom_card_info->pll_write = cail_pll_write; rdev->mode_info.atom_context = atom_parse(atom_card_info, rdev->bios); + mutex_init(&rdev->mode_info.atom_context->mutex); radeon_atom_initialize_bios_scratch_regs(rdev->ddev); atom_allocate_fb_scratch(rdev->mode_info.atom_context); return 0; -- cgit v0.10.2 From 5ea597f3764880ab3a67fe2246218634a8c12778 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Thu, 17 Dec 2009 13:50:09 +0100 Subject: drm/radeon/kms: enable memory clock reading on legacy (V2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit V2: detect IGP cards (which don't have own memory) Signed-off-by: Rafał Miłecki Acked-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 636116b..eb29217 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h @@ -33,6 +33,7 @@ */ uint32_t radeon_legacy_get_engine_clock(struct radeon_device *rdev); void radeon_legacy_set_engine_clock(struct radeon_device *rdev, uint32_t eng_clock); +uint32_t radeon_legacy_get_memory_clock(struct radeon_device *rdev); void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable); uint32_t radeon_atom_get_engine_clock(struct radeon_device *rdev); @@ -106,7 +107,7 @@ static struct radeon_asic r100_asic = { .copy = &r100_copy_blit, .get_engine_clock = &radeon_legacy_get_engine_clock, .set_engine_clock = &radeon_legacy_set_engine_clock, - .get_memory_clock = NULL, + .get_memory_clock = &radeon_legacy_get_memory_clock, .set_memory_clock = NULL, .set_pcie_lanes = NULL, .set_clock_gating = &radeon_legacy_set_clock_gating, @@ -166,7 +167,7 @@ static struct radeon_asic r300_asic = { .copy = &r100_copy_blit, .get_engine_clock = &radeon_legacy_get_engine_clock, .set_engine_clock = &radeon_legacy_set_engine_clock, - .get_memory_clock = NULL, + .get_memory_clock = &radeon_legacy_get_memory_clock, .set_memory_clock = NULL, .set_pcie_lanes = &rv370_set_pcie_lanes, .set_clock_gating = &radeon_legacy_set_clock_gating, @@ -259,7 +260,7 @@ static struct radeon_asic rs400_asic = { .copy = &r100_copy_blit, .get_engine_clock = &radeon_legacy_get_engine_clock, .set_engine_clock = &radeon_legacy_set_engine_clock, - .get_memory_clock = NULL, + .get_memory_clock = &radeon_legacy_get_memory_clock, .set_memory_clock = NULL, .set_pcie_lanes = NULL, .set_clock_gating = &radeon_legacy_set_clock_gating, diff --git a/drivers/gpu/drm/radeon/radeon_clocks.c b/drivers/gpu/drm/radeon/radeon_clocks.c index b062109..812f24d 100644 --- a/drivers/gpu/drm/radeon/radeon_clocks.c +++ b/drivers/gpu/drm/radeon/radeon_clocks.c @@ -62,7 +62,7 @@ uint32_t radeon_legacy_get_engine_clock(struct radeon_device *rdev) } /* 10 khz */ -static uint32_t radeon_legacy_get_memory_clock(struct radeon_device *rdev) +uint32_t radeon_legacy_get_memory_clock(struct radeon_device *rdev) { struct radeon_pll *mpll = &rdev->clock.mpll; uint32_t fb_div, ref_div, post_div, mclk; diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 99b95ca..14df3ad 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -391,6 +391,12 @@ int radeon_asic_init(struct radeon_device *rdev) /* FIXME: not supported yet */ return -EINVAL; } + + if (rdev->flags & RADEON_IS_IGP) { + rdev->asic->get_memory_clock = NULL; + rdev->asic->set_memory_clock = NULL; + } + return 0; } -- cgit v0.10.2 From 46c64d4bfa01cda7d58c514164f8b127ab6741b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Thu, 17 Dec 2009 06:02:28 +0100 Subject: drm/radeon/kms: allow rendering while no colorbuffer is set on r300 Because hardware cannot disable all colorbuffers directly to do depth-only rendering, a user should: - disable reading from a colorbuffer in blending - disable fastfill - set the color channel mask to 0 to prevent writing to a colorbuffer Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 84e5df7..7172746 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -2881,6 +2881,10 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) for (i = 0; i < track->num_cb; i++) { if (track->cb[i].robj == NULL) { + if (!(track->fastfill || track->color_channel_mask || + track->blend_read_enable)) { + continue; + } DRM_ERROR("[drm] No buffer for color buffer %d !\n", i); return -EINVAL; } diff --git a/drivers/gpu/drm/radeon/r100_track.h b/drivers/gpu/drm/radeon/r100_track.h index 7188c37..b27a699 100644 --- a/drivers/gpu/drm/radeon/r100_track.h +++ b/drivers/gpu/drm/radeon/r100_track.h @@ -67,13 +67,15 @@ struct r100_cs_track { unsigned immd_dwords; unsigned num_arrays; unsigned max_indx; + unsigned color_channel_mask; struct r100_cs_track_array arrays[11]; struct r100_cs_track_cb cb[R300_MAX_CB]; struct r100_cs_track_cb zb; struct r100_cs_track_texture textures[R300_TRACK_MAX_TEXTURE]; bool z_enabled; bool separate_cube; - + bool fastfill; + bool blend_read_enable; }; int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track); diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 83490c2..6a5d117 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c @@ -992,6 +992,18 @@ static int r300_packet0_check(struct radeon_cs_parser *p, } ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); break; + case 0x4e0c: + /* RB3D_COLOR_CHANNEL_MASK */ + track->color_channel_mask = idx_value; + break; + case 0x4d1c: + /* ZB_BW_CNTL */ + track->fastfill = !!(idx_value & (1 << 2)); + break; + case 0x4e04: + /* RB3D_BLENDCNTL */ + track->blend_read_enable = !!(idx_value & (1 << 2)); + break; case 0x4be8: /* valid register only on RV530 */ if (p->rdev->family == CHIP_RV530) -- cgit v0.10.2 From 512889f450c1851d9e3628f1894b9b64b0701eac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Sat, 19 Dec 2009 00:23:00 +0100 Subject: drm/radeon/kms: add 3DC compression support There are 2 formats: ATI1N: 64 bits per 4x4 block, one-channel format ATI2N: 128 bits per 4x4 block, two-channel format Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 6a5d117..3f2cc9e 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c @@ -887,6 +887,14 @@ static int r300_packet0_check(struct radeon_cs_parser *p, track->textures[i].cpp = 1; track->textures[i].compress_format = R100_TRACK_COMP_DXT1; break; + case R300_TX_FORMAT_ATI2N: + if (p->rdev->family < CHIP_R420) { + DRM_ERROR("Invalid texture format %u\n", + (idx_value & 0x1F)); + return -EINVAL; + } + /* The same rules apply as for DXT3/5. */ + /* Pass through. */ case R300_TX_FORMAT_DXT3: case R300_TX_FORMAT_DXT5: track->textures[i].cpp = 1; @@ -951,6 +959,16 @@ static int r300_packet0_check(struct radeon_cs_parser *p, track->textures[i].width_11 = tmp; tmp = ((idx_value >> 16) & 1) << 11; track->textures[i].height_11 = tmp; + + /* ATI1N */ + if (idx_value & (1 << 14)) { + /* The same rules apply as for DXT1. */ + track->textures[i].compress_format = + R100_TRACK_COMP_DXT1; + } + } else if (idx_value & (1 << 14)) { + DRM_ERROR("Forbidden bit TXFORMAT_MSB\n"); + return -EINVAL; } break; case 0x4480: diff --git a/drivers/gpu/drm/radeon/r300_reg.h b/drivers/gpu/drm/radeon/r300_reg.h index 4b7afef..1735a2b 100644 --- a/drivers/gpu/drm/radeon/r300_reg.h +++ b/drivers/gpu/drm/radeon/r300_reg.h @@ -900,6 +900,7 @@ # define R300_TX_FORMAT_FL_I32 0x1B # define R300_TX_FORMAT_FL_I32A32 0x1C # define R300_TX_FORMAT_FL_R32G32B32A32 0x1D +# define R300_TX_FORMAT_ATI2N 0x1F /* alpha modes, convenience mostly */ /* if you have alpha, pick constant appropriate to the number of channels (1 for I8, 2 for I8A8, 4 for R8G8B8A8, etc */ -- cgit v0.10.2 From d2efdf6d6f425950a61fa5cc3aa22e6718e7f3c8 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 22 Dec 2009 10:06:49 -0500 Subject: drm/radeon/kms: add cvt mode if we only have lvds w/h and no edid (v4) This fixes LVDS on some mac laptops without a panel edid. v2 - Set proper mode type flags v3 - Note that this is not neceesarily the exact panel mode, but an approximation based on the cvt formula. For these systems we should ideally read the mode info out of the registers or add a mode table, but this works and is much simpler. v4 - Update comments and debug message. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 8da06e1..2016156 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -208,6 +208,18 @@ static struct drm_display_mode *radeon_fp_native_mode(struct drm_encoder *encode drm_mode_set_name(mode); DRM_DEBUG("Adding native panel mode %s\n", mode->name); + } else if (native_mode->hdisplay != 0 && + native_mode->vdisplay != 0) { + /* mac laptops without an edid */ + /* Note that this is not necessarily the exact panel mode, + * but an approximation based on the cvt formula. For these + * systems we should ideally read the mode info out of the + * registers or add a mode table, but this works and is much + * simpler. + */ + mode = drm_cvt_mode(dev, native_mode->hdisplay, native_mode->vdisplay, 60, true, false, false); + mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER; + DRM_DEBUG("Adding cvt approximation of native panel mode %s\n", mode->name); } return mode; } -- cgit v0.10.2 From 0a0c7596c643239e8d4c3eaaba43b74a96f2411e Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Fri, 11 Dec 2009 20:36:19 +0100 Subject: drm/radeon/kms: Avoid crash when trying to cleanup uninitialized structure Add boolean to record if some part of the driver are initialized or not this allow to avoid a crash when trying to cleanup uninitialized structure members. Signed-off-by: Jerome Glisse Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index cd650fd..53b5560 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -162,6 +162,7 @@ struct radeon_fence_driver { struct list_head created; struct list_head emited; struct list_head signaled; + bool initialized; }; struct radeon_fence { @@ -202,8 +203,9 @@ struct radeon_surface_reg { struct radeon_mman { struct ttm_bo_global_ref bo_global_ref; struct ttm_global_reference mem_global_ref; - bool mem_global_referenced; struct ttm_bo_device bdev; + bool mem_global_referenced; + bool initialized; }; struct radeon_bo { diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index cb4cd97..4cdd8b4 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c @@ -324,7 +324,7 @@ int radeon_fence_driver_init(struct radeon_device *rdev) write_lock_irqsave(&rdev->fence_drv.lock, irq_flags); r = radeon_scratch_get(rdev, &rdev->fence_drv.scratch_reg); if (r) { - DRM_ERROR("Fence failed to get a scratch register."); + dev_err(rdev->dev, "fence failed to get scratch register\n"); write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); return r; } @@ -335,9 +335,10 @@ int radeon_fence_driver_init(struct radeon_device *rdev) INIT_LIST_HEAD(&rdev->fence_drv.signaled); rdev->fence_drv.count_timeout = 0; init_waitqueue_head(&rdev->fence_drv.queue); + rdev->fence_drv.initialized = true; write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); if (radeon_debugfs_fence_init(rdev)) { - DRM_ERROR("Failed to register debugfs file for fence !\n"); + dev_err(rdev->dev, "fence debugfs file creation failed\n"); } return 0; } @@ -346,11 +347,13 @@ void radeon_fence_driver_fini(struct radeon_device *rdev) { unsigned long irq_flags; + if (!rdev->fence_drv.initialized) + return; wake_up_all(&rdev->fence_drv.queue); write_lock_irqsave(&rdev->fence_drv.lock, irq_flags); radeon_scratch_free(rdev, rdev->fence_drv.scratch_reg); write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); - DRM_INFO("radeon: fence finalized\n"); + rdev->fence_drv.initialized = false; } diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 7bed412..a004507 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c @@ -494,6 +494,7 @@ int radeon_ttm_init(struct radeon_device *rdev) DRM_ERROR("failed initializing buffer object driver(%d).\n", r); return r; } + rdev->mman.initialized = true; r = ttm_bo_init_mm(&rdev->mman.bdev, TTM_PL_VRAM, rdev->mc.real_vram_size >> PAGE_SHIFT); if (r) { @@ -541,6 +542,8 @@ void radeon_ttm_fini(struct radeon_device *rdev) { int r; + if (!rdev->mman.initialized) + return; if (rdev->stollen_vga_memory) { r = radeon_bo_reserve(rdev->stollen_vga_memory, false); if (r == 0) { @@ -554,6 +557,7 @@ void radeon_ttm_fini(struct radeon_device *rdev) ttm_bo_device_release(&rdev->mman.bdev); radeon_gart_fini(rdev); radeon_ttm_global_fini(rdev); + rdev->mman.initialized = false; DRM_INFO("radeon: ttm finalized\n"); } -- cgit v0.10.2 From 3642133816f9f25065e3ca310f0720574bcdcc52 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Fri, 11 Dec 2009 21:18:34 +0100 Subject: drm/radeon/kms: Check module arguments to be valid V2 This patch add a function which check module argument to be valid. On invalid argument it prints a warning and setback the default value. V2: Allow 0 for vram limit & agp mode which are the default value Signed-off-by: Jerome Glisse Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 14df3ad..7c68480 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -546,9 +546,72 @@ void radeon_agp_disable(struct radeon_device *rdev) } } -/* - * Radeon device. - */ +void radeon_check_arguments(struct radeon_device *rdev) +{ + /* vramlimit must be a power of two */ + switch (radeon_vram_limit) { + case 0: + case 4: + case 8: + case 16: + case 32: + case 64: + case 128: + case 256: + case 512: + case 1024: + case 2048: + case 4096: + break; + default: + dev_warn(rdev->dev, "vram limit (%d) must be a power of 2\n", + radeon_vram_limit); + radeon_vram_limit = 0; + break; + } + radeon_vram_limit = radeon_vram_limit << 20; + /* gtt size must be power of two and greater or equal to 32M */ + switch (radeon_gart_size) { + case 4: + case 8: + case 16: + dev_warn(rdev->dev, "gart size (%d) too small forcing to 512M\n", + radeon_gart_size); + radeon_gart_size = 512; + break; + case 32: + case 64: + case 128: + case 256: + case 512: + case 1024: + case 2048: + case 4096: + break; + default: + dev_warn(rdev->dev, "gart size (%d) must be a power of 2\n", + radeon_gart_size); + radeon_gart_size = 512; + break; + } + rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; + /* AGP mode can only be -1, 1, 2, 4, 8 */ + switch (radeon_agpmode) { + case -1: + case 0: + case 1: + case 2: + case 4: + case 8: + break; + default: + dev_warn(rdev->dev, "invalid AGP mode %d (valid mode: " + "-1, 0, 1, 2, 4, 8)\n", radeon_agpmode); + radeon_agpmode = 0; + break; + } +} + int radeon_device_init(struct radeon_device *rdev, struct drm_device *ddev, struct pci_dev *pdev, @@ -587,9 +650,9 @@ int radeon_device_init(struct radeon_device *rdev, /* Set asic functions */ r = radeon_asic_init(rdev); - if (r) { + if (r) return r; - } + radeon_check_arguments(rdev); if (rdev->flags & RADEON_IS_AGP && radeon_agpmode == -1) { radeon_agp_disable(rdev); -- cgit v0.10.2 From f56cd64f5f713a3013c4d980a5695c198d839671 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 18 Dec 2009 11:28:22 -0500 Subject: drm/radeon/kms: never combine LVDS with another encoder When linking multiple encoders to a connector, make sure to not link LVDS with another connector. Some bioses have the same i2c line for LVDS and VGA. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index b5912c2..321044b 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -745,8 +745,7 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct else radeon_add_legacy_encoder(dev, radeon_get_encoder_id(dev, - (1 << - i), + (1 << i), dac), (1 << i)); } @@ -758,32 +757,30 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct if (bios_connectors[j].valid && (i != j)) { if (bios_connectors[i].line_mux == bios_connectors[j].line_mux) { - if (((bios_connectors[i]. - devices & - (ATOM_DEVICE_DFP_SUPPORT)) - && (bios_connectors[j]. - devices & - (ATOM_DEVICE_CRT_SUPPORT))) - || - ((bios_connectors[j]. - devices & - (ATOM_DEVICE_DFP_SUPPORT)) - && (bios_connectors[i]. - devices & - (ATOM_DEVICE_CRT_SUPPORT)))) { - bios_connectors[i]. - devices |= - bios_connectors[j]. - devices; - bios_connectors[i]. - connector_type = - DRM_MODE_CONNECTOR_DVII; - if (bios_connectors[j].devices & - (ATOM_DEVICE_DFP_SUPPORT)) + /* make sure not to combine LVDS */ + if (bios_connectors[i].devices & (ATOM_DEVICE_LCD_SUPPORT)) { + bios_connectors[i].line_mux = 53; + bios_connectors[i].ddc_bus.valid = false; + continue; + } + if (bios_connectors[j].devices & (ATOM_DEVICE_LCD_SUPPORT)) { + bios_connectors[j].line_mux = 53; + bios_connectors[j].ddc_bus.valid = false; + continue; + } + /* combine analog and digital for DVI-I */ + if (((bios_connectors[i].devices & (ATOM_DEVICE_DFP_SUPPORT)) && + (bios_connectors[j].devices & (ATOM_DEVICE_CRT_SUPPORT))) || + ((bios_connectors[j].devices & (ATOM_DEVICE_DFP_SUPPORT)) && + (bios_connectors[i].devices & (ATOM_DEVICE_CRT_SUPPORT)))) { + bios_connectors[i].devices |= + bios_connectors[j].devices; + bios_connectors[i].connector_type = + DRM_MODE_CONNECTOR_DVII; + if (bios_connectors[j].devices & (ATOM_DEVICE_DFP_SUPPORT)) bios_connectors[i].hpd = bios_connectors[j].hpd; - bios_connectors[j]. - valid = false; + bios_connectors[j].valid = false; } } } -- cgit v0.10.2 From 0786201d8cd0730e72b0e087484dd47cc5f58409 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Sat, 19 Dec 2009 12:45:12 -0500 Subject: drm/radeon/kms: add definitions for v4 power tables [airlied: just adding this for completeness to avoid drift between public atombios.h files] Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/atombios.h b/drivers/gpu/drm/radeon/atombios.h index e839276..8e28842 100644 --- a/drivers/gpu/drm/radeon/atombios.h +++ b/drivers/gpu/drm/radeon/atombios.h @@ -4690,6 +4690,205 @@ typedef struct _ATOM_POWERPLAY_INFO_V3 { ATOM_POWERMODE_INFO_V3 asPowerPlayInfo[ATOM_MAX_NUMBEROF_POWER_BLOCK]; } ATOM_POWERPLAY_INFO_V3; +/* New PPlib */ +/**************************************************************************/ +typedef struct _ATOM_PPLIB_THERMALCONTROLLER + +{ + UCHAR ucType; // one of ATOM_PP_THERMALCONTROLLER_* + UCHAR ucI2cLine; // as interpreted by DAL I2C + UCHAR ucI2cAddress; + UCHAR ucFanParameters; // Fan Control Parameters. + UCHAR ucFanMinRPM; // Fan Minimum RPM (hundreds) -- for display purposes only. + UCHAR ucFanMaxRPM; // Fan Maximum RPM (hundreds) -- for display purposes only. + UCHAR ucReserved; // ---- + UCHAR ucFlags; // to be defined +} ATOM_PPLIB_THERMALCONTROLLER; + +#define ATOM_PP_FANPARAMETERS_TACHOMETER_PULSES_PER_REVOLUTION_MASK 0x0f +#define ATOM_PP_FANPARAMETERS_NOFAN 0x80 // No fan is connected to this controller. + +#define ATOM_PP_THERMALCONTROLLER_NONE 0 +#define ATOM_PP_THERMALCONTROLLER_LM63 1 // Not used by PPLib +#define ATOM_PP_THERMALCONTROLLER_ADM1032 2 // Not used by PPLib +#define ATOM_PP_THERMALCONTROLLER_ADM1030 3 // Not used by PPLib +#define ATOM_PP_THERMALCONTROLLER_MUA6649 4 // Not used by PPLib +#define ATOM_PP_THERMALCONTROLLER_LM64 5 +#define ATOM_PP_THERMALCONTROLLER_F75375 6 // Not used by PPLib +#define ATOM_PP_THERMALCONTROLLER_RV6xx 7 +#define ATOM_PP_THERMALCONTROLLER_RV770 8 +#define ATOM_PP_THERMALCONTROLLER_ADT7473 9 + +typedef struct _ATOM_PPLIB_STATE +{ + UCHAR ucNonClockStateIndex; + UCHAR ucClockStateIndices[1]; // variable-sized +} ATOM_PPLIB_STATE; + +//// ATOM_PPLIB_POWERPLAYTABLE::ulPlatformCaps +#define ATOM_PP_PLATFORM_CAP_BACKBIAS 1 +#define ATOM_PP_PLATFORM_CAP_POWERPLAY 2 +#define ATOM_PP_PLATFORM_CAP_SBIOSPOWERSOURCE 4 +#define ATOM_PP_PLATFORM_CAP_ASPM_L0s 8 +#define ATOM_PP_PLATFORM_CAP_ASPM_L1 16 +#define ATOM_PP_PLATFORM_CAP_HARDWAREDC 32 +#define ATOM_PP_PLATFORM_CAP_GEMINIPRIMARY 64 +#define ATOM_PP_PLATFORM_CAP_STEPVDDC 128 +#define ATOM_PP_PLATFORM_CAP_VOLTAGECONTROL 256 +#define ATOM_PP_PLATFORM_CAP_SIDEPORTCONTROL 512 +#define ATOM_PP_PLATFORM_CAP_TURNOFFPLL_ASPML1 1024 +#define ATOM_PP_PLATFORM_CAP_HTLINKCONTROL 2048 + +typedef struct _ATOM_PPLIB_POWERPLAYTABLE +{ + ATOM_COMMON_TABLE_HEADER sHeader; + + UCHAR ucDataRevision; + + UCHAR ucNumStates; + UCHAR ucStateEntrySize; + UCHAR ucClockInfoSize; + UCHAR ucNonClockSize; + + // offset from start of this table to array of ucNumStates ATOM_PPLIB_STATE structures + USHORT usStateArrayOffset; + + // offset from start of this table to array of ASIC-specific structures, + // currently ATOM_PPLIB_CLOCK_INFO. + USHORT usClockInfoArrayOffset; + + // offset from start of this table to array of ATOM_PPLIB_NONCLOCK_INFO + USHORT usNonClockInfoArrayOffset; + + USHORT usBackbiasTime; // in microseconds + USHORT usVoltageTime; // in microseconds + USHORT usTableSize; //the size of this structure, or the extended structure + + ULONG ulPlatformCaps; // See ATOM_PPLIB_CAPS_* + + ATOM_PPLIB_THERMALCONTROLLER sThermalController; + + USHORT usBootClockInfoOffset; + USHORT usBootNonClockInfoOffset; + +} ATOM_PPLIB_POWERPLAYTABLE; + +//// ATOM_PPLIB_NONCLOCK_INFO::usClassification +#define ATOM_PPLIB_CLASSIFICATION_UI_MASK 0x0007 +#define ATOM_PPLIB_CLASSIFICATION_UI_SHIFT 0 +#define ATOM_PPLIB_CLASSIFICATION_UI_NONE 0 +#define ATOM_PPLIB_CLASSIFICATION_UI_BATTERY 1 +#define ATOM_PPLIB_CLASSIFICATION_UI_BALANCED 3 +#define ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE 5 +// 2, 4, 6, 7 are reserved + +#define ATOM_PPLIB_CLASSIFICATION_BOOT 0x0008 +#define ATOM_PPLIB_CLASSIFICATION_THERMAL 0x0010 +#define ATOM_PPLIB_CLASSIFICATION_LIMITEDPOWERSOURCE 0x0020 +#define ATOM_PPLIB_CLASSIFICATION_REST 0x0040 +#define ATOM_PPLIB_CLASSIFICATION_FORCED 0x0080 +#define ATOM_PPLIB_CLASSIFICATION_3DPERFORMANCE 0x0100 +#define ATOM_PPLIB_CLASSIFICATION_OVERDRIVETEMPLATE 0x0200 +#define ATOM_PPLIB_CLASSIFICATION_UVDSTATE 0x0400 +#define ATOM_PPLIB_CLASSIFICATION_3DLOW 0x0800 +#define ATOM_PPLIB_CLASSIFICATION_ACPI 0x1000 +// remaining 3 bits are reserved + +//// ATOM_PPLIB_NONCLOCK_INFO::ulCapsAndSettings +#define ATOM_PPLIB_SINGLE_DISPLAY_ONLY 0x00000001 +#define ATOM_PPLIB_SUPPORTS_VIDEO_PLAYBACK 0x00000002 + +// 0 is 2.5Gb/s, 1 is 5Gb/s +#define ATOM_PPLIB_PCIE_LINK_SPEED_MASK 0x00000004 +#define ATOM_PPLIB_PCIE_LINK_SPEED_SHIFT 2 + +// lanes - 1: 1, 2, 4, 8, 12, 16 permitted by PCIE spec +#define ATOM_PPLIB_PCIE_LINK_WIDTH_MASK 0x000000F8 +#define ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT 3 + +// lookup into reduced refresh-rate table +#define ATOM_PPLIB_LIMITED_REFRESHRATE_VALUE_MASK 0x00000F00 +#define ATOM_PPLIB_LIMITED_REFRESHRATE_VALUE_SHIFT 8 + +#define ATOM_PPLIB_LIMITED_REFRESHRATE_UNLIMITED 0 +#define ATOM_PPLIB_LIMITED_REFRESHRATE_50HZ 1 +// 2-15 TBD as needed. + +#define ATOM_PPLIB_SOFTWARE_DISABLE_LOADBALANCING 0x00001000 +#define ATOM_PPLIB_SOFTWARE_ENABLE_SLEEP_FOR_TIMESTAMPS 0x00002000 +#define ATOM_PPLIB_ENABLE_VARIBRIGHT 0x00008000 + +#define ATOM_PPLIB_DISALLOW_ON_DC 0x00004000 + +// Contained in an array starting at the offset +// in ATOM_PPLIB_POWERPLAYTABLE::usNonClockInfoArrayOffset. +// referenced from ATOM_PPLIB_STATE_INFO::ucNonClockStateIndex +typedef struct _ATOM_PPLIB_NONCLOCK_INFO +{ + USHORT usClassification; + UCHAR ucMinTemperature; + UCHAR ucMaxTemperature; + ULONG ulCapsAndSettings; + UCHAR ucRequiredPower; + UCHAR ucUnused1[3]; +} ATOM_PPLIB_NONCLOCK_INFO; + +// Contained in an array starting at the offset +// in ATOM_PPLIB_POWERPLAYTABLE::usClockInfoArrayOffset. +// referenced from ATOM_PPLIB_STATE::ucClockStateIndices +typedef struct _ATOM_PPLIB_R600_CLOCK_INFO +{ + USHORT usEngineClockLow; + UCHAR ucEngineClockHigh; + + USHORT usMemoryClockLow; + UCHAR ucMemoryClockHigh; + + USHORT usVDDC; + USHORT usUnused1; + USHORT usUnused2; + + ULONG ulFlags; // ATOM_PPLIB_R600_FLAGS_* + +} ATOM_PPLIB_R600_CLOCK_INFO; + +// ulFlags in ATOM_PPLIB_R600_CLOCK_INFO +#define ATOM_PPLIB_R600_FLAGS_PCIEGEN2 1 +#define ATOM_PPLIB_R600_FLAGS_UVDSAFE 2 +#define ATOM_PPLIB_R600_FLAGS_BACKBIASENABLE 4 +#define ATOM_PPLIB_R600_FLAGS_MEMORY_ODT_OFF 8 +#define ATOM_PPLIB_R600_FLAGS_MEMORY_DLL_OFF 16 + +typedef struct _ATOM_PPLIB_RS780_CLOCK_INFO + +{ + USHORT usLowEngineClockLow; // Low Engine clock in MHz (the same way as on the R600). + UCHAR ucLowEngineClockHigh; + USHORT usHighEngineClockLow; // High Engine clock in MHz. + UCHAR ucHighEngineClockHigh; + USHORT usMemoryClockLow; // For now one of the ATOM_PPLIB_RS780_SPMCLK_XXXX constants. + UCHAR ucMemoryClockHigh; // Currentyl unused. + UCHAR ucPadding; // For proper alignment and size. + USHORT usVDDC; // For the 780, use: None, Low, High, Variable + UCHAR ucMaxHTLinkWidth; // From SBIOS - {2, 4, 8, 16} + UCHAR ucMinHTLinkWidth; // From SBIOS - {2, 4, 8, 16}. Effective only if CDLW enabled. Minimum down stream width could be bigger as display BW requriement. + USHORT usHTLinkFreq; // See definition ATOM_PPLIB_RS780_HTLINKFREQ_xxx or in MHz(>=200). + ULONG ulFlags; +} ATOM_PPLIB_RS780_CLOCK_INFO; + +#define ATOM_PPLIB_RS780_VOLTAGE_NONE 0 +#define ATOM_PPLIB_RS780_VOLTAGE_LOW 1 +#define ATOM_PPLIB_RS780_VOLTAGE_HIGH 2 +#define ATOM_PPLIB_RS780_VOLTAGE_VARIABLE 3 + +#define ATOM_PPLIB_RS780_SPMCLK_NONE 0 // We cannot change the side port memory clock, leave it as it is. +#define ATOM_PPLIB_RS780_SPMCLK_LOW 1 +#define ATOM_PPLIB_RS780_SPMCLK_HIGH 2 + +#define ATOM_PPLIB_RS780_HTLINKFREQ_NONE 0 +#define ATOM_PPLIB_RS780_HTLINKFREQ_LOW 1 +#define ATOM_PPLIB_RS780_HTLINKFREQ_HIGH 2 + /**************************************************************************/ /* Following definitions are for compatiblity issue in different SW components. */ -- cgit v0.10.2 From 3b1c37cab3765b87efbd4ed40301ceaf72b9f5c2 Mon Sep 17 00:00:00 2001 From: Jonathan Woithe Date: Wed, 23 Dec 2009 09:19:42 +1030 Subject: fujitu-laptop: fix tests of acpi_evaluate_integer() return value Fix tests on return value from acpi_evaluate_integer(). Based on a patch by Roel Kluin and incorporating suggestions from Len Brown . Signed-off-by: Roel Kluin Signed-off-by: Jonathan Woithe Signed-off-by: Len Brown diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c index bcd4ba8..3c2d038 100644 --- a/drivers/platform/x86/fujitsu-laptop.c +++ b/drivers/platform/x86/fujitsu-laptop.c @@ -376,8 +376,8 @@ static int get_lcd_level(void) status = acpi_evaluate_integer(fujitsu->acpi_handle, "GBLL", NULL, &state); - if (status < 0) - return status; + if (ACPI_FAILURE(status)) + return 0; fujitsu->brightness_level = state & 0x0fffffff; @@ -398,8 +398,8 @@ static int get_max_brightness(void) status = acpi_evaluate_integer(fujitsu->acpi_handle, "RBLL", NULL, &state); - if (status < 0) - return status; + if (ACPI_FAILURE(status)) + return -1; fujitsu->max_brightness = state; -- cgit v0.10.2 From 0f1006b1f2b7862e35973c53cc4f99bea65d5a1d Mon Sep 17 00:00:00 2001 From: Anisse Astier Date: Thu, 17 Dec 2009 11:28:49 +0100 Subject: MAINTAINERS: add maintainer for msi-wmi driver Signed-off-by: Anisse Astier Signed-off-by: Len Brown diff --git a/MAINTAINERS b/MAINTAINERS index efd2ef2..eefe439 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3644,6 +3644,11 @@ W: http://0pointer.de/lennart/tchibo.html S: Maintained F: drivers/platform/x86/msi-laptop.c +MSI WMI SUPPORT +M: Anisse Astier +S: Supported +F: drivers/platform/x86/msi-wmi.c + MULTIFUNCTION DEVICES (MFD) M: Samuel Ortiz T: git git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6.git -- cgit v0.10.2 From f62faedbed546f4e0c1ba204999e7c206059f305 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 23 Dec 2009 09:27:51 +0100 Subject: ALSA: hda - Set mixer name after codec patch Postpone the mixer name setup after the codec patch since the codec patch may change the codec name string in itself. Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 9cfdb77..950ee5cf 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -1086,11 +1086,6 @@ int snd_hda_codec_configure(struct hda_codec *codec) if (err < 0) return err; } - /* audio codec should override the mixer name */ - if (codec->afg || !*codec->bus->card->mixername) - snprintf(codec->bus->card->mixername, - sizeof(codec->bus->card->mixername), - "%s %s", codec->vendor_name, codec->chip_name); if (is_generic_config(codec)) { err = snd_hda_parse_generic_codec(codec); @@ -1109,6 +1104,11 @@ int snd_hda_codec_configure(struct hda_codec *codec) patched: if (!err && codec->patch_ops.unsol_event) err = init_unsol_queue(codec->bus); + /* audio codec should override the mixer name */ + if (!err && (codec->afg || !*codec->bus->card->mixername)) + snprintf(codec->bus->card->mixername, + sizeof(codec->bus->card->mixername), + "%s %s", codec->vendor_name, codec->chip_name); return err; } EXPORT_SYMBOL_HDA(snd_hda_codec_configure); -- cgit v0.10.2 From 0c69774e6ce94364cfaa8bdeb18061edc414bc5a Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 22 Dec 2009 15:43:19 +0100 Subject: sched: Revert 738d2be, simplify set_task_cpu() Effectively reverts 738d2be4301007f054541c5c4bf7fb6a361c9b3a. As demonstrated by Eric, we really need to call __set_task_cpu() early in the fork() path to properly initialize the various task state -- specifically the cgroup state through set_task_rq(). [ we could probably fix this by explicitly calling __set_task_cpu() from sched_fork(), but lets try that for the next cycle and simply revert to the old behaviour for now. ] Reported-by: Eric Paris Tested-by: Eric Paris , Signed-off-by: Peter Zijlstra Cc: efault@gmx.de LKML-Reference: <1261492999.4937.36.camel@laptop> Signed-off-by: Ingo Molnar diff --git a/kernel/sched.c b/kernel/sched.c index 87f1f47..c535cc4 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -2045,11 +2045,10 @@ void set_task_cpu(struct task_struct *p, unsigned int new_cpu) trace_sched_migrate_task(p, new_cpu); - if (task_cpu(p) == new_cpu) - return; - - p->se.nr_migrations++; - perf_sw_event(PERF_COUNT_SW_CPU_MIGRATIONS, 1, 1, NULL, 0); + if (task_cpu(p) != new_cpu) { + p->se.nr_migrations++; + perf_sw_event(PERF_COUNT_SW_CPU_MIGRATIONS, 1, 1, NULL, 0); + } __set_task_cpu(p, new_cpu); } -- cgit v0.10.2 From b9bf770e0d4cc95e43ab04c66e705ba72a9bded3 Mon Sep 17 00:00:00 2001 From: Arnaud Patard Date: Wed, 9 Dec 2009 10:37:10 +0000 Subject: ARM: S3C24XX: touchscreen device definition Add definition for the touchscreen driver platform data and initial support for the H1940 machine. Signed-off-by: Arnaud Patard Signed-off-by: Ben Dooks Signed-off-by: Ben Dooks diff --git a/arch/arm/mach-s3c2410/include/mach/ts.h b/arch/arm/mach-s3c2410/include/mach/ts.h new file mode 100644 index 0000000..dc36170 --- /dev/null +++ b/arch/arm/mach-s3c2410/include/mach/ts.h @@ -0,0 +1,21 @@ +/* linux/include/asm/arch-s3c2410/ts.h + * + * Copyright (c) 2005 Arnaud Patard + * + * 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 __ASM_ARM_TS_H +#define __ASM_ARM_TS_H + +struct s3c2410_ts_mach_info { + int delay; + int presc; + int oversampling_shift; +}; + +extern void s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *); + +#endif /* __ASM_ARM_TS_H */ diff --git a/arch/arm/plat-s3c/include/plat/devs.h b/arch/arm/plat-s3c/include/plat/devs.h index 932cbbb..c1c20b0 100644 --- a/arch/arm/plat-s3c/include/plat/devs.h +++ b/arch/arm/plat-s3c/include/plat/devs.h @@ -31,6 +31,7 @@ extern struct platform_device s3c64xx_device_iisv4; extern struct platform_device s3c64xx_device_pcm0; extern struct platform_device s3c64xx_device_pcm1; +extern struct platform_device s3c_device_ts; extern struct platform_device s3c_device_fb; extern struct platform_device s3c_device_usb; extern struct platform_device s3c_device_lcd; diff --git a/arch/arm/plat-s3c24xx/devs.c b/arch/arm/plat-s3c24xx/devs.c index f52a92c..7f686a3 100644 --- a/arch/arm/plat-s3c24xx/devs.c +++ b/arch/arm/plat-s3c24xx/devs.c @@ -37,6 +37,8 @@ #include #include +#include + /* Serial port registrations */ static struct resource s3c2410_uart0_resource[] = { @@ -182,6 +184,22 @@ void __init s3c24xx_fb_set_platdata(struct s3c2410fb_mach_info *pd) } } +/* Touchscreen */ +struct platform_device s3c_device_ts = { + .name = "s3c2410-ts", + .id = -1, +}; +EXPORT_SYMBOL(s3c_device_ts); + +static struct s3c2410_ts_mach_info s3c2410ts_info; + +void __init s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *hard_s3c2410ts_info) +{ + memcpy(&s3c2410ts_info, hard_s3c2410ts_info, sizeof(struct s3c2410_ts_mach_info)); + s3c_device_ts.dev.platform_data = &s3c2410ts_info; +} +EXPORT_SYMBOL(s3c24xx_ts_set_platdata); + /* USB Device (Gadget)*/ static struct resource s3c_usbgadget_resource[] = { diff --git a/arch/arm/plat-s3c24xx/s3c244x.c b/arch/arm/plat-s3c24xx/s3c244x.c index 1364317..12623a4 100644 --- a/arch/arm/plat-s3c24xx/s3c244x.c +++ b/arch/arm/plat-s3c24xx/s3c244x.c @@ -70,6 +70,7 @@ void __init s3c244x_map_io(void) s3c_device_sdi.name = "s3c2440-sdi"; s3c_device_i2c0.name = "s3c2440-i2c"; s3c_device_nand.name = "s3c2440-nand"; + s3c_device_ts.name = "s3c2440-ts"; s3c_device_usbgadget.name = "s3c2440-usbgadget"; } -- cgit v0.10.2 From cc3e1bea5d87635c519da657303690f5538bb4eb Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Wed, 23 Dec 2009 06:52:08 -0500 Subject: ext4, jbd2: Add barriers for file systems with exernal journals This is a bit complicated because we are trying to optimize when we send barriers to the fs data disk. We could just throw in an extra barrier to the data disk whenever we send a barrier to the journal disk, but that's not always strictly necessary. We only need to send a barrier during a commit when there are data blocks which are must be written out due to an inode written in ordered mode, or if fsync() depends on the commit to force data blocks to disk. Finally, before we drop transactions from the beginning of the journal during a checkpoint operation, we need to guarantee that any blocks that were flushed out to the data disk are firmly on the rust platter before we drop the transaction from the journal. Thanks to Oleg Drokin for pointing out this flaw in ext3/ext4. Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/fsync.c b/fs/ext4/fsync.c index 0b22497..98bd140 100644 --- a/fs/ext4/fsync.c +++ b/fs/ext4/fsync.c @@ -88,9 +88,21 @@ int ext4_sync_file(struct file *file, struct dentry *dentry, int datasync) return ext4_force_commit(inode->i_sb); commit_tid = datasync ? ei->i_datasync_tid : ei->i_sync_tid; - if (jbd2_log_start_commit(journal, commit_tid)) + if (jbd2_log_start_commit(journal, commit_tid)) { + /* + * When the journal is on a different device than the + * fs data disk, we need to issue the barrier in + * writeback mode. (In ordered mode, the jbd2 layer + * will take care of issuing the barrier. In + * data=journal, all of the data blocks are written to + * the journal device.) + */ + if (ext4_should_writeback_data(inode) && + (journal->j_fs_dev != journal->j_dev) && + (journal->j_flags & JBD2_BARRIER)) + blkdev_issue_flush(inode->i_sb->s_bdev, NULL); jbd2_log_wait_commit(journal, commit_tid); - else if (journal->j_flags & JBD2_BARRIER) + } else if (journal->j_flags & JBD2_BARRIER) blkdev_issue_flush(inode->i_sb->s_bdev, NULL); return ret; } diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c index ca0f5eb..8868493 100644 --- a/fs/jbd2/checkpoint.c +++ b/fs/jbd2/checkpoint.c @@ -22,6 +22,7 @@ #include #include #include +#include #include /* @@ -515,6 +516,20 @@ int jbd2_cleanup_journal_tail(journal_t *journal) journal->j_tail_sequence = first_tid; journal->j_tail = blocknr; spin_unlock(&journal->j_state_lock); + + /* + * If there is an external journal, we need to make sure that + * any data blocks that were recently written out --- perhaps + * by jbd2_log_do_checkpoint() --- are flushed out before we + * drop the transactions from the external journal. It's + * unlikely this will be necessary, especially with a + * appropriately sized journal, but we need this to guarantee + * correctness. Fortunately jbd2_cleanup_journal_tail() + * doesn't get called all that often. + */ + if ((journal->j_fs_dev != journal->j_dev) && + (journal->j_flags & JBD2_BARRIER)) + blkdev_issue_flush(journal->j_fs_dev, NULL); if (!(journal->j_flags & JBD2_ABORT)) jbd2_journal_update_superblock(journal, 1); return 0; diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index 6a10238..1bc74b6 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c @@ -259,6 +259,7 @@ static int journal_submit_data_buffers(journal_t *journal, ret = err; spin_lock(&journal->j_list_lock); J_ASSERT(jinode->i_transaction == commit_transaction); + commit_transaction->t_flushed_data_blocks = 1; jinode->i_flags &= ~JI_COMMIT_RUNNING; wake_up_bit(&jinode->i_flags, __JI_COMMIT_RUNNING); } @@ -708,8 +709,17 @@ start_journal_io: } } - /* Done it all: now write the commit record asynchronously. */ + /* + * If the journal is not located on the file system device, + * then we must flush the file system device before we issue + * the commit record + */ + if (commit_transaction->t_flushed_data_blocks && + (journal->j_fs_dev != journal->j_dev) && + (journal->j_flags & JBD2_BARRIER)) + blkdev_issue_flush(journal->j_fs_dev, NULL); + /* Done it all: now write the commit record asynchronously. */ if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) { err = journal_submit_commit_record(journal, commit_transaction, @@ -720,13 +730,6 @@ start_journal_io: blkdev_issue_flush(journal->j_dev, NULL); } - /* - * This is the right place to wait for data buffers both for ASYNC - * and !ASYNC commit. If commit is ASYNC, we need to wait only after - * the commit block went to disk (which happens above). If commit is - * SYNC, we need to wait for data buffers before we start writing - * commit block, which happens below in such setting. - */ err = journal_finish_inode_data_buffers(journal, commit_transaction); if (err) { printk(KERN_WARNING diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h index f1011f7..638ce45 100644 --- a/include/linux/jbd2.h +++ b/include/linux/jbd2.h @@ -653,6 +653,7 @@ struct transaction_s * waiting for it to finish. */ unsigned int t_synchronous_commit:1; + unsigned int t_flushed_data_blocks:1; /* * For use by the filesystem to store fs-specific data -- cgit v0.10.2 From c459001fa4f71deafb62e00fa70d35f695498965 Mon Sep 17 00:00:00 2001 From: Dmitry Monakhov Date: Wed, 9 Dec 2009 03:05:30 +0300 Subject: ext3: quota macros cleanup [V2] Currently all quota block reservation macros contains hardcoded "2" aka MAXQUOTAS value. This is no good because in some places it is not obvious to understand what does this digit represent. Let's introduce new macro with self descriptive name. Signed-off-by: Dmitry Monakhov Signed-off-by: Jan Kara diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index ad14227..455e6e6 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c @@ -970,7 +970,7 @@ static int ext3_get_block(struct inode *inode, sector_t iblock, if (max_blocks > DIO_MAX_BLOCKS) max_blocks = DIO_MAX_BLOCKS; handle = ext3_journal_start(inode, DIO_CREDITS + - 2 * EXT3_QUOTA_TRANS_BLOCKS(inode->i_sb)); + EXT3_MAXQUOTAS_TRANS_BLOCKS(inode->i_sb)); if (IS_ERR(handle)) { ret = PTR_ERR(handle); goto out; @@ -3146,8 +3146,8 @@ int ext3_setattr(struct dentry *dentry, struct iattr *attr) /* (user+group)*(old+new) structure, inode write (sb, * inode block, ? - but truncate inode update has it) */ - handle = ext3_journal_start(inode, 2*(EXT3_QUOTA_INIT_BLOCKS(inode->i_sb)+ - EXT3_QUOTA_DEL_BLOCKS(inode->i_sb))+3); + handle = ext3_journal_start(inode, EXT3_MAXQUOTAS_INIT_BLOCKS(inode->i_sb)+ + EXT3_MAXQUOTAS_DEL_BLOCKS(inode->i_sb)+3); if (IS_ERR(handle)) { error = PTR_ERR(handle); goto err_out; @@ -3239,7 +3239,7 @@ static int ext3_writepage_trans_blocks(struct inode *inode) #ifdef CONFIG_QUOTA /* We know that structure was already allocated during vfs_dq_init so * we will be updating only the data blocks + inodes */ - ret += 2*EXT3_QUOTA_TRANS_BLOCKS(inode->i_sb); + ret += EXT3_MAXQUOTAS_TRANS_BLOCKS(inode->i_sb); #endif return ret; diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index aad6400..81f7348 100644 --- a/fs/ext3/namei.c +++ b/fs/ext3/namei.c @@ -1699,7 +1699,7 @@ static int ext3_create (struct inode * dir, struct dentry * dentry, int mode, retry: handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) + EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3 + - 2*EXT3_QUOTA_INIT_BLOCKS(dir->i_sb)); + EXT3_MAXQUOTAS_INIT_BLOCKS(dir->i_sb)); if (IS_ERR(handle)) return PTR_ERR(handle); @@ -1733,7 +1733,7 @@ static int ext3_mknod (struct inode * dir, struct dentry *dentry, retry: handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) + EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3 + - 2*EXT3_QUOTA_INIT_BLOCKS(dir->i_sb)); + EXT3_MAXQUOTAS_INIT_BLOCKS(dir->i_sb)); if (IS_ERR(handle)) return PTR_ERR(handle); @@ -1769,7 +1769,7 @@ static int ext3_mkdir(struct inode * dir, struct dentry * dentry, int mode) retry: handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) + EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3 + - 2*EXT3_QUOTA_INIT_BLOCKS(dir->i_sb)); + EXT3_MAXQUOTAS_INIT_BLOCKS(dir->i_sb)); if (IS_ERR(handle)) return PTR_ERR(handle); @@ -2175,7 +2175,7 @@ static int ext3_symlink (struct inode * dir, retry: handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) + EXT3_INDEX_EXTRA_TRANS_BLOCKS + 5 + - 2*EXT3_QUOTA_INIT_BLOCKS(dir->i_sb)); + EXT3_MAXQUOTAS_INIT_BLOCKS(dir->i_sb)); if (IS_ERR(handle)) return PTR_ERR(handle); diff --git a/include/linux/ext3_jbd.h b/include/linux/ext3_jbd.h index cf82d51..d7b5ddc 100644 --- a/include/linux/ext3_jbd.h +++ b/include/linux/ext3_jbd.h @@ -44,13 +44,13 @@ #define EXT3_DATA_TRANS_BLOCKS(sb) (EXT3_SINGLEDATA_TRANS_BLOCKS + \ EXT3_XATTR_TRANS_BLOCKS - 2 + \ - 2*EXT3_QUOTA_TRANS_BLOCKS(sb)) + EXT3_MAXQUOTAS_TRANS_BLOCKS(sb)) /* Delete operations potentially hit one directory's namespace plus an * entire inode, plus arbitrary amounts of bitmap/indirection data. Be * generous. We can grow the delete transaction later if necessary. */ -#define EXT3_DELETE_TRANS_BLOCKS(sb) (2 * EXT3_DATA_TRANS_BLOCKS(sb) + 64) +#define EXT3_DELETE_TRANS_BLOCKS(sb) (EXT3_MAXQUOTAS_TRANS_BLOCKS(sb) + 64) /* Define an arbitrary limit for the amount of data we will anticipate * writing to any given transaction. For unbounded transactions such as @@ -86,6 +86,9 @@ #define EXT3_QUOTA_INIT_BLOCKS(sb) 0 #define EXT3_QUOTA_DEL_BLOCKS(sb) 0 #endif +#define EXT3_MAXQUOTAS_TRANS_BLOCKS(sb) (MAXQUOTAS*EXT3_QUOTA_TRANS_BLOCKS(sb)) +#define EXT3_MAXQUOTAS_INIT_BLOCKS(sb) (MAXQUOTAS*EXT3_QUOTA_INIT_BLOCKS(sb)) +#define EXT3_MAXQUOTAS_DEL_BLOCKS(sb) (MAXQUOTAS*EXT3_QUOTA_DEL_BLOCKS(sb)) int ext3_mark_iloc_dirty(handle_t *handle, -- cgit v0.10.2 From b462707e7ccad058ae151e5c5b06eb5cadcb737f Mon Sep 17 00:00:00 2001 From: Dmitry Monakhov Date: Mon, 14 Dec 2009 15:21:12 +0300 Subject: Add unlocked version of inode_add_bytes() function Quota code requires unlocked version of this function. Off course we can just copy-paste the code, but copy-pasting is always an evil. Signed-off-by: Dmitry Monakhov Signed-off-by: Jan Kara diff --git a/fs/stat.c b/fs/stat.c index 075694e..c4ecd52 100644 --- a/fs/stat.c +++ b/fs/stat.c @@ -401,9 +401,9 @@ SYSCALL_DEFINE4(fstatat64, int, dfd, char __user *, filename, } #endif /* __ARCH_WANT_STAT64 */ -void inode_add_bytes(struct inode *inode, loff_t bytes) +/* Caller is here responsible for sufficient locking (ie. inode->i_lock) */ +void __inode_add_bytes(struct inode *inode, loff_t bytes) { - spin_lock(&inode->i_lock); inode->i_blocks += bytes >> 9; bytes &= 511; inode->i_bytes += bytes; @@ -411,6 +411,12 @@ void inode_add_bytes(struct inode *inode, loff_t bytes) inode->i_blocks++; inode->i_bytes -= 512; } +} + +void inode_add_bytes(struct inode *inode, loff_t bytes) +{ + spin_lock(&inode->i_lock); + __inode_add_bytes(inode, bytes); spin_unlock(&inode->i_lock); } diff --git a/include/linux/fs.h b/include/linux/fs.h index 7e3012e..9147ca8 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2297,6 +2297,7 @@ extern const struct inode_operations page_symlink_inode_operations; extern int generic_readlink(struct dentry *, char __user *, int); extern void generic_fillattr(struct inode *, struct kstat *); extern int vfs_getattr(struct vfsmount *, struct dentry *, struct kstat *); +void __inode_add_bytes(struct inode *inode, loff_t bytes); void inode_add_bytes(struct inode *inode, loff_t bytes); void inode_sub_bytes(struct inode *inode, loff_t bytes); loff_t inode_get_bytes(struct inode *inode); -- cgit v0.10.2 From fd8fbfc1709822bd94247c5b2ab15a5f5041e103 Mon Sep 17 00:00:00 2001 From: Dmitry Monakhov Date: Mon, 14 Dec 2009 15:21:13 +0300 Subject: quota: decouple fs reserved space from quota reservation Currently inode_reservation is managed by fs itself and this reservation is transfered on dquot_transfer(). This means what inode_reservation must always be in sync with dquot->dq_dqb.dqb_rsvspace. Otherwise dquot_transfer() will result in incorrect quota(WARN_ON in dquot_claim_reserved_space() will be triggered) This is not easy because of complex locking order issues for example http://bugzilla.kernel.org/show_bug.cgi?id=14739 The patch introduce quota reservation field for each fs-inode (fs specific inode is used in order to prevent bloating generic vfs inode). This reservation is managed by quota code internally similar to i_blocks/i_bytes and may not be always in sync with internal fs reservation. Also perform some code rearrangement: - Unify dquot_reserve_space() and dquot_reserve_space() - Unify dquot_release_reserved_space() and dquot_free_space() - Also this patch add missing warning update to release_rsv() dquot_release_reserved_space() must call flush_warnings() as dquot_free_space() does. Signed-off-by: Dmitry Monakhov Signed-off-by: Jan Kara diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index cd6bb9a..1cb8fa8 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c @@ -1319,6 +1319,67 @@ void vfs_dq_drop(struct inode *inode) EXPORT_SYMBOL(vfs_dq_drop); /* + * inode_reserved_space is managed internally by quota, and protected by + * i_lock similar to i_blocks+i_bytes. + */ +static qsize_t *inode_reserved_space(struct inode * inode) +{ + /* Filesystem must explicitly define it's own method in order to use + * quota reservation interface */ + BUG_ON(!inode->i_sb->dq_op->get_reserved_space); + return inode->i_sb->dq_op->get_reserved_space(inode); +} + +static void inode_add_rsv_space(struct inode *inode, qsize_t number) +{ + spin_lock(&inode->i_lock); + *inode_reserved_space(inode) += number; + spin_unlock(&inode->i_lock); +} + + +static void inode_claim_rsv_space(struct inode *inode, qsize_t number) +{ + spin_lock(&inode->i_lock); + *inode_reserved_space(inode) -= number; + __inode_add_bytes(inode, number); + spin_unlock(&inode->i_lock); +} + +static void inode_sub_rsv_space(struct inode *inode, qsize_t number) +{ + spin_lock(&inode->i_lock); + *inode_reserved_space(inode) -= number; + spin_unlock(&inode->i_lock); +} + +static qsize_t inode_get_rsv_space(struct inode *inode) +{ + qsize_t ret; + spin_lock(&inode->i_lock); + ret = *inode_reserved_space(inode); + spin_unlock(&inode->i_lock); + return ret; +} + +static void inode_incr_space(struct inode *inode, qsize_t number, + int reserve) +{ + if (reserve) + inode_add_rsv_space(inode, number); + else + inode_add_bytes(inode, number); +} + +static void inode_decr_space(struct inode *inode, qsize_t number, int reserve) +{ + if (reserve) + inode_sub_rsv_space(inode, number); + else + inode_sub_bytes(inode, number); +} + +/* * Following four functions update i_blocks+i_bytes fields and * quota information (together with appropriate checks) * NOTE: We absolutely rely on the fact that caller dirties @@ -1336,6 +1397,21 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number, int cnt, ret = QUOTA_OK; char warntype[MAXQUOTAS]; + /* + * First test before acquiring mutex - solves deadlocks when we + * re-enter the quota code and are already holding the mutex + */ + if (IS_NOQUOTA(inode)) { + inode_incr_space(inode, number, reserve); + goto out; + } + + down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); + if (IS_NOQUOTA(inode)) { + inode_incr_space(inode, number, reserve); + goto out_unlock; + } + for (cnt = 0; cnt < MAXQUOTAS; cnt++) warntype[cnt] = QUOTA_NL_NOWARN; @@ -1346,7 +1422,8 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number, if (check_bdq(inode->i_dquot[cnt], number, warn, warntype+cnt) == NO_QUOTA) { ret = NO_QUOTA; - goto out_unlock; + spin_unlock(&dq_data_lock); + goto out_flush_warn; } } for (cnt = 0; cnt < MAXQUOTAS; cnt++) { @@ -1357,64 +1434,32 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number, else dquot_incr_space(inode->i_dquot[cnt], number); } - if (!reserve) - inode_add_bytes(inode, number); -out_unlock: + inode_incr_space(inode, number, reserve); spin_unlock(&dq_data_lock); - flush_warnings(inode->i_dquot, warntype); - return ret; -} - -int dquot_alloc_space(struct inode *inode, qsize_t number, int warn) -{ - int cnt, ret = QUOTA_OK; - - /* - * First test before acquiring mutex - solves deadlocks when we - * re-enter the quota code and are already holding the mutex - */ - if (IS_NOQUOTA(inode)) { - inode_add_bytes(inode, number); - goto out; - } - - down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); - if (IS_NOQUOTA(inode)) { - inode_add_bytes(inode, number); - goto out_unlock; - } - - ret = __dquot_alloc_space(inode, number, warn, 0); - if (ret == NO_QUOTA) - goto out_unlock; + if (reserve) + goto out_flush_warn; /* Dirtify all the dquots - this can block when journalling */ for (cnt = 0; cnt < MAXQUOTAS; cnt++) if (inode->i_dquot[cnt]) mark_dquot_dirty(inode->i_dquot[cnt]); +out_flush_warn: + flush_warnings(inode->i_dquot, warntype); out_unlock: up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); out: return ret; } + +int dquot_alloc_space(struct inode *inode, qsize_t number, int warn) +{ + return __dquot_alloc_space(inode, number, warn, 0); +} EXPORT_SYMBOL(dquot_alloc_space); int dquot_reserve_space(struct inode *inode, qsize_t number, int warn) { - int ret = QUOTA_OK; - - if (IS_NOQUOTA(inode)) - goto out; - - down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); - if (IS_NOQUOTA(inode)) - goto out_unlock; - - ret = __dquot_alloc_space(inode, number, warn, 1); -out_unlock: - up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); -out: - return ret; + return __dquot_alloc_space(inode, number, warn, 1); } EXPORT_SYMBOL(dquot_reserve_space); @@ -1471,14 +1516,14 @@ int dquot_claim_space(struct inode *inode, qsize_t number) int ret = QUOTA_OK; if (IS_NOQUOTA(inode)) { - inode_add_bytes(inode, number); + inode_claim_rsv_space(inode, number); goto out; } down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); if (IS_NOQUOTA(inode)) { up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); - inode_add_bytes(inode, number); + inode_claim_rsv_space(inode, number); goto out; } @@ -1490,7 +1535,7 @@ int dquot_claim_space(struct inode *inode, qsize_t number) number); } /* Update inode bytes */ - inode_add_bytes(inode, number); + inode_claim_rsv_space(inode, number); spin_unlock(&dq_data_lock); /* Dirtify all the dquots - this can block when journalling */ for (cnt = 0; cnt < MAXQUOTAS; cnt++) @@ -1503,38 +1548,9 @@ out: EXPORT_SYMBOL(dquot_claim_space); /* - * Release reserved quota space - */ -void dquot_release_reserved_space(struct inode *inode, qsize_t number) -{ - int cnt; - - if (IS_NOQUOTA(inode)) - goto out; - - down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); - if (IS_NOQUOTA(inode)) - goto out_unlock; - - spin_lock(&dq_data_lock); - /* Release reserved dquots */ - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { - if (inode->i_dquot[cnt]) - dquot_free_reserved_space(inode->i_dquot[cnt], number); - } - spin_unlock(&dq_data_lock); - -out_unlock: - up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); -out: - return; -} -EXPORT_SYMBOL(dquot_release_reserved_space); - -/* * This operation can block, but only after everything is updated */ -int dquot_free_space(struct inode *inode, qsize_t number) +int __dquot_free_space(struct inode *inode, qsize_t number, int reserve) { unsigned int cnt; char warntype[MAXQUOTAS]; @@ -1543,7 +1559,7 @@ int dquot_free_space(struct inode *inode, qsize_t number) * re-enter the quota code and are already holding the mutex */ if (IS_NOQUOTA(inode)) { out_sub: - inode_sub_bytes(inode, number); + inode_decr_space(inode, number, reserve); return QUOTA_OK; } @@ -1558,21 +1574,43 @@ out_sub: if (!inode->i_dquot[cnt]) continue; warntype[cnt] = info_bdq_free(inode->i_dquot[cnt], number); - dquot_decr_space(inode->i_dquot[cnt], number); + if (reserve) + dquot_free_reserved_space(inode->i_dquot[cnt], number); + else + dquot_decr_space(inode->i_dquot[cnt], number); } - inode_sub_bytes(inode, number); + inode_decr_space(inode, number, reserve); spin_unlock(&dq_data_lock); + + if (reserve) + goto out_unlock; /* Dirtify all the dquots - this can block when journalling */ for (cnt = 0; cnt < MAXQUOTAS; cnt++) if (inode->i_dquot[cnt]) mark_dquot_dirty(inode->i_dquot[cnt]); +out_unlock: flush_warnings(inode->i_dquot, warntype); up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); return QUOTA_OK; } + +int dquot_free_space(struct inode *inode, qsize_t number) +{ + return __dquot_free_space(inode, number, 0); +} EXPORT_SYMBOL(dquot_free_space); /* + * Release reserved quota space + */ +void dquot_release_reserved_space(struct inode *inode, qsize_t number) +{ + __dquot_free_space(inode, number, 1); + +} +EXPORT_SYMBOL(dquot_release_reserved_space); + +/* * This operation can block, but only after everything is updated */ int dquot_free_inode(const struct inode *inode, qsize_t number) @@ -1610,19 +1648,6 @@ int dquot_free_inode(const struct inode *inode, qsize_t number) EXPORT_SYMBOL(dquot_free_inode); /* - * call back function, get reserved quota space from underlying fs - */ -qsize_t dquot_get_reserved_space(struct inode *inode) -{ - qsize_t reserved_space = 0; - - if (sb_any_quota_active(inode->i_sb) && - inode->i_sb->dq_op->get_reserved_space) - reserved_space = inode->i_sb->dq_op->get_reserved_space(inode); - return reserved_space; -} - -/* * Transfer the number of inode and blocks from one diskquota to an other. * * This operation can block, but only after everything is updated @@ -1665,7 +1690,7 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr) } spin_lock(&dq_data_lock); cur_space = inode_get_bytes(inode); - rsv_space = dquot_get_reserved_space(inode); + rsv_space = inode_get_rsv_space(inode); space = cur_space + rsv_space; /* Build the transfer_from list and check the limits */ for (cnt = 0; cnt < MAXQUOTAS; cnt++) { diff --git a/include/linux/quota.h b/include/linux/quota.h index e70e621..a6861f1 100644 --- a/include/linux/quota.h +++ b/include/linux/quota.h @@ -315,8 +315,9 @@ struct dquot_operations { int (*claim_space) (struct inode *, qsize_t); /* release rsved quota for delayed alloc */ void (*release_rsv) (struct inode *, qsize_t); - /* get reserved quota for delayed alloc */ - qsize_t (*get_reserved_space) (struct inode *); + /* get reserved quota for delayed alloc, value returned is managed by + * quota code only */ + qsize_t *(*get_reserved_space) (struct inode *); }; /* Operations handling requests from userspace */ -- cgit v0.10.2 From a9e7f4472075fb6937c545af3f6329e9946bbe66 Mon Sep 17 00:00:00 2001 From: Dmitry Monakhov Date: Mon, 14 Dec 2009 15:21:14 +0300 Subject: ext4: Convert to generic reserved quota's space management. This patch also fixes write vs chown race condition. Acked-by: "Theodore Ts'o" Signed-off-by: Dmitry Monakhov Signed-off-by: Jan Kara diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index ab31e65..56f9271 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -704,6 +704,10 @@ struct ext4_inode_info { __u16 i_extra_isize; spinlock_t i_block_reservation_lock; +#ifdef CONFIG_QUOTA + /* quota space reservation, managed internally by quota code */ + qsize_t i_reserved_quota; +#endif /* completed async DIOs that might need unwritten extents handling */ struct list_head i_aio_dio_complete_list; @@ -1435,7 +1439,7 @@ extern int ext4_chunk_trans_blocks(struct inode *, int nrblocks); extern int ext4_block_truncate_page(handle_t *handle, struct address_space *mapping, loff_t from); extern int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf); -extern qsize_t ext4_get_reserved_space(struct inode *inode); +extern qsize_t *ext4_get_reserved_space(struct inode *inode); extern int flush_aio_dio_completed_IO(struct inode *inode); /* ioctl.c */ extern long ext4_ioctl(struct file *, unsigned int, unsigned long); diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 5352db1..a31980d 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -1003,17 +1003,12 @@ out: return err; } -qsize_t ext4_get_reserved_space(struct inode *inode) +#ifdef CONFIG_QUOTA +qsize_t *ext4_get_reserved_space(struct inode *inode) { - unsigned long long total; - - spin_lock(&EXT4_I(inode)->i_block_reservation_lock); - total = EXT4_I(inode)->i_reserved_data_blocks + - EXT4_I(inode)->i_reserved_meta_blocks; - spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); - - return (total << inode->i_blkbits); + return &EXT4_I(inode)->i_reserved_quota; } +#endif /* * Calculate the number of metadata blocks need to reserve * to allocate @blocks for non extent file based file @@ -4794,6 +4789,9 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino) ((__u64)le16_to_cpu(raw_inode->i_file_acl_high)) << 32; inode->i_size = ext4_isize(raw_inode); ei->i_disksize = inode->i_size; +#ifdef CONFIG_QUOTA + ei->i_reserved_quota = 0; +#endif inode->i_generation = le32_to_cpu(raw_inode->i_generation); ei->i_block_group = iloc.block_group; ei->i_last_alloc_group = ~0; diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 827bde1..6ed9aa9 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -704,6 +704,9 @@ static struct inode *ext4_alloc_inode(struct super_block *sb) ei->i_allocated_meta_blocks = 0; ei->i_delalloc_reserved_flag = 0; spin_lock_init(&(ei->i_block_reservation_lock)); +#ifdef CONFIG_QUOTA + ei->i_reserved_quota = 0; +#endif INIT_LIST_HEAD(&ei->i_aio_dio_complete_list); ei->cur_aio_dio = NULL; ei->i_sync_tid = 0; @@ -1014,7 +1017,9 @@ static const struct dquot_operations ext4_quota_operations = { .reserve_space = dquot_reserve_space, .claim_space = dquot_claim_space, .release_rsv = dquot_release_reserved_space, +#ifdef CONFIG_QUOTA .get_reserved_space = ext4_get_reserved_space, +#endif .alloc_inode = dquot_alloc_inode, .free_space = dquot_free_space, .free_inode = dquot_free_inode, -- cgit v0.10.2 From dc52dd3a3a800e70b3440ea4424f8c87ab043e42 Mon Sep 17 00:00:00 2001 From: Dmitry Monakhov Date: Mon, 14 Dec 2009 15:21:15 +0300 Subject: quota: Move duplicated code to separate functions - for(..) { mark_dquot_dirty(); } -> mark_all_dquot_dirty() - for(..) { dput(); } -> dqput_all() Signed-off-by: Dmitry Monakhov Signed-off-by: Jan Kara diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index 1cb8fa8..dea86ab 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c @@ -323,6 +323,30 @@ int dquot_mark_dquot_dirty(struct dquot *dquot) } EXPORT_SYMBOL(dquot_mark_dquot_dirty); +/* Dirtify all the dquots - this can block when journalling */ +static inline int mark_all_dquot_dirty(struct dquot * const *dquot) +{ + int ret, err, cnt; + + ret = err = 0; + for (cnt = 0; cnt < MAXQUOTAS; cnt++) { + if (dquot[cnt]) + /* Even in case of error we have to continue */ + ret = mark_dquot_dirty(dquot[cnt]); + if (!err) + err = ret; + } + return err; +} + +static inline void dqput_all(struct dquot **dquot) +{ + unsigned int cnt; + + for (cnt = 0; cnt < MAXQUOTAS; cnt++) + dqput(dquot[cnt]); +} + /* This function needs dq_list_lock */ static inline int clear_dquot_dirty(struct dquot *dquot) { @@ -1268,8 +1292,7 @@ int dquot_initialize(struct inode *inode, int type) out_err: up_write(&sb_dqopt(sb)->dqptr_sem); /* Drop unused references */ - for (cnt = 0; cnt < MAXQUOTAS; cnt++) - dqput(got[cnt]); + dqput_all(got); return ret; } EXPORT_SYMBOL(dquot_initialize); @@ -1288,9 +1311,7 @@ int dquot_drop(struct inode *inode) inode->i_dquot[cnt] = NULL; } up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); - - for (cnt = 0; cnt < MAXQUOTAS; cnt++) - dqput(put[cnt]); + dqput_all(put); return 0; } EXPORT_SYMBOL(dquot_drop); @@ -1439,10 +1460,7 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number, if (reserve) goto out_flush_warn; - /* Dirtify all the dquots - this can block when journalling */ - for (cnt = 0; cnt < MAXQUOTAS; cnt++) - if (inode->i_dquot[cnt]) - mark_dquot_dirty(inode->i_dquot[cnt]); + mark_all_dquot_dirty(inode->i_dquot); out_flush_warn: flush_warnings(inode->i_dquot, warntype); out_unlock: @@ -1500,10 +1518,7 @@ int dquot_alloc_inode(const struct inode *inode, qsize_t number) warn_put_all: spin_unlock(&dq_data_lock); if (ret == QUOTA_OK) - /* Dirtify all the dquots - this can block when journalling */ - for (cnt = 0; cnt < MAXQUOTAS; cnt++) - if (inode->i_dquot[cnt]) - mark_dquot_dirty(inode->i_dquot[cnt]); + mark_all_dquot_dirty(inode->i_dquot); flush_warnings(inode->i_dquot, warntype); up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); return ret; @@ -1537,10 +1552,7 @@ int dquot_claim_space(struct inode *inode, qsize_t number) /* Update inode bytes */ inode_claim_rsv_space(inode, number); spin_unlock(&dq_data_lock); - /* Dirtify all the dquots - this can block when journalling */ - for (cnt = 0; cnt < MAXQUOTAS; cnt++) - if (inode->i_dquot[cnt]) - mark_dquot_dirty(inode->i_dquot[cnt]); + mark_all_dquot_dirty(inode->i_dquot); up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); out: return ret; @@ -1584,10 +1596,7 @@ out_sub: if (reserve) goto out_unlock; - /* Dirtify all the dquots - this can block when journalling */ - for (cnt = 0; cnt < MAXQUOTAS; cnt++) - if (inode->i_dquot[cnt]) - mark_dquot_dirty(inode->i_dquot[cnt]); + mark_all_dquot_dirty(inode->i_dquot); out_unlock: flush_warnings(inode->i_dquot, warntype); up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); @@ -1637,10 +1646,7 @@ int dquot_free_inode(const struct inode *inode, qsize_t number) dquot_decr_inodes(inode->i_dquot[cnt], number); } spin_unlock(&dq_data_lock); - /* Dirtify all the dquots - this can block when journalling */ - for (cnt = 0; cnt < MAXQUOTAS; cnt++) - if (inode->i_dquot[cnt]) - mark_dquot_dirty(inode->i_dquot[cnt]); + mark_all_dquot_dirty(inode->i_dquot); flush_warnings(inode->i_dquot, warntype); up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); return QUOTA_OK; @@ -1734,25 +1740,18 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr) spin_unlock(&dq_data_lock); up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); - /* Dirtify all the dquots - this can block when journalling */ - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { - if (transfer_from[cnt]) - mark_dquot_dirty(transfer_from[cnt]); - if (transfer_to[cnt]) { - mark_dquot_dirty(transfer_to[cnt]); - /* The reference we got is transferred to the inode */ - transfer_to[cnt] = NULL; - } - } + mark_all_dquot_dirty(transfer_from); + mark_all_dquot_dirty(transfer_to); + /* The reference we got is transferred to the inode */ + for (cnt = 0; cnt < MAXQUOTAS; cnt++) + transfer_to[cnt] = NULL; warn_put_all: flush_warnings(transfer_to, warntype_to); flush_warnings(transfer_from, warntype_from_inodes); flush_warnings(transfer_from, warntype_from_space); put_all: - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { - dqput(transfer_from[cnt]); - dqput(transfer_to[cnt]); - } + dqput_all(transfer_from); + dqput_all(transfer_to); return ret; over_quota: spin_unlock(&dq_data_lock); -- cgit v0.10.2 From ed505ee454dbf133b1a4067d3ac0325d4261eda1 Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Mon, 14 Dec 2009 12:59:18 -0600 Subject: ext3: Remove outdated comment about lock_super() ext3_fill_super() is no longer called by read_super(), and it is no longer called with the superblock locked. The unlock_super()/lock_super() is no longer present, so this comment is entirely superfluous. Port of ext4 commit 32ed5058ce90024efcd811254b4b1de0468099df by Theodore Ts'o . CC: Theodore Ts'o Signed-off-by: Eric Sandeen Signed-off-by: Jan Kara diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 7ad1e8c..8ad566b 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c @@ -2014,14 +2014,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent) } ext3_setup_super (sb, es, sb->s_flags & MS_RDONLY); - /* - * akpm: core read_super() calls in here with the superblock locked. - * That deadlocks, because orphan cleanup needs to lock the superblock - * in numerous places. Here we just pop the lock - it's relatively - * harmless, because we are now ready to accept write_super() requests, - * and aviro says that's the only reason for hanging onto the - * superblock lock. - */ + EXT3_SB(sb)->s_mount_state |= EXT3_ORPHAN_FS; ext3_orphan_cleanup(sb, es); EXT3_SB(sb)->s_mount_state &= ~EXT3_ORPHAN_FS; -- cgit v0.10.2 From 4854a5f0cbb1967fc7db3ea861d97afeea78b88b Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Mon, 14 Dec 2009 12:59:59 -0600 Subject: ext3: ext3_mark_recovery_complete() doesn't need to use lock_super The function ext3_mark_recovery_complete() is called from two call paths: either (a) while mounting the filesystem, in which case there's no danger of any other CPU calling write_super() until the mount is completed, and (b) while remounting the filesystem read-write, in which case the fs core has already locked the superblock. This also allows us to take out a very vile unlock_super()/lock_super() pair in ext3_remount(). Port of ext4 commit a63c9eb2ce6f5028da90f282798232c4f398ceb8 by Theodore Ts'o . CC: Theodore Ts'o Signed-off-by: Eric Sandeen Signed-off-by: Jan Kara diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 8ad566b..806b8b7 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c @@ -2396,13 +2396,11 @@ static void ext3_mark_recovery_complete(struct super_block * sb, if (journal_flush(journal) < 0) goto out; - lock_super(sb); if (EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER) && sb->s_flags & MS_RDONLY) { EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER); ext3_commit_super(sb, es, 1); } - unlock_super(sb); out: journal_unlock_updates(journal); @@ -2594,13 +2592,7 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data) (sbi->s_mount_state & EXT3_VALID_FS)) es->s_state = cpu_to_le16(sbi->s_mount_state); - /* - * We have to unlock super so that we can wait for - * transactions. - */ - unlock_super(sb); ext3_mark_recovery_complete(sb, es); - lock_super(sb); } else { __le32 ret; if ((ret = EXT3_HAS_RO_COMPAT_FEATURE(sb, -- cgit v0.10.2 From b8a052d01669977f224255b0f9f2737018171ddb Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Mon, 14 Dec 2009 13:00:30 -0600 Subject: ext3: Replace lock/unlock_super() with an explicit lock for the orphan list Use a separate lock to protect the orphan list, so we can stop overloading the use of lock_super(). Port of ext4 commit 3b9d4ed26680771295d904a6b83e88e620780893 by Theodore Ts'o . CC: Theodore Ts'o Signed-off-by: Eric Sandeen Signed-off-by: Jan Kara diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index 81f7348..7b0e44f7 100644 --- a/fs/ext3/namei.c +++ b/fs/ext3/namei.c @@ -1920,7 +1920,7 @@ int ext3_orphan_add(handle_t *handle, struct inode *inode) struct ext3_iloc iloc; int err = 0, rc; - lock_super(sb); + mutex_lock(&EXT3_SB(sb)->s_orphan_lock); if (!list_empty(&EXT3_I(inode)->i_orphan)) goto out_unlock; @@ -1929,9 +1929,13 @@ int ext3_orphan_add(handle_t *handle, struct inode *inode) /* @@@ FIXME: Observation from aviro: * I think I can trigger J_ASSERT in ext3_orphan_add(). We block - * here (on lock_super()), so race with ext3_link() which might bump + * here (on s_orphan_lock), so race with ext3_link() which might bump * ->i_nlink. For, say it, character device. Not a regular file, * not a directory, not a symlink and ->i_nlink > 0. + * + * tytso, 4/25/2009: I'm not sure how that could happen; + * shouldn't the fs core protect us from these sort of + * unlink()/link() races? */ J_ASSERT ((S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) || inode->i_nlink == 0); @@ -1968,7 +1972,7 @@ int ext3_orphan_add(handle_t *handle, struct inode *inode) jbd_debug(4, "orphan inode %lu will point to %d\n", inode->i_ino, NEXT_ORPHAN(inode)); out_unlock: - unlock_super(sb); + mutex_unlock(&EXT3_SB(sb)->s_orphan_lock); ext3_std_error(inode->i_sb, err); return err; } @@ -1986,11 +1990,9 @@ int ext3_orphan_del(handle_t *handle, struct inode *inode) struct ext3_iloc iloc; int err = 0; - lock_super(inode->i_sb); - if (list_empty(&ei->i_orphan)) { - unlock_super(inode->i_sb); - return 0; - } + mutex_lock(&EXT3_SB(inode->i_sb)->s_orphan_lock); + if (list_empty(&ei->i_orphan)) + goto out; ino_next = NEXT_ORPHAN(inode); prev = ei->i_orphan.prev; @@ -2040,7 +2042,7 @@ int ext3_orphan_del(handle_t *handle, struct inode *inode) out_err: ext3_std_error(inode->i_sb, err); out: - unlock_super(inode->i_sb); + mutex_unlock(&EXT3_SB(inode->i_sb)->s_orphan_lock); return err; out_brelse: diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 806b8b7..97dd382 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c @@ -1928,6 +1928,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent) sb->dq_op = &ext3_quota_operations; #endif INIT_LIST_HEAD(&sbi->s_orphan); /* unlinked but open files */ + mutex_init(&sbi->s_orphan_lock); sb->s_root = NULL; diff --git a/include/linux/ext3_fs_sb.h b/include/linux/ext3_fs_sb.h index f07f34d..dd61d83 100644 --- a/include/linux/ext3_fs_sb.h +++ b/include/linux/ext3_fs_sb.h @@ -72,6 +72,7 @@ struct ext3_sb_info { struct inode * s_journal_inode; struct journal_s * s_journal; struct list_head s_orphan; + struct mutex s_orphan_lock; unsigned long s_commit_interval; struct block_device *journal_bdev; #ifdef CONFIG_JBD_DEBUG -- cgit v0.10.2 From 96d2a495c25d525873529b736cdb63ad502b101c Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Mon, 14 Dec 2009 13:01:05 -0600 Subject: ext3: Replace lock/unlock_super() with an explicit lock for resizing Use a separate lock to protect s_groups_count and the other block group descriptors which get changed via an on-line resize operation, so we can stop overloading the use of lock_super(). Port of ext4 commit 32ed5058ce90024efcd811254b4b1de0468099df by Theodore Ts'o . CC: Theodore Ts'o Signed-off-by: Eric Sandeen Signed-off-by: Jan Kara diff --git a/fs/ext3/resize.c b/fs/ext3/resize.c index 5f83b61..54351ac 100644 --- a/fs/ext3/resize.c +++ b/fs/ext3/resize.c @@ -209,7 +209,7 @@ static int setup_new_group_blocks(struct super_block *sb, if (IS_ERR(handle)) return PTR_ERR(handle); - lock_super(sb); + mutex_lock(&sbi->s_resize_lock); if (input->group != sbi->s_groups_count) { err = -EBUSY; goto exit_journal; @@ -324,7 +324,7 @@ exit_bh: brelse(bh); exit_journal: - unlock_super(sb); + mutex_unlock(&sbi->s_resize_lock); if ((err2 = ext3_journal_stop(handle)) && !err) err = err2; @@ -662,11 +662,12 @@ exit_free: * important part is that the new block and inode counts are in the backup * superblocks, and the location of the new group metadata in the GDT backups. * - * We do not need lock_super() for this, because these blocks are not - * otherwise touched by the filesystem code when it is mounted. We don't - * need to worry about last changing from sbi->s_groups_count, because the - * worst that can happen is that we do not copy the full number of backups - * at this time. The resize which changed s_groups_count will backup again. + * We do not need take the s_resize_lock for this, because these + * blocks are not otherwise touched by the filesystem code when it is + * mounted. We don't need to worry about last changing from + * sbi->s_groups_count, because the worst that can happen is that we + * do not copy the full number of backups at this time. The resize + * which changed s_groups_count will backup again. */ static void update_backups(struct super_block *sb, int blk_off, char *data, int size) @@ -825,7 +826,7 @@ int ext3_group_add(struct super_block *sb, struct ext3_new_group_data *input) goto exit_put; } - lock_super(sb); + mutex_lock(&sbi->s_resize_lock); if (input->group != sbi->s_groups_count) { ext3_warning(sb, __func__, "multiple resizers run on filesystem!"); @@ -856,7 +857,7 @@ int ext3_group_add(struct super_block *sb, struct ext3_new_group_data *input) /* * OK, now we've set up the new group. Time to make it active. * - * Current kernels don't lock all allocations via lock_super(), + * We do not lock all allocations via s_resize_lock * so we have to be safe wrt. concurrent accesses the group * data. So we need to be careful to set all of the relevant * group descriptor data etc. *before* we enable the group. @@ -900,12 +901,12 @@ int ext3_group_add(struct super_block *sb, struct ext3_new_group_data *input) * * The precise rules we use are: * - * * Writers of s_groups_count *must* hold lock_super + * * Writers of s_groups_count *must* hold s_resize_lock * AND * * Writers must perform a smp_wmb() after updating all dependent * data and before modifying the groups count * - * * Readers must hold lock_super() over the access + * * Readers must hold s_resize_lock over the access * OR * * Readers must perform an smp_rmb() after reading the groups count * and before reading any dependent data. @@ -936,7 +937,7 @@ int ext3_group_add(struct super_block *sb, struct ext3_new_group_data *input) ext3_journal_dirty_metadata(handle, sbi->s_sbh); exit_journal: - unlock_super(sb); + mutex_unlock(&sbi->s_resize_lock); if ((err2 = ext3_journal_stop(handle)) && !err) err = err2; if (!err) { @@ -973,7 +974,7 @@ int ext3_group_extend(struct super_block *sb, struct ext3_super_block *es, /* We don't need to worry about locking wrt other resizers just * yet: we're going to revalidate es->s_blocks_count after - * taking lock_super() below. */ + * taking the s_resize_lock below. */ o_blocks_count = le32_to_cpu(es->s_blocks_count); o_groups_count = EXT3_SB(sb)->s_groups_count; @@ -1045,11 +1046,11 @@ int ext3_group_extend(struct super_block *sb, struct ext3_super_block *es, goto exit_put; } - lock_super(sb); + mutex_lock(&EXT3_SB(sb)->s_resize_lock); if (o_blocks_count != le32_to_cpu(es->s_blocks_count)) { ext3_warning(sb, __func__, "multiple resizers run on filesystem!"); - unlock_super(sb); + mutex_unlock(&EXT3_SB(sb)->s_resize_lock); ext3_journal_stop(handle); err = -EBUSY; goto exit_put; @@ -1059,13 +1060,13 @@ int ext3_group_extend(struct super_block *sb, struct ext3_super_block *es, EXT3_SB(sb)->s_sbh))) { ext3_warning(sb, __func__, "error %d on journal write access", err); - unlock_super(sb); + mutex_unlock(&EXT3_SB(sb)->s_resize_lock); ext3_journal_stop(handle); goto exit_put; } es->s_blocks_count = cpu_to_le32(o_blocks_count + add); ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh); - unlock_super(sb); + mutex_unlock(&EXT3_SB(sb)->s_resize_lock); ext3_debug("freeing blocks %lu through "E3FSBLK"\n", o_blocks_count, o_blocks_count + add); ext3_free_blocks_sb(handle, sb, o_blocks_count, add, &freed_blocks); diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 97dd382..afa2b56 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c @@ -1929,6 +1929,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent) #endif INIT_LIST_HEAD(&sbi->s_orphan); /* unlinked but open files */ mutex_init(&sbi->s_orphan_lock); + mutex_init(&sbi->s_resize_lock); sb->s_root = NULL; diff --git a/include/linux/ext3_fs_sb.h b/include/linux/ext3_fs_sb.h index dd61d83..258088a 100644 --- a/include/linux/ext3_fs_sb.h +++ b/include/linux/ext3_fs_sb.h @@ -73,6 +73,7 @@ struct ext3_sb_info { struct journal_s * s_journal; struct list_head s_orphan; struct mutex s_orphan_lock; + struct mutex s_resize_lock; unsigned long s_commit_interval; struct block_device *journal_bdev; #ifdef CONFIG_JBD_DEBUG -- cgit v0.10.2 From 82fdfa928cfa19d9627526b2ce164a27f8e9d34b Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Tue, 15 Dec 2009 22:24:36 +0100 Subject: quota: Fix 64-bit limits setting on 32-bit archs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix warnings: fs/quota/quota_v2.c: In function ‘v2_read_file_info’: fs/quota/quota_v2.c:123: warning: integer constant is too large for ‘long’ type fs/quota/quota_v2.c:124: warning: integer constant is too large for ‘long’ type Reported-by: Jerry Leo Signed-off-by: Jan Kara diff --git a/fs/quota/quota_v2.c b/fs/quota/quota_v2.c index 3dfc23e..669855c 100644 --- a/fs/quota/quota_v2.c +++ b/fs/quota/quota_v2.c @@ -120,8 +120,8 @@ static int v2_read_file_info(struct super_block *sb, int type) info->dqi_maxilimit = 0xffffffff; } else { /* used space is stored as unsigned 64-bit value */ - info->dqi_maxblimit = 0xffffffffffffffff; /* 2^64-1 */ - info->dqi_maxilimit = 0xffffffffffffffff; + info->dqi_maxblimit = 0xffffffffffffffffULL; /* 2^64-1 */ + info->dqi_maxilimit = 0xffffffffffffffffULL; } info->dqi_bgrace = le32_to_cpu(dinfo.dqi_bgrace); info->dqi_igrace = le32_to_cpu(dinfo.dqi_igrace); -- cgit v0.10.2 From d21cd8f163ac44b15c465aab7306db931c606908 Mon Sep 17 00:00:00 2001 From: Dmitry Monakhov Date: Thu, 10 Dec 2009 03:31:45 +0000 Subject: ext4: Fix potential quota deadlock We have to delay vfs_dq_claim_space() until allocation context destruction. Currently we have following call-trace: ext4_mb_new_blocks() /* task is already holding ac->alloc_semp */ ->ext4_mb_mark_diskspace_used ->vfs_dq_claim_space() /* acquire dqptr_sem here. Possible deadlock */ ->ext4_mb_release_context() /* drop ac->alloc_semp here */ Let's move quota claiming to ext4_da_update_reserve_space() ======================================================= [ INFO: possible circular locking dependency detected ] 2.6.32-rc7 #18 ------------------------------------------------------- write-truncate-/3465 is trying to acquire lock: (&s->s_dquot.dqptr_sem){++++..}, at: [] dquot_claim_space+0x3b/0x1b0 but task is already holding lock: (&meta_group_info[i]->alloc_sem){++++..}, at: [] ext4_mb_load_buddy+0xb2/0x370 which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #3 (&meta_group_info[i]->alloc_sem){++++..}: [] __lock_acquire+0xd7b/0x1260 [] lock_acquire+0xba/0xd0 [] down_read+0x51/0x90 [] ext4_mb_load_buddy+0xb2/0x370 [] ext4_mb_free_blocks+0x46c/0x870 [] ext4_free_blocks+0x73/0x130 [] ext4_ext_truncate+0x76c/0x8d0 [] ext4_truncate+0x187/0x5e0 [] vmtruncate+0x6b/0x70 [] inode_setattr+0x62/0x190 [] ext4_setattr+0x25a/0x370 [] notify_change+0x151/0x340 [] do_truncate+0x6d/0xa0 [] may_open+0x1d4/0x200 [] do_filp_open+0x1eb/0x910 [] do_sys_open+0x6d/0x140 [] sys_open+0x2e/0x40 [] sysenter_do_call+0x12/0x32 -> #2 (&ei->i_data_sem){++++..}: [] __lock_acquire+0xd7b/0x1260 [] lock_acquire+0xba/0xd0 [] down_read+0x51/0x90 [] ext4_get_blocks+0x47/0x450 [] ext4_getblk+0x61/0x1d0 [] ext4_bread+0x1f/0xa0 [] ext4_quota_write+0x12c/0x310 [] qtree_write_dquot+0x93/0x120 [] v2_write_dquot+0x28/0x30 [] dquot_commit+0xab/0xf0 [] ext4_write_dquot+0x77/0x90 [] ext4_mark_dquot_dirty+0x2f/0x50 [] dquot_alloc_inode+0x101/0x180 [] ext4_new_inode+0x602/0xf00 [] ext4_create+0x89/0x150 [] vfs_create+0xa2/0xc0 [] do_filp_open+0x7a7/0x910 [] do_sys_open+0x6d/0x140 [] sys_open+0x2e/0x40 [] sysenter_do_call+0x12/0x32 -> #1 (&sb->s_type->i_mutex_key#7/4){+.+...}: [] __lock_acquire+0xd7b/0x1260 [] lock_acquire+0xba/0xd0 [] mutex_lock_nested+0x65/0x2d0 [] vfs_load_quota_inode+0x4bd/0x5a0 [] vfs_quota_on_path+0x5f/0x70 [] ext4_quota_on+0x112/0x190 [] sys_quotactl+0x44a/0x8a0 [] sysenter_do_call+0x12/0x32 -> #0 (&s->s_dquot.dqptr_sem){++++..}: [] __lock_acquire+0x1091/0x1260 [] lock_acquire+0xba/0xd0 [] down_read+0x51/0x90 [] dquot_claim_space+0x3b/0x1b0 [] ext4_mb_mark_diskspace_used+0x36f/0x380 [] ext4_mb_new_blocks+0x34a/0x530 [] ext4_ext_get_blocks+0x122b/0x13c0 [] ext4_get_blocks+0x226/0x450 [] mpage_da_map_blocks+0xc3/0xaa0 [] ext4_da_writepages+0x506/0x790 [] do_writepages+0x22/0x50 [] __filemap_fdatawrite_range+0x6d/0x80 [] filemap_flush+0x2b/0x30 [] ext4_alloc_da_blocks+0x5c/0x60 [] ext4_release_file+0x75/0xb0 [] __fput+0xf9/0x210 [] fput+0x27/0x30 [] filp_close+0x4c/0x80 [] put_files_struct+0x6e/0xd0 [] exit_files+0x47/0x60 [] do_exit+0x144/0x710 [] do_group_exit+0x38/0xa0 [] get_signal_to_deliver+0x2ac/0x410 [] do_notify_resume+0xb9/0x890 [] work_notifysig+0x13/0x21 other info that might help us debug this: 3 locks held by write-truncate-/3465: #0: (jbd2_handle){+.+...}, at: [] start_this_handle+0x38f/0x5c0 #1: (&ei->i_data_sem){++++..}, at: [] ext4_get_blocks+0xb6/0x450 #2: (&meta_group_info[i]->alloc_sem){++++..}, at: [] ext4_mb_load_buddy+0xb2/0x370 stack backtrace: Pid: 3465, comm: write-truncate- Not tainted 2.6.32-rc7 #18 Call Trace: [] ? printk+0x1d/0x22 [] print_circular_bug+0xca/0xd0 [] __lock_acquire+0x1091/0x1260 [] ? sched_clock_local+0xd2/0x170 [] ? trace_hardirqs_off_caller+0x20/0xd0 [] lock_acquire+0xba/0xd0 [] ? dquot_claim_space+0x3b/0x1b0 [] down_read+0x51/0x90 [] ? dquot_claim_space+0x3b/0x1b0 [] dquot_claim_space+0x3b/0x1b0 [] ext4_mb_mark_diskspace_used+0x36f/0x380 [] ext4_mb_new_blocks+0x34a/0x530 [] ? ext4_ext_find_extent+0x25d/0x280 [] ext4_ext_get_blocks+0x122b/0x13c0 [] ? sched_clock_local+0xd2/0x170 [] ? sched_clock_cpu+0x120/0x160 [] ? cpu_clock+0x4f/0x60 [] ? trace_hardirqs_off_caller+0x20/0xd0 [] ? down_write+0x8c/0xa0 [] ext4_get_blocks+0x226/0x450 [] ? sched_clock_cpu+0x120/0x160 [] ? cpu_clock+0x4f/0x60 [] ? trace_hardirqs_off+0xb/0x10 [] mpage_da_map_blocks+0xc3/0xaa0 [] ? find_get_pages_tag+0x16c/0x180 [] ? find_get_pages_tag+0x0/0x180 [] ? __mpage_da_writepage+0x16d/0x1a0 [] ? pagevec_lookup_tag+0x2e/0x40 [] ? write_cache_pages+0xdb/0x3d0 [] ? __mpage_da_writepage+0x0/0x1a0 [] ext4_da_writepages+0x506/0x790 [] ? cpu_clock+0x4f/0x60 [] ? sched_clock_local+0xd2/0x170 [] ? sched_clock_cpu+0x120/0x160 [] ? sched_clock_cpu+0x120/0x160 [] ? ext4_da_writepages+0x0/0x790 [] do_writepages+0x22/0x50 [] __filemap_fdatawrite_range+0x6d/0x80 [] filemap_flush+0x2b/0x30 [] ext4_alloc_da_blocks+0x5c/0x60 [] ext4_release_file+0x75/0xb0 [] __fput+0xf9/0x210 [] fput+0x27/0x30 [] filp_close+0x4c/0x80 [] put_files_struct+0x6e/0xd0 [] exit_files+0x47/0x60 [] do_exit+0x144/0x710 [] ? lock_release_holdtime+0x33/0x210 [] ? _spin_unlock_irq+0x27/0x30 [] do_group_exit+0x38/0xa0 [] ? trace_hardirqs_on+0xb/0x10 [] get_signal_to_deliver+0x2ac/0x410 [] do_notify_resume+0xb9/0x890 [] ? trace_hardirqs_off_caller+0x20/0xd0 [] ? lock_release_holdtime+0x33/0x210 [] ? autoremove_wake_function+0x0/0x50 [] ? trace_hardirqs_on_caller+0x134/0x190 [] ? trace_hardirqs_on+0xb/0x10 [] ? security_file_permission+0x14/0x20 [] ? vfs_write+0x131/0x190 [] ? do_sync_write+0x0/0x120 [] ? sysenter_do_call+0x27/0x32 [] work_notifysig+0x13/0x21 CC: Theodore Ts'o Signed-off-by: Dmitry Monakhov Signed-off-by: Jan Kara diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index a31980d..ddd0a9c 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -1046,7 +1046,7 @@ static int ext4_calc_metadata_amount(struct inode *inode, int blocks) static void ext4_da_update_reserve_space(struct inode *inode, int used) { struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); - int total, mdb, mdb_free; + int total, mdb, mdb_free, mdb_claim = 0; spin_lock(&EXT4_I(inode)->i_block_reservation_lock); /* recalculate the number of metablocks still need to be reserved */ @@ -1059,7 +1059,9 @@ static void ext4_da_update_reserve_space(struct inode *inode, int used) if (mdb_free) { /* Account for allocated meta_blocks */ - mdb_free -= EXT4_I(inode)->i_allocated_meta_blocks; + mdb_claim = EXT4_I(inode)->i_allocated_meta_blocks; + BUG_ON(mdb_free < mdb_claim); + mdb_free -= mdb_claim; /* update fs dirty blocks counter */ percpu_counter_sub(&sbi->s_dirtyblocks_counter, mdb_free); @@ -1070,8 +1072,11 @@ static void ext4_da_update_reserve_space(struct inode *inode, int used) /* update per-inode reservations */ BUG_ON(used > EXT4_I(inode)->i_reserved_data_blocks); EXT4_I(inode)->i_reserved_data_blocks -= used; + percpu_counter_sub(&sbi->s_dirtyblocks_counter, used + mdb_claim); spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); + vfs_dq_claim_block(inode, used + mdb_claim); + /* * free those over-booking quota for metadata blocks */ diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index b1fd3da..d34afad 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -2755,12 +2755,6 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac, if (!(ac->ac_flags & EXT4_MB_DELALLOC_RESERVED)) /* release all the reserved blocks if non delalloc */ percpu_counter_sub(&sbi->s_dirtyblocks_counter, reserv_blks); - else { - percpu_counter_sub(&sbi->s_dirtyblocks_counter, - ac->ac_b_ex.fe_len); - /* convert reserved quota blocks to real quota blocks */ - vfs_dq_claim_block(ac->ac_inode, ac->ac_b_ex.fe_len); - } if (sbi->s_log_groups_per_flex) { ext4_group_t flex_group = ext4_flex_group(sbi, -- cgit v0.10.2 From 39bc680a8160bb9d6743f7873b535d553ff61058 Mon Sep 17 00:00:00 2001 From: Dmitry Monakhov Date: Thu, 10 Dec 2009 16:36:27 +0000 Subject: ext4: fix sleep inside spinlock issue with quota and dealloc (#14739) Unlock i_block_reservation_lock before vfs_dq_reserve_block(). This patch fixes http://bugzilla.kernel.org/show_bug.cgi?id=14739 CC: Theodore Ts'o Signed-off-by: Dmitry Monakhov Signed-off-by: Jan Kara diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index ddd0a9c..ab80796 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -1816,19 +1816,17 @@ repeat: md_needed = mdblocks - EXT4_I(inode)->i_reserved_meta_blocks; total = md_needed + nrblocks; + spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); /* * Make quota reservation here to prevent quota overflow * later. Real quota accounting is done at pages writeout * time. */ - if (vfs_dq_reserve_block(inode, total)) { - spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); + if (vfs_dq_reserve_block(inode, total)) return -EDQUOT; - } if (ext4_claim_free_blocks(sbi, total)) { - spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); vfs_dq_release_reservation_block(inode, total); if (ext4_should_retry_alloc(inode->i_sb, &retries)) { yield(); @@ -1836,10 +1834,11 @@ repeat: } return -ENOSPC; } + spin_lock(&EXT4_I(inode)->i_block_reservation_lock); EXT4_I(inode)->i_reserved_data_blocks += nrblocks; - EXT4_I(inode)->i_reserved_meta_blocks = mdblocks; - + EXT4_I(inode)->i_reserved_meta_blocks += md_needed; spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); + return 0; /* success */ } -- cgit v0.10.2 From 765f8361902d015c864d5e62019b2f139452d7ef Mon Sep 17 00:00:00 2001 From: Yin Kangkai Date: Tue, 15 Dec 2009 14:48:25 -0800 Subject: jbd: jbd-debug and jbd2-debug should be writable jbd-debug and jbd2-debug is currently read-only (S_IRUGO), which is not correct. Make it writable so that we can start debuging. Signed-off-by: Yin Kangkai Reviewed-by: Aneesh Kumar K.V Signed-off-by: Andrew Morton Signed-off-by: Jan Kara diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c index 4160afa..bd224ee 100644 --- a/fs/jbd/journal.c +++ b/fs/jbd/journal.c @@ -1913,7 +1913,7 @@ static void __init jbd_create_debugfs_entry(void) { jbd_debugfs_dir = debugfs_create_dir("jbd", NULL); if (jbd_debugfs_dir) - jbd_debug = debugfs_create_u8("jbd-debug", S_IRUGO, + jbd_debug = debugfs_create_u8("jbd-debug", S_IRUGO | S_IWUSR, jbd_debugfs_dir, &journal_enable_debug); } diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index b7ca3a9..17af879 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c @@ -2115,7 +2115,8 @@ static void __init jbd2_create_debugfs_entry(void) { jbd2_debugfs_dir = debugfs_create_dir("jbd2", NULL); if (jbd2_debugfs_dir) - jbd2_debug = debugfs_create_u8(JBD2_DEBUG_NAME, S_IRUGO, + jbd2_debug = debugfs_create_u8(JBD2_DEBUG_NAME, + S_IRUGO | S_IWUSR, jbd2_debugfs_dir, &jbd2_journal_enable_debug); } -- cgit v0.10.2 From 869835dfad3eb6f7d90c3255a24b084fea82f30d Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Mon, 21 Dec 2009 21:57:04 +0100 Subject: quota: Improve checking of quota file header When we are asked for vfsv0 quota format and the file is in vfsv1 format (or vice versa), refuse to use the quota file. Also return with error when we don't like the header of quota file. Signed-off-by: Jan Kara diff --git a/fs/quota/quota_v2.c b/fs/quota/quota_v2.c index 669855c..e3da02f 100644 --- a/fs/quota/quota_v2.c +++ b/fs/quota/quota_v2.c @@ -97,8 +97,11 @@ static int v2_read_file_info(struct super_block *sb, int type) unsigned int version; if (!v2_read_header(sb, type, &dqhead)) - return 0; + return -1; version = le32_to_cpu(dqhead.dqh_version); + if ((info->dqi_fmt_id == QFMT_VFS_V0 && version != 0) || + (info->dqi_fmt_id == QFMT_VFS_V1 && version != 1)) + return -1; size = sb->s_op->quota_read(sb, type, (char *)&dinfo, sizeof(struct v2_disk_dqinfo), V2_DQINFOOFF); -- cgit v0.10.2 From a6b43e382568a49cc64291bfaddf896652d44f70 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Dec 2009 07:48:08 -0500 Subject: ext4: fix unsigned long long printk warning in super.c sparc64 allmodconfig: fs/ext4/super.c: In function `lifetime_write_kbytes_show': fs/ext4/super.c:2174: warning: long long unsigned int format, long unsigned int arg (arg 4) fs/ext4/super.c:2174: warning: long long unsigned int format, long unsigned int arg (arg 4) Signed-off-by: Andrew Morton Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 0a06fe6..7cccb35 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -2174,9 +2174,9 @@ static ssize_t lifetime_write_kbytes_show(struct ext4_attr *a, struct super_block *sb = sbi->s_buddy_cache->i_sb; return snprintf(buf, PAGE_SIZE, "%llu\n", - sbi->s_kbytes_written + + (unsigned long long)(sbi->s_kbytes_written + ((part_stat_read(sb->s_bdev->bd_part, sectors[1]) - - EXT4_SB(sb)->s_sectors_written_start) >> 1)); + EXT4_SB(sb)->s_sectors_written_start) >> 1))); } static ssize_t inode_readahead_blks_store(struct ext4_attr *a, -- cgit v0.10.2 From d3533d72e7478a61a3e1936956fc825289a2acf4 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Wed, 23 Dec 2009 07:52:31 -0500 Subject: ext4: Eliminate potential double free on error path b_entry_name and buffer are initially NULL, are initialized within a loop to the result of calling kmalloc, and are freed at the bottom of this loop. The loop contains gotos to cleanup, which also frees b_entry_name and buffer. Some of these gotos are before the reinitializations of b_entry_name and buffer. To maintain the invariant that b_entry_name and buffer are NULL at the top of the loop, and thus acceptable arguments to kfree, these variables are now set to NULL after the kfrees. This seems to be the simplest solution. A more complicated solution would be to introduce more labels in the error handling code at the end of the function. A simplified version of the semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @r@ identifier E; expression E1; iterator I; statement S; @@ *kfree(E); ... when != E = E1 when != I(E,...) S when != &E *kfree(E); // Signed-off-by: Julia Lawall Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index 83218be..f3a2f7e 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -1332,6 +1332,8 @@ retry: goto cleanup; kfree(b_entry_name); kfree(buffer); + b_entry_name = NULL; + buffer = NULL; brelse(is->iloc.bh); kfree(is); kfree(bs); -- cgit v0.10.2 From 17bd55d037a02b04d9119511cfd1a4b985d20f63 Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Wed, 23 Dec 2009 07:57:07 -0500 Subject: fs-writeback: Add helper function to start writeback if idle ext4, at least, would like to start pushing on writeback if it starts to get close to ENOSPC when reserving worst-case blocks for delalloc writes. Writing out delalloc data will convert those worst-case predictions into usually smaller actual usage, freeing up space before we hit ENOSPC based on this speculation. Thanks to Jens for the suggestion for the helper function, & the naming help. I've made the helper return status on whether writeback was started even though I don't plan to use it in the ext4 patch; it seems like it would be potentially useful to test this in some cases. Signed-off-by: Eric Sandeen Acked-by: Jan Kara diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 49bc1b8..f6c2155 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -1187,6 +1187,23 @@ void writeback_inodes_sb(struct super_block *sb) EXPORT_SYMBOL(writeback_inodes_sb); /** + * writeback_inodes_sb_if_idle - start writeback if none underway + * @sb: the superblock + * + * Invoke writeback_inodes_sb if no writeback is currently underway. + * Returns 1 if writeback was started, 0 if not. + */ +int writeback_inodes_sb_if_idle(struct super_block *sb) +{ + if (!writeback_in_progress(sb->s_bdi)) { + writeback_inodes_sb(sb); + return 1; + } else + return 0; +} +EXPORT_SYMBOL(writeback_inodes_sb_if_idle); + +/** * sync_inodes_sb - sync sb inode pages * @sb: the superblock * diff --git a/include/linux/writeback.h b/include/linux/writeback.h index c18c008..76e8903 100644 --- a/include/linux/writeback.h +++ b/include/linux/writeback.h @@ -70,6 +70,7 @@ struct writeback_control { struct bdi_writeback; int inode_wait(void *); void writeback_inodes_sb(struct super_block *); +int writeback_inodes_sb_if_idle(struct super_block *); void sync_inodes_sb(struct super_block *); void writeback_inodes_wbc(struct writeback_control *wbc); long wb_do_writeback(struct bdi_writeback *wb, int force_wait); -- cgit v0.10.2 From c8afb44682fcef6273e8b8eb19fab13ddd05b386 Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Wed, 23 Dec 2009 07:58:12 -0500 Subject: ext4: flush delalloc blocks when space is low Creating many small files in rapid succession on a small filesystem can lead to spurious ENOSPC; on a 104MB filesystem: for i in `seq 1 22500`; do echo -n > $SCRATCH_MNT/$i echo XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX > $SCRATCH_MNT/$i done leads to ENOSPC even though after a sync, 40% of the fs is free again. This is because we reserve worst-case metadata for delalloc writes, and when data is allocated that worst-case reservation is not usually needed. When freespace is low, kicking off an async writeback will start converting that worst-case space usage into something more realistic, almost always freeing up space to continue. This resolves the testcase for me, and survives all 4 generic ENOSPC tests in xfstests. We'll still need a hard synchronous sync to squeeze out the last bit, but this fixes things up to a large degree. Signed-off-by: Eric Sandeen Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index ab80796..282621f 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -2993,11 +2993,18 @@ static int ext4_nonda_switch(struct super_block *sb) if (2 * free_blocks < 3 * dirty_blocks || free_blocks < (dirty_blocks + EXT4_FREEBLOCKS_WATERMARK)) { /* - * free block count is less that 150% of dirty blocks - * or free blocks is less that watermark + * free block count is less than 150% of dirty blocks + * or free blocks is less than watermark */ return 1; } + /* + * Even if we don't switch but are nearing capacity, + * start pushing delalloc when 1/2 of free blocks are dirty. + */ + if (free_blocks < 2 * dirty_blocks) + writeback_inodes_sb_if_idle(sb); + return 0; } -- cgit v0.10.2 From 3ebfdf885acedafcadceb4007e77438479094135 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Dec 2009 08:05:15 -0500 Subject: jbd2: don't use __GFP_NOFAIL in journal_init_common() It triggers the warning in get_page_from_freelist(), and it isn't appropriate to use __GFP_NOFAIL here anyway. Addresses http://bugzilla.kernel.org/show_bug.cgi?id=14843 Reported-by: Christian Casteyde Signed-off-by: Andrew Morton Signed-off-by: "Theodore Ts'o" diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index 17af879..ac0d027 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c @@ -814,7 +814,7 @@ static journal_t * journal_init_common (void) journal_t *journal; int err; - journal = kzalloc(sizeof(*journal), GFP_KERNEL|__GFP_NOFAIL); + journal = kzalloc(sizeof(*journal), GFP_KERNEL); if (!journal) goto fail; -- cgit v0.10.2 From 48e3cbb3f67a27d9c2db075f3d0f700246c40caa Mon Sep 17 00:00:00 2001 From: Eric Millbrandt Date: Tue, 22 Dec 2009 10:13:24 -0500 Subject: ASoC: Do not write to invalid registers on the wm9712. This patch fixes a bug where "virtual" registers were being written to the ac97 bus. This was causing unrelated registers to become corrupted (headphone 0x04, touchscreen 0x78, etc). This patch duplicates protection that was included in the wm9713 driver. Signed-off-by: Eric Millbrandt Acked-by: Liam Girdwood Signed-off-by: Mark Brown Cc: stable@kernel.org diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index 0ac1215..e237bf6 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c @@ -463,7 +463,8 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg, { u16 *cache = codec->reg_cache; - soc_ac97_ops.write(codec->ac97, reg, val); + if (reg < 0x7c) + soc_ac97_ops.write(codec->ac97, reg, val); reg = reg >> 1; if (reg < (ARRAY_SIZE(wm9712_reg))) cache[reg] = val; -- cgit v0.10.2 From f5908267b67917b8cbd98b27fd2be9b5f62ec76f Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Wed, 23 Dec 2009 23:22:34 +0800 Subject: hwrng: core - Fix double unlock in rng_dev_read When the loop terminates with size == 0 in rng_dev_read we will unlock the rng mutex twice. Reported-by: Dan Carpenter Signed-off-by: Herbert Xu diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c index e989f67..3d9c61e 100644 --- a/drivers/char/hw_random/core.c +++ b/drivers/char/hw_random/core.c @@ -158,10 +158,11 @@ static ssize_t rng_dev_read(struct file *filp, char __user *buf, goto out; } } -out_unlock: - mutex_unlock(&rng_mutex); out: return ret ? : err; +out_unlock: + mutex_unlock(&rng_mutex); + goto out; } -- cgit v0.10.2 From 119eecc831a42bd090543568932e440c6831f1bb Mon Sep 17 00:00:00 2001 From: Stefani Seibold Date: Wed, 23 Dec 2009 09:10:48 +0100 Subject: Fix usb_serial_probe() problem introduced by the recent kfifo changes The USB serial code was a new user of the kfifo API, and it was missed when porting things to the new kfifo API. Please make the write_fifo in place. Here is my patch to fix the regression and full ported version. Signed-off-by: Stefani Seibold Reported-and-tested-by: Rafael J. Wysocki Cc: Greg KH Cc: Andrew Morton Cc: Alan Stern Signed-off-by: Linus Torvalds diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index b0f1183..f1ea3a3 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -276,7 +276,7 @@ static int usb_serial_generic_write_start(struct usb_serial_port *port) if (port->write_urb_busy) start_io = false; else { - start_io = (kfifo_len(port->write_fifo) != 0); + start_io = (kfifo_len(&port->write_fifo) != 0); port->write_urb_busy = start_io; } spin_unlock_irqrestore(&port->lock, flags); @@ -285,7 +285,7 @@ static int usb_serial_generic_write_start(struct usb_serial_port *port) return 0; data = port->write_urb->transfer_buffer; - count = kfifo_out_locked(port->write_fifo, data, port->bulk_out_size, &port->lock); + count = kfifo_out_locked(&port->write_fifo, data, port->bulk_out_size, &port->lock); usb_serial_debug_data(debug, &port->dev, __func__, count, data); /* set up our urb */ @@ -345,7 +345,7 @@ int usb_serial_generic_write(struct tty_struct *tty, return usb_serial_multi_urb_write(tty, port, buf, count); - count = kfifo_in_locked(port->write_fifo, buf, count, &port->lock); + count = kfifo_in_locked(&port->write_fifo, buf, count, &port->lock); result = usb_serial_generic_write_start(port); if (result >= 0) @@ -370,7 +370,7 @@ int usb_serial_generic_write_room(struct tty_struct *tty) (serial->type->max_in_flight_urbs - port->urbs_in_flight); } else if (serial->num_bulk_out) - room = port->write_fifo->size - kfifo_len(port->write_fifo); + room = kfifo_avail(&port->write_fifo); spin_unlock_irqrestore(&port->lock, flags); dbg("%s - returns %d", __func__, room); @@ -391,7 +391,7 @@ int usb_serial_generic_chars_in_buffer(struct tty_struct *tty) chars = port->tx_bytes_flight; spin_unlock_irqrestore(&port->lock, flags); } else if (serial->num_bulk_out) - chars = kfifo_len(port->write_fifo); + chars = kfifo_len(&port->write_fifo); dbg("%s - returns %d", __func__, chars); return chars; @@ -507,7 +507,7 @@ void usb_serial_generic_write_bulk_callback(struct urb *urb) if (status) { dbg("%s - nonzero multi-urb write bulk status " "received: %d", __func__, status); - kfifo_reset(port->write_fifo); + kfifo_reset_out(&port->write_fifo); } else usb_serial_generic_write_start(port); } diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 636a4f2..33c85f7 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -595,8 +595,7 @@ static void port_release(struct device *dev) usb_free_urb(port->write_urb); usb_free_urb(port->interrupt_in_urb); usb_free_urb(port->interrupt_out_urb); - if (!IS_ERR(port->write_fifo) && port->write_fifo) - kfifo_free(port->write_fifo); + kfifo_free(&port->write_fifo); kfree(port->bulk_in_buffer); kfree(port->bulk_out_buffer); kfree(port->interrupt_in_buffer); @@ -939,7 +938,7 @@ int usb_serial_probe(struct usb_interface *interface, dev_err(&interface->dev, "No free urbs available\n"); goto probe_error; } - if (kfifo_alloc(port->write_fifo, PAGE_SIZE, GFP_KERNEL)) + if (kfifo_alloc(&port->write_fifo, PAGE_SIZE, GFP_KERNEL)) goto probe_error; buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); port->bulk_out_size = buffer_size; diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h index acf6e45..1819396 100644 --- a/include/linux/usb/serial.h +++ b/include/linux/usb/serial.h @@ -16,6 +16,7 @@ #include #include #include +#include #define SERIAL_TTY_MAJOR 188 /* Nice legal number now */ #define SERIAL_TTY_MINORS 254 /* loads of devices :) */ @@ -94,7 +95,7 @@ struct usb_serial_port { unsigned char *bulk_out_buffer; int bulk_out_size; struct urb *write_urb; - struct kfifo *write_fifo; + struct kfifo write_fifo; int write_urb_busy; __u8 bulk_out_endpointAddress; -- cgit v0.10.2 From 9c717de946ed7f5782e6dffacf2d05859073058c Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 23 Dec 2009 09:23:33 -0800 Subject: kfifo: fix Error/broken kernel-doc notation Fix kernel-doc errors and warnings in new header file kfifo.h. Don't use kernel-doc "/**" for internal functions whose comments are not in kernel-doc format. kernel-doc section header names (like "Note:") must be unique per function. Looks like I need to document that. Error(include/linux/kfifo.h:76): duplicate section name 'Note' Warning(include/linux/kfifo.h:88): Excess function parameter 'size' description in 'INIT_KFIFO' Error(include/linux/kfifo.h:101): duplicate section name 'Note' Warning(include/linux/kfifo.h:257): No description found for parameter 'fifo' (many of this last type, from internal functions) Signed-off-by: Randy Dunlap Cc: Stefani Seibold Signed-off-by: Linus Torvalds diff --git a/include/linux/kfifo.h b/include/linux/kfifo.h index 486e8ad..3d44e9c 100644 --- a/include/linux/kfifo.h +++ b/include/linux/kfifo.h @@ -69,8 +69,8 @@ struct kfifo { * @name: name of the declared kfifo datatype * @size: size of the fifo buffer * - * Note: the macro can be used inside struct or union declaration - * Note: the macro creates two objects: + * Note1: the macro can be used inside struct or union declaration + * Note2: the macro creates two objects: * A kfifo object with the given name and a buffer for the kfifo * object named name##kfifo_buffer */ @@ -83,7 +83,6 @@ union { \ /** * INIT_KFIFO - Initialize a kfifo declared by DECLARED_KFIFO * @name: name of the declared kfifo datatype - * @size: size of the fifo buffer */ #define INIT_KFIFO(name) \ name = __kfifo_initializer(sizeof(name##kfifo_buffer) - \ @@ -94,8 +93,8 @@ union { \ * @name: name of the declared kfifo datatype * @size: size of the fifo buffer * - * Note: the macro can be used for global and local kfifo data type variables - * Note: the macro creates two objects: + * Note1: the macro can be used for global and local kfifo data type variables + * Note2: the macro creates two objects: * A kfifo object with the given name and a buffer for the kfifo * object named name##kfifo_buffer */ @@ -249,7 +248,7 @@ extern __must_check unsigned int kfifo_from_user(struct kfifo *fifo, extern __must_check unsigned int kfifo_to_user(struct kfifo *fifo, void __user *to, unsigned int n); -/** +/* * __kfifo_add_out internal helper function for updating the out offset */ static inline void __kfifo_add_out(struct kfifo *fifo, @@ -259,7 +258,7 @@ static inline void __kfifo_add_out(struct kfifo *fifo, fifo->out += off; } -/** +/* * __kfifo_add_in internal helper function for updating the in offset */ static inline void __kfifo_add_in(struct kfifo *fifo, @@ -269,7 +268,7 @@ static inline void __kfifo_add_in(struct kfifo *fifo, fifo->in += off; } -/** +/* * __kfifo_off internal helper function for calculating the index of a * given offeset */ @@ -278,7 +277,7 @@ static inline unsigned int __kfifo_off(struct kfifo *fifo, unsigned int off) return off & (fifo->size - 1); } -/** +/* * __kfifo_peek_n internal helper function for determinate the length of * the next record in the fifo */ @@ -299,7 +298,7 @@ static inline unsigned int __kfifo_peek_n(struct kfifo *fifo, #undef __KFIFO_GET } -/** +/* * __kfifo_poke_n internal helper function for storing the length of * the next record into the fifo */ @@ -319,7 +318,7 @@ static inline void __kfifo_poke_n(struct kfifo *fifo, #undef __KFIFO_PUT } -/** +/* * __kfifo_in_... internal functions for put date into the fifo * do not call it directly, use kfifo_in_rec() instead */ @@ -367,7 +366,7 @@ static inline __must_check unsigned int kfifo_in_rec(struct kfifo *fifo, return __kfifo_in_rec(fifo, from, n, recsize); } -/** +/* * __kfifo_out_... internal functions for get date from the fifo * do not call it directly, use kfifo_out_rec() instead */ @@ -425,7 +424,7 @@ static inline __must_check unsigned int kfifo_out_rec(struct kfifo *fifo, return __kfifo_out_rec(fifo, to, n, recsize, total); } -/** +/* * __kfifo_from_user_... internal functions for transfer from user space into * the fifo. do not call it directly, use kfifo_from_user_rec() instead */ @@ -474,7 +473,7 @@ static inline __must_check unsigned int kfifo_from_user_rec(struct kfifo *fifo, return __kfifo_from_user_rec(fifo, from, n, recsize); } -/** +/* * __kfifo_to_user_... internal functions for transfer fifo data into user space * do not call it directly, use kfifo_to_user_rec() instead */ @@ -533,7 +532,7 @@ static inline __must_check unsigned int kfifo_to_user_rec(struct kfifo *fifo, return __kfifo_to_user_rec(fifo, to, n, recsize, total); } -/** +/* * __kfifo_peek_... internal functions for peek into the next fifo record * do not call it directly, use kfifo_peek_rec() instead */ @@ -557,7 +556,7 @@ static inline __must_check unsigned int kfifo_peek_rec(struct kfifo *fifo, return __kfifo_peek_n(fifo, recsize); } -/** +/* * __kfifo_skip_... internal functions for skip the next fifo record * do not call it directly, use kfifo_skip_rec() instead */ -- cgit v0.10.2 From 95e70e87533f9d117d369495ee633cb7d18dc802 Mon Sep 17 00:00:00 2001 From: Anisse Astier Date: Wed, 23 Dec 2009 17:28:45 +0100 Subject: ALSA: hda - Add STAC9205 PCI_QUIRK for Dell Vostro 1700 Signed-off-by: Anisse Astier Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 417fb22..eeda7be 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -2104,6 +2104,7 @@ static unsigned int ref9205_pin_configs[12] = { 10280204 1028021F 10280228 (Dell Vostro 1500) + 10280229 (Dell Vostro 1700) */ static unsigned int dell_9205_m42_pin_configs[12] = { 0x0321101F, 0x03A11020, 0x400003FA, 0x90170310, @@ -2189,6 +2190,8 @@ static struct snd_pci_quirk stac9205_cfg_tbl[] = { "Dell Inspiron", STAC_9205_DELL_M44), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0228, "Dell Vostro 1500", STAC_9205_DELL_M42), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0229, + "Dell Vostro 1700", STAC_9205_DELL_M42), /* Gateway */ SND_PCI_QUIRK(0x107b, 0x0560, "Gateway T6834c", STAC_9205_EAPD), SND_PCI_QUIRK(0x107b, 0x0565, "Gateway T1616", STAC_9205_EAPD), -- cgit v0.10.2 From f1f76f865b5f66db5b5c7f2d19874f2bb9b43b8d Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 16 Dec 2009 21:31:33 +0000 Subject: devtmpfs: Convert dirlock to a mutex devtmpfs has a rw_lock dirlock which serializes delete_path and create_path. This code was obviously never tested with the usual set of debugging facilities enabled. In the dirlock held sections the code calls: - vfs functions which take mutexes - kmalloc(, GFP_KERNEL) In both code pathes the might sleep warning triggers and spams dmesg. Convert the rw_lock to a mutex. There is no reason why this needs to be a rwlock. Signed-off-by: Thomas Gleixner Cc: Kay Sievers Cc: stable Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index 50375bb..278371c 100644 --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c @@ -32,7 +32,7 @@ static int dev_mount = 1; static int dev_mount; #endif -static rwlock_t dirlock; +static DEFINE_MUTEX(dirlock); static int __init mount_param(char *str) { @@ -93,7 +93,7 @@ static int create_path(const char *nodepath) { int err; - read_lock(&dirlock); + mutex_lock(&dirlock); err = dev_mkdir(nodepath, 0755); if (err == -ENOENT) { char *path; @@ -117,7 +117,7 @@ static int create_path(const char *nodepath) } kfree(path); } - read_unlock(&dirlock); + mutex_unlock(&dirlock); return err; } @@ -229,7 +229,7 @@ static int delete_path(const char *nodepath) if (!path) return -ENOMEM; - write_lock(&dirlock); + mutex_lock(&dirlock); for (;;) { char *base; @@ -241,7 +241,7 @@ static int delete_path(const char *nodepath) if (err) break; } - write_unlock(&dirlock); + mutex_unlock(&dirlock); kfree(path); return err; @@ -352,8 +352,6 @@ int __init devtmpfs_init(void) int err; struct vfsmount *mnt; - rwlock_init(&dirlock); - err = register_filesystem(&dev_fs_type); if (err) { printk(KERN_ERR "devtmpfs: unable to register devtmpfs " -- cgit v0.10.2 From 9329d1beaeed1a94f030c784dcec5ff973f402c4 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 18 Dec 2009 21:18:15 +0100 Subject: vfs: get_sb_single() - do not pass options twice Filesystem code usually destroys the option buffer while parsing it. This leads to errors when the same buffer is passed twice. In case we fill a new superblock do not call remount. This is needed to quite a warning that the debugfs code causes every boot. Cc: Miklos Szeredi Signed-off-by: Kay Sievers Signed-off-by: Greg Kroah-Hartman diff --git a/fs/super.c b/fs/super.c index 19eb70b..aff046b 100644 --- a/fs/super.c +++ b/fs/super.c @@ -901,8 +901,9 @@ int get_sb_single(struct file_system_type *fs_type, return error; } s->s_flags |= MS_ACTIVE; + } else { + do_remount_sb(s, flags, data, 0); } - do_remount_sb(s, flags, data, 0); simple_set_mnt(mnt, s); return 0; } -- cgit v0.10.2 From 8e9b9362266dd16255473c080d846b13e27247bf Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Sun, 6 Dec 2009 12:24:31 +0100 Subject: Doc/stable rules: add new cherry-pick logic - it is possible to submit patches for the stable queue without sending them directly stable@kernel.org. If the tag (Cc: stable@kernel.org) is available in the sign-off area than hpa's script will filter them into the stable mailbox once it hits Linus' tree. - Patches which require others to be applied first can be also specified. This was discussued in http://lkml.org/lkml/2009/11/9/474 Signed-off-by: Sebastian Andrzej Siewior Cc: Brandon Philips Signed-off-by: Greg Kroah-Hartman diff --git a/Documentation/stable_kernel_rules.txt b/Documentation/stable_kernel_rules.txt index a452227..5effa5b 100644 --- a/Documentation/stable_kernel_rules.txt +++ b/Documentation/stable_kernel_rules.txt @@ -26,13 +26,33 @@ Procedure for submitting patches to the -stable tree: - Send the patch, after verifying that it follows the above rules, to stable@kernel.org. + - To have the patch automatically included in the stable tree, add the + the tag + Cc: stable@kernel.org + in the sign-off area. Once the patch is merged it will be applied to + the stable tree without anything else needing to be done by the author + or subsystem maintainer. + - If the patch requires other patches as prerequisites which can be + cherry-picked than this can be specified in the following format in + the sign-off area: + + Cc: # .32.x: a1f84a3: sched: Check for idle + Cc: # .32.x: 1b9508f: sched: Rate-limit newidle + Cc: # .32.x: fd21073: sched: Fix affinity logic + Cc: # .32.x + Signed-off-by: Ingo Molnar + + The tag sequence has the meaning of: + git cherry-pick a1f84a3 + git cherry-pick 1b9508f + git cherry-pick fd21073 + git cherry-pick + - The sender will receive an ACK when the patch has been accepted into the queue, or a NAK if the patch is rejected. This response might take a few days, according to the developer's schedules. - If accepted, the patch will be added to the -stable queue, for review by other developers and by the relevant subsystem maintainer. - - If the stable@kernel.org address is added to a patch, when it goes into - Linus's tree it will automatically be emailed to the stable team. - Security patches should not be sent to this alias, but instead to the documented security@kernel.org address. -- cgit v0.10.2 From 26579ab70aa0e0ea434e6e100279d2f67c094431 Mon Sep 17 00:00:00 2001 From: Phil Carmody Date: Fri, 18 Dec 2009 15:34:19 +0200 Subject: Driver core: device_attribute parameters can often be const* Most device_attributes are const, and are begging to be put in a ro section. However, the create and remove file interfaces were failing to propagate the const promise which the only functions they call offer. Signed-off-by: Phil Carmody Signed-off-by: Greg Kroah-Hartman diff --git a/Documentation/filesystems/sysfs.txt b/Documentation/filesystems/sysfs.txt index b245d52..a4ac2b9 100644 --- a/Documentation/filesystems/sysfs.txt +++ b/Documentation/filesystems/sysfs.txt @@ -91,8 +91,8 @@ struct device_attribute { const char *buf, size_t count); }; -int device_create_file(struct device *, struct device_attribute *); -void device_remove_file(struct device *, struct device_attribute *); +int device_create_file(struct device *, const struct device_attribute *); +void device_remove_file(struct device *, const struct device_attribute *); It also defines this helper for defining device attributes: @@ -316,8 +316,8 @@ DEVICE_ATTR(_name, _mode, _show, _store); Creation/Removal: -int device_create_file(struct device *device, struct device_attribute * attr); -void device_remove_file(struct device * dev, struct device_attribute * attr); +int device_create_file(struct device *dev, const struct device_attribute * attr); +void device_remove_file(struct device *dev, const struct device_attribute * attr); - bus drivers (include/linux/device.h) diff --git a/drivers/base/core.c b/drivers/base/core.c index f1290cb..2fd9e61 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -446,7 +446,8 @@ struct kset *devices_kset; * @dev: device. * @attr: device attribute descriptor. */ -int device_create_file(struct device *dev, struct device_attribute *attr) +int device_create_file(struct device *dev, + const struct device_attribute *attr) { int error = 0; if (dev) @@ -459,7 +460,8 @@ int device_create_file(struct device *dev, struct device_attribute *attr) * @dev: device. * @attr: device attribute descriptor. */ -void device_remove_file(struct device *dev, struct device_attribute *attr) +void device_remove_file(struct device *dev, + const struct device_attribute *attr) { if (dev) sysfs_remove_file(&dev->kobj, &attr->attr); diff --git a/include/linux/device.h b/include/linux/device.h index 2a73d9b..aa5b3e66 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -319,9 +319,9 @@ struct device_attribute { struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store) extern int __must_check device_create_file(struct device *device, - struct device_attribute *entry); + const struct device_attribute *entry); extern void device_remove_file(struct device *dev, - struct device_attribute *attr); + const struct device_attribute *attr); extern int __must_check device_create_bin_file(struct device *dev, struct bin_attribute *attr); extern void device_remove_bin_file(struct device *dev, -- cgit v0.10.2 From 66ecb92be9eb579df93add22d19843e7869f168e Mon Sep 17 00:00:00 2001 From: Phil Carmody Date: Fri, 18 Dec 2009 15:34:20 +0200 Subject: Driver core: bin_attribute parameters can often be const* Many struct bin_attribute descriptors are purely read-only structures, and there's no need to change them. Therefore make the promise not to, which will let those descriptors be put in a ro section. Signed-off-by: Phil Carmody Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/base/core.c b/drivers/base/core.c index 2fd9e61..83afc8b 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -472,7 +472,8 @@ void device_remove_file(struct device *dev, * @dev: device. * @attr: device binary attribute descriptor. */ -int device_create_bin_file(struct device *dev, struct bin_attribute *attr) +int device_create_bin_file(struct device *dev, + const struct bin_attribute *attr) { int error = -EINVAL; if (dev) @@ -486,7 +487,8 @@ EXPORT_SYMBOL_GPL(device_create_bin_file); * @dev: device. * @attr: device binary attribute descriptor. */ -void device_remove_bin_file(struct device *dev, struct bin_attribute *attr) +void device_remove_bin_file(struct device *dev, + const struct bin_attribute *attr) { if (dev) sysfs_remove_bin_file(&dev->kobj, attr); diff --git a/fs/sysfs/bin.c b/fs/sysfs/bin.c index 60c702b..a0a500a 100644 --- a/fs/sysfs/bin.c +++ b/fs/sysfs/bin.c @@ -483,7 +483,8 @@ void unmap_bin_file(struct sysfs_dirent *attr_sd) * @attr: attribute descriptor. */ -int sysfs_create_bin_file(struct kobject * kobj, struct bin_attribute * attr) +int sysfs_create_bin_file(struct kobject *kobj, + const struct bin_attribute *attr) { BUG_ON(!kobj || !kobj->sd || !attr); @@ -497,7 +498,8 @@ int sysfs_create_bin_file(struct kobject * kobj, struct bin_attribute * attr) * @attr: attribute descriptor. */ -void sysfs_remove_bin_file(struct kobject * kobj, struct bin_attribute * attr) +void sysfs_remove_bin_file(struct kobject *kobj, + const struct bin_attribute *attr) { sysfs_hash_and_remove(kobj->sd, attr->attr.name); } diff --git a/include/linux/device.h b/include/linux/device.h index aa5b3e66..10d74ce 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -319,13 +319,13 @@ struct device_attribute { struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store) extern int __must_check device_create_file(struct device *device, - const struct device_attribute *entry); + const struct device_attribute *entry); extern void device_remove_file(struct device *dev, const struct device_attribute *attr); extern int __must_check device_create_bin_file(struct device *dev, - struct bin_attribute *attr); + const struct bin_attribute *attr); extern void device_remove_bin_file(struct device *dev, - struct bin_attribute *attr); + const struct bin_attribute *attr); extern int device_schedule_callback_owner(struct device *dev, void (*func)(struct device *dev), struct module *owner); diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index 9d68fed..cfa8308 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h @@ -99,8 +99,9 @@ int __must_check sysfs_chmod_file(struct kobject *kobj, struct attribute *attr, void sysfs_remove_file(struct kobject *kobj, const struct attribute *attr); int __must_check sysfs_create_bin_file(struct kobject *kobj, - struct bin_attribute *attr); -void sysfs_remove_bin_file(struct kobject *kobj, struct bin_attribute *attr); + const struct bin_attribute *attr); +void sysfs_remove_bin_file(struct kobject *kobj, + const struct bin_attribute *attr); int __must_check sysfs_create_link(struct kobject *kobj, struct kobject *target, const char *name); @@ -175,13 +176,13 @@ static inline void sysfs_remove_file(struct kobject *kobj, } static inline int sysfs_create_bin_file(struct kobject *kobj, - struct bin_attribute *attr) + const struct bin_attribute *attr) { return 0; } static inline void sysfs_remove_bin_file(struct kobject *kobj, - struct bin_attribute *attr) + const struct bin_attribute *attr) { } -- cgit v0.10.2 From 099c2f21d8cf0724b85abb2c589d6276953781b7 Mon Sep 17 00:00:00 2001 From: Phil Carmody Date: Fri, 18 Dec 2009 15:34:21 +0200 Subject: Driver core: driver_attribute parameters can often be const* Many struct driver_attribute descriptors are purely read-only structures, and there's no need to change them. Therefore make the promise not to, which will let those descriptors be put in a ro section. Signed-off-by: Phil Carmody Signed-off-by: Greg Kroah-Hartman diff --git a/Documentation/driver-model/driver.txt b/Documentation/driver-model/driver.txt index 60120fb..d2cd6fb 100644 --- a/Documentation/driver-model/driver.txt +++ b/Documentation/driver-model/driver.txt @@ -226,5 +226,5 @@ struct driver_attribute driver_attr_debug; This can then be used to add and remove the attribute from the driver's directory using: -int driver_create_file(struct device_driver *, struct driver_attribute *); -void driver_remove_file(struct device_driver *, struct driver_attribute *); +int driver_create_file(struct device_driver *, const struct driver_attribute *); +void driver_remove_file(struct device_driver *, const struct driver_attribute *); diff --git a/Documentation/filesystems/sysfs.txt b/Documentation/filesystems/sysfs.txt index a4ac2b9..931c806 100644 --- a/Documentation/filesystems/sysfs.txt +++ b/Documentation/filesystems/sysfs.txt @@ -358,7 +358,7 @@ DRIVER_ATTR(_name, _mode, _show, _store) Creation/Removal: -int driver_create_file(struct device_driver *, struct driver_attribute *); -void driver_remove_file(struct device_driver *, struct driver_attribute *); +int driver_create_file(struct device_driver *, const struct driver_attribute *); +void driver_remove_file(struct device_driver *, const struct driver_attribute *); diff --git a/drivers/base/driver.c b/drivers/base/driver.c index f367885..90c9fff 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c @@ -98,7 +98,7 @@ EXPORT_SYMBOL_GPL(driver_find_device); * @attr: driver attribute descriptor. */ int driver_create_file(struct device_driver *drv, - struct driver_attribute *attr) + const struct driver_attribute *attr) { int error; if (drv) @@ -115,7 +115,7 @@ EXPORT_SYMBOL_GPL(driver_create_file); * @attr: driver attribute descriptor. */ void driver_remove_file(struct device_driver *drv, - struct driver_attribute *attr) + const struct driver_attribute *attr) { if (drv) sysfs_remove_file(&drv->p->kobj, &attr->attr); diff --git a/include/linux/device.h b/include/linux/device.h index 10d74ce..a62799f 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -166,9 +166,9 @@ struct driver_attribute driver_attr_##_name = \ __ATTR(_name, _mode, _show, _store) extern int __must_check driver_create_file(struct device_driver *driver, - struct driver_attribute *attr); + const struct driver_attribute *attr); extern void driver_remove_file(struct device_driver *driver, - struct driver_attribute *attr); + const struct driver_attribute *attr); extern int __must_check driver_add_kobj(struct device_driver *drv, struct kobject *kobj, -- cgit v0.10.2 From e6309e7568d4b9d62298a887b10de42df11cb8c1 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 10 Dec 2009 19:32:49 +0000 Subject: Driver-core: Fix bogus 0 error return in device_add() If device_add() is called with a device which does not have dev->p set up, then device_private_init() is called. If that succeeds, then the error variable is set to 0. Now if the dev_name(dev) check further down fails, then device_add() correctly terminates, but returns 0. That of course lets the driver progress. If later another driver uses this half set up device as parent then device_add() of the child device explodes and renders sysfs completely unusable. Set the error to -EINVAL if dev_name() check fails. Signed-off-by: Thomas Gleixner Cc: Kay Sievers Cc: "Hans J. Koch" Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/base/core.c b/drivers/base/core.c index 83afc8b..2820257 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -909,8 +909,10 @@ int device_add(struct device *dev) dev->init_name = NULL; } - if (!dev_name(dev)) + if (!dev_name(dev)) { + error = -EINVAL; goto name_error; + } pr_debug("device: '%s': %s\n", dev_name(dev), __func__); -- cgit v0.10.2 From 99b28f1b4126582f87ce454d4affb823bddf2cd8 Mon Sep 17 00:00:00 2001 From: Phil Carmody Date: Mon, 14 Dec 2009 20:28:12 +0200 Subject: driver core: Prevent reference to freed memory on error path priv is drv->p. So only free drv->p after we've finished using priv. Found using a static code analysis tool Signed-off-by: Phil Carmody Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 63c143e..c0c5a43 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -703,9 +703,9 @@ int bus_add_driver(struct device_driver *drv) return 0; out_unregister: + kobject_put(&priv->kobj); kfree(drv->p); drv->p = NULL; - kobject_put(&priv->kobj); out_put_bus: bus_put(bus); return error; -- cgit v0.10.2 From 0787fdf70ba4c41a3350096ebaa347a17e900385 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Mon, 21 Dec 2009 11:41:08 -0500 Subject: Driver core: export platform_device_register_data as a GPL symbol This allows MFD's to register/bind drivers for their sub devices while still being compiled as a module. Signed-off-by: Michael Hennerich Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 9d2ee25..58efaf2 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -441,6 +441,7 @@ error: platform_device_put(pdev); return ERR_PTR(retval); } +EXPORT_SYMBOL_GPL(platform_device_register_data); static int platform_drv_probe(struct device *_dev) { -- cgit v0.10.2 From 8042273801059884da2d53bbca34575d090b6f4e Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 22 Dec 2009 22:25:16 +0100 Subject: devtmpfs: unlock mutex in case of string allocation error Reported-by: Kirill A. Shutemov Signed-off-by: Kay Sievers Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index 278371c..090dd48 100644 --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c @@ -101,8 +101,10 @@ static int create_path(const char *nodepath) /* parent directories do not exist, create them */ path = kstrdup(nodepath, GFP_KERNEL); - if (!path) - return -ENOMEM; + if (!path) { + err = -ENOMEM; + goto out; + } s = path; for (;;) { s = strchr(s, '/'); @@ -117,6 +119,7 @@ static int create_path(const char *nodepath) } kfree(path); } +out: mutex_unlock(&dirlock); return err; } -- cgit v0.10.2 From d7edf47947f9d921be6ca5fc8e83049124466f98 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Mon, 23 Nov 2009 10:28:24 +0800 Subject: Staging: sm7xx: add a new framebuffer driver Yeeloong netbook has a sm712 video card, need this driver, but it is not ready to upstream yet, so, go to drivers/staing at first. This source code is originally from Silicon Motion Technology Corp, and maintained at http://dev.lemote.com/code/linux_loongson for YeeLoong netbook. I have done a lot of cleanups for it and merged it into my git repository at http://dev.lemote.com/code/rt4ls. Thanks to Simon for testing it on a little-endian x86 platform. Thanks to Olivier Croset for reporting the problem about __BIG_ENDIAN compiling problem and send a relative patch. The suspend/resume and blank support are contributed by Jason from Silicon Motion Technology. Tested-by: Simon Braunschmidt Signed-off-by: Wu Zhangjin Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 093f57a..db0de94 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -145,5 +145,7 @@ source "drivers/staging/wavelan/Kconfig" source "drivers/staging/netwave/Kconfig" +source "drivers/staging/sm7xx/Kconfig" + endif # !STAGING_EXCLUDE_BUILD endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 069864f..73c6a711 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -53,3 +53,4 @@ obj-$(CONFIG_ARLAN) += arlan/ obj-$(CONFIG_WAVELAN) += wavelan/ obj-$(CONFIG_PCMCIA_WAVELAN) += wavelan/ obj-$(CONFIG_PCMCIA_NETWAVE) += netwave/ +obj-$(CONFIG_FB_SM7XX) += sm7xx/ diff --git a/drivers/staging/sm7xx/Kconfig b/drivers/staging/sm7xx/Kconfig new file mode 100644 index 0000000..204dbfc --- /dev/null +++ b/drivers/staging/sm7xx/Kconfig @@ -0,0 +1,15 @@ +config FB_SM7XX + tristate "Silicon Motion SM7XX Frame Buffer Support" + depends on FB + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + Frame Buffer driver for the Silicon Motion SM7XX serial graphic card. + +config FB_SM7XX_ACCEL + bool "Siliconmotion Acceleration functions (EXPERIMENTAL)" + depends on FB_SM7XX && EXPERIMENTAL + help + This will compile the Trident frame buffer device with + acceleration functions. diff --git a/drivers/staging/sm7xx/Makefile b/drivers/staging/sm7xx/Makefile new file mode 100644 index 0000000..f43cb91 --- /dev/null +++ b/drivers/staging/sm7xx/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_FB_SM7XX) += sm7xx.o + +sm7xx-y := smtcfb.o diff --git a/drivers/staging/sm7xx/TODO b/drivers/staging/sm7xx/TODO new file mode 100644 index 0000000..1f61f5e --- /dev/null +++ b/drivers/staging/sm7xx/TODO @@ -0,0 +1,10 @@ +TODO: +- Dual head support +- use kernel coding style +- checkpatch.pl clean +- refine the code and remove unused code +- use kernel framebuffer mode setting instead of hard code +- move it to drivers/video/sm7xx/ or make it be drivers/video/sm7xxfb.c + +Please send any patches to Greg Kroah-Hartman and +Teddy Wang . diff --git a/drivers/staging/sm7xx/smtc2d.c b/drivers/staging/sm7xx/smtc2d.c new file mode 100644 index 0000000..133b86c --- /dev/null +++ b/drivers/staging/sm7xx/smtc2d.c @@ -0,0 +1,979 @@ +/* + * Silicon Motion SM7XX 2D drawing engine functions. + * + * Copyright (C) 2006 Silicon Motion Technology Corp. + * Author: Boyod boyod.yang@siliconmotion.com.cn + * + * Copyright (C) 2009 Lemote, Inc. + * Author: Wu Zhangjin, wuzj@lemote.com + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. + * + * Version 0.10.26192.21.01 + * - Add PowerPC support + * - Add 2D support for Lynx - + * Verified on 2.6.19.2 + * Boyod.yang + */ + +unsigned char smtc_de_busy; + +void SMTC_write2Dreg(unsigned long nOffset, unsigned long nData) +{ + writel(nData, smtc_2DBaseAddress + nOffset); +} + +unsigned long SMTC_read2Dreg(unsigned long nOffset) +{ + return readl(smtc_2DBaseAddress + nOffset); +} + +void SMTC_write2Ddataport(unsigned long nOffset, unsigned long nData) +{ + writel(nData, smtc_2Ddataport + nOffset); +} + +/********************************************************************** + * + * deInit + * + * Purpose + * Drawing engine initialization. + * + **********************************************************************/ + +void deInit(unsigned int nModeWidth, unsigned int nModeHeight, + unsigned int bpp) +{ + /* Get current power configuration. */ + unsigned char clock; + clock = smtc_seqr(0x21); + + /* initialize global 'mutex lock' variable */ + smtc_de_busy = 0; + + /* Enable 2D Drawing Engine */ + smtc_seqw(0x21, clock & 0xF8); + + SMTC_write2Dreg(DE_CLIP_TL, + FIELD_VALUE(0, DE_CLIP_TL, TOP, 0) | + FIELD_SET(0, DE_CLIP_TL, STATUS, DISABLE) | + FIELD_SET(0, DE_CLIP_TL, INHIBIT, OUTSIDE) | + FIELD_VALUE(0, DE_CLIP_TL, LEFT, 0)); + + if (bpp >= 24) { + SMTC_write2Dreg(DE_PITCH, + FIELD_VALUE(0, DE_PITCH, DESTINATION, + nModeWidth * 3) | FIELD_VALUE(0, + DE_PITCH, + SOURCE, + nModeWidth + * 3)); + } else { + SMTC_write2Dreg(DE_PITCH, + FIELD_VALUE(0, DE_PITCH, DESTINATION, + nModeWidth) | FIELD_VALUE(0, + DE_PITCH, + SOURCE, + nModeWidth)); + } + + SMTC_write2Dreg(DE_WINDOW_WIDTH, + FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, + nModeWidth) | FIELD_VALUE(0, + DE_WINDOW_WIDTH, + SOURCE, + nModeWidth)); + + switch (bpp) { + case 8: + SMTC_write2Dreg(DE_STRETCH_FORMAT, + FIELD_SET(0, DE_STRETCH_FORMAT, PATTERN_XY, + NORMAL) | FIELD_VALUE(0, + DE_STRETCH_FORMAT, + PATTERN_Y, + 0) | + FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_X, + 0) | FIELD_SET(0, DE_STRETCH_FORMAT, + PIXEL_FORMAT, + 8) | FIELD_SET(0, + DE_STRETCH_FORMAT, + ADDRESSING, + XY) | + FIELD_VALUE(0, DE_STRETCH_FORMAT, + SOURCE_HEIGHT, 3)); + break; + case 24: + SMTC_write2Dreg(DE_STRETCH_FORMAT, + FIELD_SET(0, DE_STRETCH_FORMAT, PATTERN_XY, + NORMAL) | FIELD_VALUE(0, + DE_STRETCH_FORMAT, + PATTERN_Y, + 0) | + FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_X, + 0) | FIELD_SET(0, DE_STRETCH_FORMAT, + PIXEL_FORMAT, + 24) | FIELD_SET(0, + DE_STRETCH_FORMAT, + ADDRESSING, + XY) | + FIELD_VALUE(0, DE_STRETCH_FORMAT, + SOURCE_HEIGHT, 3)); + break; + case 16: + default: + SMTC_write2Dreg(DE_STRETCH_FORMAT, + FIELD_SET(0, DE_STRETCH_FORMAT, PATTERN_XY, + NORMAL) | FIELD_VALUE(0, + DE_STRETCH_FORMAT, + PATTERN_Y, + 0) | + FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_X, + 0) | FIELD_SET(0, DE_STRETCH_FORMAT, + PIXEL_FORMAT, + 16) | FIELD_SET(0, + DE_STRETCH_FORMAT, + ADDRESSING, + XY) | + FIELD_VALUE(0, DE_STRETCH_FORMAT, + SOURCE_HEIGHT, 3)); + break; + } + + SMTC_write2Dreg(DE_MASKS, + FIELD_VALUE(0, DE_MASKS, BYTE_MASK, 0xFFFF) | + FIELD_VALUE(0, DE_MASKS, BIT_MASK, 0xFFFF)); + SMTC_write2Dreg(DE_COLOR_COMPARE_MASK, + FIELD_VALUE(0, DE_COLOR_COMPARE_MASK, MASKS, \ + 0xFFFFFF)); + SMTC_write2Dreg(DE_COLOR_COMPARE, + FIELD_VALUE(0, DE_COLOR_COMPARE, COLOR, 0xFFFFFF)); +} + +void deVerticalLine(unsigned long dst_base, + unsigned long dst_pitch, + unsigned long nX, + unsigned long nY, + unsigned long dst_height, unsigned long nColor) +{ + deWaitForNotBusy(); + + SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, + FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS, + dst_base)); + + SMTC_write2Dreg(DE_PITCH, + FIELD_VALUE(0, DE_PITCH, DESTINATION, dst_pitch) | + FIELD_VALUE(0, DE_PITCH, SOURCE, dst_pitch)); + + SMTC_write2Dreg(DE_WINDOW_WIDTH, + FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, + dst_pitch) | FIELD_VALUE(0, DE_WINDOW_WIDTH, + SOURCE, + dst_pitch)); + + SMTC_write2Dreg(DE_FOREGROUND, + FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor)); + + SMTC_write2Dreg(DE_DESTINATION, + FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) | + FIELD_VALUE(0, DE_DESTINATION, X, nX) | + FIELD_VALUE(0, DE_DESTINATION, Y, nY)); + + SMTC_write2Dreg(DE_DIMENSION, + FIELD_VALUE(0, DE_DIMENSION, X, 1) | + FIELD_VALUE(0, DE_DIMENSION, Y_ET, dst_height)); + + SMTC_write2Dreg(DE_CONTROL, + FIELD_SET(0, DE_CONTROL, STATUS, START) | + FIELD_SET(0, DE_CONTROL, DIRECTION, LEFT_TO_RIGHT) | + FIELD_SET(0, DE_CONTROL, MAJOR, Y) | + FIELD_SET(0, DE_CONTROL, STEP_X, NEGATIVE) | + FIELD_SET(0, DE_CONTROL, STEP_Y, POSITIVE) | + FIELD_SET(0, DE_CONTROL, LAST_PIXEL, OFF) | + FIELD_SET(0, DE_CONTROL, COMMAND, SHORT_STROKE) | + FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) | + FIELD_VALUE(0, DE_CONTROL, ROP, 0x0C)); + + smtc_de_busy = 1; +} + +void deHorizontalLine(unsigned long dst_base, + unsigned long dst_pitch, + unsigned long nX, + unsigned long nY, + unsigned long dst_width, unsigned long nColor) +{ + deWaitForNotBusy(); + + SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, + FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS, + dst_base)); + + SMTC_write2Dreg(DE_PITCH, + FIELD_VALUE(0, DE_PITCH, DESTINATION, dst_pitch) | + FIELD_VALUE(0, DE_PITCH, SOURCE, dst_pitch)); + + SMTC_write2Dreg(DE_WINDOW_WIDTH, + FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, + dst_pitch) | FIELD_VALUE(0, DE_WINDOW_WIDTH, + SOURCE, + dst_pitch)); + SMTC_write2Dreg(DE_FOREGROUND, + FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor)); + SMTC_write2Dreg(DE_DESTINATION, + FIELD_SET(0, DE_DESTINATION, WRAP, + DISABLE) | FIELD_VALUE(0, DE_DESTINATION, X, + nX) | FIELD_VALUE(0, + DE_DESTINATION, + Y, + nY)); + SMTC_write2Dreg(DE_DIMENSION, + FIELD_VALUE(0, DE_DIMENSION, X, + dst_width) | FIELD_VALUE(0, DE_DIMENSION, + Y_ET, 1)); + SMTC_write2Dreg(DE_CONTROL, + FIELD_SET(0, DE_CONTROL, STATUS, START) | FIELD_SET(0, + DE_CONTROL, + DIRECTION, + RIGHT_TO_LEFT) + | FIELD_SET(0, DE_CONTROL, MAJOR, X) | FIELD_SET(0, + DE_CONTROL, + STEP_X, + POSITIVE) + | FIELD_SET(0, DE_CONTROL, STEP_Y, + NEGATIVE) | FIELD_SET(0, DE_CONTROL, + LAST_PIXEL, + OFF) | FIELD_SET(0, + DE_CONTROL, + COMMAND, + SHORT_STROKE) + | FIELD_SET(0, DE_CONTROL, ROP_SELECT, + ROP2) | FIELD_VALUE(0, DE_CONTROL, ROP, + 0x0C)); + + smtc_de_busy = 1; +} + +void deLine(unsigned long dst_base, + unsigned long dst_pitch, + unsigned long nX1, + unsigned long nY1, + unsigned long nX2, unsigned long nY2, unsigned long nColor) +{ + unsigned long nCommand = + FIELD_SET(0, DE_CONTROL, STATUS, START) | + FIELD_SET(0, DE_CONTROL, DIRECTION, LEFT_TO_RIGHT) | + FIELD_SET(0, DE_CONTROL, MAJOR, X) | + FIELD_SET(0, DE_CONTROL, STEP_X, POSITIVE) | + FIELD_SET(0, DE_CONTROL, STEP_Y, POSITIVE) | + FIELD_SET(0, DE_CONTROL, LAST_PIXEL, OFF) | + FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) | + FIELD_VALUE(0, DE_CONTROL, ROP, 0x0C); + unsigned long DeltaX; + unsigned long DeltaY; + + /* Calculate delta X */ + if (nX1 <= nX2) + DeltaX = nX2 - nX1; + else { + DeltaX = nX1 - nX2; + nCommand = FIELD_SET(nCommand, DE_CONTROL, STEP_X, NEGATIVE); + } + + /* Calculate delta Y */ + if (nY1 <= nY2) + DeltaY = nY2 - nY1; + else { + DeltaY = nY1 - nY2; + nCommand = FIELD_SET(nCommand, DE_CONTROL, STEP_Y, NEGATIVE); + } + + /* Determine the major axis */ + if (DeltaX < DeltaY) + nCommand = FIELD_SET(nCommand, DE_CONTROL, MAJOR, Y); + + /* Vertical line? */ + if (nX1 == nX2) + deVerticalLine(dst_base, dst_pitch, nX1, nY1, DeltaY, nColor); + + /* Horizontal line? */ + else if (nY1 == nY2) + deHorizontalLine(dst_base, dst_pitch, nX1, nY1, \ + DeltaX, nColor); + + /* Diagonal line? */ + else if (DeltaX == DeltaY) { + deWaitForNotBusy(); + + SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, + FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, + ADDRESS, dst_base)); + + SMTC_write2Dreg(DE_PITCH, + FIELD_VALUE(0, DE_PITCH, DESTINATION, + dst_pitch) | FIELD_VALUE(0, + DE_PITCH, + SOURCE, + dst_pitch)); + + SMTC_write2Dreg(DE_WINDOW_WIDTH, + FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, + dst_pitch) | FIELD_VALUE(0, + DE_WINDOW_WIDTH, + SOURCE, + dst_pitch)); + + SMTC_write2Dreg(DE_FOREGROUND, + FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor)); + + SMTC_write2Dreg(DE_DESTINATION, + FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) | + FIELD_VALUE(0, DE_DESTINATION, X, 1) | + FIELD_VALUE(0, DE_DESTINATION, Y, nY1)); + + SMTC_write2Dreg(DE_DIMENSION, + FIELD_VALUE(0, DE_DIMENSION, X, 1) | + FIELD_VALUE(0, DE_DIMENSION, Y_ET, DeltaX)); + + SMTC_write2Dreg(DE_CONTROL, + FIELD_SET(nCommand, DE_CONTROL, COMMAND, + SHORT_STROKE)); + } + + /* Generic line */ + else { + unsigned int k1, k2, et, w; + if (DeltaX < DeltaY) { + k1 = 2 * DeltaX; + et = k1 - DeltaY; + k2 = et - DeltaY; + w = DeltaY + 1; + } else { + k1 = 2 * DeltaY; + et = k1 - DeltaX; + k2 = et - DeltaX; + w = DeltaX + 1; + } + + deWaitForNotBusy(); + + SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, + FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, + ADDRESS, dst_base)); + + SMTC_write2Dreg(DE_PITCH, + FIELD_VALUE(0, DE_PITCH, DESTINATION, + dst_pitch) | FIELD_VALUE(0, + DE_PITCH, + SOURCE, + dst_pitch)); + + SMTC_write2Dreg(DE_WINDOW_WIDTH, + FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, + dst_pitch) | FIELD_VALUE(0, + DE_WINDOW_WIDTH, + SOURCE, + dst_pitch)); + + SMTC_write2Dreg(DE_FOREGROUND, + FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor)); + + SMTC_write2Dreg(DE_SOURCE, + FIELD_SET(0, DE_SOURCE, WRAP, DISABLE) | + FIELD_VALUE(0, DE_SOURCE, X_K1, k1) | + FIELD_VALUE(0, DE_SOURCE, Y_K2, k2)); + + SMTC_write2Dreg(DE_DESTINATION, + FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) | + FIELD_VALUE(0, DE_DESTINATION, X, nX1) | + FIELD_VALUE(0, DE_DESTINATION, Y, nY1)); + + SMTC_write2Dreg(DE_DIMENSION, + FIELD_VALUE(0, DE_DIMENSION, X, w) | + FIELD_VALUE(0, DE_DIMENSION, Y_ET, et)); + + SMTC_write2Dreg(DE_CONTROL, + FIELD_SET(nCommand, DE_CONTROL, COMMAND, + LINE_DRAW)); + } + + smtc_de_busy = 1; +} + +void deFillRect(unsigned long dst_base, + unsigned long dst_pitch, + unsigned long dst_X, + unsigned long dst_Y, + unsigned long dst_width, + unsigned long dst_height, unsigned long nColor) +{ + deWaitForNotBusy(); + + SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, + FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS, + dst_base)); + + if (dst_pitch) { + SMTC_write2Dreg(DE_PITCH, + FIELD_VALUE(0, DE_PITCH, DESTINATION, + dst_pitch) | FIELD_VALUE(0, + DE_PITCH, + SOURCE, + dst_pitch)); + + SMTC_write2Dreg(DE_WINDOW_WIDTH, + FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, + dst_pitch) | FIELD_VALUE(0, + DE_WINDOW_WIDTH, + SOURCE, + dst_pitch)); + } + + SMTC_write2Dreg(DE_FOREGROUND, + FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor)); + + SMTC_write2Dreg(DE_DESTINATION, + FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) | + FIELD_VALUE(0, DE_DESTINATION, X, dst_X) | + FIELD_VALUE(0, DE_DESTINATION, Y, dst_Y)); + + SMTC_write2Dreg(DE_DIMENSION, + FIELD_VALUE(0, DE_DIMENSION, X, dst_width) | + FIELD_VALUE(0, DE_DIMENSION, Y_ET, dst_height)); + + SMTC_write2Dreg(DE_CONTROL, + FIELD_SET(0, DE_CONTROL, STATUS, START) | + FIELD_SET(0, DE_CONTROL, DIRECTION, LEFT_TO_RIGHT) | + FIELD_SET(0, DE_CONTROL, LAST_PIXEL, OFF) | + FIELD_SET(0, DE_CONTROL, COMMAND, RECTANGLE_FILL) | + FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) | + FIELD_VALUE(0, DE_CONTROL, ROP, 0x0C)); + + smtc_de_busy = 1; +} + +/********************************************************************** + * + * deRotatePattern + * + * Purpose + * Rotate the given pattern if necessary + * + * Parameters + * [in] + * pPattern - Pointer to DE_SURFACE structure containing + * pattern attributes + * patternX - X position (0-7) of pattern origin + * patternY - Y position (0-7) of pattern origin + * + * [out] + * pattern_dstaddr - Pointer to pre-allocated buffer containing + * rotated pattern + * + **********************************************************************/ +void deRotatePattern(unsigned char *pattern_dstaddr, + unsigned long pattern_src_addr, + unsigned long pattern_BPP, + unsigned long pattern_stride, int patternX, int patternY) +{ + unsigned int i; + unsigned long pattern[PATTERN_WIDTH * PATTERN_HEIGHT]; + unsigned int x, y; + unsigned char *pjPatByte; + + if (pattern_dstaddr != NULL) { + deWaitForNotBusy(); + + if (patternX || patternY) { + /* Rotate pattern */ + pjPatByte = (unsigned char *)pattern; + + switch (pattern_BPP) { + case 8: + { + for (y = 0; y < 8; y++) { + unsigned char *pjBuffer = + pattern_dstaddr + + ((patternY + y) & 7) * 8; + for (x = 0; x < 8; x++) { + pjBuffer[(patternX + + x) & 7] = + pjPatByte[x]; + } + pjPatByte += pattern_stride; + } + break; + } + + case 16: + { + for (y = 0; y < 8; y++) { + unsigned short *pjBuffer = + (unsigned short *) + pattern_dstaddr + + ((patternY + y) & 7) * 8; + for (x = 0; x < 8; x++) { + pjBuffer[(patternX + + x) & 7] = + ((unsigned short *) + pjPatByte)[x]; + } + pjPatByte += pattern_stride; + } + break; + } + + case 32: + { + for (y = 0; y < 8; y++) { + unsigned long *pjBuffer = + (unsigned long *) + pattern_dstaddr + + ((patternY + y) & 7) * 8; + for (x = 0; x < 8; x++) { + pjBuffer[(patternX + + x) & 7] = + ((unsigned long *) + pjPatByte)[x]; + } + pjPatByte += pattern_stride; + } + break; + } + } + } else { + /*Don't rotate,just copy pattern into pattern_dstaddr*/ + for (i = 0; i < (pattern_BPP * 2); i++) { + ((unsigned long *)pattern_dstaddr)[i] = + pattern[i]; + } + } + + } +} + +/********************************************************************** + * + * deCopy + * + * Purpose + * Copy a rectangular area of the source surface to a destination surface + * + * Remarks + * Source bitmap must have the same color depth (BPP) as the destination + * bitmap. + * +**********************************************************************/ +void deCopy(unsigned long dst_base, + unsigned long dst_pitch, + unsigned long dst_BPP, + unsigned long dst_X, + unsigned long dst_Y, + unsigned long dst_width, + unsigned long dst_height, + unsigned long src_base, + unsigned long src_pitch, + unsigned long src_X, + unsigned long src_Y, pTransparent pTransp, unsigned char nROP2) +{ + unsigned long nDirection = 0; + unsigned long nTransparent = 0; + /* Direction of ROP2 operation: + * 1 = Left to Right, + * (-1) = Right to Left + */ + unsigned long opSign = 1; + /* xWidth is in pixels */ + unsigned long xWidth = 192 / (dst_BPP / 8); + unsigned long de_ctrl = 0; + + deWaitForNotBusy(); + + SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, + FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS, + dst_base)); + + SMTC_write2Dreg(DE_WINDOW_SOURCE_BASE, + FIELD_VALUE(0, DE_WINDOW_SOURCE_BASE, ADDRESS, + src_base)); + + if (dst_pitch && src_pitch) { + SMTC_write2Dreg(DE_PITCH, + FIELD_VALUE(0, DE_PITCH, DESTINATION, + dst_pitch) | FIELD_VALUE(0, + DE_PITCH, + SOURCE, + src_pitch)); + + SMTC_write2Dreg(DE_WINDOW_WIDTH, + FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, + dst_pitch) | FIELD_VALUE(0, + DE_WINDOW_WIDTH, + SOURCE, + src_pitch)); + } + + /* Set transparent bits if necessary */ + if (pTransp != NULL) { + nTransparent = + pTransp->match | pTransp->select | pTransp->control; + + /* Set color compare register */ + SMTC_write2Dreg(DE_COLOR_COMPARE, + FIELD_VALUE(0, DE_COLOR_COMPARE, COLOR, + pTransp->color)); + } + + /* Determine direction of operation */ + if (src_Y < dst_Y) { + /* +----------+ + |S | + | +----------+ + | | | | + | | | | + +---|------+ | + | D | + +----------+ */ + + nDirection = BOTTOM_TO_TOP; + } else if (src_Y > dst_Y) { + /* +----------+ + |D | + | +----------+ + | | | | + | | | | + +---|------+ | + | S | + +----------+ */ + + nDirection = TOP_TO_BOTTOM; + } else { + /* src_Y == dst_Y */ + + if (src_X <= dst_X) { + /* +------+---+------+ + |S | | D| + | | | | + | | | | + | | | | + +------+---+------+ */ + + nDirection = RIGHT_TO_LEFT; + } else { + /* src_X > dst_X */ + + /* +------+---+------+ + |D | | S| + | | | | + | | | | + | | | | + +------+---+------+ */ + + nDirection = LEFT_TO_RIGHT; + } + } + + if ((nDirection == BOTTOM_TO_TOP) || (nDirection == RIGHT_TO_LEFT)) { + src_X += dst_width - 1; + src_Y += dst_height - 1; + dst_X += dst_width - 1; + dst_Y += dst_height - 1; + opSign = (-1); + } + + if (dst_BPP >= 24) { + src_X *= 3; + src_Y *= 3; + dst_X *= 3; + dst_Y *= 3; + dst_width *= 3; + if ((nDirection == BOTTOM_TO_TOP) + || (nDirection == RIGHT_TO_LEFT)) { + src_X += 2; + dst_X += 2; + } + } + + /* Workaround for 192 byte hw bug */ + if ((nROP2 != 0x0C) && ((dst_width * (dst_BPP / 8)) >= 192)) { + /* + * Perform the ROP2 operation in chunks of (xWidth * + * dst_height) + */ + while (1) { + deWaitForNotBusy(); + + SMTC_write2Dreg(DE_SOURCE, + FIELD_SET(0, DE_SOURCE, WRAP, DISABLE) | + FIELD_VALUE(0, DE_SOURCE, X_K1, src_X) | + FIELD_VALUE(0, DE_SOURCE, Y_K2, src_Y)); + + SMTC_write2Dreg(DE_DESTINATION, + FIELD_SET(0, DE_DESTINATION, WRAP, + DISABLE) | FIELD_VALUE(0, + DE_DESTINATION, + X, + dst_X) + | FIELD_VALUE(0, DE_DESTINATION, Y, + dst_Y)); + + SMTC_write2Dreg(DE_DIMENSION, + FIELD_VALUE(0, DE_DIMENSION, X, + xWidth) | FIELD_VALUE(0, + DE_DIMENSION, + Y_ET, + dst_height)); + + de_ctrl = + FIELD_VALUE(0, DE_CONTROL, ROP, + nROP2) | nTransparent | FIELD_SET(0, + DE_CONTROL, + ROP_SELECT, + ROP2) + | FIELD_SET(0, DE_CONTROL, COMMAND, + BITBLT) | ((nDirection == + 1) ? FIELD_SET(0, + DE_CONTROL, + DIRECTION, + RIGHT_TO_LEFT) + : FIELD_SET(0, DE_CONTROL, + DIRECTION, + LEFT_TO_RIGHT)) | + FIELD_SET(0, DE_CONTROL, STATUS, START); + + SMTC_write2Dreg(DE_CONTROL, de_ctrl); + + src_X += (opSign * xWidth); + dst_X += (opSign * xWidth); + dst_width -= xWidth; + + if (dst_width <= 0) { + /* ROP2 operation is complete */ + break; + } + + if (xWidth > dst_width) + xWidth = dst_width; + } + } else { + deWaitForNotBusy(); + SMTC_write2Dreg(DE_SOURCE, + FIELD_SET(0, DE_SOURCE, WRAP, DISABLE) | + FIELD_VALUE(0, DE_SOURCE, X_K1, src_X) | + FIELD_VALUE(0, DE_SOURCE, Y_K2, src_Y)); + + SMTC_write2Dreg(DE_DESTINATION, + FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) | + FIELD_VALUE(0, DE_DESTINATION, X, dst_X) | + FIELD_VALUE(0, DE_DESTINATION, Y, dst_Y)); + + SMTC_write2Dreg(DE_DIMENSION, + FIELD_VALUE(0, DE_DIMENSION, X, dst_width) | + FIELD_VALUE(0, DE_DIMENSION, Y_ET, dst_height)); + + de_ctrl = FIELD_VALUE(0, DE_CONTROL, ROP, nROP2) | + nTransparent | + FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) | + FIELD_SET(0, DE_CONTROL, COMMAND, BITBLT) | + ((nDirection == 1) ? FIELD_SET(0, DE_CONTROL, DIRECTION, + RIGHT_TO_LEFT) + : FIELD_SET(0, DE_CONTROL, DIRECTION, + LEFT_TO_RIGHT)) | FIELD_SET(0, DE_CONTROL, + STATUS, START); + SMTC_write2Dreg(DE_CONTROL, de_ctrl); + } + + smtc_de_busy = 1; +} + +/* + * This function sets the pixel format that will apply to the 2D Engine. + */ +void deSetPixelFormat(unsigned long bpp) +{ + unsigned long de_format; + + de_format = SMTC_read2Dreg(DE_STRETCH_FORMAT); + + switch (bpp) { + case 8: + de_format = + FIELD_SET(de_format, DE_STRETCH_FORMAT, PIXEL_FORMAT, 8); + break; + default: + case 16: + de_format = + FIELD_SET(de_format, DE_STRETCH_FORMAT, PIXEL_FORMAT, 16); + break; + case 32: + de_format = + FIELD_SET(de_format, DE_STRETCH_FORMAT, PIXEL_FORMAT, 32); + break; + } + + SMTC_write2Dreg(DE_STRETCH_FORMAT, de_format); +} + +/* + * System memory to Video memory monochrome expansion. + * + * Source is monochrome image in system memory. This function expands the + * monochrome data to color image in video memory. + */ + +long deSystemMem2VideoMemMonoBlt(const char *pSrcbuf, + long srcDelta, + unsigned long startBit, + unsigned long dBase, + unsigned long dPitch, + unsigned long bpp, + unsigned long dx, unsigned long dy, + unsigned long width, unsigned long height, + unsigned long fColor, + unsigned long bColor, + unsigned long rop2) { + unsigned long bytePerPixel; + unsigned long ulBytesPerScan; + unsigned long ul4BytesPerScan; + unsigned long ulBytesRemain; + unsigned long de_ctrl = 0; + unsigned char ajRemain[4]; + long i, j; + + bytePerPixel = bpp / 8; + + /* Just make sure the start bit is within legal range */ + startBit &= 7; + + ulBytesPerScan = (width + startBit + 7) / 8; + ul4BytesPerScan = ulBytesPerScan & ~3; + ulBytesRemain = ulBytesPerScan & 3; + + if (smtc_de_busy) + deWaitForNotBusy(); + + /* + * 2D Source Base. Use 0 for HOST Blt. + */ + + SMTC_write2Dreg(DE_WINDOW_SOURCE_BASE, 0); + + /* + * 2D Destination Base. + * + * It is an address offset (128 bit aligned) from the beginning of + * frame buffer. + */ + + SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, dBase); + + if (dPitch) { + + /* + * Program pitch (distance between the 1st points of two + * adjacent lines). + * + * Note that input pitch is BYTE value, but the 2D Pitch + * register uses pixel values. Need Byte to pixel convertion. + */ + + SMTC_write2Dreg(DE_PITCH, + FIELD_VALUE(0, DE_PITCH, DESTINATION, + dPitch / + bytePerPixel) | FIELD_VALUE(0, + DE_PITCH, + SOURCE, + dPitch / + bytePerPixel)); + + /* Screen Window width in Pixels. + * + * 2D engine uses this value to calculate the linear address in + * frame buffer for a given point. + */ + + SMTC_write2Dreg(DE_WINDOW_WIDTH, + FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, + (dPitch / + bytePerPixel)) | FIELD_VALUE(0, + DE_WINDOW_WIDTH, + SOURCE, + (dPitch + / + bytePerPixel))); + } + /* Note: For 2D Source in Host Write, only X_K1 field is needed, and + * Y_K2 field is not used. For mono bitmap, use startBit for X_K1. + */ + + SMTC_write2Dreg(DE_SOURCE, + FIELD_SET(0, DE_SOURCE, WRAP, DISABLE) | + FIELD_VALUE(0, DE_SOURCE, X_K1, startBit) | + FIELD_VALUE(0, DE_SOURCE, Y_K2, 0)); + + SMTC_write2Dreg(DE_DESTINATION, + FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) | + FIELD_VALUE(0, DE_DESTINATION, X, dx) | + FIELD_VALUE(0, DE_DESTINATION, Y, dy)); + + SMTC_write2Dreg(DE_DIMENSION, + FIELD_VALUE(0, DE_DIMENSION, X, width) | + FIELD_VALUE(0, DE_DIMENSION, Y_ET, height)); + + SMTC_write2Dreg(DE_FOREGROUND, fColor); + SMTC_write2Dreg(DE_BACKGROUND, bColor); + + if (bpp) + deSetPixelFormat(bpp); + /* Set the pixel format of the destination */ + + de_ctrl = FIELD_VALUE(0, DE_CONTROL, ROP, rop2) | + FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) | + FIELD_SET(0, DE_CONTROL, COMMAND, HOST_WRITE) | + FIELD_SET(0, DE_CONTROL, HOST, MONO) | + FIELD_SET(0, DE_CONTROL, STATUS, START); + + SMTC_write2Dreg(DE_CONTROL, de_ctrl | deGetTransparency()); + + /* Write MONO data (line by line) to 2D Engine data port */ + for (i = 0; i < height; i++) { + /* For each line, send the data in chunks of 4 bytes */ + for (j = 0; j < (ul4BytesPerScan / 4); j++) + SMTC_write2Ddataport(0, + *(unsigned long *)(pSrcbuf + + (j * 4))); + + if (ulBytesRemain) { + memcpy(ajRemain, pSrcbuf + ul4BytesPerScan, + ulBytesRemain); + SMTC_write2Ddataport(0, *(unsigned long *)ajRemain); + } + + pSrcbuf += srcDelta; + } + smtc_de_busy = 1; + + return 0; +} + +/* + * This function gets the transparency status from DE_CONTROL register. + * It returns a double word with the transparent fields properly set, + * while other fields are 0. + */ +unsigned long deGetTransparency(void) +{ + unsigned long de_ctrl; + + de_ctrl = SMTC_read2Dreg(DE_CONTROL); + + de_ctrl &= + FIELD_MASK(DE_CONTROL_TRANSPARENCY_MATCH) | + FIELD_MASK(DE_CONTROL_TRANSPARENCY_SELECT) | + FIELD_MASK(DE_CONTROL_TRANSPARENCY); + + return de_ctrl; +} diff --git a/drivers/staging/sm7xx/smtc2d.h b/drivers/staging/sm7xx/smtc2d.h new file mode 100644 index 0000000..38d0c33 --- /dev/null +++ b/drivers/staging/sm7xx/smtc2d.h @@ -0,0 +1,530 @@ +/* + * Silicon Motion SM712 2D drawing engine functions. + * + * Copyright (C) 2006 Silicon Motion Technology Corp. + * Author: Ge Wang, gewang@siliconmotion.com + * + * Copyright (C) 2009 Lemote, Inc. + * Author: Wu Zhangjin, wuzj@lemote.com + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. + */ + +#ifndef NULL +#define NULL 0 +#endif + +/* Internal macros */ + +#define _F_START(f) (0 ? f) +#define _F_END(f) (1 ? f) +#define _F_SIZE(f) (1 + _F_END(f) - _F_START(f)) +#define _F_MASK(f) (((1ULL << _F_SIZE(f)) - 1) << _F_START(f)) +#define _F_NORMALIZE(v, f) (((v) & _F_MASK(f)) >> _F_START(f)) +#define _F_DENORMALIZE(v, f) (((v) << _F_START(f)) & _F_MASK(f)) + +/* Global macros */ + +#define FIELD_GET(x, reg, field) \ +( \ + _F_NORMALIZE((x), reg ## _ ## field) \ +) + +#define FIELD_SET(x, reg, field, value) \ +( \ + (x & ~_F_MASK(reg ## _ ## field)) \ + | _F_DENORMALIZE(reg ## _ ## field ## _ ## value, reg ## _ ## field) \ +) + +#define FIELD_VALUE(x, reg, field, value) \ +( \ + (x & ~_F_MASK(reg ## _ ## field)) \ + | _F_DENORMALIZE(value, reg ## _ ## field) \ +) + +#define FIELD_CLEAR(reg, field) \ +( \ + ~_F_MASK(reg ## _ ## field) \ +) + +/* Field Macros */ + +#define FIELD_START(field) (0 ? field) +#define FIELD_END(field) (1 ? field) +#define FIELD_SIZE(field) \ + (1 + FIELD_END(field) - FIELD_START(field)) + +#define FIELD_MASK(field) \ + (((1 << (FIELD_SIZE(field)-1)) \ + | ((1 << (FIELD_SIZE(field)-1)) - 1)) \ + << FIELD_START(field)) + +#define FIELD_NORMALIZE(reg, field) \ + (((reg) & FIELD_MASK(field)) >> FIELD_START(field)) + +#define FIELD_DENORMALIZE(field, value) \ + (((value) << FIELD_START(field)) & FIELD_MASK(field)) + +#define FIELD_INIT(reg, field, value) \ + FIELD_DENORMALIZE(reg ## _ ## field, \ + reg ## _ ## field ## _ ## value) + +#define FIELD_INIT_VAL(reg, field, value) \ + (FIELD_DENORMALIZE(reg ## _ ## field, value)) + +#define FIELD_VAL_SET(x, r, f, v) ({ \ + x = (x & ~FIELD_MASK(r ## _ ## f)) \ + | FIELD_DENORMALIZE(r ## _ ## f, r ## _ ## f ## _ ## v) \ +}) + +#define RGB(r, g, b) ((unsigned long)(((r) << 16) | ((g) << 8) | (b))) + +/* Transparent info definition */ +typedef struct { + unsigned long match; /* Matching pixel is OPAQUE/TRANSPARENT */ + unsigned long select; /* Transparency controlled by SRC/DST */ + unsigned long control; /* ENABLE/DISABLE transparency */ + unsigned long color; /* Transparent color */ +} Transparent, *pTransparent; + +#define PIXEL_DEPTH_1_BP 0 /* 1 bit per pixel */ +#define PIXEL_DEPTH_8_BPP 1 /* 8 bits per pixel */ +#define PIXEL_DEPTH_16_BPP 2 /* 16 bits per pixel */ +#define PIXEL_DEPTH_32_BPP 3 /* 32 bits per pixel */ +#define PIXEL_DEPTH_YUV422 8 /* 16 bits per pixel YUV422 */ +#define PIXEL_DEPTH_YUV420 9 /* 16 bits per pixel YUV420 */ + +#define PATTERN_WIDTH 8 +#define PATTERN_HEIGHT 8 + +#define TOP_TO_BOTTOM 0 +#define BOTTOM_TO_TOP 1 +#define RIGHT_TO_LEFT BOTTOM_TO_TOP +#define LEFT_TO_RIGHT TOP_TO_BOTTOM + +/* Constants used in Transparent structure */ +#define MATCH_OPAQUE 0x00000000 +#define MATCH_TRANSPARENT 0x00000400 +#define SOURCE 0x00000000 +#define DESTINATION 0x00000200 + +/* 2D registers. */ + +#define DE_SOURCE 0x000000 +#define DE_SOURCE_WRAP 31 : 31 +#define DE_SOURCE_WRAP_DISABLE 0 +#define DE_SOURCE_WRAP_ENABLE 1 +#define DE_SOURCE_X_K1 29 : 16 +#define DE_SOURCE_Y_K2 15 : 0 + +#define DE_DESTINATION 0x000004 +#define DE_DESTINATION_WRAP 31 : 31 +#define DE_DESTINATION_WRAP_DISABLE 0 +#define DE_DESTINATION_WRAP_ENABLE 1 +#define DE_DESTINATION_X 28 : 16 +#define DE_DESTINATION_Y 15 : 0 + +#define DE_DIMENSION 0x000008 +#define DE_DIMENSION_X 28 : 16 +#define DE_DIMENSION_Y_ET 15 : 0 + +#define DE_CONTROL 0x00000C +#define DE_CONTROL_STATUS 31 : 31 +#define DE_CONTROL_STATUS_STOP 0 +#define DE_CONTROL_STATUS_START 1 +#define DE_CONTROL_PATTERN 30 : 30 +#define DE_CONTROL_PATTERN_MONO 0 +#define DE_CONTROL_PATTERN_COLOR 1 +#define DE_CONTROL_UPDATE_DESTINATION_X 29 : 29 +#define DE_CONTROL_UPDATE_DESTINATION_X_DISABLE 0 +#define DE_CONTROL_UPDATE_DESTINATION_X_ENABLE 1 +#define DE_CONTROL_QUICK_START 28 : 28 +#define DE_CONTROL_QUICK_START_DISABLE 0 +#define DE_CONTROL_QUICK_START_ENABLE 1 +#define DE_CONTROL_DIRECTION 27 : 27 +#define DE_CONTROL_DIRECTION_LEFT_TO_RIGHT 0 +#define DE_CONTROL_DIRECTION_RIGHT_TO_LEFT 1 +#define DE_CONTROL_MAJOR 26 : 26 +#define DE_CONTROL_MAJOR_X 0 +#define DE_CONTROL_MAJOR_Y 1 +#define DE_CONTROL_STEP_X 25 : 25 +#define DE_CONTROL_STEP_X_POSITIVE 1 +#define DE_CONTROL_STEP_X_NEGATIVE 0 +#define DE_CONTROL_STEP_Y 24 : 24 +#define DE_CONTROL_STEP_Y_POSITIVE 1 +#define DE_CONTROL_STEP_Y_NEGATIVE 0 +#define DE_CONTROL_STRETCH 23 : 23 +#define DE_CONTROL_STRETCH_DISABLE 0 +#define DE_CONTROL_STRETCH_ENABLE 1 +#define DE_CONTROL_HOST 22 : 22 +#define DE_CONTROL_HOST_COLOR 0 +#define DE_CONTROL_HOST_MONO 1 +#define DE_CONTROL_LAST_PIXEL 21 : 21 +#define DE_CONTROL_LAST_PIXEL_OFF 0 +#define DE_CONTROL_LAST_PIXEL_ON 1 +#define DE_CONTROL_COMMAND 20 : 16 +#define DE_CONTROL_COMMAND_BITBLT 0 +#define DE_CONTROL_COMMAND_RECTANGLE_FILL 1 +#define DE_CONTROL_COMMAND_DE_TILE 2 +#define DE_CONTROL_COMMAND_TRAPEZOID_FILL 3 +#define DE_CONTROL_COMMAND_ALPHA_BLEND 4 +#define DE_CONTROL_COMMAND_RLE_STRIP 5 +#define DE_CONTROL_COMMAND_SHORT_STROKE 6 +#define DE_CONTROL_COMMAND_LINE_DRAW 7 +#define DE_CONTROL_COMMAND_HOST_WRITE 8 +#define DE_CONTROL_COMMAND_HOST_READ 9 +#define DE_CONTROL_COMMAND_HOST_WRITE_BOTTOM_UP 10 +#define DE_CONTROL_COMMAND_ROTATE 11 +#define DE_CONTROL_COMMAND_FONT 12 +#define DE_CONTROL_COMMAND_TEXTURE_LOAD 15 +#define DE_CONTROL_ROP_SELECT 15 : 15 +#define DE_CONTROL_ROP_SELECT_ROP3 0 +#define DE_CONTROL_ROP_SELECT_ROP2 1 +#define DE_CONTROL_ROP2_SOURCE 14 : 14 +#define DE_CONTROL_ROP2_SOURCE_BITMAP 0 +#define DE_CONTROL_ROP2_SOURCE_PATTERN 1 +#define DE_CONTROL_MONO_DATA 13 : 12 +#define DE_CONTROL_MONO_DATA_NOT_PACKED 0 +#define DE_CONTROL_MONO_DATA_8_PACKED 1 +#define DE_CONTROL_MONO_DATA_16_PACKED 2 +#define DE_CONTROL_MONO_DATA_32_PACKED 3 +#define DE_CONTROL_REPEAT_ROTATE 11 : 11 +#define DE_CONTROL_REPEAT_ROTATE_DISABLE 0 +#define DE_CONTROL_REPEAT_ROTATE_ENABLE 1 +#define DE_CONTROL_TRANSPARENCY_MATCH 10 : 10 +#define DE_CONTROL_TRANSPARENCY_MATCH_OPAQUE 0 +#define DE_CONTROL_TRANSPARENCY_MATCH_TRANSPARENT 1 +#define DE_CONTROL_TRANSPARENCY_SELECT 9 : 9 +#define DE_CONTROL_TRANSPARENCY_SELECT_SOURCE 0 +#define DE_CONTROL_TRANSPARENCY_SELECT_DESTINATION 1 +#define DE_CONTROL_TRANSPARENCY 8 : 8 +#define DE_CONTROL_TRANSPARENCY_DISABLE 0 +#define DE_CONTROL_TRANSPARENCY_ENABLE 1 +#define DE_CONTROL_ROP 7 : 0 + +/* Pseudo fields. */ + +#define DE_CONTROL_SHORT_STROKE_DIR 27 : 24 +#define DE_CONTROL_SHORT_STROKE_DIR_225 0 +#define DE_CONTROL_SHORT_STROKE_DIR_135 1 +#define DE_CONTROL_SHORT_STROKE_DIR_315 2 +#define DE_CONTROL_SHORT_STROKE_DIR_45 3 +#define DE_CONTROL_SHORT_STROKE_DIR_270 4 +#define DE_CONTROL_SHORT_STROKE_DIR_90 5 +#define DE_CONTROL_SHORT_STROKE_DIR_180 8 +#define DE_CONTROL_SHORT_STROKE_DIR_0 10 +#define DE_CONTROL_ROTATION 25 : 24 +#define DE_CONTROL_ROTATION_0 0 +#define DE_CONTROL_ROTATION_270 1 +#define DE_CONTROL_ROTATION_90 2 +#define DE_CONTROL_ROTATION_180 3 + +#define DE_PITCH 0x000010 +#define DE_PITCH_DESTINATION 28 : 16 +#define DE_PITCH_SOURCE 12 : 0 + +#define DE_FOREGROUND 0x000014 +#define DE_FOREGROUND_COLOR 31 : 0 + +#define DE_BACKGROUND 0x000018 +#define DE_BACKGROUND_COLOR 31 : 0 + +#define DE_STRETCH_FORMAT 0x00001C +#define DE_STRETCH_FORMAT_PATTERN_XY 30 : 30 +#define DE_STRETCH_FORMAT_PATTERN_XY_NORMAL 0 +#define DE_STRETCH_FORMAT_PATTERN_XY_OVERWRITE 1 +#define DE_STRETCH_FORMAT_PATTERN_Y 29 : 27 +#define DE_STRETCH_FORMAT_PATTERN_X 25 : 23 +#define DE_STRETCH_FORMAT_PIXEL_FORMAT 21 : 20 +#define DE_STRETCH_FORMAT_PIXEL_FORMAT_8 0 +#define DE_STRETCH_FORMAT_PIXEL_FORMAT_16 1 +#define DE_STRETCH_FORMAT_PIXEL_FORMAT_24 3 +#define DE_STRETCH_FORMAT_PIXEL_FORMAT_32 2 +#define DE_STRETCH_FORMAT_ADDRESSING 19 : 16 +#define DE_STRETCH_FORMAT_ADDRESSING_XY 0 +#define DE_STRETCH_FORMAT_ADDRESSING_LINEAR 15 +#define DE_STRETCH_FORMAT_SOURCE_HEIGHT 11 : 0 + +#define DE_COLOR_COMPARE 0x000020 +#define DE_COLOR_COMPARE_COLOR 23 : 0 + +#define DE_COLOR_COMPARE_MASK 0x000024 +#define DE_COLOR_COMPARE_MASK_MASKS 23 : 0 + +#define DE_MASKS 0x000028 +#define DE_MASKS_BYTE_MASK 31 : 16 +#define DE_MASKS_BIT_MASK 15 : 0 + +#define DE_CLIP_TL 0x00002C +#define DE_CLIP_TL_TOP 31 : 16 +#define DE_CLIP_TL_STATUS 13 : 13 +#define DE_CLIP_TL_STATUS_DISABLE 0 +#define DE_CLIP_TL_STATUS_ENABLE 1 +#define DE_CLIP_TL_INHIBIT 12 : 12 +#define DE_CLIP_TL_INHIBIT_OUTSIDE 0 +#define DE_CLIP_TL_INHIBIT_INSIDE 1 +#define DE_CLIP_TL_LEFT 11 : 0 + +#define DE_CLIP_BR 0x000030 +#define DE_CLIP_BR_BOTTOM 31 : 16 +#define DE_CLIP_BR_RIGHT 12 : 0 + +#define DE_MONO_PATTERN_LOW 0x000034 +#define DE_MONO_PATTERN_LOW_PATTERN 31 : 0 + +#define DE_MONO_PATTERN_HIGH 0x000038 +#define DE_MONO_PATTERN_HIGH_PATTERN 31 : 0 + +#define DE_WINDOW_WIDTH 0x00003C +#define DE_WINDOW_WIDTH_DESTINATION 28 : 16 +#define DE_WINDOW_WIDTH_SOURCE 12 : 0 + +#define DE_WINDOW_SOURCE_BASE 0x000040 +#define DE_WINDOW_SOURCE_BASE_EXT 27 : 27 +#define DE_WINDOW_SOURCE_BASE_EXT_LOCAL 0 +#define DE_WINDOW_SOURCE_BASE_EXT_EXTERNAL 1 +#define DE_WINDOW_SOURCE_BASE_CS 26 : 26 +#define DE_WINDOW_SOURCE_BASE_CS_0 0 +#define DE_WINDOW_SOURCE_BASE_CS_1 1 +#define DE_WINDOW_SOURCE_BASE_ADDRESS 25 : 0 + +#define DE_WINDOW_DESTINATION_BASE 0x000044 +#define DE_WINDOW_DESTINATION_BASE_EXT 27 : 27 +#define DE_WINDOW_DESTINATION_BASE_EXT_LOCAL 0 +#define DE_WINDOW_DESTINATION_BASE_EXT_EXTERNAL 1 +#define DE_WINDOW_DESTINATION_BASE_CS 26 : 26 +#define DE_WINDOW_DESTINATION_BASE_CS_0 0 +#define DE_WINDOW_DESTINATION_BASE_CS_1 1 +#define DE_WINDOW_DESTINATION_BASE_ADDRESS 25 : 0 + +#define DE_ALPHA 0x000048 +#define DE_ALPHA_VALUE 7 : 0 + +#define DE_WRAP 0x00004C +#define DE_WRAP_X 31 : 16 +#define DE_WRAP_Y 15 : 0 + +#define DE_STATUS 0x000050 +#define DE_STATUS_CSC 1 : 1 +#define DE_STATUS_CSC_CLEAR 0 +#define DE_STATUS_CSC_NOT_ACTIVE 0 +#define DE_STATUS_CSC_ACTIVE 1 +#define DE_STATUS_2D 0 : 0 +#define DE_STATUS_2D_CLEAR 0 +#define DE_STATUS_2D_NOT_ACTIVE 0 +#define DE_STATUS_2D_ACTIVE 1 + +/* Color Space Conversion registers. */ + +#define CSC_Y_SOURCE_BASE 0x0000C8 +#define CSC_Y_SOURCE_BASE_EXT 27 : 27 +#define CSC_Y_SOURCE_BASE_EXT_LOCAL 0 +#define CSC_Y_SOURCE_BASE_EXT_EXTERNAL 1 +#define CSC_Y_SOURCE_BASE_CS 26 : 26 +#define CSC_Y_SOURCE_BASE_CS_0 0 +#define CSC_Y_SOURCE_BASE_CS_1 1 +#define CSC_Y_SOURCE_BASE_ADDRESS 25 : 0 + +#define CSC_CONSTANTS 0x0000CC +#define CSC_CONSTANTS_Y 31 : 24 +#define CSC_CONSTANTS_R 23 : 16 +#define CSC_CONSTANTS_G 15 : 8 +#define CSC_CONSTANTS_B 7 : 0 + +#define CSC_Y_SOURCE_X 0x0000D0 +#define CSC_Y_SOURCE_X_INTEGER 26 : 16 +#define CSC_Y_SOURCE_X_FRACTION 15 : 3 + +#define CSC_Y_SOURCE_Y 0x0000D4 +#define CSC_Y_SOURCE_Y_INTEGER 27 : 16 +#define CSC_Y_SOURCE_Y_FRACTION 15 : 3 + +#define CSC_U_SOURCE_BASE 0x0000D8 +#define CSC_U_SOURCE_BASE_EXT 27 : 27 +#define CSC_U_SOURCE_BASE_EXT_LOCAL 0 +#define CSC_U_SOURCE_BASE_EXT_EXTERNAL 1 +#define CSC_U_SOURCE_BASE_CS 26 : 26 +#define CSC_U_SOURCE_BASE_CS_0 0 +#define CSC_U_SOURCE_BASE_CS_1 1 +#define CSC_U_SOURCE_BASE_ADDRESS 25 : 0 + +#define CSC_V_SOURCE_BASE 0x0000DC +#define CSC_V_SOURCE_BASE_EXT 27 : 27 +#define CSC_V_SOURCE_BASE_EXT_LOCAL 0 +#define CSC_V_SOURCE_BASE_EXT_EXTERNAL 1 +#define CSC_V_SOURCE_BASE_CS 26 : 26 +#define CSC_V_SOURCE_BASE_CS_0 0 +#define CSC_V_SOURCE_BASE_CS_1 1 +#define CSC_V_SOURCE_BASE_ADDRESS 25 : 0 + +#define CSC_SOURCE_DIMENSION 0x0000E0 +#define CSC_SOURCE_DIMENSION_X 31 : 16 +#define CSC_SOURCE_DIMENSION_Y 15 : 0 + +#define CSC_SOURCE_PITCH 0x0000E4 +#define CSC_SOURCE_PITCH_Y 31 : 16 +#define CSC_SOURCE_PITCH_UV 15 : 0 + +#define CSC_DESTINATION 0x0000E8 +#define CSC_DESTINATION_WRAP 31 : 31 +#define CSC_DESTINATION_WRAP_DISABLE 0 +#define CSC_DESTINATION_WRAP_ENABLE 1 +#define CSC_DESTINATION_X 27 : 16 +#define CSC_DESTINATION_Y 11 : 0 + +#define CSC_DESTINATION_DIMENSION 0x0000EC +#define CSC_DESTINATION_DIMENSION_X 31 : 16 +#define CSC_DESTINATION_DIMENSION_Y 15 : 0 + +#define CSC_DESTINATION_PITCH 0x0000F0 +#define CSC_DESTINATION_PITCH_X 31 : 16 +#define CSC_DESTINATION_PITCH_Y 15 : 0 + +#define CSC_SCALE_FACTOR 0x0000F4 +#define CSC_SCALE_FACTOR_HORIZONTAL 31 : 16 +#define CSC_SCALE_FACTOR_VERTICAL 15 : 0 + +#define CSC_DESTINATION_BASE 0x0000F8 +#define CSC_DESTINATION_BASE_EXT 27 : 27 +#define CSC_DESTINATION_BASE_EXT_LOCAL 0 +#define CSC_DESTINATION_BASE_EXT_EXTERNAL 1 +#define CSC_DESTINATION_BASE_CS 26 : 26 +#define CSC_DESTINATION_BASE_CS_0 0 +#define CSC_DESTINATION_BASE_CS_1 1 +#define CSC_DESTINATION_BASE_ADDRESS 25 : 0 + +#define CSC_CONTROL 0x0000FC +#define CSC_CONTROL_STATUS 31 : 31 +#define CSC_CONTROL_STATUS_STOP 0 +#define CSC_CONTROL_STATUS_START 1 +#define CSC_CONTROL_SOURCE_FORMAT 30 : 28 +#define CSC_CONTROL_SOURCE_FORMAT_YUV422 0 +#define CSC_CONTROL_SOURCE_FORMAT_YUV420I 1 +#define CSC_CONTROL_SOURCE_FORMAT_YUV420 2 +#define CSC_CONTROL_SOURCE_FORMAT_YVU9 3 +#define CSC_CONTROL_SOURCE_FORMAT_IYU1 4 +#define CSC_CONTROL_SOURCE_FORMAT_IYU2 5 +#define CSC_CONTROL_SOURCE_FORMAT_RGB565 6 +#define CSC_CONTROL_SOURCE_FORMAT_RGB8888 7 +#define CSC_CONTROL_DESTINATION_FORMAT 27 : 26 +#define CSC_CONTROL_DESTINATION_FORMAT_RGB565 0 +#define CSC_CONTROL_DESTINATION_FORMAT_RGB8888 1 +#define CSC_CONTROL_HORIZONTAL_FILTER 25 : 25 +#define CSC_CONTROL_HORIZONTAL_FILTER_DISABLE 0 +#define CSC_CONTROL_HORIZONTAL_FILTER_ENABLE 1 +#define CSC_CONTROL_VERTICAL_FILTER 24 : 24 +#define CSC_CONTROL_VERTICAL_FILTER_DISABLE 0 +#define CSC_CONTROL_VERTICAL_FILTER_ENABLE 1 +#define CSC_CONTROL_BYTE_ORDER 23 : 23 +#define CSC_CONTROL_BYTE_ORDER_YUYV 0 +#define CSC_CONTROL_BYTE_ORDER_UYVY 1 + +#define DE_DATA_PORT_501 0x110000 +#define DE_DATA_PORT_712 0x400000 +#define DE_DATA_PORT_722 0x6000 + +/* point to virtual Memory Map IO starting address */ +extern char *smtc_RegBaseAddress; +/* point to virtual video memory starting address */ +extern char *smtc_VRAMBaseAddress; +extern unsigned char smtc_de_busy; + +extern unsigned long memRead32(unsigned long nOffset); +extern void memWrite32(unsigned long nOffset, unsigned long nData); +extern unsigned long SMTC_read2Dreg(unsigned long nOffset); + +/* 2D functions */ +extern void deInit(unsigned int nModeWidth, unsigned int nModeHeight, + unsigned int bpp); + +extern void deWaitForNotBusy(void); + +extern void deVerticalLine(unsigned long dst_base, + unsigned long dst_pitch, + unsigned long nX, + unsigned long nY, + unsigned long dst_height, + unsigned long nColor); + +extern void deHorizontalLine(unsigned long dst_base, + unsigned long dst_pitch, + unsigned long nX, + unsigned long nY, + unsigned long dst_width, + unsigned long nColor); + +extern void deLine(unsigned long dst_base, + unsigned long dst_pitch, + unsigned long nX1, + unsigned long nY1, + unsigned long nX2, + unsigned long nY2, + unsigned long nColor); + +extern void deFillRect(unsigned long dst_base, + unsigned long dst_pitch, + unsigned long dst_X, + unsigned long dst_Y, + unsigned long dst_width, + unsigned long dst_height, + unsigned long nColor); + +extern void deRotatePattern(unsigned char *pattern_dstaddr, + unsigned long pattern_src_addr, + unsigned long pattern_BPP, + unsigned long pattern_stride, + int patternX, + int patternY); + +extern void deCopy(unsigned long dst_base, + unsigned long dst_pitch, + unsigned long dst_BPP, + unsigned long dst_X, + unsigned long dst_Y, + unsigned long dst_width, + unsigned long dst_height, + unsigned long src_base, + unsigned long src_pitch, + unsigned long src_X, + unsigned long src_Y, + pTransparent pTransp, + unsigned char nROP2); + +/* + * System memory to Video memory monochrome expansion. + * + * Source is monochrome image in system memory. This function expands the + * monochrome data to color image in video memory. + * + * @pSrcbuf: pointer to start of source buffer in system memory + * @srcDelta: Pitch value (in bytes) of the source buffer, +ive means top + * down and -ive mean button up + * @startBit: Mono data can start at any bit in a byte, this value should + * be 0 to 7 + * @dBase: Address of destination : offset in frame buffer + * @dPitch: Pitch value of destination surface in BYTE + * @bpp: Color depth of destination surface + * @dx, dy: Starting coordinate of destination surface + * @width, height: width and height of rectange in pixel value + * @fColor,bColor: Foreground, Background color (corresponding to a 1, 0 in + * the monochrome data) + * @rop2: ROP value + */ + +extern long deSystemMem2VideoMemMonoBlt( + const char *pSrcbuf, + long srcDelta, + unsigned long startBit, + unsigned long dBase, + unsigned long dPitch, + unsigned long bpp, + unsigned long dx, unsigned long dy, + unsigned long width, unsigned long height, + unsigned long fColor, + unsigned long bColor, + unsigned long rop2); + +extern unsigned long deGetTransparency(void); +extern void deSetPixelFormat(unsigned long bpp); diff --git a/drivers/staging/sm7xx/smtcfb.c b/drivers/staging/sm7xx/smtcfb.c new file mode 100644 index 0000000..161dbc9 --- /dev/null +++ b/drivers/staging/sm7xx/smtcfb.c @@ -0,0 +1,1253 @@ +/* + * Silicon Motion SM7XX frame buffer device + * + * Copyright (C) 2006 Silicon Motion Technology Corp. + * Authors: Ge Wang, gewang@siliconmotion.com + * Boyod boyod.yang@siliconmotion.com.cn + * + * Copyright (C) 2009 Lemote, Inc. + * Author: Wu Zhangjin, wuzj@lemote.com + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. + * + * Version 0.10.26192.21.01 + * - Add PowerPC/Big endian support + * - Add 2D support for Lynx + * - Verified on2.6.19.2 Boyod.yang + * + * Version 0.09.2621.00.01 + * - Only support Linux Kernel's version 2.6.21. + * Boyod.yang + * + * Version 0.09 + * - Only support Linux Kernel's version 2.6.12. + * Boyod.yang + */ + +#ifndef __KERNEL__ +#define __KERNEL__ +#endif + +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_PM +#include +#endif + +struct screen_info smtc_screen_info; + +#include "smtcfb.h" +#include "smtc2d.h" + +#ifdef DEBUG +#define smdbg(format, arg...) printk(KERN_DEBUG format , ## arg) +#else +#define smdbg(format, arg...) +#endif + +/* +* Private structure +*/ +struct smtcfb_info { + /* + * The following is a pointer to be passed into the + * functions below. The modules outside the main + * voyager.c driver have no knowledge as to what + * is within this structure. + */ + struct fb_info fb; + struct display_switch *dispsw; + struct pci_dev *dev; + signed int currcon; + + struct { + u8 red, green, blue; + } palette[NR_RGB]; + + u_int palette_size; +}; + +struct par_info { + /* + * Hardware + */ + u16 chipID; + unsigned char __iomem *m_pMMIO; + char __iomem *m_pLFB; + char *m_pDPR; + char *m_pVPR; + char *m_pCPR; + + u_int width; + u_int height; + u_int hz; + u_long BaseAddressInVRAM; + u8 chipRevID; +}; + +struct vesa_mode_table { + char mode_index[6]; + u16 lfb_width; + u16 lfb_height; + u16 lfb_depth; +}; + +static struct vesa_mode_table vesa_mode[] = { + {"0x301", 640, 480, 8}, + {"0x303", 800, 600, 8}, + {"0x305", 1024, 768, 8}, + {"0x307", 1280, 1024, 8}, + + {"0x311", 640, 480, 16}, + {"0x314", 800, 600, 16}, + {"0x317", 1024, 768, 16}, + {"0x31A", 1280, 1024, 16}, + + {"0x312", 640, 480, 24}, + {"0x315", 800, 600, 24}, + {"0x318", 1024, 768, 24}, + {"0x31B", 1280, 1024, 24}, +}; + +char __iomem *smtc_RegBaseAddress; /* Memory Map IO starting address */ +char __iomem *smtc_VRAMBaseAddress; /* video memory starting address */ + +char *smtc_2DBaseAddress; /* 2D engine starting address */ +char *smtc_2Ddataport; /* 2D data port offset */ +short smtc_2Dacceleration; + +static u32 colreg[17]; +static struct par_info hw; /* hardware information */ + +u16 smtc_ChipIDs[] = { + 0x710, + 0x712, + 0x720 +}; + +#define numSMTCchipIDs (sizeof(smtc_ChipIDs) / sizeof(u16)) + +void deWaitForNotBusy(void) +{ + unsigned long i = 0x1000000; + while (i--) { + if ((smtc_seqr(0x16) & 0x18) == 0x10) + break; + } + smtc_de_busy = 0; +} + +static void sm712_set_timing(struct smtcfb_info *sfb, + struct par_info *ppar_info) +{ + int i = 0, j = 0; + u32 m_nScreenStride; + + smdbg("\nppar_info->width = %d ppar_info->height = %d" + "sfb->fb.var.bits_per_pixel = %d ppar_info->hz = %d\n", + ppar_info->width, ppar_info->height, + sfb->fb.var.bits_per_pixel, ppar_info->hz); + + for (j = 0; j < numVGAModes; j++) { + if (VGAMode[j].mmSizeX == ppar_info->width && + VGAMode[j].mmSizeY == ppar_info->height && + VGAMode[j].bpp == sfb->fb.var.bits_per_pixel && + VGAMode[j].hz == ppar_info->hz) { + + smdbg("\nVGAMode[j].mmSizeX = %d VGAMode[j].mmSizeY =" + "%d VGAMode[j].bpp = %d" + "VGAMode[j].hz=%d\n", + VGAMode[j].mmSizeX, VGAMode[j].mmSizeY, + VGAMode[j].bpp, VGAMode[j].hz); + + smdbg("VGAMode index=%d\n", j); + + smtc_mmiowb(0x0, 0x3c6); + + smtc_seqw(0, 0x1); + + smtc_mmiowb(VGAMode[j].Init_MISC, 0x3c2); + + /* init SEQ register SR00 - SR04 */ + for (i = 0; i < SIZE_SR00_SR04; i++) + smtc_seqw(i, VGAMode[j].Init_SR00_SR04[i]); + + /* init SEQ register SR10 - SR24 */ + for (i = 0; i < SIZE_SR10_SR24; i++) + smtc_seqw(i + 0x10, + VGAMode[j].Init_SR10_SR24[i]); + + /* init SEQ register SR30 - SR75 */ + for (i = 0; i < SIZE_SR30_SR75; i++) + if (((i + 0x30) != 0x62) \ + && ((i + 0x30) != 0x6a) \ + && ((i + 0x30) != 0x6b)) + smtc_seqw(i + 0x30, + VGAMode[j].Init_SR30_SR75[i]); + + /* init SEQ register SR80 - SR93 */ + for (i = 0; i < SIZE_SR80_SR93; i++) + smtc_seqw(i + 0x80, + VGAMode[j].Init_SR80_SR93[i]); + + /* init SEQ register SRA0 - SRAF */ + for (i = 0; i < SIZE_SRA0_SRAF; i++) + smtc_seqw(i + 0xa0, + VGAMode[j].Init_SRA0_SRAF[i]); + + /* init Graphic register GR00 - GR08 */ + for (i = 0; i < SIZE_GR00_GR08; i++) + smtc_grphw(i, VGAMode[j].Init_GR00_GR08[i]); + + /* init Attribute register AR00 - AR14 */ + for (i = 0; i < SIZE_AR00_AR14; i++) + smtc_attrw(i, VGAMode[j].Init_AR00_AR14[i]); + + /* init CRTC register CR00 - CR18 */ + for (i = 0; i < SIZE_CR00_CR18; i++) + smtc_crtcw(i, VGAMode[j].Init_CR00_CR18[i]); + + /* init CRTC register CR30 - CR4D */ + for (i = 0; i < SIZE_CR30_CR4D; i++) + smtc_crtcw(i + 0x30, + VGAMode[j].Init_CR30_CR4D[i]); + + /* init CRTC register CR90 - CRA7 */ + for (i = 0; i < SIZE_CR90_CRA7; i++) + smtc_crtcw(i + 0x90, + VGAMode[j].Init_CR90_CRA7[i]); + } + } + smtc_mmiowb(0x67, 0x3c2); + + /* set VPR registers */ + writel(0x0, ppar_info->m_pVPR + 0x0C); + writel(0x0, ppar_info->m_pVPR + 0x40); + + /* set data width */ + m_nScreenStride = + (ppar_info->width * sfb->fb.var.bits_per_pixel) / 64; + switch (sfb->fb.var.bits_per_pixel) { + case 8: + writel(0x0, ppar_info->m_pVPR + 0x0); + break; + case 16: + writel(0x00020000, ppar_info->m_pVPR + 0x0); + break; + case 24: + writel(0x00040000, ppar_info->m_pVPR + 0x0); + break; + case 32: + writel(0x00030000, ppar_info->m_pVPR + 0x0); + break; + } + writel((u32) (((m_nScreenStride + 2) << 16) | m_nScreenStride), + ppar_info->m_pVPR + 0x10); + +} + +static void sm712_setpalette(int regno, unsigned red, unsigned green, + unsigned blue, struct fb_info *info) +{ + struct par_info *cur_par = (struct par_info *)info->par; + + if (cur_par->BaseAddressInVRAM) + /* + * second display palette for dual head. Enable CRT RAM, 6-bit + * RAM + */ + smtc_seqw(0x66, (smtc_seqr(0x66) & 0xC3) | 0x20); + else + /* primary display palette. Enable LCD RAM only, 6-bit RAM */ + smtc_seqw(0x66, (smtc_seqr(0x66) & 0xC3) | 0x10); + smtc_mmiowb(regno, dac_reg); + smtc_mmiowb(red >> 10, dac_val); + smtc_mmiowb(green >> 10, dac_val); + smtc_mmiowb(blue >> 10, dac_val); +} + +static void smtc_set_timing(struct smtcfb_info *sfb, struct par_info + *ppar_info) +{ + switch (ppar_info->chipID) { + case 0x710: + case 0x712: + case 0x720: + sm712_set_timing(sfb, ppar_info); + break; + } +} + +static struct fb_var_screeninfo smtcfb_var = { + .xres = 1024, + .yres = 600, + .xres_virtual = 1024, + .yres_virtual = 600, + .bits_per_pixel = 16, + .red = {16, 8, 0}, + .green = {8, 8, 0}, + .blue = {0, 8, 0}, + .activate = FB_ACTIVATE_NOW, + .height = -1, + .width = -1, + .vmode = FB_VMODE_NONINTERLACED, +}; + +static struct fb_fix_screeninfo smtcfb_fix = { + .id = "sm712fb", + .type = FB_TYPE_PACKED_PIXELS, + .visual = FB_VISUAL_TRUECOLOR, + .line_length = 800 * 3, + .accel = FB_ACCEL_SMI_LYNX, +}; + +/* chan_to_field + * + * convert a colour value into a field position + * + * from pxafb.c + */ + +static inline unsigned int chan_to_field(unsigned int chan, + struct fb_bitfield *bf) +{ + chan &= 0xffff; + chan >>= 16 - bf->length; + return chan << bf->offset; +} + +static int smtcfb_blank(int blank_mode, struct fb_info *info) +{ + /* clear DPMS setting */ + switch (blank_mode) { + case FB_BLANK_UNBLANK: + /* Screen On: HSync: On, VSync : On */ + smtc_seqw(0x01, (smtc_seqr(0x01) & (~0x20))); + smtc_seqw(0x6a, 0x16); + smtc_seqw(0x6b, 0x02); + smtc_seqw(0x21, (smtc_seqr(0x21) & 0x77)); + smtc_seqw(0x22, (smtc_seqr(0x22) & (~0x30))); + smtc_seqw(0x23, (smtc_seqr(0x23) & (~0xc0))); + smtc_seqw(0x24, (smtc_seqr(0x24) | 0x01)); + smtc_seqw(0x31, (smtc_seqr(0x31) | 0x03)); + break; + case FB_BLANK_NORMAL: + /* Screen Off: HSync: On, VSync : On Soft blank */ + smtc_seqw(0x01, (smtc_seqr(0x01) & (~0x20))); + smtc_seqw(0x6a, 0x16); + smtc_seqw(0x6b, 0x02); + smtc_seqw(0x22, (smtc_seqr(0x22) & (~0x30))); + smtc_seqw(0x23, (smtc_seqr(0x23) & (~0xc0))); + smtc_seqw(0x24, (smtc_seqr(0x24) | 0x01)); + smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00)); + break; + case FB_BLANK_VSYNC_SUSPEND: + /* Screen On: HSync: On, VSync : Off */ + smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20)); + smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0))); + smtc_seqw(0x6a, 0x0c); + smtc_seqw(0x6b, 0x02); + smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88)); + smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x20)); + smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0x20)); + smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01))); + smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00)); + smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80)); + break; + case FB_BLANK_HSYNC_SUSPEND: + /* Screen On: HSync: Off, VSync : On */ + smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20)); + smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0))); + smtc_seqw(0x6a, 0x0c); + smtc_seqw(0x6b, 0x02); + smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88)); + smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x10)); + smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0xD8)); + smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01))); + smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00)); + smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80)); + break; + case FB_BLANK_POWERDOWN: + /* Screen On: HSync: Off, VSync : Off */ + smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20)); + smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0))); + smtc_seqw(0x6a, 0x0c); + smtc_seqw(0x6b, 0x02); + smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88)); + smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x30)); + smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0xD8)); + smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01))); + smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00)); + smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80)); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int smtc_setcolreg(unsigned regno, unsigned red, unsigned green, + unsigned blue, unsigned trans, struct fb_info *info) +{ + struct smtcfb_info *sfb = (struct smtcfb_info *)info; + u32 val; + + if (regno > 255) + return 1; + + switch (sfb->fb.fix.visual) { + case FB_VISUAL_DIRECTCOLOR: + case FB_VISUAL_TRUECOLOR: + /* + * 16/32 bit true-colour, use pseuo-palette for 16 base color + */ + if (regno < 16) { + if (sfb->fb.var.bits_per_pixel == 16) { + u32 *pal = sfb->fb.pseudo_palette; + val = chan_to_field(red, &sfb->fb.var.red); + val |= chan_to_field(green, \ + &sfb->fb.var.green); + val |= chan_to_field(blue, &sfb->fb.var.blue); +#ifdef __BIG_ENDIAN + pal[regno] = + ((red & 0xf800) >> 8) | + ((green & 0xe000) >> 13) | + ((green & 0x1c00) << 3) | + ((blue & 0xf800) >> 3); +#else + pal[regno] = val; +#endif + } else { + u32 *pal = sfb->fb.pseudo_palette; + val = chan_to_field(red, &sfb->fb.var.red); + val |= chan_to_field(green, \ + &sfb->fb.var.green); + val |= chan_to_field(blue, &sfb->fb.var.blue); +#ifdef __BIG_ENDIAN + val = + (val & 0xff00ff00 >> 8) | + (val & 0x00ff00ff << 8); +#endif + pal[regno] = val; + } + } + break; + + case FB_VISUAL_PSEUDOCOLOR: + /* color depth 8 bit */ + sm712_setpalette(regno, red, green, blue, info); + break; + + default: + return 1; /* unknown type */ + } + + return 0; + +} + +#ifdef __BIG_ENDIAN +static ssize_t smtcfb_read(struct fb_info *info, char __user * buf, size_t + count, loff_t *ppos) +{ + unsigned long p = *ppos; + + u32 *buffer, *dst; + u32 __iomem *src; + int c, i, cnt = 0, err = 0; + unsigned long total_size; + + if (!info || !info->screen_base) + return -ENODEV; + + if (info->state != FBINFO_STATE_RUNNING) + return -EPERM; + + total_size = info->screen_size; + + if (total_size == 0) + total_size = info->fix.smem_len; + + if (p >= total_size) + return 0; + + if (count >= total_size) + count = total_size; + + if (count + p > total_size) + count = total_size - p; + + buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, GFP_KERNEL); + if (!buffer) + return -ENOMEM; + + src = (u32 __iomem *) (info->screen_base + p); + + if (info->fbops->fb_sync) + info->fbops->fb_sync(info); + + while (count) { + c = (count > PAGE_SIZE) ? PAGE_SIZE : count; + dst = buffer; + for (i = c >> 2; i--;) { + *dst = fb_readl(src++); + *dst = + (*dst & 0xff00ff00 >> 8) | + (*dst & 0x00ff00ff << 8); + dst++; + } + if (c & 3) { + u8 *dst8 = (u8 *) dst; + u8 __iomem *src8 = (u8 __iomem *) src; + + for (i = c & 3; i--;) { + if (i & 1) { + *dst8++ = fb_readb(++src8); + } else { + *dst8++ = fb_readb(--src8); + src8 += 2; + } + } + src = (u32 __iomem *) src8; + } + + if (copy_to_user(buf, buffer, c)) { + err = -EFAULT; + break; + } + *ppos += c; + buf += c; + cnt += c; + count -= c; + } + + kfree(buffer); + + return (err) ? err : cnt; +} + +static ssize_t +smtcfb_write(struct fb_info *info, const char __user *buf, size_t count, + loff_t *ppos) +{ + unsigned long p = *ppos; + + u32 *buffer, *src; + u32 __iomem *dst; + int c, i, cnt = 0, err = 0; + unsigned long total_size; + + if (!info || !info->screen_base) + return -ENODEV; + + if (info->state != FBINFO_STATE_RUNNING) + return -EPERM; + + total_size = info->screen_size; + + if (total_size == 0) + total_size = info->fix.smem_len; + + if (p > total_size) + return -EFBIG; + + if (count > total_size) { + err = -EFBIG; + count = total_size; + } + + if (count + p > total_size) { + if (!err) + err = -ENOSPC; + + count = total_size - p; + } + + buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, GFP_KERNEL); + if (!buffer) + return -ENOMEM; + + dst = (u32 __iomem *) (info->screen_base + p); + + if (info->fbops->fb_sync) + info->fbops->fb_sync(info); + + while (count) { + c = (count > PAGE_SIZE) ? PAGE_SIZE : count; + src = buffer; + + if (copy_from_user(src, buf, c)) { + err = -EFAULT; + break; + } + + for (i = c >> 2; i--;) { + fb_writel((*src & 0xff00ff00 >> 8) | + (*src & 0x00ff00ff << 8), dst++); + src++; + } + if (c & 3) { + u8 *src8 = (u8 *) src; + u8 __iomem *dst8 = (u8 __iomem *) dst; + + for (i = c & 3; i--;) { + if (i & 1) { + fb_writeb(*src8++, ++dst8); + } else { + fb_writeb(*src8++, --dst8); + dst8 += 2; + } + } + dst = (u32 __iomem *) dst8; + } + + *ppos += c; + buf += c; + cnt += c; + count -= c; + } + + kfree(buffer); + + return (cnt) ? cnt : err; +} +#endif /* ! __BIG_ENDIAN */ + +#include "smtc2d.c" + +void smtcfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) +{ + struct par_info *p = (struct par_info *)info->par; + + if (smtc_2Dacceleration) { + if (!area->width || !area->height) + return; + + deCopy(p->BaseAddressInVRAM, 0, info->var.bits_per_pixel, + area->dx, area->dy, area->width, area->height, + p->BaseAddressInVRAM, 0, area->sx, area->sy, 0, 0xC); + + } else + cfb_copyarea(info, area); +} + +void smtcfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) +{ + struct par_info *p = (struct par_info *)info->par; + + if (smtc_2Dacceleration) { + if (!rect->width || !rect->height) + return; + if (info->var.bits_per_pixel >= 24) + deFillRect(p->BaseAddressInVRAM, 0, rect->dx * 3, + rect->dy * 3, rect->width * 3, rect->height, + rect->color); + else + deFillRect(p->BaseAddressInVRAM, 0, rect->dx, rect->dy, + rect->width, rect->height, rect->color); + } else + cfb_fillrect(info, rect); +} + +void smtcfb_imageblit(struct fb_info *info, const struct fb_image *image) +{ + struct par_info *p = (struct par_info *)info->par; + u32 bg_col = 0, fg_col = 0; + + if ((smtc_2Dacceleration) && (image->depth == 1)) { + if (smtc_de_busy) + deWaitForNotBusy(); + + switch (info->var.bits_per_pixel) { + case 8: + bg_col = image->bg_color; + fg_col = image->fg_color; + break; + case 16: + bg_col = + ((u32 *) (info->pseudo_palette))[image->bg_color]; + fg_col = + ((u32 *) (info->pseudo_palette))[image->fg_color]; + break; + case 32: + bg_col = + ((u32 *) (info->pseudo_palette))[image->bg_color]; + fg_col = + ((u32 *) (info->pseudo_palette))[image->fg_color]; + break; + } + + deSystemMem2VideoMemMonoBlt( + image->data, + image->width / 8, + 0, + p->BaseAddressInVRAM, + 0, + 0, + image->dx, image->dy, + image->width, image->height, + fg_col, bg_col, + 0x0C); + + } else + cfb_imageblit(info, image); +} + +static struct fb_ops smtcfb_ops = { + .owner = THIS_MODULE, + .fb_setcolreg = smtc_setcolreg, + .fb_blank = smtcfb_blank, + .fb_fillrect = smtcfb_fillrect, + .fb_imageblit = smtcfb_imageblit, + .fb_copyarea = smtcfb_copyarea, +#ifdef __BIG_ENDIAN + .fb_read = smtcfb_read, + .fb_write = smtcfb_write, +#endif + +}; + +void smtcfb_setmode(struct smtcfb_info *sfb) +{ + switch (sfb->fb.var.bits_per_pixel) { + case 32: + sfb->fb.fix.visual = FB_VISUAL_TRUECOLOR; + sfb->fb.fix.line_length = sfb->fb.var.xres * 4; + sfb->fb.var.red.length = 8; + sfb->fb.var.green.length = 8; + sfb->fb.var.blue.length = 8; + sfb->fb.var.red.offset = 16; + sfb->fb.var.green.offset = 8; + sfb->fb.var.blue.offset = 0; + + break; + case 8: + sfb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR; + sfb->fb.fix.line_length = sfb->fb.var.xres; + sfb->fb.var.red.offset = 5; + sfb->fb.var.red.length = 3; + sfb->fb.var.green.offset = 2; + sfb->fb.var.green.length = 3; + sfb->fb.var.blue.offset = 0; + sfb->fb.var.blue.length = 2; + break; + case 24: + sfb->fb.fix.visual = FB_VISUAL_TRUECOLOR; + sfb->fb.fix.line_length = sfb->fb.var.xres * 3; + sfb->fb.var.red.length = 8; + sfb->fb.var.green.length = 8; + sfb->fb.var.blue.length = 8; + + sfb->fb.var.red.offset = 16; + sfb->fb.var.green.offset = 8; + sfb->fb.var.blue.offset = 0; + + break; + case 16: + default: + sfb->fb.fix.visual = FB_VISUAL_TRUECOLOR; + sfb->fb.fix.line_length = sfb->fb.var.xres * 2; + + sfb->fb.var.red.length = 5; + sfb->fb.var.green.length = 6; + sfb->fb.var.blue.length = 5; + + sfb->fb.var.red.offset = 11; + sfb->fb.var.green.offset = 5; + sfb->fb.var.blue.offset = 0; + + break; + } + + hw.width = sfb->fb.var.xres; + hw.height = sfb->fb.var.yres; + hw.hz = 60; + smtc_set_timing(sfb, &hw); + if (smtc_2Dacceleration) { + printk("2D acceleration enabled!\n"); + /* Init smtc drawing engine */ + deInit(sfb->fb.var.xres, sfb->fb.var.yres, + sfb->fb.var.bits_per_pixel); + } +} + +/* + * Alloc struct smtcfb_info and assign the default value + */ +static struct smtcfb_info *smtc_alloc_fb_info(struct pci_dev *dev, + char *name) +{ + struct smtcfb_info *sfb; + + sfb = kmalloc(sizeof(struct smtcfb_info), GFP_KERNEL); + + if (!sfb) + return NULL; + + memset(sfb, 0, sizeof(struct smtcfb_info)); + + sfb->currcon = -1; + sfb->dev = dev; + + /*** Init sfb->fb with default value ***/ + sfb->fb.flags = FBINFO_FLAG_DEFAULT; + sfb->fb.fbops = &smtcfb_ops; + sfb->fb.var = smtcfb_var; + sfb->fb.fix = smtcfb_fix; + + strcpy(sfb->fb.fix.id, name); + + sfb->fb.fix.type = FB_TYPE_PACKED_PIXELS; + sfb->fb.fix.type_aux = 0; + sfb->fb.fix.xpanstep = 0; + sfb->fb.fix.ypanstep = 0; + sfb->fb.fix.ywrapstep = 0; + sfb->fb.fix.accel = FB_ACCEL_SMI_LYNX; + + sfb->fb.var.nonstd = 0; + sfb->fb.var.activate = FB_ACTIVATE_NOW; + sfb->fb.var.height = -1; + sfb->fb.var.width = -1; + /* text mode acceleration */ + sfb->fb.var.accel_flags = FB_ACCELF_TEXT; + sfb->fb.var.vmode = FB_VMODE_NONINTERLACED; + sfb->fb.par = &hw; + sfb->fb.pseudo_palette = colreg; + + return sfb; +} + +/* + * Unmap in the memory mapped IO registers + */ + +static void smtc_unmap_mmio(struct smtcfb_info *sfb) +{ + if (sfb && smtc_RegBaseAddress) + smtc_RegBaseAddress = NULL; +} + +/* + * Map in the screen memory + */ + +static int smtc_map_smem(struct smtcfb_info *sfb, + struct pci_dev *dev, u_long smem_len) +{ + if (sfb->fb.var.bits_per_pixel == 32) { +#ifdef __BIG_ENDIAN + sfb->fb.fix.smem_start = pci_resource_start(dev, 0) + + 0x800000; +#else + sfb->fb.fix.smem_start = pci_resource_start(dev, 0); +#endif + } else { + sfb->fb.fix.smem_start = pci_resource_start(dev, 0); + } + + sfb->fb.fix.smem_len = smem_len; + + sfb->fb.screen_base = smtc_VRAMBaseAddress; + + if (!sfb->fb.screen_base) { + printk(KERN_INFO "%s: unable to map screen memory\n", + sfb->fb.fix.id); + return -ENOMEM; + } + + return 0; +} + +/* + * Unmap in the screen memory + * + */ +static void smtc_unmap_smem(struct smtcfb_info *sfb) +{ + if (sfb && sfb->fb.screen_base) { + iounmap(sfb->fb.screen_base); + sfb->fb.screen_base = NULL; + } +} + +/* + * We need to wake up the LynxEM+, and make sure its in linear memory mode. + */ +static inline void sm7xx_init_hw(void) +{ + outb_p(0x18, 0x3c4); + outb_p(0x11, 0x3c5); +} + +static void smtc_free_fb_info(struct smtcfb_info *sfb) +{ + if (sfb) { + fb_alloc_cmap(&sfb->fb.cmap, 0, 0); + kfree(sfb); + } +} + +/* + * sm712vga_setup - process command line options, get vga parameter + * @options: string of options + * Returns zero. + * + */ +static int __init __maybe_unused sm712vga_setup(char *options) +{ + int index; + + if (!options || !*options) { + smdbg("\n No vga parameter\n"); + return -EINVAL; + } + + smtc_screen_info.lfb_width = 0; + smtc_screen_info.lfb_height = 0; + smtc_screen_info.lfb_depth = 0; + + smdbg("\nsm712vga_setup = %s\n", options); + + for (index = 0; + index < (sizeof(vesa_mode) / sizeof(struct vesa_mode_table)); + index++) { + if (strstr(options, vesa_mode[index].mode_index)) { + smtc_screen_info.lfb_width = vesa_mode[index].lfb_width; + smtc_screen_info.lfb_height = + vesa_mode[index].lfb_height; + smtc_screen_info.lfb_depth = vesa_mode[index].lfb_depth; + return 0; + } + } + + return -1; +} +__setup("vga=", sm712vga_setup); + +/* Jason (08/13/2009) + * Original init function changed to probe method to be used by pci_drv + * process used to detect chips replaced with kernel process in pci_drv + */ +static int __init smtcfb_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + struct smtcfb_info *sfb; + u_long smem_size = 0x00800000; /* default 8MB */ + char name[16]; + int err; + unsigned long pFramebufferPhysical; + + printk(KERN_INFO + "Silicon Motion display driver " SMTC_LINUX_FB_VERSION "\n"); + + err = pci_enable_device(pdev); /* enable SMTC chip */ + + if (err) + return err; + err = -ENOMEM; + + hw.chipID = ent->device; + sprintf(name, "sm%Xfb", hw.chipID); + + sfb = smtc_alloc_fb_info(pdev, name); + + if (!sfb) + goto failed; + /* Jason (08/13/2009) + * Store fb_info to be further used when suspending and resuming + */ + pci_set_drvdata(pdev, sfb); + + sm7xx_init_hw(); + + /*get mode parameter from smtc_screen_info */ + if (smtc_screen_info.lfb_width != 0) { + sfb->fb.var.xres = smtc_screen_info.lfb_width; + sfb->fb.var.yres = smtc_screen_info.lfb_height; + sfb->fb.var.bits_per_pixel = smtc_screen_info.lfb_depth; + } else { + /* default resolution 1024x600 16bit mode */ + sfb->fb.var.xres = SCREEN_X_RES; + sfb->fb.var.yres = SCREEN_Y_RES; + sfb->fb.var.bits_per_pixel = SCREEN_BPP; + } + +#ifdef __BIG_ENDIAN + if (sfb->fb.var.bits_per_pixel == 24) + sfb->fb.var.bits_per_pixel = (smtc_screen_info.lfb_depth = 32); +#endif + /* Map address and memory detection */ + pFramebufferPhysical = pci_resource_start(pdev, 0); + pci_read_config_byte(pdev, PCI_REVISION_ID, &hw.chipRevID); + + switch (hw.chipID) { + case 0x710: + case 0x712: + sfb->fb.fix.mmio_start = pFramebufferPhysical + 0x00400000; + sfb->fb.fix.mmio_len = 0x00400000; + smem_size = SM712_VIDEOMEMORYSIZE; +#ifdef __BIG_ENDIAN + hw.m_pLFB = (smtc_VRAMBaseAddress = + ioremap(pFramebufferPhysical, 0x00c00000)); +#else + hw.m_pLFB = (smtc_VRAMBaseAddress = + ioremap(pFramebufferPhysical, 0x00800000)); +#endif + hw.m_pMMIO = (smtc_RegBaseAddress = + smtc_VRAMBaseAddress + 0x00700000); + smtc_2DBaseAddress = (hw.m_pDPR = + smtc_VRAMBaseAddress + 0x00408000); + smtc_2Ddataport = smtc_VRAMBaseAddress + DE_DATA_PORT_712; + hw.m_pVPR = hw.m_pLFB + 0x0040c000; +#ifdef __BIG_ENDIAN + if (sfb->fb.var.bits_per_pixel == 32) { + smtc_VRAMBaseAddress += 0x800000; + hw.m_pLFB += 0x800000; + printk(KERN_INFO + "\nsmtc_VRAMBaseAddress=%p hw.m_pLFB=%p\n", + smtc_VRAMBaseAddress, hw.m_pLFB); + } +#endif + if (!smtc_RegBaseAddress) { + printk(KERN_INFO + "%s: unable to map memory mapped IO\n", + sfb->fb.fix.id); + return -ENOMEM; + } + + /* set MCLK = 14.31818 * (0x16 / 0x2) */ + smtc_seqw(0x6a, 0x16); + smtc_seqw(0x6b, 0x02); + smtc_seqw(0x62, 0x3e); + /* enable PCI burst */ + smtc_seqw(0x17, 0x20); + /* enable word swap */ +#ifdef __BIG_ENDIAN + if (sfb->fb.var.bits_per_pixel == 32) + smtc_seqw(0x17, 0x30); +#endif +#ifdef CONFIG_FB_SM7XX_ACCEL + smtc_2Dacceleration = 1; +#endif + break; + case 0x720: + sfb->fb.fix.mmio_start = pFramebufferPhysical; + sfb->fb.fix.mmio_len = 0x00200000; + smem_size = SM722_VIDEOMEMORYSIZE; + smtc_2DBaseAddress = (hw.m_pDPR = + ioremap(pFramebufferPhysical, 0x00a00000)); + hw.m_pLFB = (smtc_VRAMBaseAddress = + smtc_2DBaseAddress + 0x00200000); + hw.m_pMMIO = (smtc_RegBaseAddress = + smtc_2DBaseAddress + 0x000c0000); + smtc_2Ddataport = smtc_2DBaseAddress + DE_DATA_PORT_722; + hw.m_pVPR = smtc_2DBaseAddress + 0x800; + + smtc_seqw(0x62, 0xff); + smtc_seqw(0x6a, 0x0d); + smtc_seqw(0x6b, 0x02); + smtc_2Dacceleration = 0; + break; + default: + printk(KERN_INFO + "No valid Silicon Motion display chip was detected!\n"); + + smtc_free_fb_info(sfb); + return err; + } + + /* can support 32 bpp */ + if (15 == sfb->fb.var.bits_per_pixel) + sfb->fb.var.bits_per_pixel = 16; + + sfb->fb.var.xres_virtual = sfb->fb.var.xres; + sfb->fb.var.yres_virtual = sfb->fb.var.yres; + err = smtc_map_smem(sfb, pdev, smem_size); + if (err) + goto failed; + + smtcfb_setmode(sfb); + /* Primary display starting from 0 postion */ + hw.BaseAddressInVRAM = 0; + sfb->fb.par = &hw; + + err = register_framebuffer(&sfb->fb); + if (err < 0) + goto failed; + + printk(KERN_INFO "Silicon Motion SM%X Rev%X primary display mode" + "%dx%d-%d Init Complete.\n", hw.chipID, hw.chipRevID, + sfb->fb.var.xres, sfb->fb.var.yres, + sfb->fb.var.bits_per_pixel); + + return 0; + + failed: + printk(KERN_INFO "Silicon Motion, Inc. primary display init fail\n"); + + smtc_unmap_smem(sfb); + smtc_unmap_mmio(sfb); + smtc_free_fb_info(sfb); + + return err; +} + + +/* Jason (08/11/2009) PCI_DRV wrapper essential structs */ +static struct pci_device_id smtcfb_pci_table[] = { + {0x126f, 0x710, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {0x126f, 0x712, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {0x126f, 0x720, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {0,} +}; + + +/* Jason (08/14/2009) + * do some clean up when the driver module is removed + */ +static void __devexit smtcfb_pci_remove(struct pci_dev *pdev) +{ + struct smtcfb_info *sfb; + + sfb = pci_get_drvdata(pdev); + pci_set_drvdata(pdev, NULL); + smtc_unmap_smem(sfb); + smtc_unmap_mmio(sfb); + unregister_framebuffer(&sfb->fb); + smtc_free_fb_info(sfb); +} + +/* Jason (08/14/2009) + * suspend function, called when the suspend event is triggered + */ +static int __maybe_unused smtcfb_suspend(struct pci_dev *pdev, pm_message_t msg) +{ + struct smtcfb_info *sfb; + int retv; + + sfb = pci_get_drvdata(pdev); + + /* set the hw in sleep mode use externel clock and self memory refresh + * so that we can turn off internal PLLs later on + */ + smtc_seqw(0x20, (smtc_seqr(0x20) | 0xc0)); + smtc_seqw(0x69, (smtc_seqr(0x69) & 0xf7)); + + switch (msg.event) { + case PM_EVENT_FREEZE: + case PM_EVENT_PRETHAW: + pdev->dev.power.power_state = msg; + return 0; + } + + /* when doing suspend, call fb apis and pci apis */ + if (msg.event == PM_EVENT_SUSPEND) { + acquire_console_sem(); + fb_set_suspend(&sfb->fb, 1); + release_console_sem(); + retv = pci_save_state(pdev); + pci_disable_device(pdev); + retv = pci_choose_state(pdev, msg); + retv = pci_set_power_state(pdev, retv); + } + + pdev->dev.power.power_state = msg; + + /* additionaly turn off all function blocks including internal PLLs */ + smtc_seqw(0x21, 0xff); + + return 0; +} + +static int __maybe_unused smtcfb_resume(struct pci_dev *pdev) +{ + struct smtcfb_info *sfb; + int retv; + + sfb = pci_get_drvdata(pdev); + + /* when resuming, restore pci data and fb cursor */ + if (pdev->dev.power.power_state.event != PM_EVENT_FREEZE) { + retv = pci_set_power_state(pdev, PCI_D0); + retv = pci_restore_state(pdev); + if (pci_enable_device(pdev)) + return -1; + pci_set_master(pdev); + } + + /* reinit hardware */ + sm7xx_init_hw(); + switch (hw.chipID) { + case 0x710: + case 0x712: + /* set MCLK = 14.31818 * (0x16 / 0x2) */ + smtc_seqw(0x6a, 0x16); + smtc_seqw(0x6b, 0x02); + smtc_seqw(0x62, 0x3e); + /* enable PCI burst */ + smtc_seqw(0x17, 0x20); +#ifdef __BIG_ENDIAN + if (sfb->fb.var.bits_per_pixel == 32) + smtc_seqw(0x17, 0x30); +#endif + break; + case 0x720: + smtc_seqw(0x62, 0xff); + smtc_seqw(0x6a, 0x0d); + smtc_seqw(0x6b, 0x02); + break; + } + + smtc_seqw(0x34, (smtc_seqr(0x34) | 0xc0)); + smtc_seqw(0x33, ((smtc_seqr(0x33) | 0x08) & 0xfb)); + + smtcfb_setmode(sfb); + + acquire_console_sem(); + fb_set_suspend(&sfb->fb, 0); + release_console_sem(); + + return 0; +} + +/* Jason (08/13/2009) + * pci_driver struct used to wrap the original driver + * so that it can be registered into the kernel and + * the proper method would be called when suspending and resuming + */ +static struct pci_driver smtcfb_driver = { + .name = "smtcfb", + .id_table = smtcfb_pci_table, + .probe = smtcfb_pci_probe, + .remove = __devexit_p(smtcfb_pci_remove), +#ifdef CONFIG_PM + .suspend = smtcfb_suspend, + .resume = smtcfb_resume, +#endif +}; + +static int __init smtcfb_init(void) +{ + return pci_register_driver(&smtcfb_driver); +} + +static void __exit smtcfb_exit(void) +{ + pci_unregister_driver(&smtcfb_driver); +} + +module_init(smtcfb_init); +module_exit(smtcfb_exit); + +MODULE_AUTHOR("Siliconmotion "); +MODULE_DESCRIPTION("Framebuffer driver for SMI Graphic Cards"); +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/sm7xx/smtcfb.h b/drivers/staging/sm7xx/smtcfb.h new file mode 100644 index 0000000..7f2c341 --- /dev/null +++ b/drivers/staging/sm7xx/smtcfb.h @@ -0,0 +1,793 @@ +/* + * Silicon Motion SM712 frame buffer device + * + * Copyright (C) 2006 Silicon Motion Technology Corp. + * Authors: Ge Wang, gewang@siliconmotion.com + * Boyod boyod.yang@siliconmotion.com.cn + * + * Copyright (C) 2009 Lemote, Inc. + * Author: Wu Zhangjin, wuzj@lemote.com + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. + */ + +#define SMTC_LINUX_FB_VERSION "version 0.11.2619.21.01 July 27, 2008" + +#define NR_PALETTE 256 +#define NR_RGB 2 + +#define FB_ACCEL_SMI_LYNX 88 + +#ifdef __BIG_ENDIAN +#define PC_VGA 0 +#else +#define PC_VGA 1 +#endif + +#define SCREEN_X_RES 1024 +#define SCREEN_Y_RES 600 +#define SCREEN_BPP 16 + +#ifndef FIELD_OFFSET +#define FIELD_OFSFET(type, field) \ + ((unsigned long) (PUCHAR) & (((type *)0)->field)) +#endif + +/*Assume SM712 graphics chip has 4MB VRAM */ +#define SM712_VIDEOMEMORYSIZE 0x00400000 +/*Assume SM722 graphics chip has 8MB VRAM */ +#define SM722_VIDEOMEMORYSIZE 0x00800000 + +#define dac_reg (0x3c8) +#define dac_val (0x3c9) + +extern char *smtc_RegBaseAddress; +#define smtc_mmiowb(dat, reg) writeb(dat, smtc_RegBaseAddress + reg) +#define smtc_mmioww(dat, reg) writew(dat, smtc_RegBaseAddress + reg) +#define smtc_mmiowl(dat, reg) writel(dat, smtc_RegBaseAddress + reg) + +#define smtc_mmiorb(reg) readb(smtc_RegBaseAddress + reg) +#define smtc_mmiorw(reg) readw(smtc_RegBaseAddress + reg) +#define smtc_mmiorl(reg) readl(smtc_RegBaseAddress + reg) + +#define SIZE_SR00_SR04 (0x04 - 0x00 + 1) +#define SIZE_SR10_SR24 (0x24 - 0x10 + 1) +#define SIZE_SR30_SR75 (0x75 - 0x30 + 1) +#define SIZE_SR80_SR93 (0x93 - 0x80 + 1) +#define SIZE_SRA0_SRAF (0xAF - 0xA0 + 1) +#define SIZE_GR00_GR08 (0x08 - 0x00 + 1) +#define SIZE_AR00_AR14 (0x14 - 0x00 + 1) +#define SIZE_CR00_CR18 (0x18 - 0x00 + 1) +#define SIZE_CR30_CR4D (0x4D - 0x30 + 1) +#define SIZE_CR90_CRA7 (0xA7 - 0x90 + 1) +#define SIZE_VPR (0x6C + 1) +#define SIZE_DPR (0x44 + 1) + +static inline void smtc_crtcw(int reg, int val) +{ + smtc_mmiowb(reg, 0x3d4); + smtc_mmiowb(val, 0x3d5); +} + +static inline unsigned int smtc_crtcr(int reg) +{ + smtc_mmiowb(reg, 0x3d4); + return smtc_mmiorb(0x3d5); +} + +static inline void smtc_grphw(int reg, int val) +{ + smtc_mmiowb(reg, 0x3ce); + smtc_mmiowb(val, 0x3cf); +} + +static inline unsigned int smtc_grphr(int reg) +{ + smtc_mmiowb(reg, 0x3ce); + return smtc_mmiorb(0x3cf); +} + +static inline void smtc_attrw(int reg, int val) +{ + smtc_mmiorb(0x3da); + smtc_mmiowb(reg, 0x3c0); + smtc_mmiorb(0x3c1); + smtc_mmiowb(val, 0x3c0); +} + +static inline void smtc_seqw(int reg, int val) +{ + smtc_mmiowb(reg, 0x3c4); + smtc_mmiowb(val, 0x3c5); +} + +static inline unsigned int smtc_seqr(int reg) +{ + smtc_mmiowb(reg, 0x3c4); + return smtc_mmiorb(0x3c5); +} + +/* The next structure holds all information relevant for a specific video mode. + */ + +struct ModeInit { + int mmSizeX; + int mmSizeY; + int bpp; + int hz; + unsigned char Init_MISC; + unsigned char Init_SR00_SR04[SIZE_SR00_SR04]; + unsigned char Init_SR10_SR24[SIZE_SR10_SR24]; + unsigned char Init_SR30_SR75[SIZE_SR30_SR75]; + unsigned char Init_SR80_SR93[SIZE_SR80_SR93]; + unsigned char Init_SRA0_SRAF[SIZE_SRA0_SRAF]; + unsigned char Init_GR00_GR08[SIZE_GR00_GR08]; + unsigned char Init_AR00_AR14[SIZE_AR00_AR14]; + unsigned char Init_CR00_CR18[SIZE_CR00_CR18]; + unsigned char Init_CR30_CR4D[SIZE_CR30_CR4D]; + unsigned char Init_CR90_CRA7[SIZE_CR90_CRA7]; +}; + +/********************************************************************** + SM712 Mode table. + **********************************************************************/ +struct ModeInit VGAMode[] = { + { + /* mode#0: 640 x 480 16Bpp 60Hz */ + 640, 480, 16, 60, + /* Init_MISC */ + 0xE3, + { /* Init_SR0_SR4 */ + 0x03, 0x01, 0x0F, 0x00, 0x0E, + }, + { /* Init_SR10_SR24 */ + 0xFF, 0xBE, 0xEF, 0xFF, 0x00, 0x0E, 0x17, 0x2C, + 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC4, 0x30, 0x02, 0x01, 0x01, + }, + { /* Init_SR30_SR75 */ + 0x32, 0x03, 0xA0, 0x09, 0xC0, 0x32, 0x32, 0x32, + 0x32, 0x32, 0x32, 0x32, 0x00, 0x00, 0x03, 0xFF, + 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, + 0x20, 0x0C, 0x44, 0x20, 0x00, 0x32, 0x32, 0x32, + 0x04, 0x24, 0x63, 0x4F, 0x52, 0x0B, 0xDF, 0xEA, + 0x04, 0x50, 0x19, 0x32, 0x32, 0x00, 0x00, 0x32, + 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, + 0x50, 0x03, 0x74, 0x14, 0x07, 0x82, 0x07, 0x04, + 0x00, 0x45, 0x30, 0x30, 0x40, 0x30, + }, + { /* Init_SR80_SR93 */ + 0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x32, + 0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x32, 0x32, + 0x00, 0x00, 0x00, 0x00, + }, + { /* Init_SRA0_SRAF */ + 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED, + 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xFF, 0xDF, + }, + { /* Init_GR00_GR08 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, + 0xFF, + }, + { /* Init_AR00_AR14 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x41, 0x00, 0x0F, 0x00, 0x00, + }, + { /* Init_CR00_CR18 */ + 0x5F, 0x4F, 0x4F, 0x00, 0x53, 0x1F, 0x0B, 0x3E, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xEA, 0x0C, 0xDF, 0x50, 0x40, 0xDF, 0x00, 0xE3, + 0xFF, + }, + { /* Init_CR30_CR4D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x20, + 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xFF, 0xFD, + 0x5F, 0x4F, 0x00, 0x54, 0x00, 0x0B, 0xDF, 0x00, + 0xEA, 0x0C, 0x2E, 0x00, 0x4F, 0xDF, + }, + { /* Init_CR90_CRA7 */ + 0x56, 0xDD, 0x5E, 0xEA, 0x87, 0x44, 0x8F, 0x55, + 0x0A, 0x8F, 0x55, 0x0A, 0x00, 0x00, 0x18, 0x00, + 0x11, 0x10, 0x0B, 0x0A, 0x0A, 0x0A, 0x0A, 0x00, + }, + }, + { + /* mode#1: 640 x 480 24Bpp 60Hz */ + 640, 480, 24, 60, + /* Init_MISC */ + 0xE3, + { /* Init_SR0_SR4 */ + 0x03, 0x01, 0x0F, 0x00, 0x0E, + }, + { /* Init_SR10_SR24 */ + 0xFF, 0xBE, 0xEF, 0xFF, 0x00, 0x0E, 0x17, 0x2C, + 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC4, 0x30, 0x02, 0x01, 0x01, + }, + { /* Init_SR30_SR75 */ + 0x32, 0x03, 0xA0, 0x09, 0xC0, 0x32, 0x32, 0x32, + 0x32, 0x32, 0x32, 0x32, 0x00, 0x00, 0x03, 0xFF, + 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, + 0x20, 0x0C, 0x44, 0x20, 0x00, 0x32, 0x32, 0x32, + 0x04, 0x24, 0x63, 0x4F, 0x52, 0x0B, 0xDF, 0xEA, + 0x04, 0x50, 0x19, 0x32, 0x32, 0x00, 0x00, 0x32, + 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, + 0x50, 0x03, 0x74, 0x14, 0x07, 0x82, 0x07, 0x04, + 0x00, 0x45, 0x30, 0x30, 0x40, 0x30, + }, + { /* Init_SR80_SR93 */ + 0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x32, + 0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x32, 0x32, + 0x00, 0x00, 0x00, 0x00, + }, + { /* Init_SRA0_SRAF */ + 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED, + 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xFF, 0xDF, + }, + { /* Init_GR00_GR08 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, + 0xFF, + }, + { /* Init_AR00_AR14 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x41, 0x00, 0x0F, 0x00, 0x00, + }, + { /* Init_CR00_CR18 */ + 0x5F, 0x4F, 0x4F, 0x00, 0x53, 0x1F, 0x0B, 0x3E, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xEA, 0x0C, 0xDF, 0x50, 0x40, 0xDF, 0x00, 0xE3, + 0xFF, + }, + { /* Init_CR30_CR4D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x20, + 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xFF, 0xFD, + 0x5F, 0x4F, 0x00, 0x54, 0x00, 0x0B, 0xDF, 0x00, + 0xEA, 0x0C, 0x2E, 0x00, 0x4F, 0xDF, + }, + { /* Init_CR90_CRA7 */ + 0x56, 0xDD, 0x5E, 0xEA, 0x87, 0x44, 0x8F, 0x55, + 0x0A, 0x8F, 0x55, 0x0A, 0x00, 0x00, 0x18, 0x00, + 0x11, 0x10, 0x0B, 0x0A, 0x0A, 0x0A, 0x0A, 0x00, + }, + }, + { + /* mode#0: 640 x 480 32Bpp 60Hz */ + 640, 480, 32, 60, + /* Init_MISC */ + 0xE3, + { /* Init_SR0_SR4 */ + 0x03, 0x01, 0x0F, 0x00, 0x0E, + }, + { /* Init_SR10_SR24 */ + 0xFF, 0xBE, 0xEF, 0xFF, 0x00, 0x0E, 0x17, 0x2C, + 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC4, 0x30, 0x02, 0x01, 0x01, + }, + { /* Init_SR30_SR75 */ + 0x32, 0x03, 0xA0, 0x09, 0xC0, 0x32, 0x32, 0x32, + 0x32, 0x32, 0x32, 0x32, 0x00, 0x00, 0x03, 0xFF, + 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, + 0x20, 0x0C, 0x44, 0x20, 0x00, 0x32, 0x32, 0x32, + 0x04, 0x24, 0x63, 0x4F, 0x52, 0x0B, 0xDF, 0xEA, + 0x04, 0x50, 0x19, 0x32, 0x32, 0x00, 0x00, 0x32, + 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, + 0x50, 0x03, 0x74, 0x14, 0x07, 0x82, 0x07, 0x04, + 0x00, 0x45, 0x30, 0x30, 0x40, 0x30, + }, + { /* Init_SR80_SR93 */ + 0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x32, + 0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x32, 0x32, + 0x00, 0x00, 0x00, 0x00, + }, + { /* Init_SRA0_SRAF */ + 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED, + 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xFF, 0xDF, + }, + { /* Init_GR00_GR08 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, + 0xFF, + }, + { /* Init_AR00_AR14 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x41, 0x00, 0x0F, 0x00, 0x00, + }, + { /* Init_CR00_CR18 */ + 0x5F, 0x4F, 0x4F, 0x00, 0x53, 0x1F, 0x0B, 0x3E, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xEA, 0x0C, 0xDF, 0x50, 0x40, 0xDF, 0x00, 0xE3, + 0xFF, + }, + { /* Init_CR30_CR4D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x20, + 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xFF, 0xFD, + 0x5F, 0x4F, 0x00, 0x54, 0x00, 0x0B, 0xDF, 0x00, + 0xEA, 0x0C, 0x2E, 0x00, 0x4F, 0xDF, + }, + { /* Init_CR90_CRA7 */ + 0x56, 0xDD, 0x5E, 0xEA, 0x87, 0x44, 0x8F, 0x55, + 0x0A, 0x8F, 0x55, 0x0A, 0x00, 0x00, 0x18, 0x00, + 0x11, 0x10, 0x0B, 0x0A, 0x0A, 0x0A, 0x0A, 0x00, + }, + }, + + { /* mode#2: 800 x 600 16Bpp 60Hz */ + 800, 600, 16, 60, + /* Init_MISC */ + 0x2B, + { /* Init_SR0_SR4 */ + 0x03, 0x01, 0x0F, 0x03, 0x0E, + }, + { /* Init_SR10_SR24 */ + 0xFF, 0xBE, 0xEE, 0xFF, 0x00, 0x0E, 0x17, 0x2C, + 0x99, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC4, 0x30, 0x02, 0x01, 0x01, + }, + { /* Init_SR30_SR75 */ + 0x34, 0x03, 0x20, 0x09, 0xC0, 0x24, 0x24, 0x24, + 0x24, 0x24, 0x24, 0x24, 0x00, 0x00, 0x03, 0xFF, + 0x00, 0xFC, 0x00, 0x00, 0x20, 0x38, 0x00, 0xFC, + 0x20, 0x0C, 0x44, 0x20, 0x00, 0x24, 0x24, 0x24, + 0x04, 0x48, 0x83, 0x63, 0x68, 0x72, 0x57, 0x58, + 0x04, 0x55, 0x59, 0x24, 0x24, 0x00, 0x00, 0x24, + 0x01, 0x80, 0x7A, 0x1A, 0x1A, 0x00, 0x00, 0x00, + 0x50, 0x03, 0x74, 0x14, 0x1C, 0x85, 0x35, 0x13, + 0x02, 0x45, 0x30, 0x35, 0x40, 0x20, + }, + { /* Init_SR80_SR93 */ + 0x00, 0x00, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x24, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x24, 0x24, + 0x00, 0x00, 0x00, 0x00, + }, + { /* Init_SRA0_SRAF */ + 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED, + 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xBF, 0xDF, + }, + { /* Init_GR00_GR08 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, + 0xFF, + }, + { /* Init_AR00_AR14 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x41, 0x00, 0x0F, 0x00, 0x00, + }, + { /* Init_CR00_CR18 */ + 0x7F, 0x63, 0x63, 0x00, 0x68, 0x18, 0x72, 0xF0, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x58, 0x0C, 0x57, 0x64, 0x40, 0x57, 0x00, 0xE3, + 0xFF, + }, + { /* Init_CR30_CR4D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x03, 0x20, + 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xBF, 0xFD, + 0x7F, 0x63, 0x00, 0x69, 0x18, 0x72, 0x57, 0x00, + 0x58, 0x0C, 0xE0, 0x20, 0x63, 0x57, + }, + { /* Init_CR90_CRA7 */ + 0x56, 0x4B, 0x5E, 0x55, 0x86, 0x9D, 0x8E, 0xAA, + 0xDB, 0x2A, 0xDF, 0x33, 0x00, 0x00, 0x18, 0x00, + 0x20, 0x1F, 0x1A, 0x19, 0x0F, 0x0F, 0x0F, 0x00, + }, + }, + { /* mode#3: 800 x 600 24Bpp 60Hz */ + 800, 600, 24, 60, + 0x2B, + { /* Init_SR0_SR4 */ + 0x03, 0x01, 0x0F, 0x03, 0x0E, + }, + { /* Init_SR10_SR24 */ + 0xFF, 0xBE, 0xEE, 0xFF, 0x00, 0x0E, 0x17, 0x2C, + 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC4, 0x30, 0x02, 0x01, 0x01, + }, + { /* Init_SR30_SR75 */ + 0x36, 0x03, 0x20, 0x09, 0xC0, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x03, 0xFF, + 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, + 0x20, 0x0C, 0x44, 0x20, 0x00, 0x36, 0x36, 0x36, + 0x04, 0x48, 0x83, 0x63, 0x68, 0x72, 0x57, 0x58, + 0x04, 0x55, 0x59, 0x36, 0x36, 0x00, 0x00, 0x36, + 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, + 0x50, 0x03, 0x74, 0x14, 0x1C, 0x85, 0x35, 0x13, + 0x02, 0x45, 0x30, 0x30, 0x40, 0x20, + }, + { /* Init_SR80_SR93 */ + 0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x36, + 0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, + }, + { /* Init_SRA0_SRAF */ + 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED, + 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xBF, 0xDF, + }, + { /* Init_GR00_GR08 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, + 0xFF, + }, + { /* Init_AR00_AR14 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x41, 0x00, 0x0F, 0x00, 0x00, + }, + { /* Init_CR00_CR18 */ + 0x7F, 0x63, 0x63, 0x00, 0x68, 0x18, 0x72, 0xF0, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x58, 0x0C, 0x57, 0x64, 0x40, 0x57, 0x00, 0xE3, + 0xFF, + }, + { /* Init_CR30_CR4D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x03, 0x20, + 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xBF, 0xFD, + 0x7F, 0x63, 0x00, 0x69, 0x18, 0x72, 0x57, 0x00, + 0x58, 0x0C, 0xE0, 0x20, 0x63, 0x57, + }, + { /* Init_CR90_CRA7 */ + 0x56, 0x4B, 0x5E, 0x55, 0x86, 0x9D, 0x8E, 0xAA, + 0xDB, 0x2A, 0xDF, 0x33, 0x00, 0x00, 0x18, 0x00, + 0x20, 0x1F, 0x1A, 0x19, 0x0F, 0x0F, 0x0F, 0x00, + }, + }, + { /* mode#7: 800 x 600 32Bpp 60Hz */ + 800, 600, 32, 60, + /* Init_MISC */ + 0x2B, + { /* Init_SR0_SR4 */ + 0x03, 0x01, 0x0F, 0x03, 0x0E, + }, + { /* Init_SR10_SR24 */ + 0xFF, 0xBE, 0xEE, 0xFF, 0x00, 0x0E, 0x17, 0x2C, + 0x99, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC4, 0x30, 0x02, 0x01, 0x01, + }, + { /* Init_SR30_SR75 */ + 0x34, 0x03, 0x20, 0x09, 0xC0, 0x24, 0x24, 0x24, + 0x24, 0x24, 0x24, 0x24, 0x00, 0x00, 0x03, 0xFF, + 0x00, 0xFC, 0x00, 0x00, 0x20, 0x38, 0x00, 0xFC, + 0x20, 0x0C, 0x44, 0x20, 0x00, 0x24, 0x24, 0x24, + 0x04, 0x48, 0x83, 0x63, 0x68, 0x72, 0x57, 0x58, + 0x04, 0x55, 0x59, 0x24, 0x24, 0x00, 0x00, 0x24, + 0x01, 0x80, 0x7A, 0x1A, 0x1A, 0x00, 0x00, 0x00, + 0x50, 0x03, 0x74, 0x14, 0x1C, 0x85, 0x35, 0x13, + 0x02, 0x45, 0x30, 0x35, 0x40, 0x20, + }, + { /* Init_SR80_SR93 */ + 0x00, 0x00, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x24, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x24, 0x24, + 0x00, 0x00, 0x00, 0x00, + }, + { /* Init_SRA0_SRAF */ + 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED, + 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xBF, 0xDF, + }, + { /* Init_GR00_GR08 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, + 0xFF, + }, + { /* Init_AR00_AR14 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x41, 0x00, 0x0F, 0x00, 0x00, + }, + { /* Init_CR00_CR18 */ + 0x7F, 0x63, 0x63, 0x00, 0x68, 0x18, 0x72, 0xF0, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x58, 0x0C, 0x57, 0x64, 0x40, 0x57, 0x00, 0xE3, + 0xFF, + }, + { /* Init_CR30_CR4D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x03, 0x20, + 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xBF, 0xFD, + 0x7F, 0x63, 0x00, 0x69, 0x18, 0x72, 0x57, 0x00, + 0x58, 0x0C, 0xE0, 0x20, 0x63, 0x57, + }, + { /* Init_CR90_CRA7 */ + 0x56, 0x4B, 0x5E, 0x55, 0x86, 0x9D, 0x8E, 0xAA, + 0xDB, 0x2A, 0xDF, 0x33, 0x00, 0x00, 0x18, 0x00, + 0x20, 0x1F, 0x1A, 0x19, 0x0F, 0x0F, 0x0F, 0x00, + }, + }, + /* We use 1024x768 table to light 1024x600 panel for lemote */ + { /* mode#4: 1024 x 600 16Bpp 60Hz */ + 1024, 600, 16, 60, + /* Init_MISC */ + 0xEB, + { /* Init_SR0_SR4 */ + 0x03, 0x01, 0x0F, 0x00, 0x0E, + }, + { /* Init_SR10_SR24 */ + 0xC8, 0x40, 0x14, 0x60, 0x00, 0x0A, 0x17, 0x20, + 0x51, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC4, 0x30, 0x02, 0x00, 0x01, + }, + { /* Init_SR30_SR75 */ + 0x22, 0x03, 0x24, 0x09, 0xC0, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x03, 0xFF, + 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, + 0x20, 0x0C, 0x44, 0x20, 0x00, 0x22, 0x22, 0x22, + 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03, + 0x00, 0x60, 0x59, 0x22, 0x22, 0x00, 0x00, 0x22, + 0x01, 0x80, 0x7A, 0x1A, 0x1A, 0x00, 0x00, 0x00, + 0x50, 0x03, 0x16, 0x02, 0x0D, 0x82, 0x09, 0x02, + 0x04, 0x45, 0x3F, 0x30, 0x40, 0x20, + }, + { /* Init_SR80_SR93 */ + 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A, + 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A, + 0x00, 0x00, 0x00, 0x00, + }, + { /* Init_SRA0_SRAF */ + 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED, + 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF, + }, + { /* Init_GR00_GR08 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, + 0xFF, + }, + { /* Init_AR00_AR14 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x41, 0x00, 0x0F, 0x00, 0x00, + }, + { /* Init_CR00_CR18 */ + 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3, + 0xFF, + }, + { /* Init_CR30_CR4D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20, + 0x00, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xBF, 0xFF, + 0xA3, 0x7F, 0x00, 0x82, 0x0b, 0x6f, 0x57, 0x00, + 0x5c, 0x0f, 0xE0, 0xe0, 0x7F, 0x57, + }, + { /* Init_CR90_CRA7 */ + 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26, + 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03, + }, + }, + { /* mode#5: 1024 x 768 24Bpp 60Hz */ + 1024, 768, 24, 60, + /* Init_MISC */ + 0xEB, + { /* Init_SR0_SR4 */ + 0x03, 0x01, 0x0F, 0x03, 0x0E, + }, + { /* Init_SR10_SR24 */ + 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C, + 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC4, 0x30, 0x02, 0x01, 0x01, + }, + { /* Init_SR30_SR75 */ + 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A, + 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF, + 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, + 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A, + 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03, + 0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A, + 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, + 0x50, 0x03, 0x74, 0x14, 0x3B, 0x0D, 0x09, 0x02, + 0x04, 0x45, 0x30, 0x30, 0x40, 0x20, + }, + { /* Init_SR80_SR93 */ + 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A, + 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A, + 0x00, 0x00, 0x00, 0x00, + }, + { /* Init_SRA0_SRAF */ + 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED, + 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF, + }, + { /* Init_GR00_GR08 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, + 0xFF, + }, + { /* Init_AR00_AR14 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x41, 0x00, 0x0F, 0x00, 0x00, + }, + { /* Init_CR00_CR18 */ + 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3, + 0xFF, + }, + { /* Init_CR30_CR4D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20, + 0x00, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xBF, 0xFF, + 0xA3, 0x7F, 0x00, 0x86, 0x15, 0x24, 0xFF, 0x00, + 0x01, 0x07, 0xE5, 0x20, 0x7F, 0xFF, + }, + { /* Init_CR90_CRA7 */ + 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26, + 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03, + }, + }, + { /* mode#4: 1024 x 768 32Bpp 60Hz */ + 1024, 768, 32, 60, + /* Init_MISC */ + 0xEB, + { /* Init_SR0_SR4 */ + 0x03, 0x01, 0x0F, 0x03, 0x0E, + }, + { /* Init_SR10_SR24 */ + 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C, + 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC4, 0x32, 0x02, 0x01, 0x01, + }, + { /* Init_SR30_SR75 */ + 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A, + 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF, + 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, + 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A, + 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03, + 0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A, + 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, + 0x50, 0x03, 0x74, 0x14, 0x3B, 0x0D, 0x09, 0x02, + 0x04, 0x45, 0x30, 0x30, 0x40, 0x20, + }, + { /* Init_SR80_SR93 */ + 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A, + 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A, + 0x00, 0x00, 0x00, 0x00, + }, + { /* Init_SRA0_SRAF */ + 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED, + 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF, + }, + { /* Init_GR00_GR08 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, + 0xFF, + }, + { /* Init_AR00_AR14 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x41, 0x00, 0x0F, 0x00, 0x00, + }, + { /* Init_CR00_CR18 */ + 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3, + 0xFF, + }, + { /* Init_CR30_CR4D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20, + 0x00, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xBF, 0xFF, + 0xA3, 0x7F, 0x00, 0x86, 0x15, 0x24, 0xFF, 0x00, + 0x01, 0x07, 0xE5, 0x20, 0x7F, 0xFF, + }, + { /* Init_CR90_CRA7 */ + 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26, + 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03, + }, + }, + { /* mode#6: 320 x 240 16Bpp 60Hz */ + 320, 240, 16, 60, + /* Init_MISC */ + 0xEB, + { /* Init_SR0_SR4 */ + 0x03, 0x01, 0x0F, 0x03, 0x0E, + }, + { /* Init_SR10_SR24 */ + 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C, + 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC4, 0x32, 0x02, 0x01, 0x01, + }, + { /* Init_SR30_SR75 */ + 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A, + 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF, + 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, + 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A, + 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03, + 0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A, + 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, + 0x50, 0x03, 0x74, 0x14, 0x08, 0x43, 0x08, 0x43, + 0x04, 0x45, 0x30, 0x30, 0x40, 0x20, + }, + { /* Init_SR80_SR93 */ + 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A, + 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A, + 0x00, 0x00, 0x00, 0x00, + }, + { /* Init_SRA0_SRAF */ + 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED, + 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF, + }, + { /* Init_GR00_GR08 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, + 0xFF, + }, + { /* Init_AR00_AR14 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x41, 0x00, 0x0F, 0x00, 0x00, + }, + { /* Init_CR00_CR18 */ + 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3, + 0xFF, + }, + { /* Init_CR30_CR4D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20, + 0x00, 0x00, 0x30, 0x40, 0x00, 0xFF, 0xBF, 0xFF, + 0x2E, 0x27, 0x00, 0x2b, 0x0c, 0x0F, 0xEF, 0x00, + 0xFe, 0x0f, 0x01, 0xC0, 0x27, 0xEF, + }, + { /* Init_CR90_CRA7 */ + 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26, + 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03, + }, + }, + + { /* mode#8: 320 x 240 32Bpp 60Hz */ + 320, 240, 32, 60, + /* Init_MISC */ + 0xEB, + { /* Init_SR0_SR4 */ + 0x03, 0x01, 0x0F, 0x03, 0x0E, + }, + { /* Init_SR10_SR24 */ + 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C, + 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC4, 0x32, 0x02, 0x01, 0x01, + }, + { /* Init_SR30_SR75 */ + 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A, + 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF, + 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, + 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A, + 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03, + 0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A, + 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, + 0x50, 0x03, 0x74, 0x14, 0x08, 0x43, 0x08, 0x43, + 0x04, 0x45, 0x30, 0x30, 0x40, 0x20, + }, + { /* Init_SR80_SR93 */ + 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A, + 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A, + 0x00, 0x00, 0x00, 0x00, + }, + { /* Init_SRA0_SRAF */ + 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED, + 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF, + }, + { /* Init_GR00_GR08 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, + 0xFF, + }, + { /* Init_AR00_AR14 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x41, 0x00, 0x0F, 0x00, 0x00, + }, + { /* Init_CR00_CR18 */ + 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3, + 0xFF, + }, + { /* Init_CR30_CR4D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20, + 0x00, 0x00, 0x30, 0x40, 0x00, 0xFF, 0xBF, 0xFF, + 0x2E, 0x27, 0x00, 0x2b, 0x0c, 0x0F, 0xEF, 0x00, + 0xFe, 0x0f, 0x01, 0xC0, 0x27, 0xEF, + }, + { /* Init_CR90_CRA7 */ + 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26, + 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03, + }, + }, +}; + +#define numVGAModes (sizeof(VGAMode) / sizeof(struct ModeInit)) -- cgit v0.10.2 From 29d249ed80c80b479df78e456e6809223c648505 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 18 Dec 2009 09:59:48 -0800 Subject: Staging: dst: remove from the tree DST is dead, no one is using it and upstream has abandoned it, so remove it from the tree because it is not going anywhere. Acked-by: Evgeniy Polyakov Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index db0de94..94eb863 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -87,8 +87,6 @@ source "drivers/staging/frontier/Kconfig" source "drivers/staging/dream/Kconfig" -source "drivers/staging/dst/Kconfig" - source "drivers/staging/pohmelfs/Kconfig" source "drivers/staging/b3dfg/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 73c6a711..b5e67b8 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -26,7 +26,6 @@ obj-$(CONFIG_RTL8192E) += rtl8192e/ obj-$(CONFIG_INPUT_MIMIO) += mimio/ obj-$(CONFIG_TRANZPORT) += frontier/ obj-$(CONFIG_DREAM) += dream/ -obj-$(CONFIG_DST) += dst/ obj-$(CONFIG_POHMELFS) += pohmelfs/ obj-$(CONFIG_B3DFG) += b3dfg/ obj-$(CONFIG_IDE_PHISON) += phison/ diff --git a/drivers/staging/dst/Kconfig b/drivers/staging/dst/Kconfig deleted file mode 100644 index 448d342..0000000 --- a/drivers/staging/dst/Kconfig +++ /dev/null @@ -1,67 +0,0 @@ -config DST - tristate "Distributed storage" - depends on NET && CRYPTO && SYSFS && BLK_DEV - select CONNECTOR - ---help--- - DST is a network block device storage, which can be used to organize - exported storage on the remote nodes into the local block device. - - DST works on top of any network media and protocol; it is just a matter - of configuration utility to understand the correct addresses. The most - common example is TCP over IP, which allows to pass through firewalls and - create remote backup storage in a different datacenter. DST requires - single port to be enabled on the exporting node and outgoing connections - on the local node. - - DST works with in-kernel client and server, which improves performance by - eliminating unneded data copies and by not depending on the version - of the external IO components. It requires userspace configuration utility - though. - - DST uses transaction model, when each store has to be explicitly acked - from the remote node to be considered as successfully written. There - may be lots of in-flight transactions. When remote host does not ack - the transaction it will be resent predefined number of times with specified - timeouts between them. All those parameters are configurable. Transactions - are marked as failed after all resends complete unsuccessfully; having - long enough resend timeout and/or large number of resends allows not to - return error to the higher (FS usually) layer in case of short network - problems or remote node outages. In case of network RAID setup this means - that storage will not degrade until transactions are marked as failed, and - thus will not force checksum recalculation and data rebuild. In case of - connection failure DST will try to reconnect to the remote node automatically. - DST sends ping commands at idle time to detect if remote node is alive. - - Because of transactional model it is possible to use zero-copy sending - without worry of data corruption (which in turn could be detected by the - strong checksums though). - - DST may fully encrypt the data channel in case of untrusted channel and implement - strong checksum of the transferred data. It is possible to configure algorithms - and crypto keys; they should match on both sides of the network channel. - Crypto processing does not introduce noticeble performance overhead, since DST - uses configurable pool of threads to perform crypto processing. - - DST utilizes memory pool model of all its transaction allocations (it is the - only additional allocation on the client) and server allocations (bio pools, - while pages are allocated from the slab). - - At startup DST performs a simple negotiation with the export node to determine - access permissions and size of the exported storage. It can be extended if - new parameters should be autonegotiated. - - DST carries block IO flags in the protocol, which allows to transparently implement - barriers and sync/flush operations. Those flags are used in the export node where - IO against the local storage is performed, which means that sync write will be sync - on the remote node too, which in turn improves data integrity and improved resistance - to errors and data corruption during power outages or storage damages. - - Homepage: http://www.ioremap.net/projects/dst - Userspace configuration utility and the latest releases: http://www.ioremap.net/archive/dst/ - -config DST_DEBUG - bool "DST debug" - depends on DST - ---help--- - This option will enable HEAVY debugging of the DST. - Turn it on ONLY if you have to debug some really obscure problem. diff --git a/drivers/staging/dst/Makefile b/drivers/staging/dst/Makefile deleted file mode 100644 index 3a8b0cf..0000000 --- a/drivers/staging/dst/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -obj-$(CONFIG_DST) += nst.o - -nst-y := dcore.o state.o export.o thread_pool.o crypto.o trans.o diff --git a/drivers/staging/dst/crypto.c b/drivers/staging/dst/crypto.c deleted file mode 100644 index 351295c..0000000 --- a/drivers/staging/dst/crypto.c +++ /dev/null @@ -1,733 +0,0 @@ -/* - * 2007+ Copyright (c) Evgeniy Polyakov - * All rights reserved. - * - * 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. - */ - -#include -#include -#include -#include -#include -#include - -/* - * Tricky bastard, but IV can be more complex with time... - */ -static inline u64 dst_gen_iv(struct dst_trans *t) -{ - return t->gen; -} - -/* - * Crypto machinery: hash/cipher support for the given crypto controls. - */ -static struct crypto_hash *dst_init_hash(struct dst_crypto_ctl *ctl, u8 *key) -{ - int err; - struct crypto_hash *hash; - - hash = crypto_alloc_hash(ctl->hash_algo, 0, CRYPTO_ALG_ASYNC); - if (IS_ERR(hash)) { - err = PTR_ERR(hash); - dprintk("%s: failed to allocate hash '%s', err: %d.\n", - __func__, ctl->hash_algo, err); - goto err_out_exit; - } - - ctl->crypto_attached_size = crypto_hash_digestsize(hash); - - if (!ctl->hash_keysize) - return hash; - - err = crypto_hash_setkey(hash, key, ctl->hash_keysize); - if (err) { - dprintk("%s: failed to set key for hash '%s', err: %d.\n", - __func__, ctl->hash_algo, err); - goto err_out_free; - } - - return hash; - -err_out_free: - crypto_free_hash(hash); -err_out_exit: - return ERR_PTR(err); -} - -static struct crypto_ablkcipher *dst_init_cipher(struct dst_crypto_ctl *ctl, - u8 *key) -{ - int err = -EINVAL; - struct crypto_ablkcipher *cipher; - - if (!ctl->cipher_keysize) - goto err_out_exit; - - cipher = crypto_alloc_ablkcipher(ctl->cipher_algo, 0, 0); - if (IS_ERR(cipher)) { - err = PTR_ERR(cipher); - dprintk("%s: failed to allocate cipher '%s', err: %d.\n", - __func__, ctl->cipher_algo, err); - goto err_out_exit; - } - - crypto_ablkcipher_clear_flags(cipher, ~0); - - err = crypto_ablkcipher_setkey(cipher, key, ctl->cipher_keysize); - if (err) { - dprintk("%s: failed to set key for cipher '%s', err: %d.\n", - __func__, ctl->cipher_algo, err); - goto err_out_free; - } - - return cipher; - -err_out_free: - crypto_free_ablkcipher(cipher); -err_out_exit: - return ERR_PTR(err); -} - -/* - * Crypto engine has a pool of pages to encrypt data into before sending - * it over the network. This pool is freed/allocated here. - */ -static void dst_crypto_pages_free(struct dst_crypto_engine *e) -{ - unsigned int i; - - for (i = 0; i < e->page_num; ++i) - __free_page(e->pages[i]); - kfree(e->pages); -} - -static int dst_crypto_pages_alloc(struct dst_crypto_engine *e, int num) -{ - int i; - - e->pages = kmalloc(num * sizeof(struct page **), GFP_KERNEL); - if (!e->pages) - return -ENOMEM; - - for (i = 0; i < num; ++i) { - e->pages[i] = alloc_page(GFP_KERNEL); - if (!e->pages[i]) - goto err_out_free_pages; - } - - e->page_num = num; - return 0; - -err_out_free_pages: - while (--i >= 0) - __free_page(e->pages[i]); - - kfree(e->pages); - return -ENOMEM; -} - -/* - * Initialize crypto engine for given node. - * Setup cipher/hash, keys, pool of threads and private data. - */ -static int dst_crypto_engine_init(struct dst_crypto_engine *e, - struct dst_node *n) -{ - int err; - struct dst_crypto_ctl *ctl = &n->crypto; - - err = dst_crypto_pages_alloc(e, n->max_pages); - if (err) - goto err_out_exit; - - e->size = PAGE_SIZE; - e->data = kmalloc(e->size, GFP_KERNEL); - if (!e->data) { - err = -ENOMEM; - goto err_out_free_pages; - } - - if (ctl->hash_algo[0]) { - e->hash = dst_init_hash(ctl, n->hash_key); - if (IS_ERR(e->hash)) { - err = PTR_ERR(e->hash); - e->hash = NULL; - goto err_out_free; - } - } - - if (ctl->cipher_algo[0]) { - e->cipher = dst_init_cipher(ctl, n->cipher_key); - if (IS_ERR(e->cipher)) { - err = PTR_ERR(e->cipher); - e->cipher = NULL; - goto err_out_free_hash; - } - } - - return 0; - -err_out_free_hash: - crypto_free_hash(e->hash); -err_out_free: - kfree(e->data); -err_out_free_pages: - dst_crypto_pages_free(e); -err_out_exit: - return err; -} - -static void dst_crypto_engine_exit(struct dst_crypto_engine *e) -{ - if (e->hash) - crypto_free_hash(e->hash); - if (e->cipher) - crypto_free_ablkcipher(e->cipher); - dst_crypto_pages_free(e); - kfree(e->data); -} - -/* - * Waiting for cipher processing to be completed. - */ -struct dst_crypto_completion { - struct completion complete; - int error; -}; - -static void dst_crypto_complete(struct crypto_async_request *req, int err) -{ - struct dst_crypto_completion *c = req->data; - - if (err == -EINPROGRESS) - return; - - dprintk("%s: req: %p, err: %d.\n", __func__, req, err); - c->error = err; - complete(&c->complete); -} - -static int dst_crypto_process(struct ablkcipher_request *req, - struct scatterlist *sg_dst, struct scatterlist *sg_src, - void *iv, int enc, unsigned long timeout) -{ - struct dst_crypto_completion c; - int err; - - init_completion(&c.complete); - c.error = -EINPROGRESS; - - ablkcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, - dst_crypto_complete, &c); - - ablkcipher_request_set_crypt(req, sg_src, sg_dst, sg_src->length, iv); - - if (enc) - err = crypto_ablkcipher_encrypt(req); - else - err = crypto_ablkcipher_decrypt(req); - - switch (err) { - case -EINPROGRESS: - case -EBUSY: - err = wait_for_completion_interruptible_timeout(&c.complete, - timeout); - if (!err) - err = -ETIMEDOUT; - else - err = c.error; - break; - default: - break; - } - - return err; -} - -/* - * DST uses generic iteration approach for data crypto processing. - * Single block IO request is switched into array of scatterlists, - * which are submitted to the crypto processing iterator. - * - * Input and output iterator initialization are different, since - * in output case we can not encrypt data in-place and need a - * temporary storage, which is then being sent to the remote peer. - */ -static int dst_trans_iter_out(struct bio *bio, struct dst_crypto_engine *e, - int (*iterator) (struct dst_crypto_engine *e, - struct scatterlist *dst, - struct scatterlist *src)) -{ - struct bio_vec *bv; - int err, i; - - sg_init_table(e->src, bio->bi_vcnt); - sg_init_table(e->dst, bio->bi_vcnt); - - bio_for_each_segment(bv, bio, i) { - sg_set_page(&e->src[i], bv->bv_page, bv->bv_len, bv->bv_offset); - sg_set_page(&e->dst[i], e->pages[i], bv->bv_len, bv->bv_offset); - - err = iterator(e, &e->dst[i], &e->src[i]); - if (err) - return err; - } - - return 0; -} - -static int dst_trans_iter_in(struct bio *bio, struct dst_crypto_engine *e, - int (*iterator) (struct dst_crypto_engine *e, - struct scatterlist *dst, - struct scatterlist *src)) -{ - struct bio_vec *bv; - int err, i; - - sg_init_table(e->src, bio->bi_vcnt); - sg_init_table(e->dst, bio->bi_vcnt); - - bio_for_each_segment(bv, bio, i) { - sg_set_page(&e->src[i], bv->bv_page, bv->bv_len, bv->bv_offset); - sg_set_page(&e->dst[i], bv->bv_page, bv->bv_len, bv->bv_offset); - - err = iterator(e, &e->dst[i], &e->src[i]); - if (err) - return err; - } - - return 0; -} - -static int dst_crypt_iterator(struct dst_crypto_engine *e, - struct scatterlist *sg_dst, struct scatterlist *sg_src) -{ - struct ablkcipher_request *req = e->data; - u8 iv[32]; - - memset(iv, 0, sizeof(iv)); - - memcpy(iv, &e->iv, sizeof(e->iv)); - - return dst_crypto_process(req, sg_dst, sg_src, iv, e->enc, e->timeout); -} - -static int dst_crypt(struct dst_crypto_engine *e, struct bio *bio) -{ - struct ablkcipher_request *req = e->data; - - memset(req, 0, sizeof(struct ablkcipher_request)); - ablkcipher_request_set_tfm(req, e->cipher); - - if (e->enc) - return dst_trans_iter_out(bio, e, dst_crypt_iterator); - else - return dst_trans_iter_in(bio, e, dst_crypt_iterator); -} - -static int dst_hash_iterator(struct dst_crypto_engine *e, - struct scatterlist *sg_dst, struct scatterlist *sg_src) -{ - return crypto_hash_update(e->data, sg_src, sg_src->length); -} - -static int dst_hash(struct dst_crypto_engine *e, struct bio *bio, void *dst) -{ - struct hash_desc *desc = e->data; - int err; - - desc->tfm = e->hash; - desc->flags = 0; - - err = crypto_hash_init(desc); - if (err) - return err; - - err = dst_trans_iter_in(bio, e, dst_hash_iterator); - if (err) - return err; - - err = crypto_hash_final(desc, dst); - if (err) - return err; - - return 0; -} - -/* - * Initialize/cleanup a crypto thread. The only thing it should - * do is to allocate a pool of pages as temporary storage. - * And to setup cipher and/or hash. - */ -static void *dst_crypto_thread_init(void *data) -{ - struct dst_node *n = data; - struct dst_crypto_engine *e; - int err = -ENOMEM; - - e = kzalloc(sizeof(struct dst_crypto_engine), GFP_KERNEL); - if (!e) - goto err_out_exit; - e->src = kcalloc(2 * n->max_pages, sizeof(struct scatterlist), - GFP_KERNEL); - if (!e->src) - goto err_out_free; - - e->dst = e->src + n->max_pages; - - err = dst_crypto_engine_init(e, n); - if (err) - goto err_out_free_all; - - return e; - -err_out_free_all: - kfree(e->src); -err_out_free: - kfree(e); -err_out_exit: - return ERR_PTR(err); -} - -static void dst_crypto_thread_cleanup(void *private) -{ - struct dst_crypto_engine *e = private; - - dst_crypto_engine_exit(e); - kfree(e->src); - kfree(e); -} - -/* - * Initialize crypto engine for given node: store keys, create pool - * of threads, initialize each one. - * - * Each thread has unique ID, but 0 and 1 are reserved for receiving and - * accepting threads (if export node), so IDs could start from 2, but starting - * them from 10 allows easily understand what this thread is for. - */ -int dst_node_crypto_init(struct dst_node *n, struct dst_crypto_ctl *ctl) -{ - void *key = (ctl + 1); - int err = -ENOMEM, i; - char name[32]; - - if (ctl->hash_keysize) { - n->hash_key = kmalloc(ctl->hash_keysize, GFP_KERNEL); - if (!n->hash_key) - goto err_out_exit; - memcpy(n->hash_key, key, ctl->hash_keysize); - } - - if (ctl->cipher_keysize) { - n->cipher_key = kmalloc(ctl->cipher_keysize, GFP_KERNEL); - if (!n->cipher_key) - goto err_out_free_hash; - memcpy(n->cipher_key, key, ctl->cipher_keysize); - } - memcpy(&n->crypto, ctl, sizeof(struct dst_crypto_ctl)); - - for (i = 0; i < ctl->thread_num; ++i) { - snprintf(name, sizeof(name), "%s-crypto-%d", n->name, i); - /* Unique ids... */ - err = thread_pool_add_worker(n->pool, name, i + 10, - dst_crypto_thread_init, dst_crypto_thread_cleanup, n); - if (err) - goto err_out_free_threads; - } - - return 0; - -err_out_free_threads: - while (--i >= 0) - thread_pool_del_worker_id(n->pool, i+10); - - if (ctl->cipher_keysize) - kfree(n->cipher_key); - ctl->cipher_keysize = 0; -err_out_free_hash: - if (ctl->hash_keysize) - kfree(n->hash_key); - ctl->hash_keysize = 0; -err_out_exit: - return err; -} - -void dst_node_crypto_exit(struct dst_node *n) -{ - struct dst_crypto_ctl *ctl = &n->crypto; - - if (ctl->cipher_algo[0] || ctl->hash_algo[0]) { - kfree(n->hash_key); - kfree(n->cipher_key); - } -} - -/* - * Thrad pool setup callback. Just stores a transaction in private data. - */ -static int dst_trans_crypto_setup(void *crypto_engine, void *trans) -{ - struct dst_crypto_engine *e = crypto_engine; - - e->private = trans; - return 0; -} - -#if 0 -static void dst_dump_bio(struct bio *bio) -{ - u8 *p; - struct bio_vec *bv; - int i; - - bio_for_each_segment(bv, bio, i) { - dprintk("%s: %llu/%u: size: %u, offset: %u, data: ", - __func__, bio->bi_sector, bio->bi_size, - bv->bv_len, bv->bv_offset); - - p = kmap(bv->bv_page) + bv->bv_offset; - for (i = 0; i < bv->bv_len; ++i) - printk(KERN_DEBUG "%02x ", p[i]); - kunmap(bv->bv_page); - printk("\n"); - } -} -#endif - -/* - * Encrypt/hash data and send it to the network. - */ -static int dst_crypto_process_sending(struct dst_crypto_engine *e, - struct bio *bio, u8 *hash) -{ - int err; - - if (e->cipher) { - err = dst_crypt(e, bio); - if (err) - goto err_out_exit; - } - - if (e->hash) { - err = dst_hash(e, bio, hash); - if (err) - goto err_out_exit; - -#ifdef CONFIG_DST_DEBUG - { - unsigned int i; - - /* dst_dump_bio(bio); */ - - printk(KERN_DEBUG "%s: bio: %llu/%u, rw: %lu, hash: ", - __func__, (u64)bio->bi_sector, - bio->bi_size, bio_data_dir(bio)); - for (i = 0; i < crypto_hash_digestsize(e->hash); ++i) - printk("%02x ", hash[i]); - printk("\n"); - } -#endif - } - - return 0; - -err_out_exit: - return err; -} - -/* - * Check if received data is valid. Decipher if it is. - */ -static int dst_crypto_process_receiving(struct dst_crypto_engine *e, - struct bio *bio, u8 *hash, u8 *recv_hash) -{ - int err; - - if (e->hash) { - int mismatch; - - err = dst_hash(e, bio, hash); - if (err) - goto err_out_exit; - - mismatch = !!memcmp(recv_hash, hash, - crypto_hash_digestsize(e->hash)); -#ifdef CONFIG_DST_DEBUG - /* dst_dump_bio(bio); */ - - printk(KERN_DEBUG "%s: bio: %llu/%u, rw: %lu, hash mismatch: %d", - __func__, (u64)bio->bi_sector, bio->bi_size, - bio_data_dir(bio), mismatch); - if (mismatch) { - unsigned int i; - - printk(", recv/calc: "); - for (i = 0; i < crypto_hash_digestsize(e->hash); ++i) - printk("%02x/%02x ", recv_hash[i], hash[i]); - - } - printk("\n"); -#endif - err = -1; - if (mismatch) - goto err_out_exit; - } - - if (e->cipher) { - err = dst_crypt(e, bio); - if (err) - goto err_out_exit; - } - - return 0; - -err_out_exit: - return err; -} - -/* - * Thread pool callback to encrypt data and send it to the netowork. - */ -static int dst_trans_crypto_action(void *crypto_engine, void *schedule_data) -{ - struct dst_crypto_engine *e = crypto_engine; - struct dst_trans *t = schedule_data; - struct bio *bio = t->bio; - int err; - - dprintk("%s: t: %p, gen: %llu, cipher: %p, hash: %p.\n", - __func__, t, t->gen, e->cipher, e->hash); - - e->enc = t->enc; - e->iv = dst_gen_iv(t); - - if (bio_data_dir(bio) == WRITE) { - err = dst_crypto_process_sending(e, bio, t->cmd.hash); - if (err) - goto err_out_exit; - - if (e->hash) { - t->cmd.csize = crypto_hash_digestsize(e->hash); - t->cmd.size += t->cmd.csize; - } - - return dst_trans_send(t); - } else { - u8 *hash = e->data + e->size/2; - - err = dst_crypto_process_receiving(e, bio, hash, t->cmd.hash); - if (err) - goto err_out_exit; - - dst_trans_remove(t); - dst_trans_put(t); - } - - return 0; - -err_out_exit: - t->error = err; - dst_trans_put(t); - return err; -} - -/* - * Schedule crypto processing for given transaction. - */ -int dst_trans_crypto(struct dst_trans *t) -{ - struct dst_node *n = t->n; - int err; - - err = thread_pool_schedule(n->pool, - dst_trans_crypto_setup, dst_trans_crypto_action, - t, MAX_SCHEDULE_TIMEOUT); - if (err) - goto err_out_exit; - - return 0; - -err_out_exit: - dst_trans_put(t); - return err; -} - -/* - * Crypto machinery for the export node. - */ -static int dst_export_crypto_setup(void *crypto_engine, void *bio) -{ - struct dst_crypto_engine *e = crypto_engine; - - e->private = bio; - return 0; -} - -static int dst_export_crypto_action(void *crypto_engine, void *schedule_data) -{ - struct dst_crypto_engine *e = crypto_engine; - struct bio *bio = schedule_data; - struct dst_export_priv *p = bio->bi_private; - int err; - - dprintk("%s: e: %p, data: %p, bio: %llu/%u, dir: %lu.\n", - __func__, e, e->data, (u64)bio->bi_sector, - bio->bi_size, bio_data_dir(bio)); - - e->enc = (bio_data_dir(bio) == READ); - e->iv = p->cmd.id; - - if (bio_data_dir(bio) == WRITE) { - u8 *hash = e->data + e->size/2; - - err = dst_crypto_process_receiving(e, bio, hash, p->cmd.hash); - if (err) - goto err_out_exit; - - generic_make_request(bio); - } else { - err = dst_crypto_process_sending(e, bio, p->cmd.hash); - if (err) - goto err_out_exit; - - if (e->hash) { - p->cmd.csize = crypto_hash_digestsize(e->hash); - p->cmd.size += p->cmd.csize; - } - - err = dst_export_send_bio(bio); - } - return 0; - -err_out_exit: - bio_put(bio); - return err; -} - -int dst_export_crypto(struct dst_node *n, struct bio *bio) -{ - int err; - - err = thread_pool_schedule(n->pool, - dst_export_crypto_setup, dst_export_crypto_action, - bio, MAX_SCHEDULE_TIMEOUT); - if (err) - goto err_out_exit; - - return 0; - -err_out_exit: - bio_put(bio); - return err; -} diff --git a/drivers/staging/dst/dcore.c b/drivers/staging/dst/dcore.c deleted file mode 100644 index c83ca7e..0000000 --- a/drivers/staging/dst/dcore.c +++ /dev/null @@ -1,968 +0,0 @@ -/* - * 2007+ Copyright (c) Evgeniy Polyakov - * All rights reserved. - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -static int dst_major; - -static DEFINE_MUTEX(dst_hash_lock); -static struct list_head *dst_hashtable; -static unsigned int dst_hashtable_size = 128; -module_param(dst_hashtable_size, uint, 0644); - -static char dst_name[] = "Dementianting goldfish"; - -static DEFINE_IDR(dst_index_idr); -static struct cb_id cn_dst_id = { CN_DST_IDX, CN_DST_VAL }; - -/* - * DST sysfs tree for device called 'storage': - * - * /sys/bus/dst/devices/storage/ - * /sys/bus/dst/devices/storage/type : 192.168.4.80:1025 - * /sys/bus/dst/devices/storage/size : 800 - * /sys/bus/dst/devices/storage/name : storage - */ - -static int dst_dev_match(struct device *dev, struct device_driver *drv) -{ - return 1; -} - -static struct bus_type dst_dev_bus_type = { - .name = "dst", - .match = &dst_dev_match, -}; - -static void dst_node_release(struct device *dev) -{ - struct dst_info *info = container_of(dev, struct dst_info, device); - - kfree(info); -} - -static struct device dst_node_dev = { - .bus = &dst_dev_bus_type, - .release = &dst_node_release -}; - -/* - * Setting size of the node after it was changed. - */ -static void dst_node_set_size(struct dst_node *n) -{ - struct block_device *bdev; - - set_capacity(n->disk, n->size >> 9); - - bdev = bdget_disk(n->disk, 0); - if (bdev) { - mutex_lock(&bdev->bd_inode->i_mutex); - i_size_write(bdev->bd_inode, n->size); - mutex_unlock(&bdev->bd_inode->i_mutex); - bdput(bdev); - } -} - -/* - * Distributed storage request processing function. - */ -static int dst_request(struct request_queue *q, struct bio *bio) -{ - struct dst_node *n = q->queuedata; - int err = -EIO; - - if (bio_empty_barrier(bio) && !blk_queue_discard(q)) { - /* - * This is a dirty^Wnice hack, but if we complete this - * operation with -EOPNOTSUPP like intended, XFS - * will stuck and freeze the machine. This may be - * not particulary XFS problem though, but it is the - * only FS which sends empty barrier at umount time - * I worked with. - * - * Empty barriers are not allowed anyway, see 51fd77bd9f512 - * for example, although later it was changed to - * bio_rw_flagged(bio, BIO_RW_DISCARD) only, which does not - * work in this case. - */ - /* err = -EOPNOTSUPP; */ - err = 0; - goto end_io; - } - - bio_get(bio); - - return dst_process_bio(n, bio); - -end_io: - bio_endio(bio, err); - return err; -} - -/* - * Open/close callbacks for appropriate block device. - */ -static int dst_bdev_open(struct block_device *bdev, fmode_t mode) -{ - struct dst_node *n = bdev->bd_disk->private_data; - - dst_node_get(n); - return 0; -} - -static int dst_bdev_release(struct gendisk *disk, fmode_t mode) -{ - struct dst_node *n = disk->private_data; - - dst_node_put(n); - return 0; -} - -static struct block_device_operations dst_blk_ops = { - .open = dst_bdev_open, - .release = dst_bdev_release, - .owner = THIS_MODULE, -}; - -/* - * Block layer binding - disk is created when array is fully configured - * by userspace request. - */ -static int dst_node_create_disk(struct dst_node *n) -{ - int err = -ENOMEM; - u32 index = 0; - - n->queue = blk_init_queue(NULL, NULL); - if (!n->queue) - goto err_out_exit; - - n->queue->queuedata = n; - blk_queue_make_request(n->queue, dst_request); - blk_queue_max_phys_segments(n->queue, n->max_pages); - blk_queue_max_hw_segments(n->queue, n->max_pages); - - err = -ENOMEM; - n->disk = alloc_disk(1); - if (!n->disk) - goto err_out_free_queue; - - if (!(n->state->permissions & DST_PERM_WRITE)) { - printk(KERN_INFO "DST node %s attached read-only.\n", n->name); - set_disk_ro(n->disk, 1); - } - - if (!idr_pre_get(&dst_index_idr, GFP_KERNEL)) - goto err_out_put; - - mutex_lock(&dst_hash_lock); - err = idr_get_new(&dst_index_idr, NULL, &index); - mutex_unlock(&dst_hash_lock); - if (err) - goto err_out_put; - - n->disk->major = dst_major; - n->disk->first_minor = index; - n->disk->fops = &dst_blk_ops; - n->disk->queue = n->queue; - n->disk->private_data = n; - snprintf(n->disk->disk_name, sizeof(n->disk->disk_name), - "dst-%s", n->name); - - return 0; - -err_out_put: - put_disk(n->disk); -err_out_free_queue: - blk_cleanup_queue(n->queue); -err_out_exit: - return err; -} - -/* - * Sysfs machinery: show device's size. - */ -static ssize_t dst_show_size(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct dst_info *info = container_of(dev, struct dst_info, device); - - return sprintf(buf, "%llu\n", info->size); -} - -/* - * Show local exported device. - */ -static ssize_t dst_show_local(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct dst_info *info = container_of(dev, struct dst_info, device); - - return sprintf(buf, "%s\n", info->local); -} - -/* - * Shows type of the remote node - device major/minor number - * for local nodes and address (af_inet ipv4/ipv6 only) for remote nodes. - */ -static ssize_t dst_show_type(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct dst_info *info = container_of(dev, struct dst_info, device); - int family = info->net.addr.sa_family; - - if (family == AF_INET) { - struct sockaddr_in *sin = (struct sockaddr_in *)&info->net.addr; - return sprintf(buf, "%u.%u.%u.%u:%d\n", - NIPQUAD(sin->sin_addr.s_addr), ntohs(sin->sin_port)); - } else if (family == AF_INET6) { - struct sockaddr_in6 *sin = (struct sockaddr_in6 *) - &info->net.addr; - return sprintf(buf, - "%pi6:%d\n", - &sin->sin6_addr, ntohs(sin->sin6_port)); - } else { - int i, sz = PAGE_SIZE - 2; /* 0 symbol and '\n' below */ - int size, addrlen = info->net.addr.sa_data_len; - unsigned char *a = (unsigned char *)&info->net.addr.sa_data; - char *buf_orig = buf; - - size = snprintf(buf, sz, "family: %d, addrlen: %u, addr: ", - family, addrlen); - sz -= size; - buf += size; - - for (i = 0; i < addrlen; ++i) { - if (sz < 3) - break; - - size = snprintf(buf, sz, "%02x ", a[i]); - sz -= size; - buf += size; - } - buf += sprintf(buf, "\n"); - - return buf - buf_orig; - } - return 0; -} - -static struct device_attribute dst_node_attrs[] = { - __ATTR(size, 0444, dst_show_size, NULL), - __ATTR(type, 0444, dst_show_type, NULL), - __ATTR(local, 0444, dst_show_local, NULL), -}; - -static int dst_create_node_attributes(struct dst_node *n) -{ - int err, i; - - for (i = 0; i < ARRAY_SIZE(dst_node_attrs); ++i) { - err = device_create_file(&n->info->device, - &dst_node_attrs[i]); - if (err) - goto err_out_remove_all; - } - return 0; - -err_out_remove_all: - while (--i >= 0) - device_remove_file(&n->info->device, - &dst_node_attrs[i]); - - return err; -} - -static void dst_remove_node_attributes(struct dst_node *n) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(dst_node_attrs); ++i) - device_remove_file(&n->info->device, - &dst_node_attrs[i]); -} - -/* - * Sysfs cleanup and initialization. - * Shows number of useful parameters. - */ -static void dst_node_sysfs_exit(struct dst_node *n) -{ - if (n->info) { - dst_remove_node_attributes(n); - device_unregister(&n->info->device); - n->info = NULL; - } -} - -static int dst_node_sysfs_init(struct dst_node *n) -{ - int err; - - n->info = kzalloc(sizeof(struct dst_info), GFP_KERNEL); - if (!n->info) - return -ENOMEM; - - memcpy(&n->info->device, &dst_node_dev, sizeof(struct device)); - n->info->size = n->size; - - dev_set_name(&n->info->device, "dst-%s", n->name); - err = device_register(&n->info->device); - if (err) { - dprintk(KERN_ERR "Failed to register node '%s', err: %d.\n", - n->name, err); - goto err_out_exit; - } - - dst_create_node_attributes(n); - - return 0; - -err_out_exit: - kfree(n->info); - n->info = NULL; - return err; -} - -/* - * DST node hash tables machinery. - */ -static inline unsigned int dst_hash(char *str, unsigned int size) -{ - return jhash(str, size, 0) % dst_hashtable_size; -} - -static void dst_node_remove(struct dst_node *n) -{ - mutex_lock(&dst_hash_lock); - list_del_init(&n->node_entry); - mutex_unlock(&dst_hash_lock); -} - -static void dst_node_add(struct dst_node *n) -{ - unsigned hash = dst_hash(n->name, sizeof(n->name)); - - mutex_lock(&dst_hash_lock); - list_add_tail(&n->node_entry, &dst_hashtable[hash]); - mutex_unlock(&dst_hash_lock); -} - -/* - * Cleaning node when it is about to be freed. - * There are still users of the socket though, - * so connection cleanup should be protected. - */ -static void dst_node_cleanup(struct dst_node *n) -{ - struct dst_state *st = n->state; - - if (!st) - return; - - if (n->queue) { - blk_cleanup_queue(n->queue); - - mutex_lock(&dst_hash_lock); - idr_remove(&dst_index_idr, n->disk->first_minor); - mutex_unlock(&dst_hash_lock); - - put_disk(n->disk); - } - - if (n->bdev) { - sync_blockdev(n->bdev); - close_bdev_exclusive(n->bdev, FMODE_READ|FMODE_WRITE); - } - - dst_state_lock(st); - st->need_exit = 1; - dst_state_exit_connected(st); - dst_state_unlock(st); - - wake_up(&st->thread_wait); - - dst_state_put(st); - n->state = NULL; -} - -/* - * Free security attributes attached to given node. - */ -static void dst_security_exit(struct dst_node *n) -{ - struct dst_secure *s, *tmp; - - list_for_each_entry_safe(s, tmp, &n->security_list, sec_entry) { - list_del(&s->sec_entry); - kfree(s); - } -} - -/* - * Free node when there are no more users. - * Actually node has to be freed on behalf od userspace process, - * since there are number of threads, which are embedded in the - * node, so they can not exit and free node from there, that is - * why there is a wakeup if reference counter is not equal to zero. - */ -void dst_node_put(struct dst_node *n) -{ - if (unlikely(!n)) - return; - - dprintk("%s: n: %p, refcnt: %d.\n", - __func__, n, atomic_read(&n->refcnt)); - - if (atomic_dec_and_test(&n->refcnt)) { - dst_node_remove(n); - n->trans_scan_timeout = 0; - dst_node_cleanup(n); - thread_pool_destroy(n->pool); - dst_node_sysfs_exit(n); - dst_node_crypto_exit(n); - dst_security_exit(n); - dst_node_trans_exit(n); - - kfree(n); - - dprintk("%s: freed n: %p.\n", __func__, n); - } else { - wake_up(&n->wait); - } -} - -/* - * Setting up export device: lookup by the name, get its size - * and setup listening socket, which will accept clients, which - * will submit IO for given storage. - */ -static int dst_setup_export(struct dst_node *n, struct dst_ctl *ctl, - struct dst_export_ctl *le) -{ - int err; - - snprintf(n->info->local, sizeof(n->info->local), "%s", le->device); - - n->bdev = open_bdev_exclusive(le->device, FMODE_READ|FMODE_WRITE, NULL); - if (IS_ERR(n->bdev)) - return PTR_ERR(n->bdev); - - if (n->size != 0) - n->size = min_t(loff_t, n->bdev->bd_inode->i_size, n->size); - else - n->size = n->bdev->bd_inode->i_size; - - n->info->size = n->size; - err = dst_node_init_listened(n, le); - if (err) - goto err_out_cleanup; - - return 0; - -err_out_cleanup: - close_bdev_exclusive(n->bdev, FMODE_READ|FMODE_WRITE); - n->bdev = NULL; - - return err; -} - -/* Empty thread pool callbacks for the network processing threads. */ -static inline void *dst_thread_network_init(void *data) -{ - dprintk("%s: data: %p.\n", __func__, data); - return data; -} - -static inline void dst_thread_network_cleanup(void *data) -{ - dprintk("%s: data: %p.\n", __func__, data); -} - -/* - * Allocate DST node and initialize some of its parameters. - */ -static struct dst_node *dst_alloc_node(struct dst_ctl *ctl, - int (*start)(struct dst_node *), - int num) -{ - struct dst_node *n; - int err; - - n = kzalloc(sizeof(struct dst_node), GFP_KERNEL); - if (!n) - return NULL; - - INIT_LIST_HEAD(&n->node_entry); - - INIT_LIST_HEAD(&n->security_list); - mutex_init(&n->security_lock); - - init_waitqueue_head(&n->wait); - - n->trans_scan_timeout = msecs_to_jiffies(ctl->trans_scan_timeout); - if (!n->trans_scan_timeout) - n->trans_scan_timeout = HZ; - - n->trans_max_retries = ctl->trans_max_retries; - if (!n->trans_max_retries) - n->trans_max_retries = 10; - - /* - * Pretty much arbitrary default numbers. - * 32 matches maximum number of pages in bio originated from ext3 (31). - */ - n->max_pages = ctl->max_pages; - if (!n->max_pages) - n->max_pages = 32; - - if (n->max_pages > 1024) - n->max_pages = 1024; - - n->start = start; - n->size = ctl->size; - - atomic_set(&n->refcnt, 1); - atomic_long_set(&n->gen, 0); - snprintf(n->name, sizeof(n->name), "%s", ctl->name); - - err = dst_node_sysfs_init(n); - if (err) - goto err_out_free; - - n->pool = thread_pool_create(num, n->name, dst_thread_network_init, - dst_thread_network_cleanup, n); - if (IS_ERR(n->pool)) { - err = PTR_ERR(n->pool); - goto err_out_sysfs_exit; - } - - dprintk("%s: n: %p, name: %s.\n", __func__, n, n->name); - - return n; - -err_out_sysfs_exit: - dst_node_sysfs_exit(n); -err_out_free: - kfree(n); - return NULL; -} - -/* - * Starting a node, connected to the remote server: - * register block device and initialize transaction mechanism. - * In revers order though. - * - * It will autonegotiate some parameters with the remote node - * and update local if needed. - * - * Transaction initialization should be the last thing before - * starting the node, since transaction should include not only - * block IO, but also crypto related data (if any), which are - * initialized separately. - */ -static int dst_start_remote(struct dst_node *n) -{ - int err; - - err = dst_node_trans_init(n, sizeof(struct dst_trans)); - if (err) - return err; - - err = dst_node_create_disk(n); - if (err) - return err; - - dst_node_set_size(n); - add_disk(n->disk); - - dprintk("DST: started remote node '%s', minor: %d.\n", - n->name, n->disk->first_minor); - - return 0; -} - -/* - * Adding remote node and initialize connection. - */ -static int dst_add_remote(struct dst_node *n, struct dst_ctl *ctl, - void *data, unsigned int size) -{ - int err; - struct dst_network_ctl *rctl = data; - - if (n) - return -EEXIST; - - if (size != sizeof(struct dst_network_ctl)) - return -EINVAL; - - n = dst_alloc_node(ctl, dst_start_remote, 1); - if (!n) - return -ENOMEM; - - memcpy(&n->info->net, rctl, sizeof(struct dst_network_ctl)); - err = dst_node_init_connected(n, rctl); - if (err) - goto err_out_free; - - dst_node_add(n); - - return 0; - -err_out_free: - dst_node_put(n); - return err; -} - -/* - * Adding export node: initializing block device and listening socket. - */ -static int dst_add_export(struct dst_node *n, struct dst_ctl *ctl, - void *data, unsigned int size) -{ - int err; - struct dst_export_ctl *le = data; - - if (n) - return -EEXIST; - - if (size != sizeof(struct dst_export_ctl)) - return -EINVAL; - - n = dst_alloc_node(ctl, dst_start_export, 2); - if (!n) - return -EINVAL; - - err = dst_setup_export(n, ctl, le); - if (err) - goto err_out_free; - - dst_node_add(n); - - return 0; - -err_out_free: - dst_node_put(n); - return err; -} - -static int dst_node_remove_unload(struct dst_node *n) -{ - printk(KERN_INFO "STOPPED name: '%s', size: %llu.\n", - n->name, n->size); - - if (n->disk) - del_gendisk(n->disk); - - dst_node_remove(n); - dst_node_sysfs_exit(n); - - /* - * This is not a hack. Really. - * Node's reference counter allows to implement fine grained - * node freeing, but since all transactions (which hold node's - * reference counter) are processed in the dedicated thread, - * it is possible that reference will hit zero in that thread, - * so we will not be able to exit thread and cleanup the node. - * - * So, we remove disk, so no new activity is possible, and - * wait until all pending transaction are completed (either - * in receiving thread or by timeout in workqueue), in this - * case reference counter will be less or equal to 2 (once set in - * dst_alloc_node() and then in connector message parser; - * or when we force module unloading, and connector message - * parser does not hold a reference, in this case reference - * counter will be equal to 1), - * and subsequent dst_node_put() calls will free the node. - */ - dprintk("%s: going to sleep with %d refcnt.\n", - __func__, atomic_read(&n->refcnt)); - wait_event(n->wait, atomic_read(&n->refcnt) <= 2); - - dst_node_put(n); - return 0; -} - -/* - * Remove node from the hash table. - */ -static int dst_del_node(struct dst_node *n, struct dst_ctl *ctl, - void *data, unsigned int size) -{ - if (!n) - return -ENODEV; - - return dst_node_remove_unload(n); -} - -/* - * Initialize crypto processing for given node. - */ -static int dst_crypto_init(struct dst_node *n, struct dst_ctl *ctl, - void *data, unsigned int size) -{ - struct dst_crypto_ctl *crypto = data; - - if (!n) - return -ENODEV; - - if (size != sizeof(struct dst_crypto_ctl) + crypto->hash_keysize + - crypto->cipher_keysize) - return -EINVAL; - - if (n->trans_cache) - return -EEXIST; - - return dst_node_crypto_init(n, crypto); -} - -/* - * Security attributes for given node. - */ -static int dst_security_init(struct dst_node *n, struct dst_ctl *ctl, - void *data, unsigned int size) -{ - struct dst_secure *s; - - if (!n) - return -ENODEV; - - if (size != sizeof(struct dst_secure_user)) - return -EINVAL; - - s = kmalloc(sizeof(struct dst_secure), GFP_KERNEL); - if (!s) - return -ENOMEM; - - memcpy(&s->sec, data, size); - - mutex_lock(&n->security_lock); - list_add_tail(&s->sec_entry, &n->security_list); - mutex_unlock(&n->security_lock); - - return 0; -} - -/* - * Kill'em all! - */ -static int dst_start_node(struct dst_node *n, struct dst_ctl *ctl, - void *data, unsigned int size) -{ - int err; - - if (!n) - return -ENODEV; - - if (n->trans_cache) - return 0; - - err = n->start(n); - if (err) - return err; - - printk(KERN_INFO "STARTED name: '%s', size: %llu.\n", n->name, n->size); - return 0; -} - -typedef int (*dst_command_func)(struct dst_node *n, struct dst_ctl *ctl, - void *data, unsigned int size); - -/* - * List of userspace commands. - */ -static dst_command_func dst_commands[] = { - [DST_ADD_REMOTE] = &dst_add_remote, - [DST_ADD_EXPORT] = &dst_add_export, - [DST_DEL_NODE] = &dst_del_node, - [DST_CRYPTO] = &dst_crypto_init, - [DST_SECURITY] = &dst_security_init, - [DST_START] = &dst_start_node, -}; - -/* - * Configuration parser. - */ -static void cn_dst_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp) -{ - struct dst_ctl *ctl; - int err; - struct dst_ctl_ack ack; - struct dst_node *n = NULL, *tmp; - unsigned int hash; - - if (!cap_raised(nsp->eff_cap, CAP_SYS_ADMIN)) { - err = -EPERM; - goto out; - } - - if (msg->len < sizeof(struct dst_ctl)) { - err = -EBADMSG; - goto out; - } - - ctl = (struct dst_ctl *)msg->data; - - if (ctl->cmd >= DST_CMD_MAX) { - err = -EINVAL; - goto out; - } - hash = dst_hash(ctl->name, sizeof(ctl->name)); - - mutex_lock(&dst_hash_lock); - list_for_each_entry(tmp, &dst_hashtable[hash], node_entry) { - if (!memcmp(tmp->name, ctl->name, sizeof(tmp->name))) { - n = tmp; - dst_node_get(n); - break; - } - } - mutex_unlock(&dst_hash_lock); - - err = dst_commands[ctl->cmd](n, ctl, msg->data + sizeof(struct dst_ctl), - msg->len - sizeof(struct dst_ctl)); - - dst_node_put(n); -out: - memcpy(&ack.msg, msg, sizeof(struct cn_msg)); - - ack.msg.ack = msg->ack + 1; - ack.msg.len = sizeof(struct dst_ctl_ack) - sizeof(struct cn_msg); - - ack.error = err; - - cn_netlink_send(&ack.msg, 0, GFP_KERNEL); -} - -/* - * Global initialization: sysfs, hash table, block device registration, - * connector and various caches. - */ -static int __init dst_sysfs_init(void) -{ - return bus_register(&dst_dev_bus_type); -} - -static void dst_sysfs_exit(void) -{ - bus_unregister(&dst_dev_bus_type); -} - -static int __init dst_hashtable_init(void) -{ - unsigned int i; - - dst_hashtable = kcalloc(dst_hashtable_size, sizeof(struct list_head), - GFP_KERNEL); - if (!dst_hashtable) - return -ENOMEM; - - for (i = 0; i < dst_hashtable_size; ++i) - INIT_LIST_HEAD(&dst_hashtable[i]); - - return 0; -} - -static void dst_hashtable_exit(void) -{ - unsigned int i; - struct dst_node *n, *tmp; - - for (i = 0; i < dst_hashtable_size; ++i) { - list_for_each_entry_safe(n, tmp, &dst_hashtable[i], node_entry) { - dst_node_remove_unload(n); - } - } - - kfree(dst_hashtable); -} - -static int __init dst_sys_init(void) -{ - int err = -ENOMEM; - - err = dst_hashtable_init(); - if (err) - goto err_out_exit; - - err = dst_export_init(); - if (err) - goto err_out_hashtable_exit; - - err = register_blkdev(dst_major, DST_NAME); - if (err < 0) - goto err_out_export_exit; - if (err) - dst_major = err; - - err = dst_sysfs_init(); - if (err) - goto err_out_unregister; - - err = cn_add_callback(&cn_dst_id, "DST", cn_dst_callback); - if (err) - goto err_out_sysfs_exit; - - printk(KERN_INFO "Distributed storage, '%s' release.\n", dst_name); - - return 0; - -err_out_sysfs_exit: - dst_sysfs_exit(); -err_out_unregister: - unregister_blkdev(dst_major, DST_NAME); -err_out_export_exit: - dst_export_exit(); -err_out_hashtable_exit: - dst_hashtable_exit(); -err_out_exit: - return err; -} - -static void __exit dst_sys_exit(void) -{ - cn_del_callback(&cn_dst_id); - unregister_blkdev(dst_major, DST_NAME); - dst_hashtable_exit(); - dst_sysfs_exit(); - dst_export_exit(); -} - -module_init(dst_sys_init); -module_exit(dst_sys_exit); - -MODULE_DESCRIPTION("Distributed storage"); -MODULE_AUTHOR("Evgeniy Polyakov "); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/dst/export.c b/drivers/staging/dst/export.c deleted file mode 100644 index c324230..0000000 --- a/drivers/staging/dst/export.c +++ /dev/null @@ -1,660 +0,0 @@ -/* - * 2007+ Copyright (c) Evgeniy Polyakov - * All rights reserved. - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -/* - * Export bioset is used for server block IO requests. - */ -static struct bio_set *dst_bio_set; - -int __init dst_export_init(void) -{ - int err = -ENOMEM; - - dst_bio_set = bioset_create(32, sizeof(struct dst_export_priv)); - if (!dst_bio_set) - goto err_out_exit; - - return 0; - -err_out_exit: - return err; -} - -void dst_export_exit(void) -{ - bioset_free(dst_bio_set); -} - -/* - * When client connects and autonegotiates with the server node, - * its permissions are checked in a security attributes and sent - * back. - */ -static unsigned int dst_check_permissions(struct dst_state *main, - struct dst_state *st) -{ - struct dst_node *n = main->node; - struct dst_secure *sentry; - struct dst_secure_user *s; - struct saddr *sa = &st->ctl.addr; - unsigned int perm = 0; - - mutex_lock(&n->security_lock); - list_for_each_entry(sentry, &n->security_list, sec_entry) { - s = &sentry->sec; - - if (s->addr.sa_family != sa->sa_family) - continue; - - if (s->addr.sa_data_len != sa->sa_data_len) - continue; - - /* - * This '2' below is a port field. This may be very wrong to do - * in atalk for example though. If there will be any need - * to extent protocol to something else, I can create - * per-family helpers and use them instead of this memcmp. - */ - if (memcmp(s->addr.sa_data + 2, sa->sa_data + 2, - sa->sa_data_len - 2)) - continue; - - perm = s->permissions; - } - mutex_unlock(&n->security_lock); - - return perm; -} - -/* - * Accept new client: allocate appropriate network state and check permissions. - */ -static struct dst_state *dst_accept_client(struct dst_state *st) -{ - unsigned int revents = 0; - unsigned int err_mask = POLLERR | POLLHUP | POLLRDHUP; - unsigned int mask = err_mask | POLLIN; - struct dst_node *n = st->node; - int err = 0; - struct socket *sock = NULL; - struct dst_state *new; - - while (!err && !sock) { - revents = dst_state_poll(st); - - if (!(revents & mask)) { - DEFINE_WAIT(wait); - - for (;;) { - prepare_to_wait(&st->thread_wait, - &wait, TASK_INTERRUPTIBLE); - if (!n->trans_scan_timeout || st->need_exit) - break; - - revents = dst_state_poll(st); - - if (revents & mask) - break; - - if (signal_pending(current)) - break; - - /* - * Magic HZ? Polling check above is not safe in - * all cases (like socket reset in BH context), - * so it is simpler just to postpone it to the - * process context instead of implementing - * special locking there. - */ - schedule_timeout(HZ); - } - finish_wait(&st->thread_wait, &wait); - } - - err = -ECONNRESET; - dst_state_lock(st); - - dprintk("%s: st: %p, revents: %x [err: %d, in: %d].\n", - __func__, st, revents, revents & err_mask, - revents & POLLIN); - - if (revents & err_mask) { - dprintk("%s: revents: %x, socket: %p, err: %d.\n", - __func__, revents, st->socket, err); - err = -ECONNRESET; - } - - if (!n->trans_scan_timeout || st->need_exit) - err = -ENODEV; - - if (st->socket && (revents & POLLIN)) - err = kernel_accept(st->socket, &sock, 0); - - dst_state_unlock(st); - } - - if (err) - goto err_out_exit; - - new = dst_state_alloc(st->node); - if (IS_ERR(new)) { - err = -ENOMEM; - goto err_out_release; - } - new->socket = sock; - - new->ctl.addr.sa_data_len = sizeof(struct sockaddr); - err = kernel_getpeername(sock, (struct sockaddr *)&new->ctl.addr, - (int *)&new->ctl.addr.sa_data_len); - if (err) - goto err_out_put; - - new->permissions = dst_check_permissions(st, new); - if (new->permissions == 0) { - err = -EPERM; - dst_dump_addr(sock, (struct sockaddr *)&new->ctl.addr, - "Client is not allowed to connect"); - goto err_out_put; - } - - err = dst_poll_init(new); - if (err) - goto err_out_put; - - dst_dump_addr(sock, (struct sockaddr *)&new->ctl.addr, - "Connected client"); - - return new; - -err_out_put: - dst_state_put(new); -err_out_release: - sock_release(sock); -err_out_exit: - return ERR_PTR(err); -} - -/* - * Each server's block request sometime finishes. - * Usually it happens in hard irq context of the appropriate controller, - * so to play good with all cases we just queue BIO into the queue - * and wake up processing thread, which gets completed request and - * send (encrypting if needed) it back to the client (if it was a read - * request), or sends back reply that writing successfully completed. - */ -static int dst_export_process_request_queue(struct dst_state *st) -{ - unsigned long flags; - struct dst_export_priv *p = NULL; - struct bio *bio; - int err = 0; - - while (!list_empty(&st->request_list)) { - spin_lock_irqsave(&st->request_lock, flags); - if (!list_empty(&st->request_list)) { - p = list_first_entry(&st->request_list, - struct dst_export_priv, request_entry); - list_del(&p->request_entry); - } - spin_unlock_irqrestore(&st->request_lock, flags); - - if (!p) - break; - - bio = p->bio; - - if (dst_need_crypto(st->node) && (bio_data_dir(bio) == READ)) - err = dst_export_crypto(st->node, bio); - else - err = dst_export_send_bio(bio); - - if (err) - break; - } - - return err; -} - -/* - * Cleanup export state. - * It has to wait until all requests are finished, - * and then free them all. - */ -static void dst_state_cleanup_export(struct dst_state *st) -{ - struct dst_export_priv *p; - unsigned long flags; - - /* - * This loop waits for all pending bios to be completed and freed. - */ - while (atomic_read(&st->refcnt) > 1) { - dprintk("%s: st: %p, refcnt: %d, list_empty: %d.\n", - __func__, st, atomic_read(&st->refcnt), - list_empty(&st->request_list)); - wait_event_timeout(st->thread_wait, - (atomic_read(&st->refcnt) == 1) || - !list_empty(&st->request_list), - HZ/2); - - while (!list_empty(&st->request_list)) { - p = NULL; - spin_lock_irqsave(&st->request_lock, flags); - if (!list_empty(&st->request_list)) { - p = list_first_entry(&st->request_list, - struct dst_export_priv, request_entry); - list_del(&p->request_entry); - } - spin_unlock_irqrestore(&st->request_lock, flags); - - if (p) - bio_put(p->bio); - - dprintk("%s: st: %p, refcnt: %d, list_empty: %d, p: " - "%p.\n", __func__, st, atomic_read(&st->refcnt), - list_empty(&st->request_list), p); - } - } - - dst_state_put(st); -} - -/* - * Client accepting thread. - * Not only accepts new connection, but also schedules receiving thread - * and performs request completion described above. - */ -static int dst_accept(void *init_data, void *schedule_data) -{ - struct dst_state *main_st = schedule_data; - struct dst_node *n = init_data; - struct dst_state *st; - int err; - - while (n->trans_scan_timeout && !main_st->need_exit) { - dprintk("%s: main_st: %p, n: %p.\n", __func__, main_st, n); - st = dst_accept_client(main_st); - if (IS_ERR(st)) - continue; - - err = dst_state_schedule_receiver(st); - if (!err) { - while (n->trans_scan_timeout) { - err = wait_event_interruptible_timeout(st->thread_wait, - !list_empty(&st->request_list) || - !n->trans_scan_timeout || - st->need_exit, - HZ); - - if (!n->trans_scan_timeout || st->need_exit) - break; - - if (list_empty(&st->request_list)) - continue; - - err = dst_export_process_request_queue(st); - if (err) - break; - } - - st->need_exit = 1; - wake_up(&st->thread_wait); - } - - dst_state_cleanup_export(st); - } - - dprintk("%s: freeing listening socket st: %p.\n", __func__, main_st); - - dst_state_lock(main_st); - dst_poll_exit(main_st); - dst_state_socket_release(main_st); - dst_state_unlock(main_st); - dst_state_put(main_st); - dprintk("%s: freed listening socket st: %p.\n", __func__, main_st); - - return 0; -} - -int dst_start_export(struct dst_node *n) -{ - if (list_empty(&n->security_list)) { - printk(KERN_ERR "You are trying to export node '%s' " - "without security attributes.\nNo clients will " - "be allowed to connect. Exiting.\n", n->name); - return -EINVAL; - } - return dst_node_trans_init(n, sizeof(struct dst_export_priv)); -} - -/* - * Initialize listening state and schedule accepting thread. - */ -int dst_node_init_listened(struct dst_node *n, struct dst_export_ctl *le) -{ - struct dst_state *st; - int err = -ENOMEM; - struct dst_network_ctl *ctl = &le->ctl; - - memcpy(&n->info->net, ctl, sizeof(struct dst_network_ctl)); - - st = dst_state_alloc(n); - if (IS_ERR(st)) { - err = PTR_ERR(st); - goto err_out_exit; - } - memcpy(&st->ctl, ctl, sizeof(struct dst_network_ctl)); - - err = dst_state_socket_create(st); - if (err) - goto err_out_put; - - st->socket->sk->sk_reuse = 1; - - err = kernel_bind(st->socket, (struct sockaddr *)&ctl->addr, - ctl->addr.sa_data_len); - if (err) - goto err_out_socket_release; - - err = kernel_listen(st->socket, 1024); - if (err) - goto err_out_socket_release; - n->state = st; - - err = dst_poll_init(st); - if (err) - goto err_out_socket_release; - - dst_state_get(st); - - err = thread_pool_schedule(n->pool, dst_thread_setup, - dst_accept, st, MAX_SCHEDULE_TIMEOUT); - if (err) - goto err_out_poll_exit; - - return 0; - -err_out_poll_exit: - dst_poll_exit(st); -err_out_socket_release: - dst_state_socket_release(st); -err_out_put: - dst_state_put(st); -err_out_exit: - n->state = NULL; - return err; -} - -/* - * Free bio and related private data. - * Also drop a reference counter for appropriate state, - * which waits when there are no more block IOs in-flight. - */ -static void dst_bio_destructor(struct bio *bio) -{ - struct bio_vec *bv; - struct dst_export_priv *priv = bio->bi_private; - int i; - - bio_for_each_segment(bv, bio, i) { - if (!bv->bv_page) - break; - - __free_page(bv->bv_page); - } - - if (priv) - dst_state_put(priv->state); - bio_free(bio, dst_bio_set); -} - -/* - * Block IO completion. Queue request to be sent back to - * the client (or just confirmation). - */ -static void dst_bio_end_io(struct bio *bio, int err) -{ - struct dst_export_priv *p = bio->bi_private; - struct dst_state *st = p->state; - unsigned long flags; - - spin_lock_irqsave(&st->request_lock, flags); - list_add_tail(&p->request_entry, &st->request_list); - spin_unlock_irqrestore(&st->request_lock, flags); - - wake_up(&st->thread_wait); -} - -/* - * Allocate read request for the server. - */ -static int dst_export_read_request(struct bio *bio, unsigned int total_size) -{ - unsigned int size; - struct page *page; - int err; - - while (total_size) { - err = -ENOMEM; - page = alloc_page(GFP_KERNEL); - if (!page) - goto err_out_exit; - - size = min_t(unsigned int, PAGE_SIZE, total_size); - - err = bio_add_page(bio, page, size, 0); - dprintk("%s: bio: %llu/%u, size: %u, err: %d.\n", - __func__, (u64)bio->bi_sector, bio->bi_size, - size, err); - if (err <= 0) - goto err_out_free_page; - - total_size -= size; - } - - return 0; - -err_out_free_page: - __free_page(page); -err_out_exit: - return err; -} - -/* - * Allocate write request for the server. - * Should not only get pages, but also read data from the network. - */ -static int dst_export_write_request(struct dst_state *st, - struct bio *bio, unsigned int total_size) -{ - unsigned int size; - struct page *page; - void *data; - int err; - - while (total_size) { - err = -ENOMEM; - page = alloc_page(GFP_KERNEL); - if (!page) - goto err_out_exit; - - data = kmap(page); - if (!data) - goto err_out_free_page; - - size = min_t(unsigned int, PAGE_SIZE, total_size); - - err = dst_data_recv(st, data, size); - if (err) - goto err_out_unmap_page; - - err = bio_add_page(bio, page, size, 0); - if (err <= 0) - goto err_out_unmap_page; - - kunmap(page); - - total_size -= size; - } - - return 0; - -err_out_unmap_page: - kunmap(page); -err_out_free_page: - __free_page(page); -err_out_exit: - return err; -} - -/* - * Groovy, we've gotten an IO request from the client. - * Allocate BIO from the bioset, private data from the mempool - * and lots of pages for IO. - */ -int dst_process_io(struct dst_state *st) -{ - struct dst_node *n = st->node; - struct dst_cmd *cmd = st->data; - struct bio *bio; - struct dst_export_priv *priv; - int err = -ENOMEM; - - if (unlikely(!n->bdev)) { - err = -EINVAL; - goto err_out_exit; - } - - bio = bio_alloc_bioset(GFP_KERNEL, - PAGE_ALIGN(cmd->size) >> PAGE_SHIFT, - dst_bio_set); - if (!bio) - goto err_out_exit; - - priv = (struct dst_export_priv *)(((void *)bio) - - sizeof (struct dst_export_priv)); - - priv->state = dst_state_get(st); - priv->bio = bio; - - bio->bi_private = priv; - bio->bi_end_io = dst_bio_end_io; - bio->bi_destructor = dst_bio_destructor; - bio->bi_bdev = n->bdev; - - /* - * Server side is only interested in two low bits: - * uptodate (set by itself actually) and rw block - */ - bio->bi_flags |= cmd->flags & 3; - - bio->bi_rw = cmd->rw; - bio->bi_size = 0; - bio->bi_sector = cmd->sector; - - dst_bio_to_cmd(bio, &priv->cmd, DST_IO_RESPONSE, cmd->id); - - priv->cmd.flags = 0; - priv->cmd.size = cmd->size; - - if (bio_data_dir(bio) == WRITE) { - err = dst_recv_cdata(st, priv->cmd.hash); - if (err) - goto err_out_free; - - err = dst_export_write_request(st, bio, cmd->size); - if (err) - goto err_out_free; - - if (dst_need_crypto(n)) - return dst_export_crypto(n, bio); - } else { - err = dst_export_read_request(bio, cmd->size); - if (err) - goto err_out_free; - } - - dprintk("%s: bio: %llu/%u, rw: %lu, dir: %lu, flags: %lx, phys: %d.\n", - __func__, (u64)bio->bi_sector, bio->bi_size, - bio->bi_rw, bio_data_dir(bio), - bio->bi_flags, bio->bi_phys_segments); - - generic_make_request(bio); - - return 0; - -err_out_free: - bio_put(bio); -err_out_exit: - return err; -} - -/* - * Ok, block IO is ready, let's send it back to the client... - */ -int dst_export_send_bio(struct bio *bio) -{ - struct dst_export_priv *p = bio->bi_private; - struct dst_state *st = p->state; - struct dst_cmd *cmd = &p->cmd; - int err; - - dprintk("%s: id: %llu, bio: %llu/%u, csize: %u, flags: %lu, rw: %lu.\n", - __func__, cmd->id, (u64)bio->bi_sector, bio->bi_size, - cmd->csize, bio->bi_flags, bio->bi_rw); - - dst_convert_cmd(cmd); - - dst_state_lock(st); - if (!st->socket) { - err = -ECONNRESET; - goto err_out_unlock; - } - - if (bio_data_dir(bio) == WRITE) { - /* ... or just confirmation that writing has completed. */ - cmd->size = cmd->csize = 0; - err = dst_data_send_header(st->socket, cmd, - sizeof(struct dst_cmd), 0); - if (err) - goto err_out_unlock; - } else { - err = dst_send_bio(st, cmd, bio); - if (err) - goto err_out_unlock; - } - - dst_state_unlock(st); - - bio_put(bio); - return 0; - -err_out_unlock: - dst_state_unlock(st); - - bio_put(bio); - return err; -} diff --git a/drivers/staging/dst/state.c b/drivers/staging/dst/state.c deleted file mode 100644 index 02a05e6..0000000 --- a/drivers/staging/dst/state.c +++ /dev/null @@ -1,844 +0,0 @@ -/* - * 2007+ Copyright (c) Evgeniy Polyakov - * All rights reserved. - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -/* - * Polling machinery. - */ - -struct dst_poll_helper { - poll_table pt; - struct dst_state *st; -}; - -static int dst_queue_wake(wait_queue_t *wait, unsigned mode, - int sync, void *key) -{ - struct dst_state *st = container_of(wait, struct dst_state, wait); - - wake_up(&st->thread_wait); - return 1; -} - -static void dst_queue_func(struct file *file, wait_queue_head_t *whead, - poll_table *pt) -{ - struct dst_state *st = container_of(pt, struct dst_poll_helper, pt)->st; - - st->whead = whead; - init_waitqueue_func_entry(&st->wait, dst_queue_wake); - add_wait_queue(whead, &st->wait); -} - -void dst_poll_exit(struct dst_state *st) -{ - if (st->whead) { - remove_wait_queue(st->whead, &st->wait); - st->whead = NULL; - } -} - -int dst_poll_init(struct dst_state *st) -{ - struct dst_poll_helper ph; - - ph.st = st; - init_poll_funcptr(&ph.pt, &dst_queue_func); - - st->socket->ops->poll(NULL, st->socket, &ph.pt); - return 0; -} - -/* - * Header receiving function - may block. - */ -static int dst_data_recv_header(struct socket *sock, - void *data, unsigned int size, int block) -{ - struct msghdr msg; - struct kvec iov; - int err; - - iov.iov_base = data; - iov.iov_len = size; - - msg.msg_iov = (struct iovec *)&iov; - msg.msg_iovlen = 1; - msg.msg_name = NULL; - msg.msg_namelen = 0; - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_flags = (block) ? MSG_WAITALL : MSG_DONTWAIT; - - err = kernel_recvmsg(sock, &msg, &iov, 1, iov.iov_len, - msg.msg_flags); - if (err != size) - return -1; - - return 0; -} - -/* - * Header sending function - may block. - */ -int dst_data_send_header(struct socket *sock, - void *data, unsigned int size, int more) -{ - struct msghdr msg; - struct kvec iov; - int err; - - iov.iov_base = data; - iov.iov_len = size; - - msg.msg_iov = (struct iovec *)&iov; - msg.msg_iovlen = 1; - msg.msg_name = NULL; - msg.msg_namelen = 0; - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_flags = MSG_WAITALL | (more ? MSG_MORE : 0); - - err = kernel_sendmsg(sock, &msg, &iov, 1, iov.iov_len); - if (err != size) { - dprintk("%s: size: %u, more: %d, err: %d.\n", - __func__, size, more, err); - return -1; - } - - return 0; -} - -/* - * Block autoconfiguration: request size of the storage and permissions. - */ -static int dst_request_remote_config(struct dst_state *st) -{ - struct dst_node *n = st->node; - int err = -EINVAL; - struct dst_cmd *cmd = st->data; - - memset(cmd, 0, sizeof(struct dst_cmd)); - cmd->cmd = DST_CFG; - - dst_convert_cmd(cmd); - - err = dst_data_send_header(st->socket, cmd, sizeof(struct dst_cmd), 0); - if (err) - goto out; - - err = dst_data_recv_header(st->socket, cmd, sizeof(struct dst_cmd), 1); - if (err) - goto out; - - dst_convert_cmd(cmd); - - if (cmd->cmd != DST_CFG) { - err = -EINVAL; - dprintk("%s: checking result: cmd: %d, size reported: %llu.\n", - __func__, cmd->cmd, cmd->sector); - goto out; - } - - if (n->size != 0) - n->size = min_t(loff_t, n->size, cmd->sector); - else - n->size = cmd->sector; - - n->info->size = n->size; - st->permissions = cmd->rw; - -out: - dprintk("%s: n: %p, err: %d, size: %llu, permission: %x.\n", - __func__, n, err, n->size, st->permissions); - return err; -} - -/* - * Socket machinery. - */ - -#define DST_DEFAULT_TIMEO 20000 - -int dst_state_socket_create(struct dst_state *st) -{ - int err; - struct socket *sock; - struct dst_network_ctl *ctl = &st->ctl; - - err = sock_create(ctl->addr.sa_family, ctl->type, ctl->proto, &sock); - if (err < 0) - return err; - - sock->sk->sk_sndtimeo = sock->sk->sk_rcvtimeo = - msecs_to_jiffies(DST_DEFAULT_TIMEO); - sock->sk->sk_allocation = GFP_NOIO; - - st->socket = st->read_socket = sock; - return 0; -} - -void dst_state_socket_release(struct dst_state *st) -{ - dprintk("%s: st: %p, socket: %p, n: %p.\n", - __func__, st, st->socket, st->node); - if (st->socket) { - sock_release(st->socket); - st->socket = NULL; - st->read_socket = NULL; - } -} - -void dst_dump_addr(struct socket *sk, struct sockaddr *sa, char *str) -{ - if (sk->ops->family == AF_INET) { - struct sockaddr_in *sin = (struct sockaddr_in *)sa; - printk(KERN_INFO "%s %u.%u.%u.%u:%d.\n", str, - NIPQUAD(sin->sin_addr.s_addr), ntohs(sin->sin_port)); - } else if (sk->ops->family == AF_INET6) { - struct sockaddr_in6 *sin = (struct sockaddr_in6 *)sa; - printk(KERN_INFO "%s %pi6:%d", - str, &sin->sin6_addr, ntohs(sin->sin6_port)); - } -} - -void dst_state_exit_connected(struct dst_state *st) -{ - if (st->socket) { - dst_poll_exit(st); - st->socket->ops->shutdown(st->socket, 2); - - dst_dump_addr(st->socket, (struct sockaddr *)&st->ctl.addr, - "Disconnected peer"); - dst_state_socket_release(st); - } -} - -static int dst_state_init_connected(struct dst_state *st) -{ - int err; - struct dst_network_ctl *ctl = &st->ctl; - - err = dst_state_socket_create(st); - if (err) - goto err_out_exit; - - err = kernel_connect(st->socket, (struct sockaddr *)&st->ctl.addr, - st->ctl.addr.sa_data_len, 0); - if (err) - goto err_out_release; - - err = dst_poll_init(st); - if (err) - goto err_out_release; - - dst_dump_addr(st->socket, (struct sockaddr *)&ctl->addr, - "Connected to peer"); - - return 0; - -err_out_release: - dst_state_socket_release(st); -err_out_exit: - return err; -} - -/* - * State reset is used to reconnect to the remote peer. - * May fail, but who cares, we will try again later. - */ -static inline void dst_state_reset_nolock(struct dst_state *st) -{ - dst_state_exit_connected(st); - dst_state_init_connected(st); -} - -static inline void dst_state_reset(struct dst_state *st) -{ - dst_state_lock(st); - dst_state_reset_nolock(st); - dst_state_unlock(st); -} - -/* - * Basic network sending/receiving functions. - * Blocked mode is used. - */ -static int dst_data_recv_raw(struct dst_state *st, void *buf, u64 size) -{ - struct msghdr msg; - struct kvec iov; - int err; - - BUG_ON(!size); - - iov.iov_base = buf; - iov.iov_len = size; - - msg.msg_iov = (struct iovec *)&iov; - msg.msg_iovlen = 1; - msg.msg_name = NULL; - msg.msg_namelen = 0; - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_flags = MSG_DONTWAIT; - - err = kernel_recvmsg(st->socket, &msg, &iov, 1, iov.iov_len, - msg.msg_flags); - if (err <= 0) { - dprintk("%s: failed to recv data: size: %llu, err: %d.\n", - __func__, size, err); - if (err == 0) - err = -ECONNRESET; - - dst_state_exit_connected(st); - } - - return err; -} - -/* - * Ping command to early detect failed nodes. - */ -static int dst_send_ping(struct dst_state *st) -{ - struct dst_cmd *cmd = st->data; - int err = -ECONNRESET; - - dst_state_lock(st); - if (st->socket) { - memset(cmd, 0, sizeof(struct dst_cmd)); - - cmd->cmd = __cpu_to_be32(DST_PING); - - err = dst_data_send_header(st->socket, cmd, - sizeof(struct dst_cmd), 0); - } - dprintk("%s: st: %p, socket: %p, err: %d.\n", __func__, - st, st->socket, err); - dst_state_unlock(st); - - return err; -} - -/* - * Receiving function, which should either return error or read - * whole block request. If there was no traffic for a one second, - * send a ping, since remote node may die. - */ -int dst_data_recv(struct dst_state *st, void *data, unsigned int size) -{ - unsigned int revents = 0; - unsigned int err_mask = POLLERR | POLLHUP | POLLRDHUP; - unsigned int mask = err_mask | POLLIN; - struct dst_node *n = st->node; - int err = 0; - - while (size && !err) { - revents = dst_state_poll(st); - - if (!(revents & mask)) { - DEFINE_WAIT(wait); - - for (;;) { - prepare_to_wait(&st->thread_wait, &wait, - TASK_INTERRUPTIBLE); - if (!n->trans_scan_timeout || st->need_exit) - break; - - revents = dst_state_poll(st); - - if (revents & mask) - break; - - if (signal_pending(current)) - break; - - if (!schedule_timeout(HZ)) { - err = dst_send_ping(st); - if (err) - return err; - } - - continue; - } - finish_wait(&st->thread_wait, &wait); - } - - err = -ECONNRESET; - dst_state_lock(st); - - if (st->socket && (st->read_socket == st->socket) && - (revents & POLLIN)) { - err = dst_data_recv_raw(st, data, size); - if (err > 0) { - data += err; - size -= err; - err = 0; - } - } - - if (revents & err_mask || !st->socket) { - dprintk("%s: revents: %x, socket: %p, size: %u, " - "err: %d.\n", __func__, revents, - st->socket, size, err); - err = -ECONNRESET; - } - - dst_state_unlock(st); - - if (!n->trans_scan_timeout) - err = -ENODEV; - } - - return err; -} - -/* - * Send block autoconf reply. - */ -static int dst_process_cfg(struct dst_state *st) -{ - struct dst_node *n = st->node; - struct dst_cmd *cmd = st->data; - int err; - - cmd->sector = n->size; - cmd->rw = st->permissions; - - dst_convert_cmd(cmd); - - dst_state_lock(st); - err = dst_data_send_header(st->socket, cmd, sizeof(struct dst_cmd), 0); - dst_state_unlock(st); - - return err; -} - -/* - * Receive block IO from the network. - */ -static int dst_recv_bio(struct dst_state *st, struct bio *bio, - unsigned int total_size) -{ - struct bio_vec *bv; - int i, err; - void *data; - unsigned int sz; - - bio_for_each_segment(bv, bio, i) { - sz = min(total_size, bv->bv_len); - - dprintk("%s: bio: %llu/%u, total: %u, len: %u, sz: %u, " - "off: %u.\n", __func__, (u64)bio->bi_sector, - bio->bi_size, total_size, bv->bv_len, sz, - bv->bv_offset); - - data = kmap(bv->bv_page) + bv->bv_offset; - err = dst_data_recv(st, data, sz); - kunmap(bv->bv_page); - - bv->bv_len = sz; - - if (err) - return err; - - total_size -= sz; - if (total_size == 0) - break; - } - - return 0; -} - -/* - * Our block IO has just completed and arrived: get it. - */ -static int dst_process_io_response(struct dst_state *st) -{ - struct dst_node *n = st->node; - struct dst_cmd *cmd = st->data; - struct dst_trans *t; - int err = 0; - struct bio *bio; - - mutex_lock(&n->trans_lock); - t = dst_trans_search(n, cmd->id); - mutex_unlock(&n->trans_lock); - - if (!t) - goto err_out_exit; - - bio = t->bio; - - dprintk("%s: bio: %llu/%u, cmd_size: %u, csize: %u, dir: %lu.\n", - __func__, (u64)bio->bi_sector, bio->bi_size, cmd->size, - cmd->csize, bio_data_dir(bio)); - - if (bio_data_dir(bio) == READ) { - if (bio->bi_size != cmd->size - cmd->csize) - goto err_out_exit; - - if (dst_need_crypto(n)) { - err = dst_recv_cdata(st, t->cmd.hash); - if (err) - goto err_out_exit; - } - - err = dst_recv_bio(st, t->bio, bio->bi_size); - if (err) - goto err_out_exit; - - if (dst_need_crypto(n)) - return dst_trans_crypto(t); - } else { - err = -EBADMSG; - if (cmd->size || cmd->csize) - goto err_out_exit; - } - - dst_trans_remove(t); - dst_trans_put(t); - - return 0; - -err_out_exit: - return err; -} - -/* - * Receive crypto data. - */ -int dst_recv_cdata(struct dst_state *st, void *cdata) -{ - struct dst_cmd *cmd = st->data; - struct dst_node *n = st->node; - struct dst_crypto_ctl *c = &n->crypto; - int err; - - if (cmd->csize != c->crypto_attached_size) { - dprintk("%s: cmd: cmd: %u, sector: %llu, size: %u, " - "csize: %u != digest size %u.\n", - __func__, cmd->cmd, cmd->sector, cmd->size, - cmd->csize, c->crypto_attached_size); - err = -EINVAL; - goto err_out_exit; - } - - err = dst_data_recv(st, cdata, cmd->csize); - if (err) - goto err_out_exit; - - cmd->size -= cmd->csize; - return 0; - -err_out_exit: - return err; -} - -/* - * Receive the command and start its processing. - */ -static int dst_recv_processing(struct dst_state *st) -{ - int err = -EINTR; - struct dst_cmd *cmd = st->data; - - /* - * If socket will be reset after this statement, then - * dst_data_recv() will just fail and loop will - * start again, so it can be done without any locks. - * - * st->read_socket is needed to prevents state machine - * breaking between this data reading and subsequent one - * in protocol specific functions during connection reset. - * In case of reset we have to read next command and do - * not expect data for old command to magically appear in - * new connection. - */ - st->read_socket = st->socket; - err = dst_data_recv(st, cmd, sizeof(struct dst_cmd)); - if (err) - goto out_exit; - - dst_convert_cmd(cmd); - - dprintk("%s: cmd: %u, size: %u, csize: %u, id: %llu, " - "sector: %llu, flags: %llx, rw: %llx.\n", - __func__, cmd->cmd, cmd->size, - cmd->csize, cmd->id, cmd->sector, - cmd->flags, cmd->rw); - - /* - * This should catch protocol breakage and random garbage - * instead of commands. - */ - if (unlikely(cmd->csize > st->size - sizeof(struct dst_cmd))) { - err = -EBADMSG; - goto out_exit; - } - - err = -EPROTO; - switch (cmd->cmd) { - case DST_IO_RESPONSE: - err = dst_process_io_response(st); - break; - case DST_IO: - err = dst_process_io(st); - break; - case DST_CFG: - err = dst_process_cfg(st); - break; - case DST_PING: - err = 0; - break; - default: - break; - } - -out_exit: - return err; -} - -/* - * Receiving thread. For the client node we should try to reconnect, - * for accepted client we just drop the state and expect it to reconnect. - */ -static int dst_recv(void *init_data, void *schedule_data) -{ - struct dst_state *st = schedule_data; - struct dst_node *n = init_data; - int err = 0; - - dprintk("%s: start st: %p, n: %p, scan: %lu, need_exit: %d.\n", - __func__, st, n, n->trans_scan_timeout, st->need_exit); - - while (n->trans_scan_timeout && !st->need_exit) { - err = dst_recv_processing(st); - if (err < 0) { - if (!st->ctl.type) - break; - - if (!n->trans_scan_timeout || st->need_exit) - break; - - dst_state_reset(st); - msleep(1000); - } - } - - st->need_exit = 1; - wake_up(&st->thread_wait); - - dprintk("%s: freeing receiving socket st: %p.\n", __func__, st); - dst_state_lock(st); - dst_state_exit_connected(st); - dst_state_unlock(st); - dst_state_put(st); - - dprintk("%s: freed receiving socket st: %p.\n", __func__, st); - - return err; -} - -/* - * Network state dies here and borns couple of lines below. - * This object is the main network state processing engine: - * sending, receiving, reconnections, all network related - * tasks are handled on behalf of the state. - */ -static void dst_state_free(struct dst_state *st) -{ - dprintk("%s: st: %p.\n", __func__, st); - if (st->cleanup) - st->cleanup(st); - kfree(st->data); - kfree(st); -} - -struct dst_state *dst_state_alloc(struct dst_node *n) -{ - struct dst_state *st; - int err = -ENOMEM; - - st = kzalloc(sizeof(struct dst_state), GFP_KERNEL); - if (!st) - goto err_out_exit; - - st->node = n; - st->need_exit = 0; - - st->size = PAGE_SIZE; - st->data = kmalloc(st->size, GFP_KERNEL); - if (!st->data) - goto err_out_free; - - spin_lock_init(&st->request_lock); - INIT_LIST_HEAD(&st->request_list); - - mutex_init(&st->state_lock); - init_waitqueue_head(&st->thread_wait); - - /* - * One for processing thread, another one for node itself. - */ - atomic_set(&st->refcnt, 2); - - dprintk("%s: st: %p, n: %p.\n", __func__, st, st->node); - - return st; - -err_out_free: - kfree(st); -err_out_exit: - return ERR_PTR(err); -} - -int dst_state_schedule_receiver(struct dst_state *st) -{ - return thread_pool_schedule_private(st->node->pool, dst_thread_setup, - dst_recv, st, MAX_SCHEDULE_TIMEOUT, st->node); -} - -/* - * Initialize client's connection to the remote peer: allocate state, - * connect and perform block IO autoconfiguration. - */ -int dst_node_init_connected(struct dst_node *n, struct dst_network_ctl *r) -{ - struct dst_state *st; - int err = -ENOMEM; - - st = dst_state_alloc(n); - if (IS_ERR(st)) { - err = PTR_ERR(st); - goto err_out_exit; - } - memcpy(&st->ctl, r, sizeof(struct dst_network_ctl)); - - err = dst_state_init_connected(st); - if (err) - goto err_out_free_data; - - err = dst_request_remote_config(st); - if (err) - goto err_out_exit_connected; - n->state = st; - - err = dst_state_schedule_receiver(st); - if (err) - goto err_out_exit_connected; - - return 0; - -err_out_exit_connected: - dst_state_exit_connected(st); -err_out_free_data: - dst_state_free(st); -err_out_exit: - n->state = NULL; - return err; -} - -void dst_state_put(struct dst_state *st) -{ - dprintk("%s: st: %p, refcnt: %d.\n", - __func__, st, atomic_read(&st->refcnt)); - if (atomic_dec_and_test(&st->refcnt)) - dst_state_free(st); -} - -/* - * Send block IO to the network one by one using zero-copy ->sendpage(). - */ -int dst_send_bio(struct dst_state *st, struct dst_cmd *cmd, struct bio *bio) -{ - struct bio_vec *bv; - struct dst_crypto_ctl *c = &st->node->crypto; - int err, i = 0; - int flags = MSG_WAITALL; - - err = dst_data_send_header(st->socket, cmd, - sizeof(struct dst_cmd) + c->crypto_attached_size, bio->bi_vcnt); - if (err) - goto err_out_exit; - - bio_for_each_segment(bv, bio, i) { - if (i < bio->bi_vcnt - 1) - flags |= MSG_MORE; - - err = kernel_sendpage(st->socket, bv->bv_page, bv->bv_offset, - bv->bv_len, flags); - if (err <= 0) - goto err_out_exit; - } - - return 0; - -err_out_exit: - dprintk("%s: %d/%d, flags: %x, err: %d.\n", - __func__, i, bio->bi_vcnt, flags, err); - return err; -} - -/* - * Send transaction to the remote peer. - */ -int dst_trans_send(struct dst_trans *t) -{ - int err; - struct dst_state *st = t->n->state; - struct bio *bio = t->bio; - - dst_convert_cmd(&t->cmd); - - dst_state_lock(st); - if (!st->socket) { - err = dst_state_init_connected(st); - if (err) - goto err_out_unlock; - } - - if (bio_data_dir(bio) == WRITE) { - err = dst_send_bio(st, &t->cmd, t->bio); - } else { - err = dst_data_send_header(st->socket, &t->cmd, - sizeof(struct dst_cmd), 0); - } - if (err) - goto err_out_reset; - - dst_state_unlock(st); - return 0; - -err_out_reset: - dst_state_reset_nolock(st); -err_out_unlock: - dst_state_unlock(st); - - return err; -} diff --git a/drivers/staging/dst/thread_pool.c b/drivers/staging/dst/thread_pool.c deleted file mode 100644 index 29a82b2..0000000 --- a/drivers/staging/dst/thread_pool.c +++ /dev/null @@ -1,348 +0,0 @@ -/* - * 2007+ Copyright (c) Evgeniy Polyakov - * All rights reserved. - * - * 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. - */ - -#include -#include -#include -#include - -/* - * Thread pool abstraction allows to schedule a work to be performed - * on behalf of kernel thread. One does not operate with threads itself, - * instead user provides setup and cleanup callbacks for thread pool itself, - * and action and cleanup callbacks for each submitted work. - * - * Each worker has private data initialized at creation time and data, - * provided by user at scheduling time. - * - * When action is being performed, thread can not be used by other users, - * instead they will sleep until there is free thread to pick their work. - */ -struct thread_pool_worker { - struct list_head worker_entry; - - struct task_struct *thread; - - struct thread_pool *pool; - - int error; - int has_data; - int need_exit; - unsigned int id; - - wait_queue_head_t wait; - - void *private; - void *schedule_data; - - int (*action)(void *private, void *schedule_data); - void (*cleanup)(void *private); -}; - -static void thread_pool_exit_worker(struct thread_pool_worker *w) -{ - kthread_stop(w->thread); - - w->cleanup(w->private); - kfree(w); -} - -/* - * Called to mark thread as ready and allow users to schedule new work. - */ -static void thread_pool_worker_make_ready(struct thread_pool_worker *w) -{ - struct thread_pool *p = w->pool; - - mutex_lock(&p->thread_lock); - - if (!w->need_exit) { - list_move_tail(&w->worker_entry, &p->ready_list); - w->has_data = 0; - mutex_unlock(&p->thread_lock); - - wake_up(&p->wait); - } else { - p->thread_num--; - list_del(&w->worker_entry); - mutex_unlock(&p->thread_lock); - - thread_pool_exit_worker(w); - } -} - -/* - * Thread action loop: waits until there is new work. - */ -static int thread_pool_worker_func(void *data) -{ - struct thread_pool_worker *w = data; - - while (!kthread_should_stop()) { - wait_event_interruptible(w->wait, - kthread_should_stop() || w->has_data); - - if (kthread_should_stop()) - break; - - if (!w->has_data) - continue; - - w->action(w->private, w->schedule_data); - thread_pool_worker_make_ready(w); - } - - return 0; -} - -/* - * Remove single worker without specifying which one. - */ -void thread_pool_del_worker(struct thread_pool *p) -{ - struct thread_pool_worker *w = NULL; - - while (!w && p->thread_num) { - wait_event(p->wait, !list_empty(&p->ready_list) || - !p->thread_num); - - dprintk("%s: locking list_empty: %d, thread_num: %d.\n", - __func__, list_empty(&p->ready_list), - p->thread_num); - - mutex_lock(&p->thread_lock); - if (!list_empty(&p->ready_list)) { - w = list_first_entry(&p->ready_list, - struct thread_pool_worker, - worker_entry); - - dprintk("%s: deleting w: %p, thread_num: %d, " - "list: %p [%p.%p].\n", __func__, - w, p->thread_num, &p->ready_list, - p->ready_list.prev, p->ready_list.next); - - p->thread_num--; - list_del(&w->worker_entry); - } - mutex_unlock(&p->thread_lock); - } - - if (w) - thread_pool_exit_worker(w); - dprintk("%s: deleted w: %p, thread_num: %d.\n", - __func__, w, p->thread_num); -} - -/* - * Remove a worker with given ID. - */ -void thread_pool_del_worker_id(struct thread_pool *p, unsigned int id) -{ - struct thread_pool_worker *w; - int found = 0; - - mutex_lock(&p->thread_lock); - list_for_each_entry(w, &p->ready_list, worker_entry) { - if (w->id == id) { - found = 1; - p->thread_num--; - list_del(&w->worker_entry); - break; - } - } - - if (!found) { - list_for_each_entry(w, &p->active_list, worker_entry) { - if (w->id == id) { - w->need_exit = 1; - break; - } - } - } - mutex_unlock(&p->thread_lock); - - if (found) - thread_pool_exit_worker(w); -} - -/* - * Add new worker thread with given parameters. - * If initialization callback fails, return error. - */ -int thread_pool_add_worker(struct thread_pool *p, - char *name, - unsigned int id, - void *(*init)(void *private), - void (*cleanup)(void *private), - void *private) -{ - struct thread_pool_worker *w; - int err = -ENOMEM; - - w = kzalloc(sizeof(struct thread_pool_worker), GFP_KERNEL); - if (!w) - goto err_out_exit; - - w->pool = p; - init_waitqueue_head(&w->wait); - w->cleanup = cleanup; - w->id = id; - - w->thread = kthread_run(thread_pool_worker_func, w, "%s", name); - if (IS_ERR(w->thread)) { - err = PTR_ERR(w->thread); - goto err_out_free; - } - - w->private = init(private); - if (IS_ERR(w->private)) { - err = PTR_ERR(w->private); - goto err_out_stop_thread; - } - - mutex_lock(&p->thread_lock); - list_add_tail(&w->worker_entry, &p->ready_list); - p->thread_num++; - mutex_unlock(&p->thread_lock); - - return 0; - -err_out_stop_thread: - kthread_stop(w->thread); -err_out_free: - kfree(w); -err_out_exit: - return err; -} - -/* - * Destroy the whole pool. - */ -void thread_pool_destroy(struct thread_pool *p) -{ - while (p->thread_num) { - dprintk("%s: num: %d.\n", __func__, p->thread_num); - thread_pool_del_worker(p); - } - - kfree(p); -} - -/* - * Create a pool with given number of threads. - * They will have sequential IDs started from zero. - */ -struct thread_pool *thread_pool_create(int num, char *name, - void *(*init)(void *private), - void (*cleanup)(void *private), - void *private) -{ - struct thread_pool_worker *w, *tmp; - struct thread_pool *p; - int err = -ENOMEM; - int i; - - p = kzalloc(sizeof(struct thread_pool), GFP_KERNEL); - if (!p) - goto err_out_exit; - - init_waitqueue_head(&p->wait); - mutex_init(&p->thread_lock); - INIT_LIST_HEAD(&p->ready_list); - INIT_LIST_HEAD(&p->active_list); - p->thread_num = 0; - - for (i = 0; i < num; ++i) { - err = thread_pool_add_worker(p, name, i, init, - cleanup, private); - if (err) - goto err_out_free_all; - } - - return p; - -err_out_free_all: - list_for_each_entry_safe(w, tmp, &p->ready_list, worker_entry) { - list_del(&w->worker_entry); - thread_pool_exit_worker(w); - } - kfree(p); -err_out_exit: - return ERR_PTR(err); -} - -/* - * Schedule execution of the action on a given thread, - * provided ID pointer has to match previously stored - * private data. - */ -int thread_pool_schedule_private(struct thread_pool *p, - int (*setup)(void *private, void *data), - int (*action)(void *private, void *data), - void *data, long timeout, void *id) -{ - struct thread_pool_worker *w, *tmp, *worker = NULL; - int err = 0; - - while (!worker && !err) { - timeout = wait_event_interruptible_timeout(p->wait, - !list_empty(&p->ready_list), - timeout); - - if (!timeout) { - err = -ETIMEDOUT; - break; - } - - worker = NULL; - mutex_lock(&p->thread_lock); - list_for_each_entry_safe(w, tmp, &p->ready_list, worker_entry) { - if (id && id != w->private) - continue; - - worker = w; - - list_move_tail(&w->worker_entry, &p->active_list); - - err = setup(w->private, data); - if (!err) { - w->schedule_data = data; - w->action = action; - w->has_data = 1; - wake_up(&w->wait); - } else { - list_move_tail(&w->worker_entry, - &p->ready_list); - } - - break; - } - mutex_unlock(&p->thread_lock); - } - - return err; -} - -/* - * Schedule execution on arbitrary thread from the pool. - */ -int thread_pool_schedule(struct thread_pool *p, - int (*setup)(void *private, void *data), - int (*action)(void *private, void *data), - void *data, long timeout) -{ - return thread_pool_schedule_private(p, setup, - action, data, timeout, NULL); -} diff --git a/drivers/staging/dst/trans.c b/drivers/staging/dst/trans.c deleted file mode 100644 index 1c36a6b..0000000 --- a/drivers/staging/dst/trans.c +++ /dev/null @@ -1,337 +0,0 @@ -/* - * 2007+ Copyright (c) Evgeniy Polyakov - * All rights reserved. - * - * 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. - */ - -#include -#include -#include -#include - -/* - * Transaction memory pool size. - */ -static int dst_mempool_num = 32; -module_param(dst_mempool_num, int, 0644); - -/* - * Transaction tree management. - */ -static inline int dst_trans_cmp(dst_gen_t gen, dst_gen_t new) -{ - if (gen < new) - return 1; - if (gen > new) - return -1; - return 0; -} - -struct dst_trans *dst_trans_search(struct dst_node *node, dst_gen_t gen) -{ - struct rb_root *root = &node->trans_root; - struct rb_node *n = root->rb_node; - struct dst_trans *t, *ret = NULL; - int cmp; - - while (n) { - t = rb_entry(n, struct dst_trans, trans_entry); - - cmp = dst_trans_cmp(t->gen, gen); - if (cmp < 0) - n = n->rb_left; - else if (cmp > 0) - n = n->rb_right; - else { - ret = t; - break; - } - } - - dprintk("%s: %s transaction: id: %llu.\n", __func__, - (ret) ? "found" : "not found", gen); - - return ret; -} - -static int dst_trans_insert(struct dst_trans *new) -{ - struct rb_root *root = &new->n->trans_root; - struct rb_node **n = &root->rb_node, *parent = NULL; - struct dst_trans *ret = NULL, *t; - int cmp; - - while (*n) { - parent = *n; - - t = rb_entry(parent, struct dst_trans, trans_entry); - - cmp = dst_trans_cmp(t->gen, new->gen); - if (cmp < 0) - n = &parent->rb_left; - else if (cmp > 0) - n = &parent->rb_right; - else { - ret = t; - break; - } - } - - new->send_time = jiffies; - if (ret) { - printk(KERN_DEBUG "%s: exist: old: gen: %llu, bio: %llu/%u, " - "send_time: %lu, new: gen: %llu, bio: %llu/%u, " - "send_time: %lu.\n", __func__, - ret->gen, (u64)ret->bio->bi_sector, - ret->bio->bi_size, ret->send_time, - new->gen, (u64)new->bio->bi_sector, - new->bio->bi_size, new->send_time); - return -EEXIST; - } - - rb_link_node(&new->trans_entry, parent, n); - rb_insert_color(&new->trans_entry, root); - - dprintk("%s: inserted: gen: %llu, bio: %llu/%u, send_time: %lu.\n", - __func__, new->gen, (u64)new->bio->bi_sector, - new->bio->bi_size, new->send_time); - - return 0; -} - -int dst_trans_remove_nolock(struct dst_trans *t) -{ - struct dst_node *n = t->n; - - if (t->trans_entry.rb_parent_color) { - rb_erase(&t->trans_entry, &n->trans_root); - t->trans_entry.rb_parent_color = 0; - } - return 0; -} - -int dst_trans_remove(struct dst_trans *t) -{ - int ret; - struct dst_node *n = t->n; - - mutex_lock(&n->trans_lock); - ret = dst_trans_remove_nolock(t); - mutex_unlock(&n->trans_lock); - - return ret; -} - -/* - * When transaction is completed and there are no more users, - * we complete appriate block IO request with given error status. - */ -void dst_trans_put(struct dst_trans *t) -{ - if (atomic_dec_and_test(&t->refcnt)) { - struct bio *bio = t->bio; - - dprintk("%s: completed t: %p, gen: %llu, bio: %p.\n", - __func__, t, t->gen, bio); - - bio_endio(bio, t->error); - bio_put(bio); - - dst_node_put(t->n); - mempool_free(t, t->n->trans_pool); - } -} - -/* - * Process given block IO request: allocate transaction, insert it into the tree - * and send/schedule crypto processing. - */ -int dst_process_bio(struct dst_node *n, struct bio *bio) -{ - struct dst_trans *t; - int err = -ENOMEM; - - t = mempool_alloc(n->trans_pool, GFP_NOFS); - if (!t) - goto err_out_exit; - - t->n = dst_node_get(n); - t->bio = bio; - t->error = 0; - t->retries = 0; - atomic_set(&t->refcnt, 1); - t->gen = atomic_long_inc_return(&n->gen); - - t->enc = bio_data_dir(bio); - dst_bio_to_cmd(bio, &t->cmd, DST_IO, t->gen); - - mutex_lock(&n->trans_lock); - err = dst_trans_insert(t); - mutex_unlock(&n->trans_lock); - if (err) - goto err_out_free; - - dprintk("%s: gen: %llu, bio: %llu/%u, dir/enc: %d, need_crypto: %d.\n", - __func__, t->gen, (u64)bio->bi_sector, - bio->bi_size, t->enc, dst_need_crypto(n)); - - if (dst_need_crypto(n) && t->enc) - dst_trans_crypto(t); - else - dst_trans_send(t); - - return 0; - -err_out_free: - dst_node_put(n); - mempool_free(t, n->trans_pool); -err_out_exit: - bio_endio(bio, err); - bio_put(bio); - return err; -} - -/* - * Scan for timeout/stale transactions. - * Each transaction is being resent multiple times before error completion. - */ -static void dst_trans_scan(struct work_struct *work) -{ - struct dst_node *n = container_of(work, struct dst_node, - trans_work.work); - struct rb_node *rb_node; - struct dst_trans *t; - unsigned long timeout = n->trans_scan_timeout; - int num = 10 * n->trans_max_retries; - - mutex_lock(&n->trans_lock); - - for (rb_node = rb_first(&n->trans_root); rb_node; ) { - t = rb_entry(rb_node, struct dst_trans, trans_entry); - - if (timeout && time_after(t->send_time + timeout, jiffies) - && t->retries == 0) - break; -#if 0 - dprintk("%s: t: %p, gen: %llu, n: %s, retries: %u, max: %u.\n", - __func__, t, t->gen, n->name, - t->retries, n->trans_max_retries); -#endif - if (--num == 0) - break; - - dst_trans_get(t); - - rb_node = rb_next(rb_node); - - if (timeout && (++t->retries < n->trans_max_retries)) { - dst_trans_send(t); - } else { - t->error = -ETIMEDOUT; - dst_trans_remove_nolock(t); - dst_trans_put(t); - } - - dst_trans_put(t); - } - - mutex_unlock(&n->trans_lock); - - /* - * If no timeout specified then system is in the middle of exiting - * process, so no need to reschedule scanning process again. - */ - if (timeout) { - if (!num) - timeout = HZ; - schedule_delayed_work(&n->trans_work, timeout); - } -} - -/* - * Flush all transactions and mark them as timed out. - * Destroy transaction pools. - */ -void dst_node_trans_exit(struct dst_node *n) -{ - struct dst_trans *t; - struct rb_node *rb_node; - - if (!n->trans_cache) - return; - - dprintk("%s: n: %p, cancelling the work.\n", __func__, n); - cancel_delayed_work_sync(&n->trans_work); - flush_scheduled_work(); - dprintk("%s: n: %p, work has been cancelled.\n", __func__, n); - - for (rb_node = rb_first(&n->trans_root); rb_node; ) { - t = rb_entry(rb_node, struct dst_trans, trans_entry); - - dprintk("%s: t: %p, gen: %llu, n: %s.\n", - __func__, t, t->gen, n->name); - - rb_node = rb_next(rb_node); - - t->error = -ETIMEDOUT; - dst_trans_remove_nolock(t); - dst_trans_put(t); - } - - mempool_destroy(n->trans_pool); - kmem_cache_destroy(n->trans_cache); -} - -/* - * Initialize transaction storage for given node. - * Transaction stores not only control information, - * but also network command and crypto data (if needed) - * to reduce number of allocations. Thus transaction size - * differs from node to node. - */ -int dst_node_trans_init(struct dst_node *n, unsigned int size) -{ - /* - * We need this, since node with given name can be dropped from the - * hash table, but be still alive, so subsequent creation of the node - * with the same name may collide with existing cache name. - */ - - snprintf(n->cache_name, sizeof(n->cache_name), "%s-%p", n->name, n); - - n->trans_cache = kmem_cache_create(n->cache_name, - size + n->crypto.crypto_attached_size, - 0, 0, NULL); - if (!n->trans_cache) - goto err_out_exit; - - n->trans_pool = mempool_create_slab_pool(dst_mempool_num, - n->trans_cache); - if (!n->trans_pool) - goto err_out_cache_destroy; - - mutex_init(&n->trans_lock); - n->trans_root = RB_ROOT; - - INIT_DELAYED_WORK(&n->trans_work, dst_trans_scan); - schedule_delayed_work(&n->trans_work, n->trans_scan_timeout); - - dprintk("%s: n: %p, size: %u, crypto: %u.\n", - __func__, n, size, n->crypto.crypto_attached_size); - - return 0; - -err_out_cache_destroy: - kmem_cache_destroy(n->trans_cache); -err_out_exit: - return -ENOMEM; -} diff --git a/include/linux/dst.h b/include/linux/dst.h deleted file mode 100644 index e26fed8..0000000 --- a/include/linux/dst.h +++ /dev/null @@ -1,587 +0,0 @@ -/* - * 2007+ Copyright (c) Evgeniy Polyakov - * All rights reserved. - * - * 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. - */ - -#ifndef __DST_H -#define __DST_H - -#include -#include - -#define DST_NAMELEN 32 -#define DST_NAME "dst" - -enum { - /* Remove node with given id from storage */ - DST_DEL_NODE = 0, - /* Add remote node with given id to the storage */ - DST_ADD_REMOTE, - /* Add local node with given id to the storage to be exported and used by remote peers */ - DST_ADD_EXPORT, - /* Crypto initialization command (hash/cipher used to protect the connection) */ - DST_CRYPTO, - /* Security attributes for given connection (permissions for example) */ - DST_SECURITY, - /* Register given node in the block layer subsystem */ - DST_START, - DST_CMD_MAX -}; - -struct dst_ctl -{ - /* Storage name */ - char name[DST_NAMELEN]; - /* Command flags */ - __u32 flags; - /* Command itself (see above) */ - __u32 cmd; - /* Maximum number of pages per single request in this device */ - __u32 max_pages; - /* Stale/error transaction scanning timeout in milliseconds */ - __u32 trans_scan_timeout; - /* Maximum number of retry sends before completing transaction as broken */ - __u32 trans_max_retries; - /* Storage size */ - __u64 size; -}; - -/* Reply command carries completion status */ -struct dst_ctl_ack -{ - struct cn_msg msg; - int error; - int unused[3]; -}; - -/* - * Unfortunaltely socket address structure is not exported to userspace - * and is redefined there. - */ -#define SADDR_MAX_DATA 128 - -struct saddr { - /* address family, AF_xxx */ - unsigned short sa_family; - /* 14 bytes of protocol address */ - char sa_data[SADDR_MAX_DATA]; - /* Number of bytes used in sa_data */ - unsigned short sa_data_len; -}; - -/* Address structure */ -struct dst_network_ctl -{ - /* Socket type: datagram, stream...*/ - unsigned int type; - /* Let me guess, is it a Jupiter diameter? */ - unsigned int proto; - /* Peer's address */ - struct saddr addr; -}; - -struct dst_crypto_ctl -{ - /* Cipher and hash names */ - char cipher_algo[DST_NAMELEN]; - char hash_algo[DST_NAMELEN]; - - /* Key sizes. Can be zero for digest for example */ - unsigned int cipher_keysize, hash_keysize; - /* Alignment. Calculated by the DST itself. */ - unsigned int crypto_attached_size; - /* Number of threads to perform crypto operations */ - int thread_num; -}; - -/* Export security attributes have this bits checked in when client connects */ -#define DST_PERM_READ (1<<0) -#define DST_PERM_WRITE (1<<1) - -/* - * Right now it is simple model, where each remote address - * is assigned to set of permissions it is allowed to perform. - * In real world block device does not know anything but - * reading and writing, so it should be more than enough. - */ -struct dst_secure_user -{ - unsigned int permissions; - struct saddr addr; -}; - -/* - * Export control command: device to export and network address to accept - * clients to work with given device - */ -struct dst_export_ctl -{ - char device[DST_NAMELEN]; - struct dst_network_ctl ctl; -}; - -enum { - DST_CFG = 1, /* Request remote configuration */ - DST_IO, /* IO command */ - DST_IO_RESPONSE, /* IO response */ - DST_PING, /* Keepalive message */ - DST_NCMD_MAX, -}; - -struct dst_cmd -{ - /* Network command itself, see above */ - __u32 cmd; - /* - * Size of the attached data - * (in most cases, for READ command it means how many bytes were requested) - */ - __u32 size; - /* Crypto size: number of attached bytes with digest/hmac */ - __u32 csize; - /* Here we can carry secret data */ - __u32 reserved; - /* Read/write bits, see how they are encoded in bio structure */ - __u64 rw; - /* BIO flags */ - __u64 flags; - /* Unique command id (like transaction ID) */ - __u64 id; - /* Sector to start IO from */ - __u64 sector; - /* Hash data is placed after this header */ - __u8 hash[0]; -}; - -/* - * Convert command to/from network byte order. - * We do not use hton*() functions, since there is - * no 64-bit implementation. - */ -static inline void dst_convert_cmd(struct dst_cmd *c) -{ - c->cmd = __cpu_to_be32(c->cmd); - c->csize = __cpu_to_be32(c->csize); - c->size = __cpu_to_be32(c->size); - c->sector = __cpu_to_be64(c->sector); - c->id = __cpu_to_be64(c->id); - c->flags = __cpu_to_be64(c->flags); - c->rw = __cpu_to_be64(c->rw); -} - -/* Transaction id */ -typedef __u64 dst_gen_t; - -#ifdef __KERNEL__ - -#include -#include -#include -#include -#include -#include -#include - -#ifdef CONFIG_DST_DEBUG -#define dprintk(f, a...) printk(KERN_NOTICE f, ##a) -#else -static inline void __attribute__ ((format (printf, 1, 2))) - dprintk(const char *fmt, ...) {} -#endif - -struct dst_node; - -struct dst_trans -{ - /* DST node we are working with */ - struct dst_node *n; - - /* Entry inside transaction tree */ - struct rb_node trans_entry; - - /* Merlin kills this transaction when this memory cell equals zero */ - atomic_t refcnt; - - /* How this transaction should be processed by crypto engine */ - short enc; - /* How many times this transaction was resent */ - short retries; - /* Completion status */ - int error; - - /* When did we send it to the remote peer */ - long send_time; - - /* My name is... - * Well, computers does not speak, they have unique id instead */ - dst_gen_t gen; - - /* Block IO we are working with */ - struct bio *bio; - - /* Network command for above block IO request */ - struct dst_cmd cmd; -}; - -struct dst_crypto_engine -{ - /* What should we do with all block requests */ - struct crypto_hash *hash; - struct crypto_ablkcipher *cipher; - - /* Pool of pages used to encrypt data into before sending */ - int page_num; - struct page **pages; - - /* What to do with current request */ - int enc; - /* Who we are and where do we go */ - struct scatterlist *src, *dst; - - /* Maximum timeout waiting for encryption to be completed */ - long timeout; - /* IV is a 64-bit sequential counter */ - u64 iv; - - /* Secret data */ - void *private; - - /* Cached temporary data lives here */ - int size; - void *data; -}; - -struct dst_state -{ - /* The main state protection */ - struct mutex state_lock; - - /* Polling machinery for sockets */ - wait_queue_t wait; - wait_queue_head_t *whead; - /* Most of events are being waited here */ - wait_queue_head_t thread_wait; - - /* Who owns this? */ - struct dst_node *node; - - /* Network address for this state */ - struct dst_network_ctl ctl; - - /* Permissions to work with: read-only or rw connection */ - u32 permissions; - - /* Called when we need to clean private data */ - void (* cleanup)(struct dst_state *st); - - /* Used by the server: BIO completion queues BIOs here */ - struct list_head request_list; - spinlock_t request_lock; - - /* Guess what? No, it is not number of planets */ - atomic_t refcnt; - - /* This flags is set when connection should be dropped */ - int need_exit; - - /* - * Socket to work with. Second pointer is used for - * lockless check if socket was changed before performing - * next action (like working with cached polling result) - */ - struct socket *socket, *read_socket; - - /* Cached preallocated data */ - void *data; - unsigned int size; - - /* Currently processed command */ - struct dst_cmd cmd; -}; - -struct dst_info -{ - /* Device size */ - u64 size; - - /* Local device name for export devices */ - char local[DST_NAMELEN]; - - /* Network setup */ - struct dst_network_ctl net; - - /* Sysfs bits use this */ - struct device device; -}; - -struct dst_node -{ - struct list_head node_entry; - - /* Hi, my name is stored here */ - char name[DST_NAMELEN]; - /* My cache name is stored here */ - char cache_name[DST_NAMELEN]; - - /* Block device attached to given node. - * Only valid for exporting nodes */ - struct block_device *bdev; - /* Network state machine for given peer */ - struct dst_state *state; - - /* Block IO machinery */ - struct request_queue *queue; - struct gendisk *disk; - - /* Number of threads in processing pool */ - int thread_num; - /* Maximum number of pages in single IO */ - int max_pages; - - /* I'm that big in bytes */ - loff_t size; - - /* Exported to userspace node information */ - struct dst_info *info; - - /* - * Security attribute list. - * Used only by exporting node currently. - */ - struct list_head security_list; - struct mutex security_lock; - - /* - * When this unerflows below zero, university collapses. - * But this will not happen, since node will be freed, - * when reference counter reaches zero. - */ - atomic_t refcnt; - - /* How precisely should I be started? */ - int (*start)(struct dst_node *); - - /* Crypto capabilities */ - struct dst_crypto_ctl crypto; - u8 *hash_key; - u8 *cipher_key; - - /* Pool of processing thread */ - struct thread_pool *pool; - - /* Transaction IDs live here */ - atomic_long_t gen; - - /* - * How frequently and how many times transaction - * tree should be scanned to drop stale objects. - */ - long trans_scan_timeout; - int trans_max_retries; - - /* Small gnomes live here */ - struct rb_root trans_root; - struct mutex trans_lock; - - /* - * Transaction cache/memory pool. - * It is big enough to contain not only transaction - * itself, but additional crypto data (digest/hmac). - */ - struct kmem_cache *trans_cache; - mempool_t *trans_pool; - - /* This entity scans transaction tree */ - struct delayed_work trans_work; - - wait_queue_head_t wait; -}; - -/* Kernel representation of the security attribute */ -struct dst_secure -{ - struct list_head sec_entry; - struct dst_secure_user sec; -}; - -int dst_process_bio(struct dst_node *n, struct bio *bio); - -int dst_node_init_connected(struct dst_node *n, struct dst_network_ctl *r); -int dst_node_init_listened(struct dst_node *n, struct dst_export_ctl *le); - -static inline struct dst_state *dst_state_get(struct dst_state *st) -{ - BUG_ON(atomic_read(&st->refcnt) == 0); - atomic_inc(&st->refcnt); - return st; -} - -void dst_state_put(struct dst_state *st); - -struct dst_state *dst_state_alloc(struct dst_node *n); -int dst_state_socket_create(struct dst_state *st); -void dst_state_socket_release(struct dst_state *st); - -void dst_state_exit_connected(struct dst_state *st); - -int dst_state_schedule_receiver(struct dst_state *st); - -void dst_dump_addr(struct socket *sk, struct sockaddr *sa, char *str); - -static inline void dst_state_lock(struct dst_state *st) -{ - mutex_lock(&st->state_lock); -} - -static inline void dst_state_unlock(struct dst_state *st) -{ - mutex_unlock(&st->state_lock); -} - -void dst_poll_exit(struct dst_state *st); -int dst_poll_init(struct dst_state *st); - -static inline unsigned int dst_state_poll(struct dst_state *st) -{ - unsigned int revents = POLLHUP | POLLERR; - - dst_state_lock(st); - if (st->socket) - revents = st->socket->ops->poll(NULL, st->socket, NULL); - dst_state_unlock(st); - - return revents; -} - -static inline int dst_thread_setup(void *private, void *data) -{ - return 0; -} - -void dst_node_put(struct dst_node *n); - -static inline struct dst_node *dst_node_get(struct dst_node *n) -{ - atomic_inc(&n->refcnt); - return n; -} - -int dst_data_recv(struct dst_state *st, void *data, unsigned int size); -int dst_recv_cdata(struct dst_state *st, void *cdata); -int dst_data_send_header(struct socket *sock, - void *data, unsigned int size, int more); - -int dst_send_bio(struct dst_state *st, struct dst_cmd *cmd, struct bio *bio); - -int dst_process_io(struct dst_state *st); -int dst_export_crypto(struct dst_node *n, struct bio *bio); -int dst_export_send_bio(struct bio *bio); -int dst_start_export(struct dst_node *n); - -int __init dst_export_init(void); -void dst_export_exit(void); - -/* Private structure for export block IO requests */ -struct dst_export_priv -{ - struct list_head request_entry; - struct dst_state *state; - struct bio *bio; - struct dst_cmd cmd; -}; - -static inline void dst_trans_get(struct dst_trans *t) -{ - atomic_inc(&t->refcnt); -} - -struct dst_trans *dst_trans_search(struct dst_node *node, dst_gen_t gen); -int dst_trans_remove(struct dst_trans *t); -int dst_trans_remove_nolock(struct dst_trans *t); -void dst_trans_put(struct dst_trans *t); - -/* - * Convert bio into network command. - */ -static inline void dst_bio_to_cmd(struct bio *bio, struct dst_cmd *cmd, - u32 command, u64 id) -{ - cmd->cmd = command; - cmd->flags = (bio->bi_flags << BIO_POOL_BITS) >> BIO_POOL_BITS; - cmd->rw = bio->bi_rw; - cmd->size = bio->bi_size; - cmd->csize = 0; - cmd->id = id; - cmd->sector = bio->bi_sector; -}; - -int dst_trans_send(struct dst_trans *t); -int dst_trans_crypto(struct dst_trans *t); - -int dst_node_crypto_init(struct dst_node *n, struct dst_crypto_ctl *ctl); -void dst_node_crypto_exit(struct dst_node *n); - -static inline int dst_need_crypto(struct dst_node *n) -{ - struct dst_crypto_ctl *c = &n->crypto; - /* - * Logical OR is appropriate here, but boolean one produces - * more optimal code, so it is used instead. - */ - return (c->hash_algo[0] | c->cipher_algo[0]); -} - -int dst_node_trans_init(struct dst_node *n, unsigned int size); -void dst_node_trans_exit(struct dst_node *n); - -/* - * Pool of threads. - * Ready list contains threads currently free to be used, - * active one contains threads with some work scheduled for them. - * Caller can wait in given queue when thread is ready. - */ -struct thread_pool -{ - int thread_num; - struct mutex thread_lock; - struct list_head ready_list, active_list; - - wait_queue_head_t wait; -}; - -void thread_pool_del_worker(struct thread_pool *p); -void thread_pool_del_worker_id(struct thread_pool *p, unsigned int id); -int thread_pool_add_worker(struct thread_pool *p, - char *name, - unsigned int id, - void *(* init)(void *data), - void (* cleanup)(void *data), - void *data); - -void thread_pool_destroy(struct thread_pool *p); -struct thread_pool *thread_pool_create(int num, char *name, - void *(* init)(void *data), - void (* cleanup)(void *data), - void *data); - -int thread_pool_schedule(struct thread_pool *p, - int (* setup)(void *stored_private, void *setup_data), - int (* action)(void *stored_private, void *setup_data), - void *setup_data, long timeout); -int thread_pool_schedule_private(struct thread_pool *p, - int (* setup)(void *private, void *data), - int (* action)(void *private, void *data), - void *data, long timeout, void *id); - -#endif /* __KERNEL__ */ -#endif /* __DST_H */ -- cgit v0.10.2 From d4c3a56587af3edbe5f618b20e800e9f9fde13cb Mon Sep 17 00:00:00 2001 From: Bernd Porr Date: Fri, 27 Nov 2009 12:00:53 +0000 Subject: Staging: comedi: usbdux.c: fix locking up of the driver when the comedi ringbuffer runs empty Jan-Matthias Braun spotted a bug which locks up the driver when the comedi ring buffer runs empty and provided a patch. The driver would still send the data to comedi but the reader won't wake up any more. What's required is setting the flag COMEDI_CB_BLOCK after new data has arrived which wakes up the reader and therefore the read() command. Signed-off-by: Bernd Porr Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index 06c0204..9a1b559 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -1,4 +1,4 @@ -#define DRIVER_VERSION "v2.3" +#define DRIVER_VERSION "v2.4" #define DRIVER_AUTHOR "Bernd Porr, BerndPorr@f2s.com" #define DRIVER_DESC "Stirling/ITL USB-DUX -- Bernd.Porr@f2s.com" /* @@ -81,6 +81,8 @@ sampling rate. If you sample two channels you get 4kHz and so on. * 2.1: changed PWM API * 2.2: added firmware kernel request to fix an udev problem * 2.3: corrected a bug in bulk timeouts which were far too short + * 2.4: fixed a bug which causes the driver to hang when it ran out of data. + * Thanks to Jan-Matthias Braun and Ian to spot the bug and fix it. * */ @@ -532,6 +534,7 @@ static void usbduxsub_ai_IsocIrq(struct urb *urb) } } /* tell comedi that data is there */ + s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS; comedi_event(this_usbduxsub->comedidev, s); } -- cgit v0.10.2 From d103bef45180892515345e761f42db5601de9846 Mon Sep 17 00:00:00 2001 From: Bernd Porr Date: Fri, 27 Nov 2009 12:07:48 +0000 Subject: Staging: comedi: removed "depricated" from COMEDI_CB_BLOCK The flag COMEDI_CB_BLOCK was marked as "depricated in the header file". However, this flag is important to wake up the data-reader (and writer) after new data has arrived from(for) the DAQ card. Signed-off-by: Bernd Porr Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/comedi.h b/drivers/staging/comedi/comedi.h index ccc5cdc..b559a9c 100644 --- a/drivers/staging/comedi/comedi.h +++ b/drivers/staging/comedi/comedi.h @@ -451,7 +451,7 @@ #define COMEDI_CB_EOS 1 /* end of scan */ #define COMEDI_CB_EOA 2 /* end of acquisition */ -#define COMEDI_CB_BLOCK 4 /* DEPRECATED: convenient block size */ +#define COMEDI_CB_BLOCK 4 /* data has arrived: wakes up read() / write() */ #define COMEDI_CB_EOBUF 8 /* DEPRECATED: end of buffer */ #define COMEDI_CB_ERROR 16 /* card error during acquisition */ #define COMEDI_CB_OVERFLOW 32 /* buffer overflow/underflow */ -- cgit v0.10.2 From fa5c5f4ce0c9ba03a670c640cad17e14cb35678b Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 30 Nov 2009 10:59:27 +0000 Subject: Staging: comedi: jr3_pci: Don't ioremap too much space. Check result. For the JR3/PCI cards, the size of the PCIBAR0 region depends on the number of channels. Don't try and ioremap space for 4 channels if the card has fewer channels. Also check for ioremap failure. Thanks to Anders Blomdell for input and Sami Hussein for testing. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c index 0d2c2eb23..bd39784 100644 --- a/drivers/staging/comedi/drivers/jr3_pci.c +++ b/drivers/staging/comedi/drivers/jr3_pci.c @@ -849,8 +849,11 @@ static int jr3_pci_attach(struct comedi_device *dev, } devpriv->pci_enabled = 1; - devpriv->iobase = - ioremap(pci_resource_start(card, 0), sizeof(struct jr3_t)); + devpriv->iobase = ioremap(pci_resource_start(card, 0), + offsetof(struct jr3_t, channel[devpriv->n_channels])); + if (!devpriv->iobase) + return -ENOMEM; + result = alloc_subdevices(dev, devpriv->n_channels); if (result < 0) goto out; -- cgit v0.10.2 From aad445f8ccd554cd3013af7bd0a6cfae599a2505 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Fri, 20 Nov 2009 20:12:33 +0100 Subject: Staging: rtl8192su: fix test for negative error in rtl8192_rx_isr() The error tested for is negative Signed-off-by: Roel Kluin Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8192su/r8192U_core.c b/drivers/staging/rtl8192su/r8192U_core.c index 66274d7..b492ff5 100644 --- a/drivers/staging/rtl8192su/r8192U_core.c +++ b/drivers/staging/rtl8192su/r8192U_core.c @@ -1501,7 +1501,7 @@ static void rtl8192_rx_isr(struct urb *urb) urb->context = skb; skb_queue_tail(&priv->rx_queue, skb); err = usb_submit_urb(urb, GFP_ATOMIC); - if(err && err != EPERM) + if(err && err != -EPERM) printk("can not submit rxurb, err is %x,URB status is %x\n",err,urb->status); } -- cgit v0.10.2 From df574b8ecfb3a84af96229f336a6be88ca4a7055 Mon Sep 17 00:00:00 2001 From: George Kadianakis Date: Thu, 17 Dec 2009 01:16:00 +0200 Subject: Staging: fix rtl8187se compilation errors with mac80211 This patch fixes compilation problems that were caused by function naming conflicts between the rtl8187se driver and the mac80211 stack. Signed-off-by: George Kadianakis Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211.h b/drivers/staging/rtl8187se/ieee80211/ieee80211.h index 3222c22..0d490c1 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211.h @@ -1318,13 +1318,13 @@ extern int ieee80211_encrypt_fragment( struct sk_buff *frag, int hdr_len); -extern int ieee80211_xmit(struct sk_buff *skb, +extern int ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev); extern void ieee80211_txb_free(struct ieee80211_txb *); /* ieee80211_rx.c */ -extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, +extern int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats); extern void ieee80211_rx_mgt(struct ieee80211_device *ieee, struct ieee80211_hdr_4addr *header, @@ -1376,8 +1376,8 @@ extern void ieee80211_stop_protocol(struct ieee80211_device *ieee); extern void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee); extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee); extern void ieee80211_reset_queue(struct ieee80211_device *ieee); -extern void ieee80211_wake_queue(struct ieee80211_device *ieee); -extern void ieee80211_stop_queue(struct ieee80211_device *ieee); +extern void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee); +extern void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee); extern struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee); extern void ieee80211_start_send_beacons(struct ieee80211_device *ieee); extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee); @@ -1385,7 +1385,7 @@ extern int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct extern void notify_wx_assoc_event(struct ieee80211_device *ieee); extern void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success); extern void SendDisassociation(struct ieee80211_device *ieee,u8* asSta,u8 asRsn); -extern void ieee80211_start_scan(struct ieee80211_device *ieee); +extern void ieee80211_rtl_start_scan(struct ieee80211_device *ieee); //Add for RF power on power off by lizhaoming 080512 extern void SendDisassociation(struct ieee80211_device *ieee, diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c index f882dd8..9128c18 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c @@ -469,7 +469,7 @@ drop: /* All received frames are sent to this function. @skb contains the frame in * IEEE 802.11 format, i.e., in the format it was sent over air. * This function is called only as a tasklet (software IRQ). */ -int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, +int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats) { struct net_device *dev = ieee->dev; diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c index 1fe19c3..c7c645a 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c @@ -689,7 +689,7 @@ void ieee80211_stop_scan(struct ieee80211_device *ieee) } /* called with ieee->lock held */ -void ieee80211_start_scan(struct ieee80211_device *ieee) +void ieee80211_rtl_start_scan(struct ieee80211_device *ieee) { if(IS_DOT11D_ENABLE(ieee) ) { @@ -1196,7 +1196,7 @@ void ieee80211_associate_step1(struct ieee80211_device *ieee) } } -void ieee80211_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, int chlen) +void ieee80211_rtl_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, int chlen) { u8 *c; struct sk_buff *skb; @@ -1898,7 +1898,7 @@ associate_complete: ieee80211_associate_step2(ieee); }else{ - ieee80211_auth_challenge(ieee, challenge, chlen); + ieee80211_rtl_auth_challenge(ieee, challenge, chlen); } }else{ ieee->softmac_stats.rx_auth_rs_err++; @@ -2047,7 +2047,7 @@ void ieee80211_reset_queue(struct ieee80211_device *ieee) } -void ieee80211_wake_queue(struct ieee80211_device *ieee) +void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee) { unsigned long flags; @@ -2089,7 +2089,7 @@ exit : } -void ieee80211_stop_queue(struct ieee80211_device *ieee) +void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee) { //unsigned long flags; //spin_lock_irqsave(&ieee->lock,flags); @@ -2301,7 +2301,7 @@ void ieee80211_start_bss(struct ieee80211_device *ieee) //#else if (ieee->state == IEEE80211_NOLINK){ ieee->actscanning = true; - ieee80211_start_scan(ieee); + ieee80211_rtl_start_scan(ieee); } //#endif spin_unlock_irqrestore(&ieee->lock, flags); @@ -2357,7 +2357,7 @@ void ieee80211_associate_retry_wq(struct work_struct *work) if(ieee->state == IEEE80211_NOLINK){ ieee->beinretry = false; ieee->actscanning = true; - ieee80211_start_scan(ieee); + ieee80211_rtl_start_scan(ieee); } //YJ,add,080828, notify os here if(ieee->state == IEEE80211_NOLINK) diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c index dde1f2e..69bd021 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c @@ -304,7 +304,7 @@ ieee80211_classify(struct sk_buff *skb, struct ieee80211_network *network) } /* SKBs are added to the ieee->tx_queue. */ -int ieee80211_xmit(struct sk_buff *skb, +int ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev) { struct ieee80211_device *ieee = netdev_priv(dev); diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c index 57c62b0..e0f13ef 100644 --- a/drivers/staging/rtl8187se/r8180_core.c +++ b/drivers/staging/rtl8187se/r8180_core.c @@ -1811,7 +1811,7 @@ void rtl8180_rx(struct net_device *dev) if(priv->rx_skb->len > 4) skb_trim(priv->rx_skb,priv->rx_skb->len-4); #ifndef RX_DONT_PASS_UL - if(!ieee80211_rx(priv->ieee80211, + if(!ieee80211_rtl_rx(priv->ieee80211, priv->rx_skb, &stats)){ #endif // RX_DONT_PASS_UL @@ -1917,11 +1917,11 @@ rate) if (!check_nic_enought_desc(dev, priority)){ DMESGW("Error: no descriptor left by previous TX (avail %d) ", get_curr_tx_free_desc(dev, priority)); - ieee80211_stop_queue(priv->ieee80211); + ieee80211_rtl_stop_queue(priv->ieee80211); } rtl8180_tx(dev, skb->data, skb->len, priority, morefrag,0,rate); if (!check_nic_enought_desc(dev, priority)) - ieee80211_stop_queue(priv->ieee80211); + ieee80211_rtl_stop_queue(priv->ieee80211); spin_unlock_irqrestore(&priv->tx_lock,flags); } @@ -3680,7 +3680,7 @@ static const struct net_device_ops rtl8180_netdev_ops = { .ndo_set_mac_address = r8180_set_mac_adr, .ndo_validate_addr = eth_validate_addr, .ndo_change_mtu = eth_change_mtu, - .ndo_start_xmit = ieee80211_xmit, + .ndo_start_xmit = ieee80211_rtl_xmit, }; static int __devinit rtl8180_pci_probe(struct pci_dev *pdev, @@ -3900,7 +3900,7 @@ void rtl8180_try_wake_queue(struct net_device *dev, int pri) spin_unlock_irqrestore(&priv->tx_lock,flags); if(enough_desc) - ieee80211_wake_queue(priv->ieee80211); + ieee80211_rtl_wake_queue(priv->ieee80211); } void rtl8180_tx_isr(struct net_device *dev, int pri,short error) diff --git a/drivers/staging/rtl8187se/r8180_wx.c b/drivers/staging/rtl8187se/r8180_wx.c index 536cb6e..124cde3 100644 --- a/drivers/staging/rtl8187se/r8180_wx.c +++ b/drivers/staging/rtl8187se/r8180_wx.c @@ -377,7 +377,7 @@ static int r8180_wx_set_scan(struct net_device *dev, struct iw_request_info *a, // queue_work(priv->ieee80211->wq, &priv->ieee80211->wx_sync_scan_wq); //printk("start scan============================>\n"); ieee80211_softmac_ips_scan_syncro(priv->ieee80211); -//ieee80211_start_scan(priv->ieee80211); +//ieee80211_rtl_start_scan(priv->ieee80211); /* intentionally forget to up sem */ // up(&priv->ieee80211->wx_sem); ret = 0; -- cgit v0.10.2 From fb5fe2776d1e2a0645d8aa3286a1d5ddd95b0723 Mon Sep 17 00:00:00 2001 From: George Kadianakis Date: Thu, 17 Dec 2009 01:18:08 +0200 Subject: staging: fix rtl8192e compilation errors with mac80211 This patch series fixes compilation problems that were caused by function naming conflicts between the rtl8192e driver and the mac80211 stack. Signed-off-by: George Kadianakis Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8192e/ieee80211.h b/drivers/staging/rtl8192e/ieee80211.h index 97137dd..3ba9e9e 100644 --- a/drivers/staging/rtl8192e/ieee80211.h +++ b/drivers/staging/rtl8192e/ieee80211.h @@ -303,8 +303,8 @@ enum _ReasonCode{ #define ieee80211_rx_mgt ieee80211_rx_mgt_rsl #define ieee80211_get_beacon ieee80211_get_beacon_rsl -#define ieee80211_wake_queue ieee80211_wake_queue_rsl -#define ieee80211_stop_queue ieee80211_stop_queue_rsl +#define ieee80211_rtl_wake_queue ieee80211_rtl_wake_queue_rsl +#define ieee80211_rtl_stop_queue ieee80211_rtl_stop_queue_rsl #define ieee80211_reset_queue ieee80211_reset_queue_rsl #define ieee80211_softmac_stop_protocol ieee80211_softmac_stop_protocol_rsl #define ieee80211_softmac_start_protocol ieee80211_softmac_start_protocol_rsl @@ -2435,13 +2435,13 @@ extern int ieee80211_encrypt_fragment( struct sk_buff *frag, int hdr_len); -extern int ieee80211_xmit(struct sk_buff *skb, +extern int ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev); extern void ieee80211_txb_free(struct ieee80211_txb *); /* ieee80211_rx.c */ -extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, +extern int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats); extern void ieee80211_rx_mgt(struct ieee80211_device *ieee, struct ieee80211_hdr_4addr *header, @@ -2502,8 +2502,8 @@ extern void ieee80211_stop_protocol(struct ieee80211_device *ieee); extern void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee); extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee); extern void ieee80211_reset_queue(struct ieee80211_device *ieee); -extern void ieee80211_wake_queue(struct ieee80211_device *ieee); -extern void ieee80211_stop_queue(struct ieee80211_device *ieee); +extern void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee); +extern void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee); extern struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee); extern void ieee80211_start_send_beacons(struct ieee80211_device *ieee); extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee); diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211.h b/drivers/staging/rtl8192e/ieee80211/ieee80211.h index 83c8452..aa76390 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211.h @@ -333,8 +333,8 @@ enum _ReasonCode{ #define ieee80211_rx_mgt ieee80211_rx_mgt_rsl #define ieee80211_get_beacon ieee80211_get_beacon_rsl -#define ieee80211_wake_queue ieee80211_wake_queue_rsl -#define ieee80211_stop_queue ieee80211_stop_queue_rsl +#define ieee80211_rtl_wake_queue ieee80211_rtl_wake_queue_rsl +#define ieee80211_rtl_stop_queue ieee80211_rtl_stop_queue_rsl #define ieee80211_reset_queue ieee80211_reset_queue_rsl #define ieee80211_softmac_stop_protocol ieee80211_softmac_stop_protocol_rsl #define ieee80211_softmac_start_protocol ieee80211_softmac_start_protocol_rsl @@ -2546,13 +2546,13 @@ extern int ieee80211_encrypt_fragment( struct sk_buff *frag, int hdr_len); -extern int ieee80211_xmit(struct sk_buff *skb, +extern int ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev); extern void ieee80211_txb_free(struct ieee80211_txb *); /* ieee80211_rx.c */ -extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, +extern int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats); extern void ieee80211_rx_mgt(struct ieee80211_device *ieee, struct ieee80211_hdr_4addr *header, @@ -2613,8 +2613,8 @@ extern void ieee80211_stop_protocol(struct ieee80211_device *ieee); extern void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee); extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee); extern void ieee80211_reset_queue(struct ieee80211_device *ieee); -extern void ieee80211_wake_queue(struct ieee80211_device *ieee); -extern void ieee80211_stop_queue(struct ieee80211_device *ieee); +extern void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee); +extern void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee); extern struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee); extern void ieee80211_start_send_beacons(struct ieee80211_device *ieee); extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee); diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c index 2644155..f43a7db 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c @@ -119,7 +119,7 @@ struct net_device *alloc_ieee80211(int sizeof_priv) ieee = (struct ieee80211_device *)dev->priv; #endif #if 0 - dev->hard_start_xmit = ieee80211_xmit; + dev->hard_start_xmit = ieee80211_rtl_xmit; #endif memset(ieee, 0, sizeof(struct ieee80211_device)+sizeof_priv); @@ -333,7 +333,7 @@ extern void ieee80211_crypto_ccmp_exit(void); extern int ieee80211_crypto_wep_init(void); extern void ieee80211_crypto_wep_exit(void); -int __init ieee80211_init(void) +int __init ieee80211_rtl_init(void) { struct proc_dir_entry *e; int retval; @@ -389,7 +389,7 @@ int __init ieee80211_init(void) return 0; } -void __exit ieee80211_exit(void) +void __exit ieee80211_rtl_exit(void) { if (ieee80211_proc) { remove_proc_entry("debug_level", ieee80211_proc); @@ -412,8 +412,8 @@ module_param(debug, int, 0444); MODULE_PARM_DESC(debug, "debug output mask"); -//module_exit(ieee80211_exit); -//module_init(ieee80211_init); +//module_exit(ieee80211_rtl_exit); +//module_init(ieee80211_rtl_init); #endif #endif diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c index 5dc478b..06d9171 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c @@ -923,7 +923,7 @@ u8 parse_subframe(struct sk_buff *skb, /* All received frames are sent to this function. @skb contains the frame in * IEEE 802.11 format, i.e., in the format it was sent over air. * This function is called only as a tasklet (software IRQ). */ -int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, +int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats) { struct net_device *dev = ieee->dev; diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c index 593d228..6d1ddec 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c @@ -684,7 +684,7 @@ void ieee80211_stop_scan(struct ieee80211_device *ieee) } /* called with ieee->lock held */ -void ieee80211_start_scan(struct ieee80211_device *ieee) +void ieee80211_rtl_start_scan(struct ieee80211_device *ieee) { #ifdef ENABLE_DOT11D if(IS_DOT11D_ENABLE(ieee) ) @@ -1430,7 +1430,7 @@ void ieee80211_associate_step1(struct ieee80211_device *ieee) } } -void ieee80211_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, int chlen) +void ieee80211_rtl_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, int chlen) { u8 *c; struct sk_buff *skb; @@ -2262,7 +2262,7 @@ ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb, ieee80211_associate_step2(ieee); }else{ - ieee80211_auth_challenge(ieee, challenge, chlen); + ieee80211_rtl_auth_challenge(ieee, challenge, chlen); } }else{ ieee->softmac_stats.rx_auth_rs_err++; @@ -2376,7 +2376,7 @@ void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device * * to check it any more. * */ //printk("error:no descriptor left@queue_index %d\n", queue_index); - //ieee80211_stop_queue(ieee); + //ieee80211_rtl_stop_queue(ieee); #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE skb_queue_tail(&ieee->skb_drv_aggQ[queue_index], txb->fragments[i]); #else @@ -2440,7 +2440,7 @@ void ieee80211_reset_queue(struct ieee80211_device *ieee) } -void ieee80211_wake_queue(struct ieee80211_device *ieee) +void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee) { unsigned long flags; @@ -2481,7 +2481,7 @@ exit : } -void ieee80211_stop_queue(struct ieee80211_device *ieee) +void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee) { //unsigned long flags; //spin_lock_irqsave(&ieee->lock,flags); @@ -2706,7 +2706,7 @@ void ieee80211_start_bss(struct ieee80211_device *ieee) if (ieee->state == IEEE80211_NOLINK){ ieee->actscanning = true; - ieee80211_start_scan(ieee); + ieee80211_rtl_start_scan(ieee); } spin_unlock_irqrestore(&ieee->lock, flags); } @@ -2775,7 +2775,7 @@ void ieee80211_associate_retry_wq(struct ieee80211_device *ieee) { ieee->is_roaming= false; ieee->actscanning = true; - ieee80211_start_scan(ieee); + ieee80211_rtl_start_scan(ieee); } spin_unlock_irqrestore(&ieee->lock, flags); @@ -3497,8 +3497,8 @@ void notify_wx_assoc_event(struct ieee80211_device *ieee) #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) //EXPORT_SYMBOL(ieee80211_get_beacon); -//EXPORT_SYMBOL(ieee80211_wake_queue); -//EXPORT_SYMBOL(ieee80211_stop_queue); +//EXPORT_SYMBOL(ieee80211_rtl_wake_queue); +//EXPORT_SYMBOL(ieee80211_rtl_stop_queue); //EXPORT_SYMBOL(ieee80211_reset_queue); //EXPORT_SYMBOL(ieee80211_softmac_stop_protocol); //EXPORT_SYMBOL(ieee80211_softmac_start_protocol); @@ -3518,8 +3518,8 @@ void notify_wx_assoc_event(struct ieee80211_device *ieee) //EXPORT_SYMBOL(ieee80211_start_scan_syncro); #else EXPORT_SYMBOL_NOVERS(ieee80211_get_beacon); -EXPORT_SYMBOL_NOVERS(ieee80211_wake_queue); -EXPORT_SYMBOL_NOVERS(ieee80211_stop_queue); +EXPORT_SYMBOL_NOVERS(ieee80211_rtl_wake_queue); +EXPORT_SYMBOL_NOVERS(ieee80211_rtl_stop_queue); EXPORT_SYMBOL_NOVERS(ieee80211_reset_queue); EXPORT_SYMBOL_NOVERS(ieee80211_softmac_stop_protocol); EXPORT_SYMBOL_NOVERS(ieee80211_softmac_start_protocol); diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c index 103b33c..798fb41 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c @@ -604,7 +604,7 @@ void ieee80211_query_seqnum(struct ieee80211_device*ieee, struct sk_buff* skb, u } } -int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) +int ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev) { #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) struct ieee80211_device *ieee = netdev_priv(dev); diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index ff8fe7e..0ca5d8b 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -5795,7 +5795,7 @@ static void rtl8192_rx(struct net_device *dev) stats.fragoffset = 0; stats.ntotalfrag = 1; - if(!ieee80211_rx(priv->ieee80211, skb, &stats)){ + if(!ieee80211_rtl_rx(priv->ieee80211, skb, &stats)){ dev_kfree_skb_any(skb); } else { priv->stats.rxok++; @@ -5837,7 +5837,7 @@ static const struct net_device_ops rtl8192_netdev_ops = { .ndo_do_ioctl = rtl8192_ioctl, .ndo_set_multicast_list = r8192_set_multicast, .ndo_set_mac_address = r8192_set_mac_adr, - .ndo_start_xmit = ieee80211_xmit, + .ndo_start_xmit = ieee80211_rtl_xmit, }; /**************************************************************************** @@ -6121,14 +6121,14 @@ static void __devexit rtl8192_pci_disconnect(struct pci_dev *pdev) RT_TRACE(COMP_DOWN, "wlan driver removed\n"); } -extern int ieee80211_init(void); -extern void ieee80211_exit(void); +extern int ieee80211_rtl_init(void); +extern void ieee80211_rtl_exit(void); static int __init rtl8192_pci_module_init(void) { int retval; - retval = ieee80211_init(); + retval = ieee80211_rtl_init(); if (retval) return retval; @@ -6153,7 +6153,7 @@ static void __exit rtl8192_pci_module_exit(void) RT_TRACE(COMP_DOWN, "Exiting"); rtl8192_proc_module_remove(); - ieee80211_exit(); + ieee80211_rtl_exit(); } //warning message WB @@ -6313,7 +6313,7 @@ void rtl8192_try_wake_queue(struct net_device *dev, int pri) spin_unlock_irqrestore(&priv->tx_lock,flags); if(enough_desc) - ieee80211_wake_queue(priv->ieee80211); + ieee80211_rtl_wake_queue(priv->ieee80211); #endif } -- cgit v0.10.2 From 55c7d5fc185e592c317e7cb175f91ee6b9d6c637 Mon Sep 17 00:00:00 2001 From: George Kadianakis Date: Thu, 17 Dec 2009 01:19:13 +0200 Subject: staging: fix rtl8192su compilation errors with mac80211 This patch series fixes compilation problems that were caused by function naming conflicts between the rtl8192su driver and the mac80211 stack. Signed-off-by: George Kadianakis Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211.h b/drivers/staging/rtl8192su/ieee80211/ieee80211.h index f22d024..9a4c858 100644 --- a/drivers/staging/rtl8192su/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8192su/ieee80211/ieee80211.h @@ -1721,13 +1721,13 @@ extern int ieee80211_encrypt_fragment( struct sk_buff *frag, int hdr_len); -extern int rtl8192_ieee80211_xmit(struct sk_buff *skb, +extern int rtl8192_ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev); extern void ieee80211_txb_free(struct ieee80211_txb *); /* ieee80211_rx.c */ -extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, +extern int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats); extern void ieee80211_rx_mgt(struct ieee80211_device *ieee, struct ieee80211_hdr_4addr *header, @@ -1783,8 +1783,8 @@ extern void ieee80211_stop_protocol(struct ieee80211_device *ieee); extern void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee); extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee); extern void ieee80211_reset_queue(struct ieee80211_device *ieee); -extern void ieee80211_wake_queue(struct ieee80211_device *ieee); -extern void ieee80211_stop_queue(struct ieee80211_device *ieee); +extern void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee); +extern void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee); extern struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee); extern void ieee80211_start_send_beacons(struct ieee80211_device *ieee); extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee); diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c index ac223ce..fecfa12 100644 --- a/drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c +++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c @@ -208,7 +208,7 @@ static int ieee80211_frag_cache_invalidate(struct ieee80211_device *ieee, * * Responsible for handling management control frames * - * Called by ieee80211_rx */ + * Called by ieee80211_rtl_rx */ static inline int ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats, u16 type, @@ -289,7 +289,7 @@ static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee, return 0; } -/* Called only as a tasklet (software IRQ), by ieee80211_rx */ +/* Called only as a tasklet (software IRQ), by ieee80211_rtl_rx */ static inline int ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb, struct ieee80211_crypt_data *crypt) @@ -858,7 +858,7 @@ u8 parse_subframe(struct sk_buff *skb, /* All received frames are sent to this function. @skb contains the frame in * IEEE 802.11 format, i.e., in the format it was sent over air. * This function is called only as a tasklet (software IRQ). */ -int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, +int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats) { struct net_device *dev = ieee->dev; diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c index 203c0a5..95d4f84 100644 --- a/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c @@ -610,7 +610,7 @@ void ieee80211_stop_scan(struct ieee80211_device *ieee) } /* called with ieee->lock held */ -void ieee80211_start_scan(struct ieee80211_device *ieee) +void ieee80211_rtl_start_scan(struct ieee80211_device *ieee) { if(IS_DOT11D_ENABLE(ieee) ) { @@ -1281,7 +1281,7 @@ void ieee80211_associate_step1(struct ieee80211_device *ieee) } } -void ieee80211_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, int chlen) +void ieee80211_rtl_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, int chlen) { u8 *c; struct sk_buff *skb; @@ -2054,7 +2054,7 @@ ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb, ieee80211_associate_step2(ieee); }else{ - ieee80211_auth_challenge(ieee, challenge, chlen); + ieee80211_rtl_auth_challenge(ieee, challenge, chlen); } }else{ ieee->softmac_stats.rx_auth_rs_err++; @@ -2162,7 +2162,7 @@ void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device * * to check it any more. * */ //printk("error:no descriptor left@queue_index %d, %d, %d\n", queue_index, skb_queue_len(&ieee->skb_waitQ[queue_index]), ieee->check_nic_enough_desc(ieee->dev,queue_index)); - //ieee80211_stop_queue(ieee); + //ieee80211_rtl_stop_queue(ieee); skb_queue_tail(&ieee->skb_waitQ[queue_index], txb->fragments[i]); }else{ ieee->softmac_data_hard_start_xmit( @@ -2222,7 +2222,7 @@ void ieee80211_reset_queue(struct ieee80211_device *ieee) } -void ieee80211_wake_queue(struct ieee80211_device *ieee) +void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee) { unsigned long flags; @@ -2263,7 +2263,7 @@ exit : } -void ieee80211_stop_queue(struct ieee80211_device *ieee) +void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee) { //unsigned long flags; //spin_lock_irqsave(&ieee->lock,flags); @@ -2479,7 +2479,7 @@ void ieee80211_start_bss(struct ieee80211_device *ieee) if (ieee->state == IEEE80211_NOLINK){ ieee->actscanning = true; - ieee80211_start_scan(ieee); + ieee80211_rtl_start_scan(ieee); } spin_unlock_irqrestore(&ieee->lock, flags); } @@ -2552,7 +2552,7 @@ void ieee80211_associate_retry_wq(struct work_struct *work) if(ieee->state == IEEE80211_NOLINK) { ieee->actscanning = true; - ieee80211_start_scan(ieee); + ieee80211_rtl_start_scan(ieee); } spin_unlock_irqrestore(&ieee->lock, flags); diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_tx.c index 60621d6..4d54e1e 100644 --- a/drivers/staging/rtl8192su/ieee80211/ieee80211_tx.c +++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_tx.c @@ -604,7 +604,7 @@ void ieee80211_query_seqnum(struct ieee80211_device*ieee, struct sk_buff* skb, u } } -int rtl8192_ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) +int rtl8192_ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev) { struct ieee80211_device *ieee = netdev_priv(dev); struct ieee80211_txb *txb = NULL; diff --git a/drivers/staging/rtl8192su/r8192U_core.c b/drivers/staging/rtl8192su/r8192U_core.c index b492ff5..b06fca0 100644 --- a/drivers/staging/rtl8192su/r8192U_core.c +++ b/drivers/staging/rtl8192su/r8192U_core.c @@ -7155,7 +7155,7 @@ void rtl8192SU_rx_nomal(struct sk_buff* skb) unicast_packet = true; } - if(!ieee80211_rx(priv->ieee80211,skb, &stats)) { + if(!ieee80211_rtl_rx(priv->ieee80211,skb, &stats)) { dev_kfree_skb_any(skb); } else { // priv->stats.rxoktotal++; //YJ,test,090108 @@ -7426,7 +7426,7 @@ static const struct net_device_ops rtl8192_netdev_ops = { .ndo_set_mac_address = r8192_set_mac_adr, .ndo_validate_addr = eth_validate_addr, .ndo_change_mtu = eth_change_mtu, - .ndo_start_xmit = rtl8192_ieee80211_xmit, + .ndo_start_xmit = rtl8192_ieee80211_rtl_xmit, }; static int __devinit rtl8192_usb_probe(struct usb_interface *intf, @@ -7619,7 +7619,7 @@ void rtl8192_try_wake_queue(struct net_device *dev, int pri) spin_unlock_irqrestore(&priv->tx_lock,flags); if(enough_desc) - ieee80211_wake_queue(priv->ieee80211); + ieee80211_rtl_wake_queue(priv->ieee80211); } void EnableHWSecurityConfig8192(struct net_device *dev) -- cgit v0.10.2 From 488d3749620779ab2668c0dba2962836e51e3cd6 Mon Sep 17 00:00:00 2001 From: Stephane Glondu Date: Thu, 17 Dec 2009 15:41:23 +0100 Subject: staging: rtl8192su: add USB VID/PID for HWNUm-300 The Hercules Wireless N USB mini (HWNUm-300) uses the RTL8191S chipset and seems to work with this driver. Signed-off-by: Stephane Glondu Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8192su/r8192U_core.c b/drivers/staging/rtl8192su/r8192U_core.c index b06fca0..ccb9d5b 100644 --- a/drivers/staging/rtl8192su/r8192U_core.c +++ b/drivers/staging/rtl8192su/r8192U_core.c @@ -126,6 +126,8 @@ static struct usb_device_id rtl8192_usb_id_tbl[] = { {USB_DEVICE(0x2001, 0x3301)}, /* Zinwell */ {USB_DEVICE(0x5a57, 0x0290)}, + /* Guillemot */ + {USB_DEVICE(0x06f8, 0xe031)}, //92SU {USB_DEVICE(0x0bda, 0x8172)}, {} -- cgit v0.10.2 From 4068fe8b2aa3e12643db0ad5dd4bcf6755a7320f Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Wed, 9 Dec 2009 20:25:04 +0100 Subject: Staging: wlan-ng: fix Correct size given to memset Memset should be given the size of the structure, not the size of the pointer. The semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ type T; T *x; expression E; @@ memset(x, E, sizeof( + * x)) // Signed-off-by: Julia Lawall Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/wlan-ng/prism2fw.c b/drivers/staging/wlan-ng/prism2fw.c index 7d76a7f..aaa70ed 100644 --- a/drivers/staging/wlan-ng/prism2fw.c +++ b/drivers/staging/wlan-ng/prism2fw.c @@ -439,7 +439,7 @@ void free_chunks(imgchunk_t *fchunk, unsigned int *nfchunks) } } *nfchunks = 0; - memset(fchunk, 0, sizeof(fchunk)); + memset(fchunk, 0, sizeof(*fchunk)); } -- cgit v0.10.2 From 3d8affc001a37664b2f5cb29aa12cf8f6c582d52 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 24 Nov 2009 12:13:55 -0800 Subject: Staging: rtl8192x: fix printk formats Fix printk format warnings in rtl8192[eu]: drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c:979: warning: format '%d' expects type 'int', but argument 2 has type 'size_t' drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c:385: warning: format '%d' expects type 'int', but argument 3 has type 'long unsigned int' drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c:484: warning: format '%d' expects type 'int', but argument 3 has type 'long unsigned int' drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c:614: warning: format '%d' expects type 'int', but argument 3 has type 'long unsigned int' drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c:848: warning: format '%d' expects type 'int', but argument 2 has type 'size_t' drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c:343: warning: format '%d' expects type 'int', but argument 3 has type 'long unsigned int' drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c:442: warning: format '%d' expects type 'int', but argument 3 has type 'long unsigned int' drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c:572: warning: format '%d' expects type 'int', but argument 3 has type 'long unsigned int' Signed-off-by: Randy Dunlap Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c index 4e34a1f4..3441b72 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c @@ -976,7 +976,7 @@ int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len) { if (len != ie[1]+2) { - printk("len:%d, ie:%d\n", len, ie[1]); + printk("len:%zu, ie:%d\n", len, ie[1]); return -EINVAL; } buf = kmalloc(len, GFP_KERNEL); diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c b/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c index 98b3bb6..e41e8a0 100644 --- a/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c +++ b/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c @@ -382,7 +382,7 @@ int ieee80211_rx_ADDBAReq( struct ieee80211_device* ieee, struct sk_buff *skb) if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9) { - IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BAREQ(%d / %d)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 9)); + IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BAREQ(%d / %zu)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 9)); return -1; } @@ -481,7 +481,7 @@ int ieee80211_rx_ADDBARsp( struct ieee80211_device* ieee, struct sk_buff *skb) if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9) { - IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BARSP(%d / %d)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 9)); + IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BARSP(%d / %zu)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 9)); return -1; } rsp = ( struct ieee80211_hdr_3addr*)skb->data; @@ -611,7 +611,7 @@ int ieee80211_rx_DELBA(struct ieee80211_device* ieee,struct sk_buff *skb) if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 6) { - IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in DELBA(%d / %d)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 6)); + IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in DELBA(%d / %zu)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 6)); return -1; } diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c index d397f1d..5f12d62 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c @@ -845,7 +845,7 @@ int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len) { if (len != ie[1]+2) { - printk("len:%d, ie:%d\n", len, ie[1]); + printk("len:%zu, ie:%d\n", len, ie[1]); return -EINVAL; } buf = kmalloc(len, GFP_KERNEL); diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c b/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c index 26af43b..512a57a 100644 --- a/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c +++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c @@ -340,7 +340,7 @@ int ieee80211_rx_ADDBAReq( struct ieee80211_device* ieee, struct sk_buff *skb) if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9) { - IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BAREQ(%d / %d)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 9)); + IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BAREQ(%d / %zu)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 9)); return -1; } @@ -439,7 +439,7 @@ int ieee80211_rx_ADDBARsp( struct ieee80211_device* ieee, struct sk_buff *skb) if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9) { - IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BARSP(%d / %d)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 9)); + IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BARSP(%d / %zu)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 9)); return -1; } rsp = ( struct ieee80211_hdr_3addr*)skb->data; @@ -569,7 +569,7 @@ int ieee80211_rx_DELBA(struct ieee80211_device* ieee,struct sk_buff *skb) if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 6) { - IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in DELBA(%d / %d)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 6)); + IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in DELBA(%d / %zu)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 6)); return -1; } -- cgit v0.10.2 From 30fb8a7141e906116bb536dd54be99480b8fd238 Mon Sep 17 00:00:00 2001 From: Nitin Gupta Date: Sat, 12 Dec 2009 11:44:46 +0530 Subject: Staging: ramzswap: remove ARM specific d-cache hack Remove d-cache hack in ramzswap driver that was needed to workaround a bug in ARM version of update_mmu_cache() which caused stale data in d-cache to be transferred to userspace. This bug was fixed by git commit: 787b2faadc4356b6c2c71feb42fb944fece9a12f This also brings down one entry in TODO file. Signed-off-by: Nitin Gupta Acked-by: Pekka Enberg Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/ramzswap/TODO b/drivers/staging/ramzswap/TODO index bac40d6..8d64e28 100644 --- a/drivers/staging/ramzswap/TODO +++ b/drivers/staging/ramzswap/TODO @@ -1,6 +1,5 @@ TODO: - Add support for swap notifiers - - Remove CONFIG_ARM hack Please send patches to Greg Kroah-Hartman and Nitin Gupta diff --git a/drivers/staging/ramzswap/ramzswap_drv.c b/drivers/staging/ramzswap/ramzswap_drv.c index b839f05..989fac5 100644 --- a/drivers/staging/ramzswap/ramzswap_drv.c +++ b/drivers/staging/ramzswap/ramzswap_drv.c @@ -222,28 +222,6 @@ out: return ret; } -static void ramzswap_flush_dcache_page(struct page *page) -{ -#ifdef CONFIG_ARM - int flag = 0; - /* - * Ugly hack to get flush_dcache_page() work on ARM. - * page_mapping(page) == NULL after clearing this swap cache flag. - * Without clearing this flag, flush_dcache_page() will simply set - * "PG_dcache_dirty" bit and return. - */ - if (PageSwapCache(page)) { - flag = 1; - ClearPageSwapCache(page); - } -#endif - flush_dcache_page(page); -#ifdef CONFIG_ARM - if (flag) - SetPageSwapCache(page); -#endif -} - void ramzswap_ioctl_get_stats(struct ramzswap *rzs, struct ramzswap_ioctl_stats *s) { @@ -655,7 +633,7 @@ static int handle_zero_page(struct bio *bio) memset(user_mem, 0, PAGE_SIZE); kunmap_atomic(user_mem, KM_USER0); - ramzswap_flush_dcache_page(page); + flush_dcache_page(page); set_bit(BIO_UPTODATE, &bio->bi_flags); bio_endio(bio, 0); @@ -679,7 +657,7 @@ static int handle_uncompressed_page(struct ramzswap *rzs, struct bio *bio) kunmap_atomic(user_mem, KM_USER0); kunmap_atomic(cmem, KM_USER1); - ramzswap_flush_dcache_page(page); + flush_dcache_page(page); set_bit(BIO_UPTODATE, &bio->bi_flags); bio_endio(bio, 0); @@ -779,7 +757,7 @@ static int ramzswap_read(struct ramzswap *rzs, struct bio *bio) goto out; } - ramzswap_flush_dcache_page(page); + flush_dcache_page(page); set_bit(BIO_UPTODATE, &bio->bi_flags); bio_endio(bio, 0); -- cgit v0.10.2 From a6a6c90804f657a91fb080c7a525a8f90bc38867 Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Tue, 15 Dec 2009 06:21:45 +0100 Subject: Staging: panel: Fix compilation error with custom lcd charset When compiling panel.c with a DEFAULT_LCD_CHARSET it fails to compile with the following error message: drivers/staging/panel/panel.c: In function >>lcd_init<<: drivers/staging/panel/panel.c:1396: error: expected expression before >>;<< token drivers/staging/panel/panel.c:1475: error: expected expression before >>;<< token make[3]: *** [drivers/staging/panel/panel.o] error 1 make[2]: *** [drivers/staging/panel] error 2 make[1]: *** [drivers/staging] error 2 The config used was: CONFIG_PANEL=m CONFIG_PANEL_PARPORT=0 CONFIG_PANEL_PROFILE=0 CONFIG_PANEL_KEYPAD=0 CONFIG_PANEL_LCD=1 CONFIG_PANEL_LCD_HEIGHT=2 CONFIG_PANEL_LCD_WIDTH=20 CONFIG_PANEL_LCD_BWIDTH=40 CONFIG_PANEL_LCD_HWIDTH=64 CONFIG_PANEL_LCD_CHARSET=0 CONFIG_PANEL_LCD_PROTO=0 CONFIG_PANEL_LCD_PIN_E=14 CONFIG_PANEL_LCD_PIN_RS=17 CONFIG_PANEL_LCD_PIN_RW=16 CONFIG_PANEL_LCD_PIN_BL=0 This patch fixes both errors, as it fixes the define Patch against current linux-next tree at Tue Dec 15 06:07:01 2009 +0100 Signed-off-by: Peter Huewe Acked-by: Willy Tarreau Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/panel/panel.c b/drivers/staging/panel/panel.c index f98a524..95c93e8 100644 --- a/drivers/staging/panel/panel.c +++ b/drivers/staging/panel/panel.c @@ -378,7 +378,7 @@ static unsigned char lcd_bits[LCD_PORTS][LCD_BITS][BIT_STATES]; #ifdef CONFIG_PANEL_LCD_CHARSET #undef DEFAULT_LCD_CHARSET -#define DEFAULT_LCD_CHARSET +#define DEFAULT_LCD_CHARSET CONFIG_PANEL_LCD_CHARSET #endif #endif /* DEFAULT_PROFILE == 0 */ -- cgit v0.10.2 From ae08961a99853c5b930845b00e3e609ad13dd61a Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Tue, 15 Dec 2009 06:37:36 +0100 Subject: Staging: panel: Adjust range for PANEL_KEYPAD in Kconfig In panel.c there are only the values 0-3 defined. So 4 is invalid: Signed-off-by: Peter Huewe Cc: Willy Tarreau Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/panel/Kconfig b/drivers/staging/panel/Kconfig index 3abe7c9..3defa01 100644 --- a/drivers/staging/panel/Kconfig +++ b/drivers/staging/panel/Kconfig @@ -47,7 +47,7 @@ config PANEL_PROFILE config PANEL_KEYPAD depends on PANEL && PANEL_PROFILE="0" int "Keypad type (0=none, 1=old 6 keys, 2=new 6 keys, 3=Nexcom 4 keys)" - range 0 4 + range 0 3 default 0 ---help--- This enables and configures a keypad connected to the parallel port. -- cgit v0.10.2 From ae67491ea085529759ab7475f73e7f3f1e825704 Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Sat, 12 Dec 2009 23:39:47 +0100 Subject: Staging: batman-adv: Add Kconfig dependancies on PROC_FS and PACKET. Signed-off-by: Andrew Lunn Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/batman-adv/Kconfig b/drivers/staging/batman-adv/Kconfig index 7632f57..1d74dab 100644 --- a/drivers/staging/batman-adv/Kconfig +++ b/drivers/staging/batman-adv/Kconfig @@ -4,6 +4,7 @@ config BATMAN_ADV tristate "B.A.T.M.A.N. Advanced Meshing Protocol" + depends on PROC_FS && PACKET default n ---help--- -- cgit v0.10.2 From e281cf8966fa723d067343364ba576fb736bfa13 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 13 Dec 2009 14:11:39 +0100 Subject: Staging: batman-adv: introduce missing kfree Error handling code following a kzalloc should free the allocated data. Similarly for usb-alloc urb. The semantic match that finds the first problem is as follows: (http://www.emn.fr/x-info/coccinelle/) // @r exists@ local idexpression x; statement S; expression E; identifier f,f1,l; position p1,p2; expression *ptr != NULL; @@ x@p1 = \(kmalloc\|kzalloc\|kcalloc\)(...); ... if (x == NULL) S <... when != x when != if (...) { <+...x...+> } ( x->f1 = E | (x->f1 == NULL || ...) | f(...,x->f1,...) ) ...> ( return \(0\|<+...x...+>\|ptr\); | return@p2 ...; ) @script:python@ p1 << r.p1; p2 << r.p2; @@ print "* file: %s kmalloc %s return %s" % (p1[0].file,p1[0].line,p2[0].line) // Signed-off-by: Julia Lawall Cc: Andrew Lunn Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/batman-adv/send.c b/drivers/staging/batman-adv/send.c index d724798..eb61750 100644 --- a/drivers/staging/batman-adv/send.c +++ b/drivers/staging/batman-adv/send.c @@ -363,8 +363,10 @@ void add_bcast_packet_to_list(unsigned char *packet_buff, int packet_len) return; forw_packet->packet_buff = kmalloc(packet_len, GFP_ATOMIC); - if (!forw_packet->packet_buff) + if (!forw_packet->packet_buff) { + kfree(forw_packet); return; + } forw_packet->packet_len = packet_len; memcpy(forw_packet->packet_buff, packet_buff, forw_packet->packet_len); -- cgit v0.10.2 From b2cd41496c70a1653f28c6d07b61cbdd25167679 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 14 Dec 2009 08:44:46 -0800 Subject: Staging/vt66*: kconfig, depends on WLAN The vt665[56] drivers can be built when CONFIG_NET=n & CONFIG_NETDEVICES=n or just when CONFIG_WLAN=n. This leads to build failures. Prevent this by making them depend on WLAN. [This patch was lost in a dualing trees merge; still needs to be re-applied.] Signed-off-by: Randy Dunlap Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/vt6655/Kconfig b/drivers/staging/vt6655/Kconfig index 825bbc4..061e730 100644 --- a/drivers/staging/vt6655/Kconfig +++ b/drivers/staging/vt6655/Kconfig @@ -1,6 +1,6 @@ config VT6655 tristate "VIA Technologies VT6655 support" - depends on PCI + depends on PCI && WLAN select WIRELESS_EXT select WEXT_PRIV ---help--- diff --git a/drivers/staging/vt6656/Kconfig b/drivers/staging/vt6656/Kconfig index 87bcd26..1055b52 100644 --- a/drivers/staging/vt6656/Kconfig +++ b/drivers/staging/vt6656/Kconfig @@ -1,6 +1,6 @@ config VT6656 tristate "VIA Technologies VT6656 support" - depends on USB + depends on USB && WLAN select WIRELESS_EXT select WEXT_PRIV ---help--- -- cgit v0.10.2 From d9237380754ccb25bf6aaa1437b0e132ccc70315 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Wed, 23 Dec 2009 19:25:01 +0000 Subject: ARM: mach-osiris: add NAND_SCAN_SILENT_NODEV to optional devices Add the NAND_SCAN_SILENT_NODEV to the optional NAND devices that may not be fitted to the board Signed-off-by: Ben Dooks Signed-off-by: Simtec Linux Team Signed-off-by: Ben Dooks diff --git a/arch/arm/mach-s3c2440/mach-osiris.c b/arch/arm/mach-s3c2440/mach-osiris.c index 015dfb2..f35371d 100644 --- a/arch/arm/mach-s3c2440/mach-osiris.c +++ b/arch/arm/mach-s3c2440/mach-osiris.c @@ -208,6 +208,7 @@ static struct s3c2410_nand_set __initdata osiris_nand_sets[] = { .name = "External", .nr_chips = 1, .nr_map = external_map, + .options = NAND_SCAN_SILENT_NODEV, .nr_partitions = ARRAY_SIZE(osiris_default_nand_part), .partitions = osiris_default_nand_part, }, @@ -222,6 +223,7 @@ static struct s3c2410_nand_set __initdata osiris_nand_sets[] = { .name = "chip1", .nr_chips = 1, .nr_map = chip1_map, + .options = NAND_SCAN_SILENT_NODEV, .nr_partitions = ARRAY_SIZE(osiris_default_nand_part), .partitions = osiris_default_nand_part, }, -- cgit v0.10.2 From d3ef7ee4a7abd0bec23420e589eeaa88ba391e8c Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Wed, 23 Dec 2009 19:25:02 +0000 Subject: ARM: mach-bast: add NAND_SCAN_SILENT_NODEV to optional devices Add the NAND_SCAN_SILENT_NODEV to the optional NAND devices that may not be fitted to the board Signed-off-by: Ben Dooks Signed-off-by: Simtec Linux Team Signed-off-by: Ben Dooks diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c index 4c79ac8..97162fd 100644 --- a/arch/arm/mach-s3c2410/mach-bast.c +++ b/arch/arm/mach-s3c2410/mach-bast.c @@ -279,6 +279,7 @@ static struct s3c2410_nand_set __initdata bast_nand_sets[] = { .name = "SmartMedia", .nr_chips = 1, .nr_map = smartmedia_map, + .options = NAND_SCAN_SILENT_NODEV, .nr_partitions = ARRAY_SIZE(bast_default_nand_part), .partitions = bast_default_nand_part, }, @@ -293,6 +294,7 @@ static struct s3c2410_nand_set __initdata bast_nand_sets[] = { .name = "chip1", .nr_chips = 1, .nr_map = chip1_map, + .options = NAND_SCAN_SILENT_NODEV, .nr_partitions = ARRAY_SIZE(bast_default_nand_part), .partitions = bast_default_nand_part, }, @@ -300,6 +302,7 @@ static struct s3c2410_nand_set __initdata bast_nand_sets[] = { .name = "chip2", .nr_chips = 1, .nr_map = chip2_map, + .options = NAND_SCAN_SILENT_NODEV, .nr_partitions = ARRAY_SIZE(bast_default_nand_part), .partitions = bast_default_nand_part, } -- cgit v0.10.2 From ce8877b542d946ee4fb29b57dc9d6549648b1558 Mon Sep 17 00:00:00 2001 From: Arnaud Patard Date: Wed, 23 Dec 2009 19:25:05 +0000 Subject: ARM: S3C24XX: touchscreen device definition Add definition for the touchscreen driver platform data and initial support for the H1940 machine. Signed-off-by: Arnaud Patard Signed-off-by: Ben Dooks Signed-off-by: Ben Dooks diff --git a/arch/arm/mach-s3c2410/include/mach/ts.h b/arch/arm/mach-s3c2410/include/mach/ts.h new file mode 100644 index 0000000..dc36170 --- /dev/null +++ b/arch/arm/mach-s3c2410/include/mach/ts.h @@ -0,0 +1,21 @@ +/* linux/include/asm/arch-s3c2410/ts.h + * + * Copyright (c) 2005 Arnaud Patard + * + * 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 __ASM_ARM_TS_H +#define __ASM_ARM_TS_H + +struct s3c2410_ts_mach_info { + int delay; + int presc; + int oversampling_shift; +}; + +extern void s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *); + +#endif /* __ASM_ARM_TS_H */ diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c index 4905325..1e34abe 100644 --- a/arch/arm/mach-s3c2410/mach-h1940.c +++ b/arch/arm/mach-s3c2410/mach-h1940.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include @@ -140,6 +141,11 @@ static struct s3c2410_udc_mach_info h1940_udc_cfg __initdata = { .vbus_pin_inverted = 1, }; +static struct s3c2410_ts_mach_info h1940_ts_cfg __initdata = { + .delay = 10000, + .presc = 49, + .oversampling_shift = 2, +}; /** * Set lcd on or off @@ -265,6 +271,7 @@ static struct platform_device h1940_lcd_powerdev = { }; static struct platform_device *h1940_devices[] __initdata = { + &s3c_device_ts, &s3c_device_usb, &s3c_device_lcd, &s3c_device_wdt, @@ -305,6 +312,7 @@ static void __init h1940_init(void) s3c24xx_fb_set_platdata(&h1940_fb_info); s3c24xx_udc_set_platdata(&h1940_udc_cfg); + s3c24xx_ts_set_platdata(&h1940_ts_cfg); s3c_i2c0_set_platdata(NULL); s3c_device_sdi.dev.platform_data = &h1940_mmc_cfg; diff --git a/arch/arm/plat-s3c/include/plat/devs.h b/arch/arm/plat-s3c/include/plat/devs.h index 932cbbb..c1c20b0 100644 --- a/arch/arm/plat-s3c/include/plat/devs.h +++ b/arch/arm/plat-s3c/include/plat/devs.h @@ -31,6 +31,7 @@ extern struct platform_device s3c64xx_device_iisv4; extern struct platform_device s3c64xx_device_pcm0; extern struct platform_device s3c64xx_device_pcm1; +extern struct platform_device s3c_device_ts; extern struct platform_device s3c_device_fb; extern struct platform_device s3c_device_usb; extern struct platform_device s3c_device_lcd; diff --git a/arch/arm/plat-s3c24xx/devs.c b/arch/arm/plat-s3c24xx/devs.c index f52a92c..7f686a3 100644 --- a/arch/arm/plat-s3c24xx/devs.c +++ b/arch/arm/plat-s3c24xx/devs.c @@ -37,6 +37,8 @@ #include #include +#include + /* Serial port registrations */ static struct resource s3c2410_uart0_resource[] = { @@ -182,6 +184,22 @@ void __init s3c24xx_fb_set_platdata(struct s3c2410fb_mach_info *pd) } } +/* Touchscreen */ +struct platform_device s3c_device_ts = { + .name = "s3c2410-ts", + .id = -1, +}; +EXPORT_SYMBOL(s3c_device_ts); + +static struct s3c2410_ts_mach_info s3c2410ts_info; + +void __init s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *hard_s3c2410ts_info) +{ + memcpy(&s3c2410ts_info, hard_s3c2410ts_info, sizeof(struct s3c2410_ts_mach_info)); + s3c_device_ts.dev.platform_data = &s3c2410ts_info; +} +EXPORT_SYMBOL(s3c24xx_ts_set_platdata); + /* USB Device (Gadget)*/ static struct resource s3c_usbgadget_resource[] = { diff --git a/arch/arm/plat-s3c24xx/s3c244x.c b/arch/arm/plat-s3c24xx/s3c244x.c index 1364317..12623a4 100644 --- a/arch/arm/plat-s3c24xx/s3c244x.c +++ b/arch/arm/plat-s3c24xx/s3c244x.c @@ -70,6 +70,7 @@ void __init s3c244x_map_io(void) s3c_device_sdi.name = "s3c2440-sdi"; s3c_device_i2c0.name = "s3c2440-i2c"; s3c_device_nand.name = "s3c2440-nand"; + s3c_device_ts.name = "s3c2440-ts"; s3c_device_usbgadget.name = "s3c2440-usbgadget"; } -- cgit v0.10.2 From baf67741bf52b985e318bed3c4acadcda5351e08 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 8 Dec 2009 15:49:48 -0500 Subject: USB: power management documentation update This patch (as1313) updates the documentation concerning USB power management. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman diff --git a/Documentation/ABI/testing/sysfs-bus-usb b/Documentation/ABI/testing/sysfs-bus-usb index deb6b48..a07c0f3 100644 --- a/Documentation/ABI/testing/sysfs-bus-usb +++ b/Documentation/ABI/testing/sysfs-bus-usb @@ -21,25 +21,27 @@ Contact: Alan Stern Description: Each USB device directory will contain a file named power/level. This file holds a power-level setting for - the device, one of "on", "auto", or "suspend". + the device, either "on" or "auto". "on" means that the device is not allowed to autosuspend, although normal suspends for system sleep will still be honored. "auto" means the device will autosuspend and autoresume in the usual manner, according to the - capabilities of its driver. "suspend" means the device - is forced into a suspended state and it will not autoresume - in response to I/O requests. However remote-wakeup requests - from the device may still be enabled (the remote-wakeup - setting is controlled separately by the power/wakeup - attribute). + capabilities of its driver. During normal use, devices should be left in the "auto" - level. The other levels are meant for administrative uses. + level. The "on" level is meant for administrative uses. If you want to suspend a device immediately but leave it free to wake up in response to I/O requests, you should write "0" to power/autosuspend. + Device not capable of proper suspend and resume should be + left in the "on" level. Although the USB spec requires + devices to support suspend/resume, many of them do not. + In fact so many don't that by default, the USB core + initializes all non-hub devices in the "on" level. Some + drivers may change this setting when they are bound. + What: /sys/bus/usb/devices/.../power/persist Date: May 2007 KernelVersion: 2.6.23 diff --git a/Documentation/usb/power-management.txt b/Documentation/usb/power-management.txt index c7c1dc2..3bf6818 100644 --- a/Documentation/usb/power-management.txt +++ b/Documentation/usb/power-management.txt @@ -71,12 +71,10 @@ being accessed through sysfs, then it definitely is idle. Forms of dynamic PM ------------------- -Dynamic suspends can occur in two ways: manual and automatic. -"Manual" means that the user has told the kernel to suspend a device, -whereas "automatic" means that the kernel has decided all by itself to -suspend a device. Automatic suspend is called "autosuspend" for -short. In general, a device won't be autosuspended unless it has been -idle for some minimum period of time, the so-called idle-delay time. +Dynamic suspends occur when the kernel decides to suspend an idle +device. This is called "autosuspend" for short. In general, a device +won't be autosuspended unless it has been idle for some minimum period +of time, the so-called idle-delay time. Of course, nothing the kernel does on its own initiative should prevent the computer or its devices from working properly. If a @@ -96,10 +94,11 @@ idle. We can categorize power management events in two broad classes: external and internal. External events are those triggered by some agent outside the USB stack: system suspend/resume (triggered by -userspace), manual dynamic suspend/resume (also triggered by -userspace), and remote wakeup (triggered by the device). Internal -events are those triggered within the USB stack: autosuspend and -autoresume. +userspace), manual dynamic resume (also triggered by userspace), and +remote wakeup (triggered by the device). Internal events are those +triggered within the USB stack: autosuspend and autoresume. Note that +all dynamic suspend events are internal; external agents are not +allowed to issue dynamic suspends. The user interface for dynamic PM @@ -145,9 +144,9 @@ relevant attribute files are: wakeup, level, and autosuspend. number of seconds the device should remain idle before the kernel will autosuspend it (the idle-delay time). The default is 2. 0 means to autosuspend as soon as - the device becomes idle, and -1 means never to - autosuspend. You can write a number to the file to - change the autosuspend idle-delay time. + the device becomes idle, and negative values mean + never to autosuspend. You can write a number to the + file to change the autosuspend idle-delay time. Writing "-1" to power/autosuspend and writing "on" to power/level do essentially the same thing -- they both prevent the device from being @@ -377,9 +376,9 @@ the device hasn't been idle for long enough, a delayed workqueue routine is automatically set up to carry out the operation when the autosuspend idle-delay has expired. -Autoresume attempts also can fail. This will happen if power/level is -set to "suspend" or if the device doesn't manage to resume properly. -Unlike autosuspend, there's no delay for an autoresume. +Autoresume attempts also can fail, although failure would mean that +the device is no longer present or operating properly. Unlike +autosuspend, there's no delay for an autoresume. Other parts of the driver interface @@ -527,13 +526,3 @@ succeed, it may still remain active and thus cause the system to resume as soon as the system suspend is complete. Or the remote wakeup may fail and get lost. Which outcome occurs depends on timing and on the hardware and firmware design. - -More interestingly, a device might undergo a manual resume or -autoresume during system suspend. With current kernels this shouldn't -happen, because manual resumes must be initiated by userspace and -autoresumes happen in response to I/O requests, but all user processes -and I/O should be quiescent during a system suspend -- thanks to the -freezer. However there are plans to do away with the freezer, which -would mean these things would become possible. If and when this comes -about, the USB core will carefully arrange matters so that either type -of resume will block until the entire system has resumed. -- cgit v0.10.2 From 8d8558d10806b7e805cb80df867ebb0a453d4765 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 8 Dec 2009 15:50:41 -0500 Subject: USB: rename usb_configure_device This patch (as1314) renames usb_configure_device() and usb_configure_device_otg() in the hub driver. Neither name is appropriate because these routines enumerate devices, they don't configure them. That's handled by usb_choose_configuration() and usb_set_configuration(). Signed-off-by: Alan Stern Cc: stable Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 06af970..28738fa 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1658,12 +1658,12 @@ static inline void announce_device(struct usb_device *udev) { } #endif /** - * usb_configure_device_otg - FIXME (usbcore-internal) + * usb_enumerate_device_otg - FIXME (usbcore-internal) * @udev: newly addressed device (in ADDRESS state) * - * Do configuration for On-The-Go devices + * Finish enumeration for On-The-Go devices */ -static int usb_configure_device_otg(struct usb_device *udev) +static int usb_enumerate_device_otg(struct usb_device *udev) { int err = 0; @@ -1734,7 +1734,7 @@ fail: /** - * usb_configure_device - Detect and probe device intfs/otg (usbcore-internal) + * usb_enumerate_device - Read device configs/intfs/otg (usbcore-internal) * @udev: newly addressed device (in ADDRESS state) * * This is only called by usb_new_device() and usb_authorize_device() @@ -1745,7 +1745,7 @@ fail: * the string descriptors, as they will be errored out by the device * until it has been authorized. */ -static int usb_configure_device(struct usb_device *udev) +static int usb_enumerate_device(struct usb_device *udev) { int err; @@ -1769,7 +1769,7 @@ static int usb_configure_device(struct usb_device *udev) udev->descriptor.iManufacturer); udev->serial = usb_cache_string(udev, udev->descriptor.iSerialNumber); } - err = usb_configure_device_otg(udev); + err = usb_enumerate_device_otg(udev); fail: return err; } @@ -1779,8 +1779,8 @@ fail: * usb_new_device - perform initial device setup (usbcore-internal) * @udev: newly addressed device (in ADDRESS state) * - * This is called with devices which have been enumerated, but not yet - * configured. The device descriptor is available, but not descriptors + * This is called with devices which have been detected but not fully + * enumerated. The device descriptor is available, but not descriptors * for any device configuration. The caller must have locked either * the parent hub (if udev is a normal device) or else the * usb_bus_list_lock (if udev is a root hub). The parent's pointer to @@ -1803,8 +1803,8 @@ int usb_new_device(struct usb_device *udev) if (udev->parent) usb_autoresume_device(udev->parent); - usb_detect_quirks(udev); /* Determine quirks */ - err = usb_configure_device(udev); /* detect & probe dev/intfs */ + usb_detect_quirks(udev); + err = usb_enumerate_device(udev); /* Read descriptors */ if (err < 0) goto fail; dev_dbg(&udev->dev, "udev %d, busnum %d, minor = %d\n", @@ -1895,9 +1895,9 @@ int usb_authorize_device(struct usb_device *usb_dev) goto error_device_descriptor; } usb_dev->authorized = 1; - result = usb_configure_device(usb_dev); + result = usb_enumerate_device(usb_dev); if (result < 0) - goto error_configure; + goto error_enumerate; /* Choose and set the configuration. This registers the interfaces * with the driver core and lets interface drivers bind to them. */ @@ -1912,7 +1912,7 @@ int usb_authorize_device(struct usb_device *usb_dev) } } dev_info(&usb_dev->dev, "authorized to connect\n"); -error_configure: +error_enumerate: error_device_descriptor: error_autoresume: out_authorized: -- cgit v0.10.2 From da307123c621b01cce147a4be313d8a754674f63 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 8 Dec 2009 15:54:44 -0500 Subject: USB: fix bugs in usb_(de)authorize_device This patch (as1315) fixes some bugs in the USB core authorization code: usb_deauthorize_device() should deallocate the device strings instead of leaking them, and it should invoke usb_destroy_configuration() (which does proper reference counting) instead of freeing the config information directly. usb_authorize_device() shouldn't change the device strings until it knows that the authorization will succeed, and it should autosuspend the device at the end (having autoresumed the device at the start). Because the device strings can be changed, the sysfs routines to display the strings must protect the string pointers by locking the device. Signed-off-by: Alan Stern CC: Inaky Perez-Gonzalez Acked-by: David Vrabel Cc: stable Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 28738fa..0cec6ca 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1849,21 +1849,23 @@ fail: */ int usb_deauthorize_device(struct usb_device *usb_dev) { - unsigned cnt; usb_lock_device(usb_dev); if (usb_dev->authorized == 0) goto out_unauthorized; + usb_dev->authorized = 0; usb_set_configuration(usb_dev, -1); + + kfree(usb_dev->product); usb_dev->product = kstrdup("n/a (unauthorized)", GFP_KERNEL); + kfree(usb_dev->manufacturer); usb_dev->manufacturer = kstrdup("n/a (unauthorized)", GFP_KERNEL); + kfree(usb_dev->serial); usb_dev->serial = kstrdup("n/a (unauthorized)", GFP_KERNEL); - kfree(usb_dev->config); - usb_dev->config = NULL; - for (cnt = 0; cnt < usb_dev->descriptor.bNumConfigurations; cnt++) - kfree(usb_dev->rawdescriptors[cnt]); + + usb_destroy_configuration(usb_dev); usb_dev->descriptor.bNumConfigurations = 0; - kfree(usb_dev->rawdescriptors); + out_unauthorized: usb_unlock_device(usb_dev); return 0; @@ -1873,15 +1875,11 @@ out_unauthorized: int usb_authorize_device(struct usb_device *usb_dev) { int result = 0, c; + usb_lock_device(usb_dev); if (usb_dev->authorized == 1) goto out_authorized; - kfree(usb_dev->product); - usb_dev->product = NULL; - kfree(usb_dev->manufacturer); - usb_dev->manufacturer = NULL; - kfree(usb_dev->serial); - usb_dev->serial = NULL; + result = usb_autoresume_device(usb_dev); if (result < 0) { dev_err(&usb_dev->dev, @@ -1894,6 +1892,14 @@ int usb_authorize_device(struct usb_device *usb_dev) "authorization: %d\n", result); goto error_device_descriptor; } + + kfree(usb_dev->product); + usb_dev->product = NULL; + kfree(usb_dev->manufacturer); + usb_dev->manufacturer = NULL; + kfree(usb_dev->serial); + usb_dev->serial = NULL; + usb_dev->authorized = 1; result = usb_enumerate_device(usb_dev); if (result < 0) @@ -1912,8 +1918,10 @@ int usb_authorize_device(struct usb_device *usb_dev) } } dev_info(&usb_dev->dev, "authorized to connect\n"); + error_enumerate: error_device_descriptor: + usb_autosuspend_device(usb_dev); error_autoresume: out_authorized: usb_unlock_device(usb_dev); // complements locktree diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 1547700..485edf9 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -82,9 +82,13 @@ static ssize_t show_##name(struct device *dev, \ struct device_attribute *attr, char *buf) \ { \ struct usb_device *udev; \ + int retval; \ \ udev = to_usb_device(dev); \ - return sprintf(buf, "%s\n", udev->name); \ + usb_lock_device(udev); \ + retval = sprintf(buf, "%s\n", udev->name); \ + usb_unlock_device(udev); \ + return retval; \ } \ static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL); -- cgit v0.10.2 From ff3b968ceeb73c037cf4759d21923943970f9a7a Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Wed, 9 Dec 2009 14:23:32 +0100 Subject: USB: gadget: Use ERR_PTR/IS_ERR Use ERR_PTR and IS_ERR rather than mixing integers and pointers. The semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @@ expression *E; @@ * E < 0 // Signed-off-by: Julia Lawall Acked-by: David Brownell Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/gadget/f_audio.c b/drivers/usb/gadget/f_audio.c index c43c89f..0f2eee1 100644 --- a/drivers/usb/gadget/f_audio.c +++ b/drivers/usb/gadget/f_audio.c @@ -252,12 +252,12 @@ static struct f_audio_buf *f_audio_buffer_alloc(int buf_size) copy_buf = kzalloc(sizeof *copy_buf, GFP_ATOMIC); if (!copy_buf) - return (struct f_audio_buf *)-ENOMEM; + return ERR_PTR(-ENOMEM); copy_buf->buf = kzalloc(buf_size, GFP_ATOMIC); if (!copy_buf->buf) { kfree(copy_buf); - return (struct f_audio_buf *)-ENOMEM; + return ERR_PTR(-ENOMEM); } return copy_buf; @@ -332,7 +332,7 @@ static int f_audio_out_ep_complete(struct usb_ep *ep, struct usb_request *req) list_add_tail(©_buf->list, &audio->play_queue); schedule_work(&audio->playback_work); copy_buf = f_audio_buffer_alloc(audio_buf_size); - if (copy_buf < 0) + if (IS_ERR(copy_buf)) return -ENOMEM; } @@ -576,6 +576,8 @@ static int f_audio_set_alt(struct usb_function *f, unsigned intf, unsigned alt) usb_ep_enable(out_ep, audio->out_desc); out_ep->driver_data = audio; audio->copy_buf = f_audio_buffer_alloc(audio_buf_size); + if (IS_ERR(audio->copy_buf)) + return -ENOMEM; /* * allocate a bunch of read buffers -- cgit v0.10.2 From 179192d38e8906f00479ec944c15b685400232b0 Mon Sep 17 00:00:00 2001 From: Bill Gatliff Date: Fri, 18 Dec 2009 09:57:22 -0600 Subject: USB: Fix double-linking of drivers/usb/otg when ULPI is selected This patch corrects a problem where drivers/usb/otg is linked twice if CONFIG_USB_ULPI is selected, resulting in a build error (symbol conflict). The files in that directory are properly linked already as part of CONFIG_USB, and need not be indicated specifically for CONFIG_USB_ULPI. Signed-off-by: Bill Gatliff Acked-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index 473aa1a..be3c9b8 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile @@ -44,5 +44,3 @@ obj-y += early/ obj-$(CONFIG_USB_ATM) += atm/ obj-$(CONFIG_USB_SPEEDTOUCH) += atm/ - -obj-$(CONFIG_USB_ULPI) += otg/ -- cgit v0.10.2 From 27f1281d5f72e4f161e215ccad3d7d86b9e624a9 Mon Sep 17 00:00:00 2001 From: Blaise Gassend Date: Fri, 18 Dec 2009 15:23:38 -0800 Subject: USB: serial: Extra device/vendor ID for mos7840 driver Signed-off-by: Blaise Gassend Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 485fa9c..2cfe245 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c @@ -127,8 +127,9 @@ #define BANDB_DEVICE_ID_US9ML2_4 0xAC30 #define BANDB_DEVICE_ID_USPTL4_2 0xAC31 #define BANDB_DEVICE_ID_USPTL4_4 0xAC32 -#define BANDB_DEVICE_ID_USOPTL4_2 0xAC42 -#define BANDB_DEVICE_ID_USOPTL4_4 0xAC44 +#define BANDB_DEVICE_ID_USOPTL4_2 0xAC42 +#define BANDB_DEVICE_ID_USOPTL4_4 0xAC44 +#define BANDB_DEVICE_ID_USOPTL2_4 0xAC24 /* This driver also supports * ATEN UC2324 device using Moschip MCS7840 @@ -191,6 +192,7 @@ static struct usb_device_id moschip_port_id_table[] = { {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_4)}, {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)}, {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)}, + {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL2_4)}, {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)}, {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2322)}, {} /* terminating entry */ @@ -207,6 +209,7 @@ static __devinitdata struct usb_device_id moschip_id_table_combined[] = { {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_4)}, {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)}, {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)}, + {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL2_4)}, {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)}, {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2322)}, {} /* terminating entry */ -- cgit v0.10.2 From ac06c06770bb8761b1f1f9bdf2f5420fa6d3e9fa Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 21 Dec 2009 15:36:44 -0800 Subject: USB: emi62: fix crash when trying to load EMI 6|2 firmware While converting emi62 to use request_firmware(), the driver was also changed to use the ihex helper functions. However, this broke the loading of the FPGA firmware because the code tries to access the addr field of the EOF record which works with a plain array that has an empty last record but not with the ihex helper functions where the end of the data is signaled with a NULL record pointer, resulting in: BUG: unable to handle kernel NULL pointer dereference at (null) IP: [] emi62_load_firmware+0x33c/0x740 [emi62] This can be fixed by changing the loop condition to test the return value of ihex_next_binrec() directly (like in emi26.c). Signed-off-by: Clemens Ladisch Reported-and-tested-by: Der Mickster Acked-by: David Woodhouse Cc: stable Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/misc/emi62.c b/drivers/usb/misc/emi62.c index 602ee05..59860b3 100644 --- a/drivers/usb/misc/emi62.c +++ b/drivers/usb/misc/emi62.c @@ -167,7 +167,7 @@ static int emi62_load_firmware (struct usb_device *dev) err("%s - error loading firmware: error = %d", __func__, err); goto wraperr; } - } while (i > 0); + } while (rec); /* Assert reset (stop the CPU in the EMI) */ err = emi62_set_reset(dev,1); -- cgit v0.10.2 From 40b52371be92cf9990de162e4c7b4fd9160150a7 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Fri, 20 Nov 2009 13:50:53 +0000 Subject: USB: fix section mismatch in early ehci dbgp Commit 917778267fbe67703ab7d5c6f0b7a05d4c3df485 removed __init from ehci_wait_for_port(), but left it in place on ehci_reset_port(), which is being called from the former function. Signed-off-by: Jan Beulich Acked-by: Jason Wessel Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/early/ehci-dbgp.c b/drivers/usb/early/ehci-dbgp.c index 1206a26..2958a12 100644 --- a/drivers/usb/early/ehci-dbgp.c +++ b/drivers/usb/early/ehci-dbgp.c @@ -613,7 +613,7 @@ err: } EXPORT_SYMBOL_GPL(dbgp_external_startup); -static int __init ehci_reset_port(int port) +static int ehci_reset_port(int port) { u32 portsc; u32 delay_time, delay; -- cgit v0.10.2 From 4b372072b554723b508e53249dd1b594ad93fbc2 Mon Sep 17 00:00:00 2001 From: pancho horrillo Date: Wed, 2 Dec 2009 20:19:42 +0100 Subject: USB: add device ID for Apple Cinema Display 23in 2007 Hi! $ lsusb -v Bus 001 Device 008: ID 05ac:921c Apple, Inc. Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 1.10 bDeviceClass 0 (Defined at Interface level) bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 8 idVendor 0x05ac Apple, Inc. idProduct 0x921c bcdDevice 1.15 iManufacturer 1 iProduct 2 iSerial 0 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 34 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 0 bmAttributes 0xe0 Self Powered Remote Wakeup MaxPower 2mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 3 Human Interface Device bInterfaceSubClass 0 No Subclass bInterfaceProtocol 0 None iInterface 0 HID Device Descriptor: bLength 9 bDescriptorType 33 bcdHID 1.11 bCountryCode 0 Not supported bNumDescriptors 1 bDescriptorType 34 Report wDescriptorLength 92 Report Descriptors: ** UNAVAILABLE ** Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0008 1x 8 bytes bInterval 16 Signed-off-by: pancho horrillo Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/misc/appledisplay.c b/drivers/usb/misc/appledisplay.c index 1d8e39a..8dc4afa 100644 --- a/drivers/usb/misc/appledisplay.c +++ b/drivers/usb/misc/appledisplay.c @@ -60,6 +60,7 @@ static struct usb_device_id appledisplay_table [] = { { APPLEDISPLAY_DEVICE(0x9218) }, { APPLEDISPLAY_DEVICE(0x9219) }, + { APPLEDISPLAY_DEVICE(0x921c) }, { APPLEDISPLAY_DEVICE(0x921d) }, /* Terminating entry */ -- cgit v0.10.2 From 70445ae6c669865e464307a155e881096e4a0ae7 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sun, 13 Dec 2009 10:17:16 -0800 Subject: USB core: fix recent kernel-doc warnings Fix new kernel-doc warnings in usb core: Warning(drivers/usb/core/usb.c:79): No description found for parameter 'config' Warning(drivers/usb/core/usb.c:79): No description found for parameter 'iface_num' Warning(drivers/usb/core/usb.c:79): No description found for parameter 'alt_num' Warning(drivers/usb/core/hcd.c:1622): No description found for parameter 'udev' Signed-off-by: Randy Dunlap Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 6dac3b8..0495fa6 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -1597,7 +1597,9 @@ rescan: } /** - * Check whether a new bandwidth setting exceeds the bus bandwidth. + * usb_hcd_alloc_bandwidth - check whether a new bandwidth setting exceeds + * the bus bandwidth + * @udev: target &usb_device * @new_config: new configuration to install * @cur_alt: the current alternate interface setting * @new_alt: alternate interface setting that is being installed diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 2fb4204..0daff0d 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -66,9 +66,9 @@ MODULE_PARM_DESC(autosuspend, "default autosuspend delay"); /** * usb_find_alt_setting() - Given a configuration, find the alternate setting * for the given interface. - * @config - the configuration to search (not necessarily the current config). - * @iface_num - interface number to search in - * @alt_num - alternate interface setting number to search for. + * @config: the configuration to search (not necessarily the current config). + * @iface_num: interface number to search in + * @alt_num: alternate interface setting number to search for. * * Search the configuration's interface cache for the given alt setting. */ -- cgit v0.10.2 From 31844d55800e1b93fe75c4d6188a4a44db2e1bbe Mon Sep 17 00:00:00 2001 From: Andreas Mohr Date: Wed, 16 Dec 2009 21:45:10 +0100 Subject: USB: ftdi_sio: isolate all device IDs to new ftdi_sio_ids.h header This is a strictly move-only patch to relocate all FTDI device product ID definitions to their own ftdi_sio_ids.h header (following the usual *_ids.h kernel tree convention, too), thus correcting the slightly too messy appearance (crucial driver defines were stuck somewhere in the decaying middle swamp of the huge existing header). Compile-tested, based on latest mainline git. Signed-off-by: Andreas Mohr Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index f99498f..216f187 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -44,6 +44,7 @@ #include #include #include "ftdi_sio.h" +#include "ftdi_sio_ids.h" /* * Version Information diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 4586a24..b0e0d64 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h @@ -1,7 +1,10 @@ /* - * Definitions for the FTDI USB Single Port Serial Converter - + * Driver definitions for the FTDI USB Single Port Serial Converter - * known as FTDI_SIO (Serial Input/Output application of the chipset) * + * For USB vendor/product IDs (VID/PID), please see ftdi_sio_ids.h + * + * * The example I have is known as the USC-1000 which is available from * http://www.dse.co.nz - cat no XH4214 It looks similar to this: * http://www.dansdata.com/usbser.htm but I can't be sure There are other @@ -17,880 +20,7 @@ * Bill Ryder - bryder@sgi.com formerly of Silicon Graphics, Inc.- wrote the * FTDI_SIO implementation. * - * Philipp Gühring - pg@futureware.at - added the Device ID of the USB relais - * from Rudolf Gugler - * - */ - -#define FTDI_VID 0x0403 /* Vendor Id */ -#define FTDI_SIO_PID 0x8372 /* Product Id SIO application of 8U100AX */ -#define FTDI_8U232AM_PID 0x6001 /* Similar device to SIO above */ -#define FTDI_8U232AM_ALT_PID 0x6006 /* FTDI's alternate PID for above */ -#define FTDI_8U2232C_PID 0x6010 /* Dual channel device */ -#define FTDI_232RL_PID 0xFBFA /* Product ID for FT232RL */ -#define FTDI_4232H_PID 0x6011 /* Quad channel hi-speed device */ -#define FTDI_RELAIS_PID 0xFA10 /* Relais device from Rudolf Gugler */ -#define FTDI_NF_RIC_VID 0x0DCD /* Vendor Id */ -#define FTDI_NF_RIC_PID 0x0001 /* Product Id */ -#define FTDI_USBX_707_PID 0xF857 /* ADSTech IR Blaster USBX-707 */ - -/* Larsen and Brusgaard AltiTrack/USBtrack */ -#define LARSENBRUSGAARD_VID 0x0FD8 -#define LB_ALTITRACK_PID 0x0001 - -/* www.canusb.com Lawicel CANUSB device */ -#define FTDI_CANUSB_PID 0xFFA8 /* Product Id */ - -/* AlphaMicro Components AMC-232USB01 device */ -#define FTDI_AMC232_PID 0xFF00 /* Product Id */ - -/* www.candapter.com Ewert Energy Systems CANdapter device */ -#define FTDI_CANDAPTER_PID 0x9F80 /* Product Id */ - -/* SCS HF Radio Modems PID's (http://www.scs-ptc.com) */ -/* the VID is the standard ftdi vid (FTDI_VID) */ -#define FTDI_SCS_DEVICE_0_PID 0xD010 /* SCS PTC-IIusb */ -#define FTDI_SCS_DEVICE_1_PID 0xD011 /* SCS Tracker / DSP TNC */ -#define FTDI_SCS_DEVICE_2_PID 0xD012 -#define FTDI_SCS_DEVICE_3_PID 0xD013 -#define FTDI_SCS_DEVICE_4_PID 0xD014 -#define FTDI_SCS_DEVICE_5_PID 0xD015 -#define FTDI_SCS_DEVICE_6_PID 0xD016 -#define FTDI_SCS_DEVICE_7_PID 0xD017 - -/* ACT Solutions HomePro ZWave interface (http://www.act-solutions.com/HomePro.htm) */ -#define FTDI_ACTZWAVE_PID 0xF2D0 - - -/* www.starting-point-systems.com µChameleon device */ -#define FTDI_MICRO_CHAMELEON_PID 0xCAA0 /* Product Id */ - -/* www.irtrans.de device */ -#define FTDI_IRTRANS_PID 0xFC60 /* Product Id */ - - -/* www.thoughttechnology.com/ TT-USB provide with procomp use ftdi_sio */ -#define FTDI_TTUSB_PID 0xFF20 /* Product Id */ - -/* iPlus device */ -#define FTDI_IPLUS_PID 0xD070 /* Product Id */ -#define FTDI_IPLUS2_PID 0xD071 /* Product Id */ - -/* DMX4ALL DMX Interfaces */ -#define FTDI_DMX4ALL 0xC850 - -/* OpenDCC (www.opendcc.de) product id */ -#define FTDI_OPENDCC_PID 0xBFD8 -#define FTDI_OPENDCC_SNIFFER_PID 0xBFD9 -#define FTDI_OPENDCC_THROTTLE_PID 0xBFDA -#define FTDI_OPENDCC_GATEWAY_PID 0xBFDB - -/* Sprog II (Andrew Crosland's SprogII DCC interface) */ -#define FTDI_SPROG_II 0xF0C8 - -/* www.crystalfontz.com devices - thanx for providing free devices for evaluation ! */ -/* they use the ftdi chipset for the USB interface and the vendor id is the same */ -#define FTDI_XF_632_PID 0xFC08 /* 632: 16x2 Character Display */ -#define FTDI_XF_634_PID 0xFC09 /* 634: 20x4 Character Display */ -#define FTDI_XF_547_PID 0xFC0A /* 547: Two line Display */ -#define FTDI_XF_633_PID 0xFC0B /* 633: 16x2 Character Display with Keys */ -#define FTDI_XF_631_PID 0xFC0C /* 631: 20x2 Character Display */ -#define FTDI_XF_635_PID 0xFC0D /* 635: 20x4 Character Display */ -#define FTDI_XF_640_PID 0xFC0E /* 640: Two line Display */ -#define FTDI_XF_642_PID 0xFC0F /* 642: Two line Display */ - -/* Video Networks Limited / Homechoice in the UK use an ftdi-based device for their 1Mb */ -/* broadband internet service. The following PID is exhibited by the usb device supplied */ -/* (the VID is the standard ftdi vid (FTDI_VID) */ -#define FTDI_VNHCPCUSB_D_PID 0xfe38 /* Product Id */ - -/* - * PCDJ use ftdi based dj-controllers. The following PID is for their DAC-2 device - * http://www.pcdjhardware.com/DAC2.asp (PID sent by Wouter Paesen) - * (the VID is the standard ftdi vid (FTDI_VID) */ -#define FTDI_PCDJ_DAC2_PID 0xFA88 - -/* - * The following are the values for the Matrix Orbital LCD displays, - * which are the FT232BM ( similar to the 8U232AM ) - */ -#define FTDI_MTXORB_0_PID 0xFA00 /* Matrix Orbital Product Id */ -#define FTDI_MTXORB_1_PID 0xFA01 /* Matrix Orbital Product Id */ -#define FTDI_MTXORB_2_PID 0xFA02 /* Matrix Orbital Product Id */ -#define FTDI_MTXORB_3_PID 0xFA03 /* Matrix Orbital Product Id */ -#define FTDI_MTXORB_4_PID 0xFA04 /* Matrix Orbital Product Id */ -#define FTDI_MTXORB_5_PID 0xFA05 /* Matrix Orbital Product Id */ -#define FTDI_MTXORB_6_PID 0xFA06 /* Matrix Orbital Product Id */ - -/* OOCDlink by Joern Kaipf - * (http://www.joernonline.de/dw/doku.php?id=start&idx=projects:oocdlink) */ -#define FTDI_OOCDLINK_PID 0xbaf8 /* Amontec JTAGkey */ - -/* - * The following are the values for the Matrix Orbital FTDI Range - * Anything in this range will use an FT232RL. - */ -#define MTXORB_VID 0x1B3D -#define MTXORB_FTDI_RANGE_0100_PID 0x0100 -#define MTXORB_FTDI_RANGE_0101_PID 0x0101 -#define MTXORB_FTDI_RANGE_0102_PID 0x0102 -#define MTXORB_FTDI_RANGE_0103_PID 0x0103 -#define MTXORB_FTDI_RANGE_0104_PID 0x0104 -#define MTXORB_FTDI_RANGE_0105_PID 0x0105 -#define MTXORB_FTDI_RANGE_0106_PID 0x0106 -#define MTXORB_FTDI_RANGE_0107_PID 0x0107 -#define MTXORB_FTDI_RANGE_0108_PID 0x0108 -#define MTXORB_FTDI_RANGE_0109_PID 0x0109 -#define MTXORB_FTDI_RANGE_010A_PID 0x010A -#define MTXORB_FTDI_RANGE_010B_PID 0x010B -#define MTXORB_FTDI_RANGE_010C_PID 0x010C -#define MTXORB_FTDI_RANGE_010D_PID 0x010D -#define MTXORB_FTDI_RANGE_010E_PID 0x010E -#define MTXORB_FTDI_RANGE_010F_PID 0x010F -#define MTXORB_FTDI_RANGE_0110_PID 0x0110 -#define MTXORB_FTDI_RANGE_0111_PID 0x0111 -#define MTXORB_FTDI_RANGE_0112_PID 0x0112 -#define MTXORB_FTDI_RANGE_0113_PID 0x0113 -#define MTXORB_FTDI_RANGE_0114_PID 0x0114 -#define MTXORB_FTDI_RANGE_0115_PID 0x0115 -#define MTXORB_FTDI_RANGE_0116_PID 0x0116 -#define MTXORB_FTDI_RANGE_0117_PID 0x0117 -#define MTXORB_FTDI_RANGE_0118_PID 0x0118 -#define MTXORB_FTDI_RANGE_0119_PID 0x0119 -#define MTXORB_FTDI_RANGE_011A_PID 0x011A -#define MTXORB_FTDI_RANGE_011B_PID 0x011B -#define MTXORB_FTDI_RANGE_011C_PID 0x011C -#define MTXORB_FTDI_RANGE_011D_PID 0x011D -#define MTXORB_FTDI_RANGE_011E_PID 0x011E -#define MTXORB_FTDI_RANGE_011F_PID 0x011F -#define MTXORB_FTDI_RANGE_0120_PID 0x0120 -#define MTXORB_FTDI_RANGE_0121_PID 0x0121 -#define MTXORB_FTDI_RANGE_0122_PID 0x0122 -#define MTXORB_FTDI_RANGE_0123_PID 0x0123 -#define MTXORB_FTDI_RANGE_0124_PID 0x0124 -#define MTXORB_FTDI_RANGE_0125_PID 0x0125 -#define MTXORB_FTDI_RANGE_0126_PID 0x0126 -#define MTXORB_FTDI_RANGE_0127_PID 0x0127 -#define MTXORB_FTDI_RANGE_0128_PID 0x0128 -#define MTXORB_FTDI_RANGE_0129_PID 0x0129 -#define MTXORB_FTDI_RANGE_012A_PID 0x012A -#define MTXORB_FTDI_RANGE_012B_PID 0x012B -#define MTXORB_FTDI_RANGE_012C_PID 0x012C -#define MTXORB_FTDI_RANGE_012D_PID 0x012D -#define MTXORB_FTDI_RANGE_012E_PID 0x012E -#define MTXORB_FTDI_RANGE_012F_PID 0x012F -#define MTXORB_FTDI_RANGE_0130_PID 0x0130 -#define MTXORB_FTDI_RANGE_0131_PID 0x0131 -#define MTXORB_FTDI_RANGE_0132_PID 0x0132 -#define MTXORB_FTDI_RANGE_0133_PID 0x0133 -#define MTXORB_FTDI_RANGE_0134_PID 0x0134 -#define MTXORB_FTDI_RANGE_0135_PID 0x0135 -#define MTXORB_FTDI_RANGE_0136_PID 0x0136 -#define MTXORB_FTDI_RANGE_0137_PID 0x0137 -#define MTXORB_FTDI_RANGE_0138_PID 0x0138 -#define MTXORB_FTDI_RANGE_0139_PID 0x0139 -#define MTXORB_FTDI_RANGE_013A_PID 0x013A -#define MTXORB_FTDI_RANGE_013B_PID 0x013B -#define MTXORB_FTDI_RANGE_013C_PID 0x013C -#define MTXORB_FTDI_RANGE_013D_PID 0x013D -#define MTXORB_FTDI_RANGE_013E_PID 0x013E -#define MTXORB_FTDI_RANGE_013F_PID 0x013F -#define MTXORB_FTDI_RANGE_0140_PID 0x0140 -#define MTXORB_FTDI_RANGE_0141_PID 0x0141 -#define MTXORB_FTDI_RANGE_0142_PID 0x0142 -#define MTXORB_FTDI_RANGE_0143_PID 0x0143 -#define MTXORB_FTDI_RANGE_0144_PID 0x0144 -#define MTXORB_FTDI_RANGE_0145_PID 0x0145 -#define MTXORB_FTDI_RANGE_0146_PID 0x0146 -#define MTXORB_FTDI_RANGE_0147_PID 0x0147 -#define MTXORB_FTDI_RANGE_0148_PID 0x0148 -#define MTXORB_FTDI_RANGE_0149_PID 0x0149 -#define MTXORB_FTDI_RANGE_014A_PID 0x014A -#define MTXORB_FTDI_RANGE_014B_PID 0x014B -#define MTXORB_FTDI_RANGE_014C_PID 0x014C -#define MTXORB_FTDI_RANGE_014D_PID 0x014D -#define MTXORB_FTDI_RANGE_014E_PID 0x014E -#define MTXORB_FTDI_RANGE_014F_PID 0x014F -#define MTXORB_FTDI_RANGE_0150_PID 0x0150 -#define MTXORB_FTDI_RANGE_0151_PID 0x0151 -#define MTXORB_FTDI_RANGE_0152_PID 0x0152 -#define MTXORB_FTDI_RANGE_0153_PID 0x0153 -#define MTXORB_FTDI_RANGE_0154_PID 0x0154 -#define MTXORB_FTDI_RANGE_0155_PID 0x0155 -#define MTXORB_FTDI_RANGE_0156_PID 0x0156 -#define MTXORB_FTDI_RANGE_0157_PID 0x0157 -#define MTXORB_FTDI_RANGE_0158_PID 0x0158 -#define MTXORB_FTDI_RANGE_0159_PID 0x0159 -#define MTXORB_FTDI_RANGE_015A_PID 0x015A -#define MTXORB_FTDI_RANGE_015B_PID 0x015B -#define MTXORB_FTDI_RANGE_015C_PID 0x015C -#define MTXORB_FTDI_RANGE_015D_PID 0x015D -#define MTXORB_FTDI_RANGE_015E_PID 0x015E -#define MTXORB_FTDI_RANGE_015F_PID 0x015F -#define MTXORB_FTDI_RANGE_0160_PID 0x0160 -#define MTXORB_FTDI_RANGE_0161_PID 0x0161 -#define MTXORB_FTDI_RANGE_0162_PID 0x0162 -#define MTXORB_FTDI_RANGE_0163_PID 0x0163 -#define MTXORB_FTDI_RANGE_0164_PID 0x0164 -#define MTXORB_FTDI_RANGE_0165_PID 0x0165 -#define MTXORB_FTDI_RANGE_0166_PID 0x0166 -#define MTXORB_FTDI_RANGE_0167_PID 0x0167 -#define MTXORB_FTDI_RANGE_0168_PID 0x0168 -#define MTXORB_FTDI_RANGE_0169_PID 0x0169 -#define MTXORB_FTDI_RANGE_016A_PID 0x016A -#define MTXORB_FTDI_RANGE_016B_PID 0x016B -#define MTXORB_FTDI_RANGE_016C_PID 0x016C -#define MTXORB_FTDI_RANGE_016D_PID 0x016D -#define MTXORB_FTDI_RANGE_016E_PID 0x016E -#define MTXORB_FTDI_RANGE_016F_PID 0x016F -#define MTXORB_FTDI_RANGE_0170_PID 0x0170 -#define MTXORB_FTDI_RANGE_0171_PID 0x0171 -#define MTXORB_FTDI_RANGE_0172_PID 0x0172 -#define MTXORB_FTDI_RANGE_0173_PID 0x0173 -#define MTXORB_FTDI_RANGE_0174_PID 0x0174 -#define MTXORB_FTDI_RANGE_0175_PID 0x0175 -#define MTXORB_FTDI_RANGE_0176_PID 0x0176 -#define MTXORB_FTDI_RANGE_0177_PID 0x0177 -#define MTXORB_FTDI_RANGE_0178_PID 0x0178 -#define MTXORB_FTDI_RANGE_0179_PID 0x0179 -#define MTXORB_FTDI_RANGE_017A_PID 0x017A -#define MTXORB_FTDI_RANGE_017B_PID 0x017B -#define MTXORB_FTDI_RANGE_017C_PID 0x017C -#define MTXORB_FTDI_RANGE_017D_PID 0x017D -#define MTXORB_FTDI_RANGE_017E_PID 0x017E -#define MTXORB_FTDI_RANGE_017F_PID 0x017F -#define MTXORB_FTDI_RANGE_0180_PID 0x0180 -#define MTXORB_FTDI_RANGE_0181_PID 0x0181 -#define MTXORB_FTDI_RANGE_0182_PID 0x0182 -#define MTXORB_FTDI_RANGE_0183_PID 0x0183 -#define MTXORB_FTDI_RANGE_0184_PID 0x0184 -#define MTXORB_FTDI_RANGE_0185_PID 0x0185 -#define MTXORB_FTDI_RANGE_0186_PID 0x0186 -#define MTXORB_FTDI_RANGE_0187_PID 0x0187 -#define MTXORB_FTDI_RANGE_0188_PID 0x0188 -#define MTXORB_FTDI_RANGE_0189_PID 0x0189 -#define MTXORB_FTDI_RANGE_018A_PID 0x018A -#define MTXORB_FTDI_RANGE_018B_PID 0x018B -#define MTXORB_FTDI_RANGE_018C_PID 0x018C -#define MTXORB_FTDI_RANGE_018D_PID 0x018D -#define MTXORB_FTDI_RANGE_018E_PID 0x018E -#define MTXORB_FTDI_RANGE_018F_PID 0x018F -#define MTXORB_FTDI_RANGE_0190_PID 0x0190 -#define MTXORB_FTDI_RANGE_0191_PID 0x0191 -#define MTXORB_FTDI_RANGE_0192_PID 0x0192 -#define MTXORB_FTDI_RANGE_0193_PID 0x0193 -#define MTXORB_FTDI_RANGE_0194_PID 0x0194 -#define MTXORB_FTDI_RANGE_0195_PID 0x0195 -#define MTXORB_FTDI_RANGE_0196_PID 0x0196 -#define MTXORB_FTDI_RANGE_0197_PID 0x0197 -#define MTXORB_FTDI_RANGE_0198_PID 0x0198 -#define MTXORB_FTDI_RANGE_0199_PID 0x0199 -#define MTXORB_FTDI_RANGE_019A_PID 0x019A -#define MTXORB_FTDI_RANGE_019B_PID 0x019B -#define MTXORB_FTDI_RANGE_019C_PID 0x019C -#define MTXORB_FTDI_RANGE_019D_PID 0x019D -#define MTXORB_FTDI_RANGE_019E_PID 0x019E -#define MTXORB_FTDI_RANGE_019F_PID 0x019F -#define MTXORB_FTDI_RANGE_01A0_PID 0x01A0 -#define MTXORB_FTDI_RANGE_01A1_PID 0x01A1 -#define MTXORB_FTDI_RANGE_01A2_PID 0x01A2 -#define MTXORB_FTDI_RANGE_01A3_PID 0x01A3 -#define MTXORB_FTDI_RANGE_01A4_PID 0x01A4 -#define MTXORB_FTDI_RANGE_01A5_PID 0x01A5 -#define MTXORB_FTDI_RANGE_01A6_PID 0x01A6 -#define MTXORB_FTDI_RANGE_01A7_PID 0x01A7 -#define MTXORB_FTDI_RANGE_01A8_PID 0x01A8 -#define MTXORB_FTDI_RANGE_01A9_PID 0x01A9 -#define MTXORB_FTDI_RANGE_01AA_PID 0x01AA -#define MTXORB_FTDI_RANGE_01AB_PID 0x01AB -#define MTXORB_FTDI_RANGE_01AC_PID 0x01AC -#define MTXORB_FTDI_RANGE_01AD_PID 0x01AD -#define MTXORB_FTDI_RANGE_01AE_PID 0x01AE -#define MTXORB_FTDI_RANGE_01AF_PID 0x01AF -#define MTXORB_FTDI_RANGE_01B0_PID 0x01B0 -#define MTXORB_FTDI_RANGE_01B1_PID 0x01B1 -#define MTXORB_FTDI_RANGE_01B2_PID 0x01B2 -#define MTXORB_FTDI_RANGE_01B3_PID 0x01B3 -#define MTXORB_FTDI_RANGE_01B4_PID 0x01B4 -#define MTXORB_FTDI_RANGE_01B5_PID 0x01B5 -#define MTXORB_FTDI_RANGE_01B6_PID 0x01B6 -#define MTXORB_FTDI_RANGE_01B7_PID 0x01B7 -#define MTXORB_FTDI_RANGE_01B8_PID 0x01B8 -#define MTXORB_FTDI_RANGE_01B9_PID 0x01B9 -#define MTXORB_FTDI_RANGE_01BA_PID 0x01BA -#define MTXORB_FTDI_RANGE_01BB_PID 0x01BB -#define MTXORB_FTDI_RANGE_01BC_PID 0x01BC -#define MTXORB_FTDI_RANGE_01BD_PID 0x01BD -#define MTXORB_FTDI_RANGE_01BE_PID 0x01BE -#define MTXORB_FTDI_RANGE_01BF_PID 0x01BF -#define MTXORB_FTDI_RANGE_01C0_PID 0x01C0 -#define MTXORB_FTDI_RANGE_01C1_PID 0x01C1 -#define MTXORB_FTDI_RANGE_01C2_PID 0x01C2 -#define MTXORB_FTDI_RANGE_01C3_PID 0x01C3 -#define MTXORB_FTDI_RANGE_01C4_PID 0x01C4 -#define MTXORB_FTDI_RANGE_01C5_PID 0x01C5 -#define MTXORB_FTDI_RANGE_01C6_PID 0x01C6 -#define MTXORB_FTDI_RANGE_01C7_PID 0x01C7 -#define MTXORB_FTDI_RANGE_01C8_PID 0x01C8 -#define MTXORB_FTDI_RANGE_01C9_PID 0x01C9 -#define MTXORB_FTDI_RANGE_01CA_PID 0x01CA -#define MTXORB_FTDI_RANGE_01CB_PID 0x01CB -#define MTXORB_FTDI_RANGE_01CC_PID 0x01CC -#define MTXORB_FTDI_RANGE_01CD_PID 0x01CD -#define MTXORB_FTDI_RANGE_01CE_PID 0x01CE -#define MTXORB_FTDI_RANGE_01CF_PID 0x01CF -#define MTXORB_FTDI_RANGE_01D0_PID 0x01D0 -#define MTXORB_FTDI_RANGE_01D1_PID 0x01D1 -#define MTXORB_FTDI_RANGE_01D2_PID 0x01D2 -#define MTXORB_FTDI_RANGE_01D3_PID 0x01D3 -#define MTXORB_FTDI_RANGE_01D4_PID 0x01D4 -#define MTXORB_FTDI_RANGE_01D5_PID 0x01D5 -#define MTXORB_FTDI_RANGE_01D6_PID 0x01D6 -#define MTXORB_FTDI_RANGE_01D7_PID 0x01D7 -#define MTXORB_FTDI_RANGE_01D8_PID 0x01D8 -#define MTXORB_FTDI_RANGE_01D9_PID 0x01D9 -#define MTXORB_FTDI_RANGE_01DA_PID 0x01DA -#define MTXORB_FTDI_RANGE_01DB_PID 0x01DB -#define MTXORB_FTDI_RANGE_01DC_PID 0x01DC -#define MTXORB_FTDI_RANGE_01DD_PID 0x01DD -#define MTXORB_FTDI_RANGE_01DE_PID 0x01DE -#define MTXORB_FTDI_RANGE_01DF_PID 0x01DF -#define MTXORB_FTDI_RANGE_01E0_PID 0x01E0 -#define MTXORB_FTDI_RANGE_01E1_PID 0x01E1 -#define MTXORB_FTDI_RANGE_01E2_PID 0x01E2 -#define MTXORB_FTDI_RANGE_01E3_PID 0x01E3 -#define MTXORB_FTDI_RANGE_01E4_PID 0x01E4 -#define MTXORB_FTDI_RANGE_01E5_PID 0x01E5 -#define MTXORB_FTDI_RANGE_01E6_PID 0x01E6 -#define MTXORB_FTDI_RANGE_01E7_PID 0x01E7 -#define MTXORB_FTDI_RANGE_01E8_PID 0x01E8 -#define MTXORB_FTDI_RANGE_01E9_PID 0x01E9 -#define MTXORB_FTDI_RANGE_01EA_PID 0x01EA -#define MTXORB_FTDI_RANGE_01EB_PID 0x01EB -#define MTXORB_FTDI_RANGE_01EC_PID 0x01EC -#define MTXORB_FTDI_RANGE_01ED_PID 0x01ED -#define MTXORB_FTDI_RANGE_01EE_PID 0x01EE -#define MTXORB_FTDI_RANGE_01EF_PID 0x01EF -#define MTXORB_FTDI_RANGE_01F0_PID 0x01F0 -#define MTXORB_FTDI_RANGE_01F1_PID 0x01F1 -#define MTXORB_FTDI_RANGE_01F2_PID 0x01F2 -#define MTXORB_FTDI_RANGE_01F3_PID 0x01F3 -#define MTXORB_FTDI_RANGE_01F4_PID 0x01F4 -#define MTXORB_FTDI_RANGE_01F5_PID 0x01F5 -#define MTXORB_FTDI_RANGE_01F6_PID 0x01F6 -#define MTXORB_FTDI_RANGE_01F7_PID 0x01F7 -#define MTXORB_FTDI_RANGE_01F8_PID 0x01F8 -#define MTXORB_FTDI_RANGE_01F9_PID 0x01F9 -#define MTXORB_FTDI_RANGE_01FA_PID 0x01FA -#define MTXORB_FTDI_RANGE_01FB_PID 0x01FB -#define MTXORB_FTDI_RANGE_01FC_PID 0x01FC -#define MTXORB_FTDI_RANGE_01FD_PID 0x01FD -#define MTXORB_FTDI_RANGE_01FE_PID 0x01FE -#define MTXORB_FTDI_RANGE_01FF_PID 0x01FF - - - -/* Interbiometrics USB I/O Board */ -/* Developed for Interbiometrics by Rudolf Gugler */ -#define INTERBIOMETRICS_VID 0x1209 -#define INTERBIOMETRICS_IOBOARD_PID 0x1002 -#define INTERBIOMETRICS_MINI_IOBOARD_PID 0x1006 - -/* - * The following are the values for the Perle Systems - * UltraPort USB serial converters - */ -#define FTDI_PERLE_ULTRAPORT_PID 0xF0C0 /* Perle UltraPort Product Id */ - -/* - * The following are the values for the Sealevel SeaLINK+ adapters. - * (Original list sent by Tuan Hoang. Ian Abbott renamed the macros and - * removed some PIDs that don't seem to match any existing products.) - */ -#define SEALEVEL_VID 0x0c52 /* Sealevel Vendor ID */ -#define SEALEVEL_2101_PID 0x2101 /* SeaLINK+232 (2101/2105) */ -#define SEALEVEL_2102_PID 0x2102 /* SeaLINK+485 (2102) */ -#define SEALEVEL_2103_PID 0x2103 /* SeaLINK+232I (2103) */ -#define SEALEVEL_2104_PID 0x2104 /* SeaLINK+485I (2104) */ -#define SEALEVEL_2106_PID 0x9020 /* SeaLINK+422 (2106) */ -#define SEALEVEL_2201_1_PID 0x2211 /* SeaPORT+2/232 (2201) Port 1 */ -#define SEALEVEL_2201_2_PID 0x2221 /* SeaPORT+2/232 (2201) Port 2 */ -#define SEALEVEL_2202_1_PID 0x2212 /* SeaPORT+2/485 (2202) Port 1 */ -#define SEALEVEL_2202_2_PID 0x2222 /* SeaPORT+2/485 (2202) Port 2 */ -#define SEALEVEL_2203_1_PID 0x2213 /* SeaPORT+2 (2203) Port 1 */ -#define SEALEVEL_2203_2_PID 0x2223 /* SeaPORT+2 (2203) Port 2 */ -#define SEALEVEL_2401_1_PID 0x2411 /* SeaPORT+4/232 (2401) Port 1 */ -#define SEALEVEL_2401_2_PID 0x2421 /* SeaPORT+4/232 (2401) Port 2 */ -#define SEALEVEL_2401_3_PID 0x2431 /* SeaPORT+4/232 (2401) Port 3 */ -#define SEALEVEL_2401_4_PID 0x2441 /* SeaPORT+4/232 (2401) Port 4 */ -#define SEALEVEL_2402_1_PID 0x2412 /* SeaPORT+4/485 (2402) Port 1 */ -#define SEALEVEL_2402_2_PID 0x2422 /* SeaPORT+4/485 (2402) Port 2 */ -#define SEALEVEL_2402_3_PID 0x2432 /* SeaPORT+4/485 (2402) Port 3 */ -#define SEALEVEL_2402_4_PID 0x2442 /* SeaPORT+4/485 (2402) Port 4 */ -#define SEALEVEL_2403_1_PID 0x2413 /* SeaPORT+4 (2403) Port 1 */ -#define SEALEVEL_2403_2_PID 0x2423 /* SeaPORT+4 (2403) Port 2 */ -#define SEALEVEL_2403_3_PID 0x2433 /* SeaPORT+4 (2403) Port 3 */ -#define SEALEVEL_2403_4_PID 0x2443 /* SeaPORT+4 (2403) Port 4 */ -#define SEALEVEL_2801_1_PID 0X2811 /* SeaLINK+8/232 (2801) Port 1 */ -#define SEALEVEL_2801_2_PID 0X2821 /* SeaLINK+8/232 (2801) Port 2 */ -#define SEALEVEL_2801_3_PID 0X2831 /* SeaLINK+8/232 (2801) Port 3 */ -#define SEALEVEL_2801_4_PID 0X2841 /* SeaLINK+8/232 (2801) Port 4 */ -#define SEALEVEL_2801_5_PID 0X2851 /* SeaLINK+8/232 (2801) Port 5 */ -#define SEALEVEL_2801_6_PID 0X2861 /* SeaLINK+8/232 (2801) Port 6 */ -#define SEALEVEL_2801_7_PID 0X2871 /* SeaLINK+8/232 (2801) Port 7 */ -#define SEALEVEL_2801_8_PID 0X2881 /* SeaLINK+8/232 (2801) Port 8 */ -#define SEALEVEL_2802_1_PID 0X2812 /* SeaLINK+8/485 (2802) Port 1 */ -#define SEALEVEL_2802_2_PID 0X2822 /* SeaLINK+8/485 (2802) Port 2 */ -#define SEALEVEL_2802_3_PID 0X2832 /* SeaLINK+8/485 (2802) Port 3 */ -#define SEALEVEL_2802_4_PID 0X2842 /* SeaLINK+8/485 (2802) Port 4 */ -#define SEALEVEL_2802_5_PID 0X2852 /* SeaLINK+8/485 (2802) Port 5 */ -#define SEALEVEL_2802_6_PID 0X2862 /* SeaLINK+8/485 (2802) Port 6 */ -#define SEALEVEL_2802_7_PID 0X2872 /* SeaLINK+8/485 (2802) Port 7 */ -#define SEALEVEL_2802_8_PID 0X2882 /* SeaLINK+8/485 (2802) Port 8 */ -#define SEALEVEL_2803_1_PID 0X2813 /* SeaLINK+8 (2803) Port 1 */ -#define SEALEVEL_2803_2_PID 0X2823 /* SeaLINK+8 (2803) Port 2 */ -#define SEALEVEL_2803_3_PID 0X2833 /* SeaLINK+8 (2803) Port 3 */ -#define SEALEVEL_2803_4_PID 0X2843 /* SeaLINK+8 (2803) Port 4 */ -#define SEALEVEL_2803_5_PID 0X2853 /* SeaLINK+8 (2803) Port 5 */ -#define SEALEVEL_2803_6_PID 0X2863 /* SeaLINK+8 (2803) Port 6 */ -#define SEALEVEL_2803_7_PID 0X2873 /* SeaLINK+8 (2803) Port 7 */ -#define SEALEVEL_2803_8_PID 0X2883 /* SeaLINK+8 (2803) Port 8 */ - -/* - * The following are the values for two KOBIL chipcard terminals. - */ -#define KOBIL_VID 0x0d46 /* KOBIL Vendor ID */ -#define KOBIL_CONV_B1_PID 0x2020 /* KOBIL Konverter for B1 */ -#define KOBIL_CONV_KAAN_PID 0x2021 /* KOBIL_Konverter for KAAN */ - -/* - * Icom ID-1 digital transceiver - */ - -#define ICOM_ID1_VID 0x0C26 -#define ICOM_ID1_PID 0x0004 - -/* - * ASK.fr devices - */ -#define FTDI_ASK_RDR400_PID 0xC991 /* ASK RDR 400 series card reader */ - -/* - * FTDI USB UART chips used in construction projects from the - * Elektor Electronics magazine (http://elektor-electronics.co.uk) - */ -#define ELEKTOR_VID 0x0C7D -#define ELEKTOR_FT323R_PID 0x0005 /* RFID-Reader, issue 09-2006 */ - -/* - * DSS-20 Sync Station for Sony Ericsson P800 - */ -#define FTDI_DSS20_PID 0xFC82 - -/* - * Home Electronics (www.home-electro.com) USB gadgets - */ -#define FTDI_HE_TIRA1_PID 0xFA78 /* Tira-1 IR transceiver */ - -/* USB-UIRT - An infrared receiver and transmitter using the 8U232AM chip */ -/* http://home.earthlink.net/~jrhees/USBUIRT/index.htm */ -#define FTDI_USB_UIRT_PID 0xF850 /* Product Id */ - -/* TNC-X USB-to-packet-radio adapter, versions prior to 3.0 (DLP module) */ - -#define FTDI_TNC_X_PID 0xEBE0 - -/* - * ELV USB devices submitted by Christian Abt of ELV (www.elv.de). - * All of these devices use FTDI's vendor ID (0x0403). - * - * The previously included PID for the UO 100 module was incorrect. - * In fact, that PID was for ELV's UR 100 USB-RS232 converter (0xFB58). - * - * Armin Laeuger originally sent the PID for the UM 100 module. - */ -#define FTDI_R2000KU_TRUE_RNG 0xFB80 /* R2000KU TRUE RNG */ -#define FTDI_ELV_UR100_PID 0xFB58 /* USB-RS232-Umsetzer (UR 100) */ -#define FTDI_ELV_UM100_PID 0xFB5A /* USB-Modul UM 100 */ -#define FTDI_ELV_UO100_PID 0xFB5B /* USB-Modul UO 100 */ -#define FTDI_ELV_ALC8500_PID 0xF06E /* ALC 8500 Expert */ -/* Additional ELV PIDs that default to using the FTDI D2XX drivers on - * MS Windows, rather than the FTDI Virtual Com Port drivers. - * Maybe these will be easier to use with the libftdi/libusb user-space - * drivers, or possibly the Comedi drivers in some cases. */ -#define FTDI_ELV_CLI7000_PID 0xFB59 /* Computer-Light-Interface (CLI 7000) */ -#define FTDI_ELV_PPS7330_PID 0xFB5C /* Processor-Power-Supply (PPS 7330) */ -#define FTDI_ELV_TFM100_PID 0xFB5D /* Temperartur-Feuchte Messgeraet (TFM 100) */ -#define FTDI_ELV_UDF77_PID 0xFB5E /* USB DCF Funkurh (UDF 77) */ -#define FTDI_ELV_UIO88_PID 0xFB5F /* USB-I/O Interface (UIO 88) */ -#define FTDI_ELV_UAD8_PID 0xF068 /* USB-AD-Wandler (UAD 8) */ -#define FTDI_ELV_UDA7_PID 0xF069 /* USB-DA-Wandler (UDA 7) */ -#define FTDI_ELV_USI2_PID 0xF06A /* USB-Schrittmotoren-Interface (USI 2) */ -#define FTDI_ELV_T1100_PID 0xF06B /* Thermometer (T 1100) */ -#define FTDI_ELV_PCD200_PID 0xF06C /* PC-Datenlogger (PCD 200) */ -#define FTDI_ELV_ULA200_PID 0xF06D /* USB-LCD-Ansteuerung (ULA 200) */ -#define FTDI_ELV_FHZ1000PC_PID 0xF06F /* FHZ 1000 PC */ -#define FTDI_ELV_CSI8_PID 0xE0F0 /* Computer-Schalt-Interface (CSI 8) */ -#define FTDI_ELV_EM1000DL_PID 0xE0F1 /* PC-Datenlogger fuer Energiemonitor (EM 1000 DL) */ -#define FTDI_ELV_PCK100_PID 0xE0F2 /* PC-Kabeltester (PCK 100) */ -#define FTDI_ELV_RFP500_PID 0xE0F3 /* HF-Leistungsmesser (RFP 500) */ -#define FTDI_ELV_FS20SIG_PID 0xE0F4 /* Signalgeber (FS 20 SIG) */ -#define FTDI_ELV_WS300PC_PID 0xE0F6 /* PC-Wetterstation (WS 300 PC) */ -#define FTDI_ELV_FHZ1300PC_PID 0xE0E8 /* FHZ 1300 PC */ -#define FTDI_ELV_WS500_PID 0xE0E9 /* PC-Wetterstation (WS 500) */ -#define FTDI_ELV_HS485_PID 0xE0EA /* USB to RS-485 adapter */ -#define FTDI_ELV_EM1010PC_PID 0xE0EF /* Engery monitor EM 1010 PC */ -#define FTDI_PHI_FISCO_PID 0xE40B /* PHI Fisco USB to Serial cable */ - -/* - * Definitions for ID TECH (www.idt-net.com) devices - */ -#define IDTECH_VID 0x0ACD /* ID TECH Vendor ID */ -#define IDTECH_IDT1221U_PID 0x0300 /* IDT1221U USB to RS-232 adapter */ - -/* - * Definitions for Omnidirectional Control Technology, Inc. devices - */ -#define OCT_VID 0x0B39 /* OCT vendor ID */ -/* Note: OCT US101 is also rebadged as Dick Smith Electronics (NZ) XH6381 */ -/* Also rebadged as Dick Smith Electronics (Aus) XH6451 */ -/* Also rebadged as SIIG Inc. model US2308 hardware version 1 */ -#define OCT_US101_PID 0x0421 /* OCT US101 USB to RS-232 */ - -/* an infrared receiver for user access control with IR tags */ -#define FTDI_PIEGROUP_PID 0xF208 /* Product Id */ - -/* - * Definitions for Artemis astronomical USB based cameras - * Check it at http://www.artemisccd.co.uk/ - */ -#define FTDI_ARTEMIS_PID 0xDF28 /* All Artemis Cameras */ - -/* - * Definitions for ATIK Instruments astronomical USB based cameras - * Check it at http://www.atik-instruments.com/ - */ -#define FTDI_ATIK_ATK16_PID 0xDF30 /* ATIK ATK-16 Grayscale Camera */ -#define FTDI_ATIK_ATK16C_PID 0xDF32 /* ATIK ATK-16C Colour Camera */ -#define FTDI_ATIK_ATK16HR_PID 0xDF31 /* ATIK ATK-16HR Grayscale Camera */ -#define FTDI_ATIK_ATK16HRC_PID 0xDF33 /* ATIK ATK-16HRC Colour Camera */ -#define FTDI_ATIK_ATK16IC_PID 0xDF35 /* ATIK ATK-16IC Grayscale Camera */ - -/* - * Protego product ids - */ -#define PROTEGO_SPECIAL_1 0xFC70 /* special/unknown device */ -#define PROTEGO_R2X0 0xFC71 /* R200-USB TRNG unit (R210, R220, and R230) */ -#define PROTEGO_SPECIAL_3 0xFC72 /* special/unknown device */ -#define PROTEGO_SPECIAL_4 0xFC73 /* special/unknown device */ - -/* - * Gude Analog- und Digitalsysteme GmbH - */ -#define FTDI_GUDEADS_E808_PID 0xE808 -#define FTDI_GUDEADS_E809_PID 0xE809 -#define FTDI_GUDEADS_E80A_PID 0xE80A -#define FTDI_GUDEADS_E80B_PID 0xE80B -#define FTDI_GUDEADS_E80C_PID 0xE80C -#define FTDI_GUDEADS_E80D_PID 0xE80D -#define FTDI_GUDEADS_E80E_PID 0xE80E -#define FTDI_GUDEADS_E80F_PID 0xE80F -#define FTDI_GUDEADS_E888_PID 0xE888 /* Expert ISDN Control USB */ -#define FTDI_GUDEADS_E889_PID 0xE889 /* USB RS-232 OptoBridge */ -#define FTDI_GUDEADS_E88A_PID 0xE88A -#define FTDI_GUDEADS_E88B_PID 0xE88B -#define FTDI_GUDEADS_E88C_PID 0xE88C -#define FTDI_GUDEADS_E88D_PID 0xE88D -#define FTDI_GUDEADS_E88E_PID 0xE88E -#define FTDI_GUDEADS_E88F_PID 0xE88F - -/* - * Linx Technologies product ids - */ -#define LINX_SDMUSBQSS_PID 0xF448 /* Linx SDM-USB-QS-S */ -#define LINX_MASTERDEVEL2_PID 0xF449 /* Linx Master Development 2.0 */ -#define LINX_FUTURE_0_PID 0xF44A /* Linx future device */ -#define LINX_FUTURE_1_PID 0xF44B /* Linx future device */ -#define LINX_FUTURE_2_PID 0xF44C /* Linx future device */ - -/* CCS Inc. ICDU/ICDU40 product ID - the FT232BM is used in an in-circuit-debugger */ -/* unit for PIC16's/PIC18's */ -#define FTDI_CCSICDU20_0_PID 0xF9D0 -#define FTDI_CCSICDU40_1_PID 0xF9D1 -#define FTDI_CCSMACHX_2_PID 0xF9D2 -#define FTDI_CCSLOAD_N_GO_3_PID 0xF9D3 -#define FTDI_CCSICDU64_4_PID 0xF9D4 -#define FTDI_CCSPRIME8_5_PID 0xF9D5 - -/* Inside Accesso contactless reader (http://www.insidefr.com) */ -#define INSIDE_ACCESSO 0xFAD0 - -/* - * Intrepid Control Systems (http://www.intrepidcs.com/) ValueCAN and NeoVI - */ -#define INTREPID_VID 0x093C -#define INTREPID_VALUECAN_PID 0x0601 -#define INTREPID_NEOVI_PID 0x0701 - -/* - * Falcom Wireless Communications GmbH - */ -#define FALCOM_VID 0x0F94 /* Vendor Id */ -#define FALCOM_TWIST_PID 0x0001 /* Falcom Twist USB GPRS modem */ -#define FALCOM_SAMBA_PID 0x0005 /* Falcom Samba USB GPRS modem */ - -/* - * SUUNTO product ids - */ -#define FTDI_SUUNTO_SPORTS_PID 0xF680 /* Suunto Sports instrument */ - -/* - * Oceanic product ids - */ -#define FTDI_OCEANIC_PID 0xF460 /* Oceanic dive instrument */ - -/* - * TTi (Thurlby Thandar Instruments) - */ -#define TTI_VID 0x103E /* Vendor Id */ -#define TTI_QL355P_PID 0x03E8 /* TTi QL355P power supply */ - -/* - * Definitions for B&B Electronics products. - */ -#define BANDB_VID 0x0856 /* B&B Electronics Vendor ID */ -#define BANDB_USOTL4_PID 0xAC01 /* USOTL4 Isolated RS-485 Converter */ -#define BANDB_USTL4_PID 0xAC02 /* USTL4 RS-485 Converter */ -#define BANDB_USO9ML2_PID 0xAC03 /* USO9ML2 Isolated RS-232 Converter */ -#define BANDB_USOPTL4_PID 0xAC11 -#define BANDB_USPTL4_PID 0xAC12 -#define BANDB_USO9ML2DR_2_PID 0xAC16 -#define BANDB_USO9ML2DR_PID 0xAC17 -#define BANDB_USOPTL4DR2_PID 0xAC18 /* USOPTL4R-2 2-port Isolated RS-232 Converter */ -#define BANDB_USOPTL4DR_PID 0xAC19 -#define BANDB_485USB9F_2W_PID 0xAC25 -#define BANDB_485USB9F_4W_PID 0xAC26 -#define BANDB_232USB9M_PID 0xAC27 -#define BANDB_485USBTB_2W_PID 0xAC33 -#define BANDB_485USBTB_4W_PID 0xAC34 -#define BANDB_TTL5USB9M_PID 0xAC49 -#define BANDB_TTL3USB9M_PID 0xAC50 -#define BANDB_ZZ_PROG1_USB_PID 0xBA02 - -/* - * RM Michaelides CANview USB (http://www.rmcan.com) - * CAN fieldbus interface adapter, added by port GmbH www.port.de) - * Ian Abbott changed the macro names for consistency. - */ -#define FTDI_RM_CANVIEW_PID 0xfd60 /* Product Id */ - -/* - * EVER Eco Pro UPS (http://www.ever.com.pl/) - */ - -#define EVER_ECO_PRO_CDS 0xe520 /* RS-232 converter */ - -/* - * 4N-GALAXY.DE PIDs for CAN-USB, USB-RS232, USB-RS422, USB-RS485, - * USB-TTY activ, USB-TTY passiv. Some PIDs are used by several devices - * and I'm not entirely sure which are used by which. - */ -#define FTDI_4N_GALAXY_DE_1_PID 0xF3C0 -#define FTDI_4N_GALAXY_DE_2_PID 0xF3C1 - -/* - * Mobility Electronics products. - */ -#define MOBILITY_VID 0x1342 -#define MOBILITY_USB_SERIAL_PID 0x0202 /* EasiDock USB 200 serial */ - -/* - * microHAM product IDs (http://www.microham.com). - * Submitted by Justin Burket (KL1RL) - * and Mike Studer (K6EEP) . - * Ian Abbott added a few more from the driver INF file. - */ -#define FTDI_MHAM_KW_PID 0xEEE8 /* USB-KW interface */ -#define FTDI_MHAM_YS_PID 0xEEE9 /* USB-YS interface */ -#define FTDI_MHAM_Y6_PID 0xEEEA /* USB-Y6 interface */ -#define FTDI_MHAM_Y8_PID 0xEEEB /* USB-Y8 interface */ -#define FTDI_MHAM_IC_PID 0xEEEC /* USB-IC interface */ -#define FTDI_MHAM_DB9_PID 0xEEED /* USB-DB9 interface */ -#define FTDI_MHAM_RS232_PID 0xEEEE /* USB-RS232 interface */ -#define FTDI_MHAM_Y9_PID 0xEEEF /* USB-Y9 interface */ - -/* - * Active Robots product ids. - */ -#define FTDI_ACTIVE_ROBOTS_PID 0xE548 /* USB comms board */ - -/* - * Xsens Technologies BV products (http://www.xsens.com). - */ -#define XSENS_CONVERTER_0_PID 0xD388 -#define XSENS_CONVERTER_1_PID 0xD389 -#define XSENS_CONVERTER_2_PID 0xD38A -#define XSENS_CONVERTER_3_PID 0xD38B -#define XSENS_CONVERTER_4_PID 0xD38C -#define XSENS_CONVERTER_5_PID 0xD38D -#define XSENS_CONVERTER_6_PID 0xD38E -#define XSENS_CONVERTER_7_PID 0xD38F - -/* - * Teratronik product ids. - * Submitted by O. Wölfelschneider. - */ -#define FTDI_TERATRONIK_VCP_PID 0xEC88 /* Teratronik device (preferring VCP driver on windows) */ -#define FTDI_TERATRONIK_D2XX_PID 0xEC89 /* Teratronik device (preferring D2XX driver on windows) */ - -/* - * Evolution Robotics products (http://www.evolution.com/). - * Submitted by Shawn M. Lavelle. - */ -#define EVOLUTION_VID 0xDEEE /* Vendor ID */ -#define EVOLUTION_ER1_PID 0x0300 /* ER1 Control Module */ -#define EVO_8U232AM_PID 0x02FF /* Evolution robotics RCM2 (FT232AM)*/ -#define EVO_HYBRID_PID 0x0302 /* Evolution robotics RCM4 PID (FT232BM)*/ -#define EVO_RCM4_PID 0x0303 /* Evolution robotics RCM4 PID */ - -/* Pyramid Computer GmbH */ -#define FTDI_PYRAMID_PID 0xE6C8 /* Pyramid Appliance Display */ - -/* - * NDI (www.ndigital.com) product ids - */ -#define FTDI_NDI_HUC_PID 0xDA70 /* NDI Host USB Converter */ -#define FTDI_NDI_SPECTRA_SCU_PID 0xDA71 /* NDI Spectra SCU */ -#define FTDI_NDI_FUTURE_2_PID 0xDA72 /* NDI future device #2 */ -#define FTDI_NDI_FUTURE_3_PID 0xDA73 /* NDI future device #3 */ -#define FTDI_NDI_AURORA_SCU_PID 0xDA74 /* NDI Aurora SCU */ - -/* - * Posiflex inc retail equipment (http://www.posiflex.com.tw) - */ -#define POSIFLEX_VID 0x0d3a /* Vendor ID */ -#define POSIFLEX_PP7000_PID 0x0300 /* PP-7000II thermal printer */ - -/* - * Westrex International devices submitted by Cory Lee - */ -#define FTDI_WESTREX_MODEL_777_PID 0xDC00 /* Model 777 */ -#define FTDI_WESTREX_MODEL_8900F_PID 0xDC01 /* Model 8900F */ - -/* - * RR-CirKits LocoBuffer USB (http://www.rr-cirkits.com) - */ -#define FTDI_RRCIRKITS_LOCOBUFFER_PID 0xc7d0 /* LocoBuffer USB */ - -/* - * Eclo (http://www.eclo.pt/) product IDs. - * PID 0xEA90 submitted by Martin Grill. - */ -#define FTDI_ECLO_COM_1WIRE_PID 0xEA90 /* COM to 1-Wire USB adaptor */ - -/* - * Papouch products (http://www.papouch.com/) - * Submitted by Folkert van Heusden - */ - -#define PAPOUCH_VID 0x5050 /* Vendor ID */ -#define PAPOUCH_TMU_PID 0x0400 /* TMU USB Thermometer */ -#define PAPOUCH_QUIDO4x4_PID 0x0900 /* Quido 4/4 Module */ - -/* - * ACG Identification Technologies GmbH products (http://www.acg.de/). - * Submitted by anton -at- goto10 -dot- org. */ -#define FTDI_ACG_HFDUAL_PID 0xDD20 /* HF Dual ISO Reader (RFID) */ - -/* - * Yost Engineering, Inc. products (www.yostengineering.com). - * PID 0xE050 submitted by Aaron Prose. - */ -#define FTDI_YEI_SERVOCENTER31_PID 0xE050 /* YEI ServoCenter3.1 USB */ - -/* - * ThorLabs USB motor drivers - */ -#define FTDI_THORLABS_PID 0xfaf0 /* ThorLabs USB motor drivers */ - -/* - * Testo products (http://www.testo.com/) - * Submitted by Colin Leroy - */ -#define TESTO_VID 0x128D -#define TESTO_USB_INTERFACE_PID 0x0001 - -/* - * Gamma Scout (http://gamma-scout.com/). Submitted by rsc@runtux.com. - */ -#define FTDI_GAMMA_SCOUT_PID 0xD678 /* Gamma Scout online */ - -/* - * Tactrix OpenPort (ECU) devices. - * OpenPort 1.3M submitted by Donour Sizemore. - * OpenPort 1.3S and 1.3U submitted by Ian Abbott. - */ -#define FTDI_TACTRIX_OPENPORT_13M_PID 0xCC48 /* OpenPort 1.3 Mitsubishi */ -#define FTDI_TACTRIX_OPENPORT_13S_PID 0xCC49 /* OpenPort 1.3 Subaru */ -#define FTDI_TACTRIX_OPENPORT_13U_PID 0xCC4A /* OpenPort 1.3 Universal */ - -/* - * Telldus Technologies - */ -#define TELLDUS_VID 0x1781 /* Vendor ID */ -#define TELLDUS_TELLSTICK_PID 0x0C30 /* RF control dongle 433 MHz using FT232RL */ - -/* - * IBS elektronik product ids - * Submitted by Thomas Schleusener - */ -#define FTDI_IBS_US485_PID 0xff38 /* IBS US485 (USB<-->RS422/485 interface) */ -#define FTDI_IBS_PICPRO_PID 0xff39 /* IBS PIC-Programmer */ -#define FTDI_IBS_PCMCIA_PID 0xff3a /* IBS Card reader for PCMCIA SRAM-cards */ -#define FTDI_IBS_PK1_PID 0xff3b /* IBS PK1 - Particel counter */ -#define FTDI_IBS_RS232MON_PID 0xff3c /* IBS RS232 - Monitor */ -#define FTDI_IBS_APP70_PID 0xff3d /* APP 70 (dust monitoring system) */ -#define FTDI_IBS_PEDO_PID 0xff3e /* IBS PEDO-Modem (RF modem 868.35 MHz) */ -#define FTDI_IBS_PROD_PID 0xff3f /* future device */ - -/* - * MaxStream devices www.maxstream.net - */ -#define FTDI_MAXSTREAM_PID 0xEE18 /* Xbee PKG-U Module */ - -/* Olimex */ -#define OLIMEX_VID 0x15BA -#define OLIMEX_ARM_USB_OCD_PID 0x0003 - -/* Luminary Micro Stellaris Boards, VID = FTDI_VID */ -/* FTDI 2332C Dual channel device, side A=245 FIFO (JTAG), Side B=RS232 UART */ -#define LMI_LM3S_DEVEL_BOARD_PID 0xbcd8 -#define LMI_LM3S_EVAL_BOARD_PID 0xbcd9 - -/* www.elsterelectricity.com Elster Unicom III Optical Probe */ -#define FTDI_ELSTER_UNICOM_PID 0xE700 /* Product Id */ - -/* - * The Mobility Lab (TML) - * Submitted by Pierre Castella - */ -#define TML_VID 0x1B91 /* Vendor ID */ -#define TML_USB_SERIAL_PID 0x0064 /* USB - Serial Converter */ - -/* Propox devices */ -#define FTDI_PROPOX_JTAGCABLEII_PID 0xD738 - -/* Rig Expert Ukraine devices */ -#define FTDI_REU_TINY_PID 0xED22 /* RigExpert Tiny */ - -/* Domintell products http://www.domintell.com */ -#define FTDI_DOMINTELL_DGQG_PID 0xEF50 /* Master */ -#define FTDI_DOMINTELL_DUSB_PID 0xEF51 /* DUSB01 module */ - -/* Alti-2 products http://www.alti-2.com */ -#define ALTI2_VID 0x1BC9 -#define ALTI2_N3_PID 0x6001 /* Neptune 3 */ /* Commands */ #define FTDI_SIO_RESET 0 /* Reset the port */ @@ -910,86 +40,6 @@ #define INTERFACE_C 3 #define INTERFACE_D 4 -/* - * FIC / OpenMoko, Inc. http://wiki.openmoko.org/wiki/Neo1973_Debug_Board_v3 - * Submitted by Harald Welte - */ -#define FIC_VID 0x1457 -#define FIC_NEO1973_DEBUG_PID 0x5118 - -/* - * RATOC REX-USB60F - */ -#define RATOC_VENDOR_ID 0x0584 -#define RATOC_PRODUCT_ID_USB60F 0xb020 - -/* - * DIEBOLD BCS SE923 - */ -#define DIEBOLD_BCS_SE923_PID 0xfb99 - -/* - * Atmel STK541 - */ -#define ATMEL_VID 0x03eb /* Vendor ID */ -#define STK541_PID 0x2109 /* Zigbee Controller */ - -/* - * Dresden Elektronic Sensor Terminal Board - */ -#define DE_VID 0x1cf1 /* Vendor ID */ -#define STB_PID 0x0001 /* Sensor Terminal Board */ -#define WHT_PID 0x0004 /* Wireless Handheld Terminal */ - -/* - * Blackfin gnICE JTAG - * http://docs.blackfin.uclinux.org/doku.php?id=hw:jtag:gnice - */ -#define ADI_VID 0x0456 -#define ADI_GNICE_PID 0xF000 -#define ADI_GNICEPLUS_PID 0xF001 - -/* - * JETI SPECTROMETER SPECBOS 1201 - * http://www.jeti.com/products/sys/scb/scb1201.php - */ -#define JETI_VID 0x0c6c -#define JETI_SPC1201_PID 0x04b2 - -/* - * Marvell SheevaPlug - */ -#define MARVELL_VID 0x9e88 -#define MARVELL_SHEEVAPLUG_PID 0x9e8f - -#define FTDI_TURTELIZER_PID 0xBDC8 /* JTAG/RS-232 adapter by egnite GmBH */ - -/* - * GN Otometrics (http://www.otometrics.com) - * Submitted by Ville Sundberg. - */ -#define GN_OTOMETRICS_VID 0x0c33 /* Vendor ID */ -#define AURICAL_USB_PID 0x0010 /* Aurical USB Audiometer */ - -/* - * Bayer Ascensia Contour blood glucose meter USB-converter cable. - * http://winglucofacts.com/cables/ - */ -#define BAYER_VID 0x1A79 -#define BAYER_CONTOUR_CABLE_PID 0x6001 - -/* - * Marvell OpenRD Base, Client - * http://www.open-rd.org - * OpenRD Base, Client use VID 0x0403 - */ -#define MARVELL_OPENRD_PID 0x9e90 - -/* - * Hameg HO820 and HO870 interface (using VID 0x0403) - */ -#define HAMEG_HO820_PID 0xed74 -#define HAMEG_HO870_PID 0xed71 /* * BmRequestType: 1100 0000b @@ -1504,4 +554,3 @@ typedef enum { * B2..7 Length of message - (not including Byte 0) * */ - diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h new file mode 100644 index 0000000..2b5017b --- /dev/null +++ b/drivers/usb/serial/ftdi_sio_ids.h @@ -0,0 +1,959 @@ +/* + * vendor/product IDs (VID/PID) of devices using FTDI USB serial converters. + * + * Philipp Ghring - pg@futureware.at - added the Device ID of the USB relais + * from Rudolf Gugler + * + */ + +#define FTDI_VID 0x0403 /* Vendor Id */ +#define FTDI_SIO_PID 0x8372 /* Product Id SIO application of 8U100AX */ +#define FTDI_8U232AM_PID 0x6001 /* Similar device to SIO above */ +#define FTDI_8U232AM_ALT_PID 0x6006 /* FTDI's alternate PID for above */ +#define FTDI_8U2232C_PID 0x6010 /* Dual channel device */ +#define FTDI_232RL_PID 0xFBFA /* Product ID for FT232RL */ +#define FTDI_4232H_PID 0x6011 /* Quad channel hi-speed device */ +#define FTDI_RELAIS_PID 0xFA10 /* Relais device from Rudolf Gugler */ +#define FTDI_NF_RIC_VID 0x0DCD /* Vendor Id */ +#define FTDI_NF_RIC_PID 0x0001 /* Product Id */ +#define FTDI_USBX_707_PID 0xF857 /* ADSTech IR Blaster USBX-707 */ + +/* Larsen and Brusgaard AltiTrack/USBtrack */ +#define LARSENBRUSGAARD_VID 0x0FD8 +#define LB_ALTITRACK_PID 0x0001 + +/* www.canusb.com Lawicel CANUSB device */ +#define FTDI_CANUSB_PID 0xFFA8 /* Product Id */ + +/* AlphaMicro Components AMC-232USB01 device */ +#define FTDI_AMC232_PID 0xFF00 /* Product Id */ + +/* www.candapter.com Ewert Energy Systems CANdapter device */ +#define FTDI_CANDAPTER_PID 0x9F80 /* Product Id */ + +/* SCS HF Radio Modems PID's (http://www.scs-ptc.com) */ +/* the VID is the standard ftdi vid (FTDI_VID) */ +#define FTDI_SCS_DEVICE_0_PID 0xD010 /* SCS PTC-IIusb */ +#define FTDI_SCS_DEVICE_1_PID 0xD011 /* SCS Tracker / DSP TNC */ +#define FTDI_SCS_DEVICE_2_PID 0xD012 +#define FTDI_SCS_DEVICE_3_PID 0xD013 +#define FTDI_SCS_DEVICE_4_PID 0xD014 +#define FTDI_SCS_DEVICE_5_PID 0xD015 +#define FTDI_SCS_DEVICE_6_PID 0xD016 +#define FTDI_SCS_DEVICE_7_PID 0xD017 + +/* ACT Solutions HomePro ZWave interface (http://www.act-solutions.com/HomePro.htm) */ +#define FTDI_ACTZWAVE_PID 0xF2D0 + + +/* www.starting-point-systems.com Chameleon device */ +#define FTDI_MICRO_CHAMELEON_PID 0xCAA0 /* Product Id */ + +/* www.irtrans.de device */ +#define FTDI_IRTRANS_PID 0xFC60 /* Product Id */ + + +/* www.thoughttechnology.com/ TT-USB provide with procomp use ftdi_sio */ +#define FTDI_TTUSB_PID 0xFF20 /* Product Id */ + +/* iPlus device */ +#define FTDI_IPLUS_PID 0xD070 /* Product Id */ +#define FTDI_IPLUS2_PID 0xD071 /* Product Id */ + +/* DMX4ALL DMX Interfaces */ +#define FTDI_DMX4ALL 0xC850 + +/* OpenDCC (www.opendcc.de) product id */ +#define FTDI_OPENDCC_PID 0xBFD8 +#define FTDI_OPENDCC_SNIFFER_PID 0xBFD9 +#define FTDI_OPENDCC_THROTTLE_PID 0xBFDA +#define FTDI_OPENDCC_GATEWAY_PID 0xBFDB + +/* Sprog II (Andrew Crosland's SprogII DCC interface) */ +#define FTDI_SPROG_II 0xF0C8 + +/* www.crystalfontz.com devices - thanx for providing free devices for evaluation ! */ +/* they use the ftdi chipset for the USB interface and the vendor id is the same */ +#define FTDI_XF_632_PID 0xFC08 /* 632: 16x2 Character Display */ +#define FTDI_XF_634_PID 0xFC09 /* 634: 20x4 Character Display */ +#define FTDI_XF_547_PID 0xFC0A /* 547: Two line Display */ +#define FTDI_XF_633_PID 0xFC0B /* 633: 16x2 Character Display with Keys */ +#define FTDI_XF_631_PID 0xFC0C /* 631: 20x2 Character Display */ +#define FTDI_XF_635_PID 0xFC0D /* 635: 20x4 Character Display */ +#define FTDI_XF_640_PID 0xFC0E /* 640: Two line Display */ +#define FTDI_XF_642_PID 0xFC0F /* 642: Two line Display */ + +/* Video Networks Limited / Homechoice in the UK use an ftdi-based device for their 1Mb */ +/* broadband internet service. The following PID is exhibited by the usb device supplied */ +/* (the VID is the standard ftdi vid (FTDI_VID) */ +#define FTDI_VNHCPCUSB_D_PID 0xfe38 /* Product Id */ + +/* + * PCDJ use ftdi based dj-controllers. The following PID is for their DAC-2 device + * http://www.pcdjhardware.com/DAC2.asp (PID sent by Wouter Paesen) + * (the VID is the standard ftdi vid (FTDI_VID) */ +#define FTDI_PCDJ_DAC2_PID 0xFA88 + +/* + * The following are the values for the Matrix Orbital LCD displays, + * which are the FT232BM ( similar to the 8U232AM ) + */ +#define FTDI_MTXORB_0_PID 0xFA00 /* Matrix Orbital Product Id */ +#define FTDI_MTXORB_1_PID 0xFA01 /* Matrix Orbital Product Id */ +#define FTDI_MTXORB_2_PID 0xFA02 /* Matrix Orbital Product Id */ +#define FTDI_MTXORB_3_PID 0xFA03 /* Matrix Orbital Product Id */ +#define FTDI_MTXORB_4_PID 0xFA04 /* Matrix Orbital Product Id */ +#define FTDI_MTXORB_5_PID 0xFA05 /* Matrix Orbital Product Id */ +#define FTDI_MTXORB_6_PID 0xFA06 /* Matrix Orbital Product Id */ + +/* OOCDlink by Joern Kaipf + * (http://www.joernonline.de/dw/doku.php?id=start&idx=projects:oocdlink) */ +#define FTDI_OOCDLINK_PID 0xbaf8 /* Amontec JTAGkey */ + +/* + * The following are the values for the Matrix Orbital FTDI Range + * Anything in this range will use an FT232RL. + */ +#define MTXORB_VID 0x1B3D +#define MTXORB_FTDI_RANGE_0100_PID 0x0100 +#define MTXORB_FTDI_RANGE_0101_PID 0x0101 +#define MTXORB_FTDI_RANGE_0102_PID 0x0102 +#define MTXORB_FTDI_RANGE_0103_PID 0x0103 +#define MTXORB_FTDI_RANGE_0104_PID 0x0104 +#define MTXORB_FTDI_RANGE_0105_PID 0x0105 +#define MTXORB_FTDI_RANGE_0106_PID 0x0106 +#define MTXORB_FTDI_RANGE_0107_PID 0x0107 +#define MTXORB_FTDI_RANGE_0108_PID 0x0108 +#define MTXORB_FTDI_RANGE_0109_PID 0x0109 +#define MTXORB_FTDI_RANGE_010A_PID 0x010A +#define MTXORB_FTDI_RANGE_010B_PID 0x010B +#define MTXORB_FTDI_RANGE_010C_PID 0x010C +#define MTXORB_FTDI_RANGE_010D_PID 0x010D +#define MTXORB_FTDI_RANGE_010E_PID 0x010E +#define MTXORB_FTDI_RANGE_010F_PID 0x010F +#define MTXORB_FTDI_RANGE_0110_PID 0x0110 +#define MTXORB_FTDI_RANGE_0111_PID 0x0111 +#define MTXORB_FTDI_RANGE_0112_PID 0x0112 +#define MTXORB_FTDI_RANGE_0113_PID 0x0113 +#define MTXORB_FTDI_RANGE_0114_PID 0x0114 +#define MTXORB_FTDI_RANGE_0115_PID 0x0115 +#define MTXORB_FTDI_RANGE_0116_PID 0x0116 +#define MTXORB_FTDI_RANGE_0117_PID 0x0117 +#define MTXORB_FTDI_RANGE_0118_PID 0x0118 +#define MTXORB_FTDI_RANGE_0119_PID 0x0119 +#define MTXORB_FTDI_RANGE_011A_PID 0x011A +#define MTXORB_FTDI_RANGE_011B_PID 0x011B +#define MTXORB_FTDI_RANGE_011C_PID 0x011C +#define MTXORB_FTDI_RANGE_011D_PID 0x011D +#define MTXORB_FTDI_RANGE_011E_PID 0x011E +#define MTXORB_FTDI_RANGE_011F_PID 0x011F +#define MTXORB_FTDI_RANGE_0120_PID 0x0120 +#define MTXORB_FTDI_RANGE_0121_PID 0x0121 +#define MTXORB_FTDI_RANGE_0122_PID 0x0122 +#define MTXORB_FTDI_RANGE_0123_PID 0x0123 +#define MTXORB_FTDI_RANGE_0124_PID 0x0124 +#define MTXORB_FTDI_RANGE_0125_PID 0x0125 +#define MTXORB_FTDI_RANGE_0126_PID 0x0126 +#define MTXORB_FTDI_RANGE_0127_PID 0x0127 +#define MTXORB_FTDI_RANGE_0128_PID 0x0128 +#define MTXORB_FTDI_RANGE_0129_PID 0x0129 +#define MTXORB_FTDI_RANGE_012A_PID 0x012A +#define MTXORB_FTDI_RANGE_012B_PID 0x012B +#define MTXORB_FTDI_RANGE_012C_PID 0x012C +#define MTXORB_FTDI_RANGE_012D_PID 0x012D +#define MTXORB_FTDI_RANGE_012E_PID 0x012E +#define MTXORB_FTDI_RANGE_012F_PID 0x012F +#define MTXORB_FTDI_RANGE_0130_PID 0x0130 +#define MTXORB_FTDI_RANGE_0131_PID 0x0131 +#define MTXORB_FTDI_RANGE_0132_PID 0x0132 +#define MTXORB_FTDI_RANGE_0133_PID 0x0133 +#define MTXORB_FTDI_RANGE_0134_PID 0x0134 +#define MTXORB_FTDI_RANGE_0135_PID 0x0135 +#define MTXORB_FTDI_RANGE_0136_PID 0x0136 +#define MTXORB_FTDI_RANGE_0137_PID 0x0137 +#define MTXORB_FTDI_RANGE_0138_PID 0x0138 +#define MTXORB_FTDI_RANGE_0139_PID 0x0139 +#define MTXORB_FTDI_RANGE_013A_PID 0x013A +#define MTXORB_FTDI_RANGE_013B_PID 0x013B +#define MTXORB_FTDI_RANGE_013C_PID 0x013C +#define MTXORB_FTDI_RANGE_013D_PID 0x013D +#define MTXORB_FTDI_RANGE_013E_PID 0x013E +#define MTXORB_FTDI_RANGE_013F_PID 0x013F +#define MTXORB_FTDI_RANGE_0140_PID 0x0140 +#define MTXORB_FTDI_RANGE_0141_PID 0x0141 +#define MTXORB_FTDI_RANGE_0142_PID 0x0142 +#define MTXORB_FTDI_RANGE_0143_PID 0x0143 +#define MTXORB_FTDI_RANGE_0144_PID 0x0144 +#define MTXORB_FTDI_RANGE_0145_PID 0x0145 +#define MTXORB_FTDI_RANGE_0146_PID 0x0146 +#define MTXORB_FTDI_RANGE_0147_PID 0x0147 +#define MTXORB_FTDI_RANGE_0148_PID 0x0148 +#define MTXORB_FTDI_RANGE_0149_PID 0x0149 +#define MTXORB_FTDI_RANGE_014A_PID 0x014A +#define MTXORB_FTDI_RANGE_014B_PID 0x014B +#define MTXORB_FTDI_RANGE_014C_PID 0x014C +#define MTXORB_FTDI_RANGE_014D_PID 0x014D +#define MTXORB_FTDI_RANGE_014E_PID 0x014E +#define MTXORB_FTDI_RANGE_014F_PID 0x014F +#define MTXORB_FTDI_RANGE_0150_PID 0x0150 +#define MTXORB_FTDI_RANGE_0151_PID 0x0151 +#define MTXORB_FTDI_RANGE_0152_PID 0x0152 +#define MTXORB_FTDI_RANGE_0153_PID 0x0153 +#define MTXORB_FTDI_RANGE_0154_PID 0x0154 +#define MTXORB_FTDI_RANGE_0155_PID 0x0155 +#define MTXORB_FTDI_RANGE_0156_PID 0x0156 +#define MTXORB_FTDI_RANGE_0157_PID 0x0157 +#define MTXORB_FTDI_RANGE_0158_PID 0x0158 +#define MTXORB_FTDI_RANGE_0159_PID 0x0159 +#define MTXORB_FTDI_RANGE_015A_PID 0x015A +#define MTXORB_FTDI_RANGE_015B_PID 0x015B +#define MTXORB_FTDI_RANGE_015C_PID 0x015C +#define MTXORB_FTDI_RANGE_015D_PID 0x015D +#define MTXORB_FTDI_RANGE_015E_PID 0x015E +#define MTXORB_FTDI_RANGE_015F_PID 0x015F +#define MTXORB_FTDI_RANGE_0160_PID 0x0160 +#define MTXORB_FTDI_RANGE_0161_PID 0x0161 +#define MTXORB_FTDI_RANGE_0162_PID 0x0162 +#define MTXORB_FTDI_RANGE_0163_PID 0x0163 +#define MTXORB_FTDI_RANGE_0164_PID 0x0164 +#define MTXORB_FTDI_RANGE_0165_PID 0x0165 +#define MTXORB_FTDI_RANGE_0166_PID 0x0166 +#define MTXORB_FTDI_RANGE_0167_PID 0x0167 +#define MTXORB_FTDI_RANGE_0168_PID 0x0168 +#define MTXORB_FTDI_RANGE_0169_PID 0x0169 +#define MTXORB_FTDI_RANGE_016A_PID 0x016A +#define MTXORB_FTDI_RANGE_016B_PID 0x016B +#define MTXORB_FTDI_RANGE_016C_PID 0x016C +#define MTXORB_FTDI_RANGE_016D_PID 0x016D +#define MTXORB_FTDI_RANGE_016E_PID 0x016E +#define MTXORB_FTDI_RANGE_016F_PID 0x016F +#define MTXORB_FTDI_RANGE_0170_PID 0x0170 +#define MTXORB_FTDI_RANGE_0171_PID 0x0171 +#define MTXORB_FTDI_RANGE_0172_PID 0x0172 +#define MTXORB_FTDI_RANGE_0173_PID 0x0173 +#define MTXORB_FTDI_RANGE_0174_PID 0x0174 +#define MTXORB_FTDI_RANGE_0175_PID 0x0175 +#define MTXORB_FTDI_RANGE_0176_PID 0x0176 +#define MTXORB_FTDI_RANGE_0177_PID 0x0177 +#define MTXORB_FTDI_RANGE_0178_PID 0x0178 +#define MTXORB_FTDI_RANGE_0179_PID 0x0179 +#define MTXORB_FTDI_RANGE_017A_PID 0x017A +#define MTXORB_FTDI_RANGE_017B_PID 0x017B +#define MTXORB_FTDI_RANGE_017C_PID 0x017C +#define MTXORB_FTDI_RANGE_017D_PID 0x017D +#define MTXORB_FTDI_RANGE_017E_PID 0x017E +#define MTXORB_FTDI_RANGE_017F_PID 0x017F +#define MTXORB_FTDI_RANGE_0180_PID 0x0180 +#define MTXORB_FTDI_RANGE_0181_PID 0x0181 +#define MTXORB_FTDI_RANGE_0182_PID 0x0182 +#define MTXORB_FTDI_RANGE_0183_PID 0x0183 +#define MTXORB_FTDI_RANGE_0184_PID 0x0184 +#define MTXORB_FTDI_RANGE_0185_PID 0x0185 +#define MTXORB_FTDI_RANGE_0186_PID 0x0186 +#define MTXORB_FTDI_RANGE_0187_PID 0x0187 +#define MTXORB_FTDI_RANGE_0188_PID 0x0188 +#define MTXORB_FTDI_RANGE_0189_PID 0x0189 +#define MTXORB_FTDI_RANGE_018A_PID 0x018A +#define MTXORB_FTDI_RANGE_018B_PID 0x018B +#define MTXORB_FTDI_RANGE_018C_PID 0x018C +#define MTXORB_FTDI_RANGE_018D_PID 0x018D +#define MTXORB_FTDI_RANGE_018E_PID 0x018E +#define MTXORB_FTDI_RANGE_018F_PID 0x018F +#define MTXORB_FTDI_RANGE_0190_PID 0x0190 +#define MTXORB_FTDI_RANGE_0191_PID 0x0191 +#define MTXORB_FTDI_RANGE_0192_PID 0x0192 +#define MTXORB_FTDI_RANGE_0193_PID 0x0193 +#define MTXORB_FTDI_RANGE_0194_PID 0x0194 +#define MTXORB_FTDI_RANGE_0195_PID 0x0195 +#define MTXORB_FTDI_RANGE_0196_PID 0x0196 +#define MTXORB_FTDI_RANGE_0197_PID 0x0197 +#define MTXORB_FTDI_RANGE_0198_PID 0x0198 +#define MTXORB_FTDI_RANGE_0199_PID 0x0199 +#define MTXORB_FTDI_RANGE_019A_PID 0x019A +#define MTXORB_FTDI_RANGE_019B_PID 0x019B +#define MTXORB_FTDI_RANGE_019C_PID 0x019C +#define MTXORB_FTDI_RANGE_019D_PID 0x019D +#define MTXORB_FTDI_RANGE_019E_PID 0x019E +#define MTXORB_FTDI_RANGE_019F_PID 0x019F +#define MTXORB_FTDI_RANGE_01A0_PID 0x01A0 +#define MTXORB_FTDI_RANGE_01A1_PID 0x01A1 +#define MTXORB_FTDI_RANGE_01A2_PID 0x01A2 +#define MTXORB_FTDI_RANGE_01A3_PID 0x01A3 +#define MTXORB_FTDI_RANGE_01A4_PID 0x01A4 +#define MTXORB_FTDI_RANGE_01A5_PID 0x01A5 +#define MTXORB_FTDI_RANGE_01A6_PID 0x01A6 +#define MTXORB_FTDI_RANGE_01A7_PID 0x01A7 +#define MTXORB_FTDI_RANGE_01A8_PID 0x01A8 +#define MTXORB_FTDI_RANGE_01A9_PID 0x01A9 +#define MTXORB_FTDI_RANGE_01AA_PID 0x01AA +#define MTXORB_FTDI_RANGE_01AB_PID 0x01AB +#define MTXORB_FTDI_RANGE_01AC_PID 0x01AC +#define MTXORB_FTDI_RANGE_01AD_PID 0x01AD +#define MTXORB_FTDI_RANGE_01AE_PID 0x01AE +#define MTXORB_FTDI_RANGE_01AF_PID 0x01AF +#define MTXORB_FTDI_RANGE_01B0_PID 0x01B0 +#define MTXORB_FTDI_RANGE_01B1_PID 0x01B1 +#define MTXORB_FTDI_RANGE_01B2_PID 0x01B2 +#define MTXORB_FTDI_RANGE_01B3_PID 0x01B3 +#define MTXORB_FTDI_RANGE_01B4_PID 0x01B4 +#define MTXORB_FTDI_RANGE_01B5_PID 0x01B5 +#define MTXORB_FTDI_RANGE_01B6_PID 0x01B6 +#define MTXORB_FTDI_RANGE_01B7_PID 0x01B7 +#define MTXORB_FTDI_RANGE_01B8_PID 0x01B8 +#define MTXORB_FTDI_RANGE_01B9_PID 0x01B9 +#define MTXORB_FTDI_RANGE_01BA_PID 0x01BA +#define MTXORB_FTDI_RANGE_01BB_PID 0x01BB +#define MTXORB_FTDI_RANGE_01BC_PID 0x01BC +#define MTXORB_FTDI_RANGE_01BD_PID 0x01BD +#define MTXORB_FTDI_RANGE_01BE_PID 0x01BE +#define MTXORB_FTDI_RANGE_01BF_PID 0x01BF +#define MTXORB_FTDI_RANGE_01C0_PID 0x01C0 +#define MTXORB_FTDI_RANGE_01C1_PID 0x01C1 +#define MTXORB_FTDI_RANGE_01C2_PID 0x01C2 +#define MTXORB_FTDI_RANGE_01C3_PID 0x01C3 +#define MTXORB_FTDI_RANGE_01C4_PID 0x01C4 +#define MTXORB_FTDI_RANGE_01C5_PID 0x01C5 +#define MTXORB_FTDI_RANGE_01C6_PID 0x01C6 +#define MTXORB_FTDI_RANGE_01C7_PID 0x01C7 +#define MTXORB_FTDI_RANGE_01C8_PID 0x01C8 +#define MTXORB_FTDI_RANGE_01C9_PID 0x01C9 +#define MTXORB_FTDI_RANGE_01CA_PID 0x01CA +#define MTXORB_FTDI_RANGE_01CB_PID 0x01CB +#define MTXORB_FTDI_RANGE_01CC_PID 0x01CC +#define MTXORB_FTDI_RANGE_01CD_PID 0x01CD +#define MTXORB_FTDI_RANGE_01CE_PID 0x01CE +#define MTXORB_FTDI_RANGE_01CF_PID 0x01CF +#define MTXORB_FTDI_RANGE_01D0_PID 0x01D0 +#define MTXORB_FTDI_RANGE_01D1_PID 0x01D1 +#define MTXORB_FTDI_RANGE_01D2_PID 0x01D2 +#define MTXORB_FTDI_RANGE_01D3_PID 0x01D3 +#define MTXORB_FTDI_RANGE_01D4_PID 0x01D4 +#define MTXORB_FTDI_RANGE_01D5_PID 0x01D5 +#define MTXORB_FTDI_RANGE_01D6_PID 0x01D6 +#define MTXORB_FTDI_RANGE_01D7_PID 0x01D7 +#define MTXORB_FTDI_RANGE_01D8_PID 0x01D8 +#define MTXORB_FTDI_RANGE_01D9_PID 0x01D9 +#define MTXORB_FTDI_RANGE_01DA_PID 0x01DA +#define MTXORB_FTDI_RANGE_01DB_PID 0x01DB +#define MTXORB_FTDI_RANGE_01DC_PID 0x01DC +#define MTXORB_FTDI_RANGE_01DD_PID 0x01DD +#define MTXORB_FTDI_RANGE_01DE_PID 0x01DE +#define MTXORB_FTDI_RANGE_01DF_PID 0x01DF +#define MTXORB_FTDI_RANGE_01E0_PID 0x01E0 +#define MTXORB_FTDI_RANGE_01E1_PID 0x01E1 +#define MTXORB_FTDI_RANGE_01E2_PID 0x01E2 +#define MTXORB_FTDI_RANGE_01E3_PID 0x01E3 +#define MTXORB_FTDI_RANGE_01E4_PID 0x01E4 +#define MTXORB_FTDI_RANGE_01E5_PID 0x01E5 +#define MTXORB_FTDI_RANGE_01E6_PID 0x01E6 +#define MTXORB_FTDI_RANGE_01E7_PID 0x01E7 +#define MTXORB_FTDI_RANGE_01E8_PID 0x01E8 +#define MTXORB_FTDI_RANGE_01E9_PID 0x01E9 +#define MTXORB_FTDI_RANGE_01EA_PID 0x01EA +#define MTXORB_FTDI_RANGE_01EB_PID 0x01EB +#define MTXORB_FTDI_RANGE_01EC_PID 0x01EC +#define MTXORB_FTDI_RANGE_01ED_PID 0x01ED +#define MTXORB_FTDI_RANGE_01EE_PID 0x01EE +#define MTXORB_FTDI_RANGE_01EF_PID 0x01EF +#define MTXORB_FTDI_RANGE_01F0_PID 0x01F0 +#define MTXORB_FTDI_RANGE_01F1_PID 0x01F1 +#define MTXORB_FTDI_RANGE_01F2_PID 0x01F2 +#define MTXORB_FTDI_RANGE_01F3_PID 0x01F3 +#define MTXORB_FTDI_RANGE_01F4_PID 0x01F4 +#define MTXORB_FTDI_RANGE_01F5_PID 0x01F5 +#define MTXORB_FTDI_RANGE_01F6_PID 0x01F6 +#define MTXORB_FTDI_RANGE_01F7_PID 0x01F7 +#define MTXORB_FTDI_RANGE_01F8_PID 0x01F8 +#define MTXORB_FTDI_RANGE_01F9_PID 0x01F9 +#define MTXORB_FTDI_RANGE_01FA_PID 0x01FA +#define MTXORB_FTDI_RANGE_01FB_PID 0x01FB +#define MTXORB_FTDI_RANGE_01FC_PID 0x01FC +#define MTXORB_FTDI_RANGE_01FD_PID 0x01FD +#define MTXORB_FTDI_RANGE_01FE_PID 0x01FE +#define MTXORB_FTDI_RANGE_01FF_PID 0x01FF + + + +/* Interbiometrics USB I/O Board */ +/* Developed for Interbiometrics by Rudolf Gugler */ +#define INTERBIOMETRICS_VID 0x1209 +#define INTERBIOMETRICS_IOBOARD_PID 0x1002 +#define INTERBIOMETRICS_MINI_IOBOARD_PID 0x1006 + +/* + * The following are the values for the Perle Systems + * UltraPort USB serial converters + */ +#define FTDI_PERLE_ULTRAPORT_PID 0xF0C0 /* Perle UltraPort Product Id */ + +/* + * The following are the values for the Sealevel SeaLINK+ adapters. + * (Original list sent by Tuan Hoang. Ian Abbott renamed the macros and + * removed some PIDs that don't seem to match any existing products.) + */ +#define SEALEVEL_VID 0x0c52 /* Sealevel Vendor ID */ +#define SEALEVEL_2101_PID 0x2101 /* SeaLINK+232 (2101/2105) */ +#define SEALEVEL_2102_PID 0x2102 /* SeaLINK+485 (2102) */ +#define SEALEVEL_2103_PID 0x2103 /* SeaLINK+232I (2103) */ +#define SEALEVEL_2104_PID 0x2104 /* SeaLINK+485I (2104) */ +#define SEALEVEL_2106_PID 0x9020 /* SeaLINK+422 (2106) */ +#define SEALEVEL_2201_1_PID 0x2211 /* SeaPORT+2/232 (2201) Port 1 */ +#define SEALEVEL_2201_2_PID 0x2221 /* SeaPORT+2/232 (2201) Port 2 */ +#define SEALEVEL_2202_1_PID 0x2212 /* SeaPORT+2/485 (2202) Port 1 */ +#define SEALEVEL_2202_2_PID 0x2222 /* SeaPORT+2/485 (2202) Port 2 */ +#define SEALEVEL_2203_1_PID 0x2213 /* SeaPORT+2 (2203) Port 1 */ +#define SEALEVEL_2203_2_PID 0x2223 /* SeaPORT+2 (2203) Port 2 */ +#define SEALEVEL_2401_1_PID 0x2411 /* SeaPORT+4/232 (2401) Port 1 */ +#define SEALEVEL_2401_2_PID 0x2421 /* SeaPORT+4/232 (2401) Port 2 */ +#define SEALEVEL_2401_3_PID 0x2431 /* SeaPORT+4/232 (2401) Port 3 */ +#define SEALEVEL_2401_4_PID 0x2441 /* SeaPORT+4/232 (2401) Port 4 */ +#define SEALEVEL_2402_1_PID 0x2412 /* SeaPORT+4/485 (2402) Port 1 */ +#define SEALEVEL_2402_2_PID 0x2422 /* SeaPORT+4/485 (2402) Port 2 */ +#define SEALEVEL_2402_3_PID 0x2432 /* SeaPORT+4/485 (2402) Port 3 */ +#define SEALEVEL_2402_4_PID 0x2442 /* SeaPORT+4/485 (2402) Port 4 */ +#define SEALEVEL_2403_1_PID 0x2413 /* SeaPORT+4 (2403) Port 1 */ +#define SEALEVEL_2403_2_PID 0x2423 /* SeaPORT+4 (2403) Port 2 */ +#define SEALEVEL_2403_3_PID 0x2433 /* SeaPORT+4 (2403) Port 3 */ +#define SEALEVEL_2403_4_PID 0x2443 /* SeaPORT+4 (2403) Port 4 */ +#define SEALEVEL_2801_1_PID 0X2811 /* SeaLINK+8/232 (2801) Port 1 */ +#define SEALEVEL_2801_2_PID 0X2821 /* SeaLINK+8/232 (2801) Port 2 */ +#define SEALEVEL_2801_3_PID 0X2831 /* SeaLINK+8/232 (2801) Port 3 */ +#define SEALEVEL_2801_4_PID 0X2841 /* SeaLINK+8/232 (2801) Port 4 */ +#define SEALEVEL_2801_5_PID 0X2851 /* SeaLINK+8/232 (2801) Port 5 */ +#define SEALEVEL_2801_6_PID 0X2861 /* SeaLINK+8/232 (2801) Port 6 */ +#define SEALEVEL_2801_7_PID 0X2871 /* SeaLINK+8/232 (2801) Port 7 */ +#define SEALEVEL_2801_8_PID 0X2881 /* SeaLINK+8/232 (2801) Port 8 */ +#define SEALEVEL_2802_1_PID 0X2812 /* SeaLINK+8/485 (2802) Port 1 */ +#define SEALEVEL_2802_2_PID 0X2822 /* SeaLINK+8/485 (2802) Port 2 */ +#define SEALEVEL_2802_3_PID 0X2832 /* SeaLINK+8/485 (2802) Port 3 */ +#define SEALEVEL_2802_4_PID 0X2842 /* SeaLINK+8/485 (2802) Port 4 */ +#define SEALEVEL_2802_5_PID 0X2852 /* SeaLINK+8/485 (2802) Port 5 */ +#define SEALEVEL_2802_6_PID 0X2862 /* SeaLINK+8/485 (2802) Port 6 */ +#define SEALEVEL_2802_7_PID 0X2872 /* SeaLINK+8/485 (2802) Port 7 */ +#define SEALEVEL_2802_8_PID 0X2882 /* SeaLINK+8/485 (2802) Port 8 */ +#define SEALEVEL_2803_1_PID 0X2813 /* SeaLINK+8 (2803) Port 1 */ +#define SEALEVEL_2803_2_PID 0X2823 /* SeaLINK+8 (2803) Port 2 */ +#define SEALEVEL_2803_3_PID 0X2833 /* SeaLINK+8 (2803) Port 3 */ +#define SEALEVEL_2803_4_PID 0X2843 /* SeaLINK+8 (2803) Port 4 */ +#define SEALEVEL_2803_5_PID 0X2853 /* SeaLINK+8 (2803) Port 5 */ +#define SEALEVEL_2803_6_PID 0X2863 /* SeaLINK+8 (2803) Port 6 */ +#define SEALEVEL_2803_7_PID 0X2873 /* SeaLINK+8 (2803) Port 7 */ +#define SEALEVEL_2803_8_PID 0X2883 /* SeaLINK+8 (2803) Port 8 */ + +/* + * The following are the values for two KOBIL chipcard terminals. + */ +#define KOBIL_VID 0x0d46 /* KOBIL Vendor ID */ +#define KOBIL_CONV_B1_PID 0x2020 /* KOBIL Konverter for B1 */ +#define KOBIL_CONV_KAAN_PID 0x2021 /* KOBIL_Konverter for KAAN */ + +/* + * Icom ID-1 digital transceiver + */ + +#define ICOM_ID1_VID 0x0C26 +#define ICOM_ID1_PID 0x0004 + +/* + * ASK.fr devices + */ +#define FTDI_ASK_RDR400_PID 0xC991 /* ASK RDR 400 series card reader */ + +/* + * FTDI USB UART chips used in construction projects from the + * Elektor Electronics magazine (http://elektor-electronics.co.uk) + */ +#define ELEKTOR_VID 0x0C7D +#define ELEKTOR_FT323R_PID 0x0005 /* RFID-Reader, issue 09-2006 */ + +/* + * DSS-20 Sync Station for Sony Ericsson P800 + */ +#define FTDI_DSS20_PID 0xFC82 + +/* + * Home Electronics (www.home-electro.com) USB gadgets + */ +#define FTDI_HE_TIRA1_PID 0xFA78 /* Tira-1 IR transceiver */ + +/* USB-UIRT - An infrared receiver and transmitter using the 8U232AM chip */ +/* http://home.earthlink.net/~jrhees/USBUIRT/index.htm */ +#define FTDI_USB_UIRT_PID 0xF850 /* Product Id */ + +/* TNC-X USB-to-packet-radio adapter, versions prior to 3.0 (DLP module) */ + +#define FTDI_TNC_X_PID 0xEBE0 + +/* + * ELV USB devices submitted by Christian Abt of ELV (www.elv.de). + * All of these devices use FTDI's vendor ID (0x0403). + * + * The previously included PID for the UO 100 module was incorrect. + * In fact, that PID was for ELV's UR 100 USB-RS232 converter (0xFB58). + * + * Armin Laeuger originally sent the PID for the UM 100 module. + */ +#define FTDI_R2000KU_TRUE_RNG 0xFB80 /* R2000KU TRUE RNG */ +#define FTDI_ELV_UR100_PID 0xFB58 /* USB-RS232-Umsetzer (UR 100) */ +#define FTDI_ELV_UM100_PID 0xFB5A /* USB-Modul UM 100 */ +#define FTDI_ELV_UO100_PID 0xFB5B /* USB-Modul UO 100 */ +#define FTDI_ELV_ALC8500_PID 0xF06E /* ALC 8500 Expert */ +/* Additional ELV PIDs that default to using the FTDI D2XX drivers on + * MS Windows, rather than the FTDI Virtual Com Port drivers. + * Maybe these will be easier to use with the libftdi/libusb user-space + * drivers, or possibly the Comedi drivers in some cases. */ +#define FTDI_ELV_CLI7000_PID 0xFB59 /* Computer-Light-Interface (CLI 7000) */ +#define FTDI_ELV_PPS7330_PID 0xFB5C /* Processor-Power-Supply (PPS 7330) */ +#define FTDI_ELV_TFM100_PID 0xFB5D /* Temperartur-Feuchte Messgeraet (TFM 100) */ +#define FTDI_ELV_UDF77_PID 0xFB5E /* USB DCF Funkurh (UDF 77) */ +#define FTDI_ELV_UIO88_PID 0xFB5F /* USB-I/O Interface (UIO 88) */ +#define FTDI_ELV_UAD8_PID 0xF068 /* USB-AD-Wandler (UAD 8) */ +#define FTDI_ELV_UDA7_PID 0xF069 /* USB-DA-Wandler (UDA 7) */ +#define FTDI_ELV_USI2_PID 0xF06A /* USB-Schrittmotoren-Interface (USI 2) */ +#define FTDI_ELV_T1100_PID 0xF06B /* Thermometer (T 1100) */ +#define FTDI_ELV_PCD200_PID 0xF06C /* PC-Datenlogger (PCD 200) */ +#define FTDI_ELV_ULA200_PID 0xF06D /* USB-LCD-Ansteuerung (ULA 200) */ +#define FTDI_ELV_FHZ1000PC_PID 0xF06F /* FHZ 1000 PC */ +#define FTDI_ELV_CSI8_PID 0xE0F0 /* Computer-Schalt-Interface (CSI 8) */ +#define FTDI_ELV_EM1000DL_PID 0xE0F1 /* PC-Datenlogger fuer Energiemonitor (EM 1000 DL) */ +#define FTDI_ELV_PCK100_PID 0xE0F2 /* PC-Kabeltester (PCK 100) */ +#define FTDI_ELV_RFP500_PID 0xE0F3 /* HF-Leistungsmesser (RFP 500) */ +#define FTDI_ELV_FS20SIG_PID 0xE0F4 /* Signalgeber (FS 20 SIG) */ +#define FTDI_ELV_WS300PC_PID 0xE0F6 /* PC-Wetterstation (WS 300 PC) */ +#define FTDI_ELV_FHZ1300PC_PID 0xE0E8 /* FHZ 1300 PC */ +#define FTDI_ELV_WS500_PID 0xE0E9 /* PC-Wetterstation (WS 500) */ +#define FTDI_ELV_HS485_PID 0xE0EA /* USB to RS-485 adapter */ +#define FTDI_ELV_EM1010PC_PID 0xE0EF /* Engery monitor EM 1010 PC */ +#define FTDI_PHI_FISCO_PID 0xE40B /* PHI Fisco USB to Serial cable */ + +/* + * Definitions for ID TECH (www.idt-net.com) devices + */ +#define IDTECH_VID 0x0ACD /* ID TECH Vendor ID */ +#define IDTECH_IDT1221U_PID 0x0300 /* IDT1221U USB to RS-232 adapter */ + +/* + * Definitions for Omnidirectional Control Technology, Inc. devices + */ +#define OCT_VID 0x0B39 /* OCT vendor ID */ +/* Note: OCT US101 is also rebadged as Dick Smith Electronics (NZ) XH6381 */ +/* Also rebadged as Dick Smith Electronics (Aus) XH6451 */ +/* Also rebadged as SIIG Inc. model US2308 hardware version 1 */ +#define OCT_US101_PID 0x0421 /* OCT US101 USB to RS-232 */ + +/* an infrared receiver for user access control with IR tags */ +#define FTDI_PIEGROUP_PID 0xF208 /* Product Id */ + +/* + * Definitions for Artemis astronomical USB based cameras + * Check it at http://www.artemisccd.co.uk/ + */ +#define FTDI_ARTEMIS_PID 0xDF28 /* All Artemis Cameras */ + +/* + * Definitions for ATIK Instruments astronomical USB based cameras + * Check it at http://www.atik-instruments.com/ + */ +#define FTDI_ATIK_ATK16_PID 0xDF30 /* ATIK ATK-16 Grayscale Camera */ +#define FTDI_ATIK_ATK16C_PID 0xDF32 /* ATIK ATK-16C Colour Camera */ +#define FTDI_ATIK_ATK16HR_PID 0xDF31 /* ATIK ATK-16HR Grayscale Camera */ +#define FTDI_ATIK_ATK16HRC_PID 0xDF33 /* ATIK ATK-16HRC Colour Camera */ +#define FTDI_ATIK_ATK16IC_PID 0xDF35 /* ATIK ATK-16IC Grayscale Camera */ + +/* + * Protego product ids + */ +#define PROTEGO_SPECIAL_1 0xFC70 /* special/unknown device */ +#define PROTEGO_R2X0 0xFC71 /* R200-USB TRNG unit (R210, R220, and R230) */ +#define PROTEGO_SPECIAL_3 0xFC72 /* special/unknown device */ +#define PROTEGO_SPECIAL_4 0xFC73 /* special/unknown device */ + +/* + * Gude Analog- und Digitalsysteme GmbH + */ +#define FTDI_GUDEADS_E808_PID 0xE808 +#define FTDI_GUDEADS_E809_PID 0xE809 +#define FTDI_GUDEADS_E80A_PID 0xE80A +#define FTDI_GUDEADS_E80B_PID 0xE80B +#define FTDI_GUDEADS_E80C_PID 0xE80C +#define FTDI_GUDEADS_E80D_PID 0xE80D +#define FTDI_GUDEADS_E80E_PID 0xE80E +#define FTDI_GUDEADS_E80F_PID 0xE80F +#define FTDI_GUDEADS_E888_PID 0xE888 /* Expert ISDN Control USB */ +#define FTDI_GUDEADS_E889_PID 0xE889 /* USB RS-232 OptoBridge */ +#define FTDI_GUDEADS_E88A_PID 0xE88A +#define FTDI_GUDEADS_E88B_PID 0xE88B +#define FTDI_GUDEADS_E88C_PID 0xE88C +#define FTDI_GUDEADS_E88D_PID 0xE88D +#define FTDI_GUDEADS_E88E_PID 0xE88E +#define FTDI_GUDEADS_E88F_PID 0xE88F + +/* + * Linx Technologies product ids + */ +#define LINX_SDMUSBQSS_PID 0xF448 /* Linx SDM-USB-QS-S */ +#define LINX_MASTERDEVEL2_PID 0xF449 /* Linx Master Development 2.0 */ +#define LINX_FUTURE_0_PID 0xF44A /* Linx future device */ +#define LINX_FUTURE_1_PID 0xF44B /* Linx future device */ +#define LINX_FUTURE_2_PID 0xF44C /* Linx future device */ + +/* CCS Inc. ICDU/ICDU40 product ID - the FT232BM is used in an in-circuit-debugger */ +/* unit for PIC16's/PIC18's */ +#define FTDI_CCSICDU20_0_PID 0xF9D0 +#define FTDI_CCSICDU40_1_PID 0xF9D1 +#define FTDI_CCSMACHX_2_PID 0xF9D2 +#define FTDI_CCSLOAD_N_GO_3_PID 0xF9D3 +#define FTDI_CCSICDU64_4_PID 0xF9D4 +#define FTDI_CCSPRIME8_5_PID 0xF9D5 + +/* Inside Accesso contactless reader (http://www.insidefr.com) */ +#define INSIDE_ACCESSO 0xFAD0 + +/* + * Intrepid Control Systems (http://www.intrepidcs.com/) ValueCAN and NeoVI + */ +#define INTREPID_VID 0x093C +#define INTREPID_VALUECAN_PID 0x0601 +#define INTREPID_NEOVI_PID 0x0701 + +/* + * Falcom Wireless Communications GmbH + */ +#define FALCOM_VID 0x0F94 /* Vendor Id */ +#define FALCOM_TWIST_PID 0x0001 /* Falcom Twist USB GPRS modem */ +#define FALCOM_SAMBA_PID 0x0005 /* Falcom Samba USB GPRS modem */ + +/* + * SUUNTO product ids + */ +#define FTDI_SUUNTO_SPORTS_PID 0xF680 /* Suunto Sports instrument */ + +/* + * Oceanic product ids + */ +#define FTDI_OCEANIC_PID 0xF460 /* Oceanic dive instrument */ + +/* + * TTi (Thurlby Thandar Instruments) + */ +#define TTI_VID 0x103E /* Vendor Id */ +#define TTI_QL355P_PID 0x03E8 /* TTi QL355P power supply */ + +/* + * Definitions for B&B Electronics products. + */ +#define BANDB_VID 0x0856 /* B&B Electronics Vendor ID */ +#define BANDB_USOTL4_PID 0xAC01 /* USOTL4 Isolated RS-485 Converter */ +#define BANDB_USTL4_PID 0xAC02 /* USTL4 RS-485 Converter */ +#define BANDB_USO9ML2_PID 0xAC03 /* USO9ML2 Isolated RS-232 Converter */ +#define BANDB_USOPTL4_PID 0xAC11 +#define BANDB_USPTL4_PID 0xAC12 +#define BANDB_USO9ML2DR_2_PID 0xAC16 +#define BANDB_USO9ML2DR_PID 0xAC17 +#define BANDB_USOPTL4DR2_PID 0xAC18 /* USOPTL4R-2 2-port Isolated RS-232 Converter */ +#define BANDB_USOPTL4DR_PID 0xAC19 +#define BANDB_485USB9F_2W_PID 0xAC25 +#define BANDB_485USB9F_4W_PID 0xAC26 +#define BANDB_232USB9M_PID 0xAC27 +#define BANDB_485USBTB_2W_PID 0xAC33 +#define BANDB_485USBTB_4W_PID 0xAC34 +#define BANDB_TTL5USB9M_PID 0xAC49 +#define BANDB_TTL3USB9M_PID 0xAC50 +#define BANDB_ZZ_PROG1_USB_PID 0xBA02 + +/* + * RM Michaelides CANview USB (http://www.rmcan.com) + * CAN fieldbus interface adapter, added by port GmbH www.port.de) + * Ian Abbott changed the macro names for consistency. + */ +#define FTDI_RM_CANVIEW_PID 0xfd60 /* Product Id */ + +/* + * EVER Eco Pro UPS (http://www.ever.com.pl/) + */ + +#define EVER_ECO_PRO_CDS 0xe520 /* RS-232 converter */ + +/* + * 4N-GALAXY.DE PIDs for CAN-USB, USB-RS232, USB-RS422, USB-RS485, + * USB-TTY activ, USB-TTY passiv. Some PIDs are used by several devices + * and I'm not entirely sure which are used by which. + */ +#define FTDI_4N_GALAXY_DE_1_PID 0xF3C0 +#define FTDI_4N_GALAXY_DE_2_PID 0xF3C1 + +/* + * Mobility Electronics products. + */ +#define MOBILITY_VID 0x1342 +#define MOBILITY_USB_SERIAL_PID 0x0202 /* EasiDock USB 200 serial */ + +/* + * microHAM product IDs (http://www.microham.com). + * Submitted by Justin Burket (KL1RL) + * and Mike Studer (K6EEP) . + * Ian Abbott added a few more from the driver INF file. + */ +#define FTDI_MHAM_KW_PID 0xEEE8 /* USB-KW interface */ +#define FTDI_MHAM_YS_PID 0xEEE9 /* USB-YS interface */ +#define FTDI_MHAM_Y6_PID 0xEEEA /* USB-Y6 interface */ +#define FTDI_MHAM_Y8_PID 0xEEEB /* USB-Y8 interface */ +#define FTDI_MHAM_IC_PID 0xEEEC /* USB-IC interface */ +#define FTDI_MHAM_DB9_PID 0xEEED /* USB-DB9 interface */ +#define FTDI_MHAM_RS232_PID 0xEEEE /* USB-RS232 interface */ +#define FTDI_MHAM_Y9_PID 0xEEEF /* USB-Y9 interface */ + +/* + * Active Robots product ids. + */ +#define FTDI_ACTIVE_ROBOTS_PID 0xE548 /* USB comms board */ + +/* + * Xsens Technologies BV products (http://www.xsens.com). + */ +#define XSENS_CONVERTER_0_PID 0xD388 +#define XSENS_CONVERTER_1_PID 0xD389 +#define XSENS_CONVERTER_2_PID 0xD38A +#define XSENS_CONVERTER_3_PID 0xD38B +#define XSENS_CONVERTER_4_PID 0xD38C +#define XSENS_CONVERTER_5_PID 0xD38D +#define XSENS_CONVERTER_6_PID 0xD38E +#define XSENS_CONVERTER_7_PID 0xD38F + +/* + * Teratronik product ids. + * Submitted by O. Wlfelschneider. + */ +#define FTDI_TERATRONIK_VCP_PID 0xEC88 /* Teratronik device (preferring VCP driver on windows) */ +#define FTDI_TERATRONIK_D2XX_PID 0xEC89 /* Teratronik device (preferring D2XX driver on windows) */ + +/* + * Evolution Robotics products (http://www.evolution.com/). + * Submitted by Shawn M. Lavelle. + */ +#define EVOLUTION_VID 0xDEEE /* Vendor ID */ +#define EVOLUTION_ER1_PID 0x0300 /* ER1 Control Module */ +#define EVO_8U232AM_PID 0x02FF /* Evolution robotics RCM2 (FT232AM)*/ +#define EVO_HYBRID_PID 0x0302 /* Evolution robotics RCM4 PID (FT232BM)*/ +#define EVO_RCM4_PID 0x0303 /* Evolution robotics RCM4 PID */ + +/* Pyramid Computer GmbH */ +#define FTDI_PYRAMID_PID 0xE6C8 /* Pyramid Appliance Display */ + +/* + * NDI (www.ndigital.com) product ids + */ +#define FTDI_NDI_HUC_PID 0xDA70 /* NDI Host USB Converter */ +#define FTDI_NDI_SPECTRA_SCU_PID 0xDA71 /* NDI Spectra SCU */ +#define FTDI_NDI_FUTURE_2_PID 0xDA72 /* NDI future device #2 */ +#define FTDI_NDI_FUTURE_3_PID 0xDA73 /* NDI future device #3 */ +#define FTDI_NDI_AURORA_SCU_PID 0xDA74 /* NDI Aurora SCU */ + +/* + * Posiflex inc retail equipment (http://www.posiflex.com.tw) + */ +#define POSIFLEX_VID 0x0d3a /* Vendor ID */ +#define POSIFLEX_PP7000_PID 0x0300 /* PP-7000II thermal printer */ + +/* + * Westrex International devices submitted by Cory Lee + */ +#define FTDI_WESTREX_MODEL_777_PID 0xDC00 /* Model 777 */ +#define FTDI_WESTREX_MODEL_8900F_PID 0xDC01 /* Model 8900F */ + +/* + * RR-CirKits LocoBuffer USB (http://www.rr-cirkits.com) + */ +#define FTDI_RRCIRKITS_LOCOBUFFER_PID 0xc7d0 /* LocoBuffer USB */ + +/* + * Eclo (http://www.eclo.pt/) product IDs. + * PID 0xEA90 submitted by Martin Grill. + */ +#define FTDI_ECLO_COM_1WIRE_PID 0xEA90 /* COM to 1-Wire USB adaptor */ + +/* + * Papouch products (http://www.papouch.com/) + * Submitted by Folkert van Heusden + */ + +#define PAPOUCH_VID 0x5050 /* Vendor ID */ +#define PAPOUCH_TMU_PID 0x0400 /* TMU USB Thermometer */ +#define PAPOUCH_QUIDO4x4_PID 0x0900 /* Quido 4/4 Module */ + +/* + * ACG Identification Technologies GmbH products (http://www.acg.de/). + * Submitted by anton -at- goto10 -dot- org. + */ +#define FTDI_ACG_HFDUAL_PID 0xDD20 /* HF Dual ISO Reader (RFID) */ + +/* + * Yost Engineering, Inc. products (www.yostengineering.com). + * PID 0xE050 submitted by Aaron Prose. + */ +#define FTDI_YEI_SERVOCENTER31_PID 0xE050 /* YEI ServoCenter3.1 USB */ + +/* + * ThorLabs USB motor drivers + */ +#define FTDI_THORLABS_PID 0xfaf0 /* ThorLabs USB motor drivers */ + +/* + * Testo products (http://www.testo.com/) + * Submitted by Colin Leroy + */ +#define TESTO_VID 0x128D +#define TESTO_USB_INTERFACE_PID 0x0001 + +/* + * Gamma Scout (http://gamma-scout.com/). Submitted by rsc@runtux.com. + */ +#define FTDI_GAMMA_SCOUT_PID 0xD678 /* Gamma Scout online */ + +/* + * Tactrix OpenPort (ECU) devices. + * OpenPort 1.3M submitted by Donour Sizemore. + * OpenPort 1.3S and 1.3U submitted by Ian Abbott. + */ +#define FTDI_TACTRIX_OPENPORT_13M_PID 0xCC48 /* OpenPort 1.3 Mitsubishi */ +#define FTDI_TACTRIX_OPENPORT_13S_PID 0xCC49 /* OpenPort 1.3 Subaru */ +#define FTDI_TACTRIX_OPENPORT_13U_PID 0xCC4A /* OpenPort 1.3 Universal */ + +/* + * Telldus Technologies + */ +#define TELLDUS_VID 0x1781 /* Vendor ID */ +#define TELLDUS_TELLSTICK_PID 0x0C30 /* RF control dongle 433 MHz using FT232RL */ + +/* + * IBS elektronik product ids + * Submitted by Thomas Schleusener + */ +#define FTDI_IBS_US485_PID 0xff38 /* IBS US485 (USB<-->RS422/485 interface) */ +#define FTDI_IBS_PICPRO_PID 0xff39 /* IBS PIC-Programmer */ +#define FTDI_IBS_PCMCIA_PID 0xff3a /* IBS Card reader for PCMCIA SRAM-cards */ +#define FTDI_IBS_PK1_PID 0xff3b /* IBS PK1 - Particel counter */ +#define FTDI_IBS_RS232MON_PID 0xff3c /* IBS RS232 - Monitor */ +#define FTDI_IBS_APP70_PID 0xff3d /* APP 70 (dust monitoring system) */ +#define FTDI_IBS_PEDO_PID 0xff3e /* IBS PEDO-Modem (RF modem 868.35 MHz) */ +#define FTDI_IBS_PROD_PID 0xff3f /* future device */ + +/* + * MaxStream devices www.maxstream.net + */ +#define FTDI_MAXSTREAM_PID 0xEE18 /* Xbee PKG-U Module */ + +/* Olimex */ +#define OLIMEX_VID 0x15BA +#define OLIMEX_ARM_USB_OCD_PID 0x0003 + +/* Luminary Micro Stellaris Boards, VID = FTDI_VID */ +/* FTDI 2332C Dual channel device, side A=245 FIFO (JTAG), Side B=RS232 UART */ +#define LMI_LM3S_DEVEL_BOARD_PID 0xbcd8 +#define LMI_LM3S_EVAL_BOARD_PID 0xbcd9 + +/* www.elsterelectricity.com Elster Unicom III Optical Probe */ +#define FTDI_ELSTER_UNICOM_PID 0xE700 /* Product Id */ + +/* + * The Mobility Lab (TML) + * Submitted by Pierre Castella + */ +#define TML_VID 0x1B91 /* Vendor ID */ +#define TML_USB_SERIAL_PID 0x0064 /* USB - Serial Converter */ + +/* Propox devices */ +#define FTDI_PROPOX_JTAGCABLEII_PID 0xD738 + +/* Rig Expert Ukraine devices */ +#define FTDI_REU_TINY_PID 0xED22 /* RigExpert Tiny */ + +/* Domintell products http://www.domintell.com */ +#define FTDI_DOMINTELL_DGQG_PID 0xEF50 /* Master */ +#define FTDI_DOMINTELL_DUSB_PID 0xEF51 /* DUSB01 module */ + +/* Alti-2 products http://www.alti-2.com */ +#define ALTI2_VID 0x1BC9 +#define ALTI2_N3_PID 0x6001 /* Neptune 3 */ + +/* + * FIC / OpenMoko, Inc. http://wiki.openmoko.org/wiki/Neo1973_Debug_Board_v3 + * Submitted by Harald Welte + */ +#define FIC_VID 0x1457 +#define FIC_NEO1973_DEBUG_PID 0x5118 + +/* + * RATOC REX-USB60F + */ +#define RATOC_VENDOR_ID 0x0584 +#define RATOC_PRODUCT_ID_USB60F 0xb020 + +/* + * DIEBOLD BCS SE923 + */ +#define DIEBOLD_BCS_SE923_PID 0xfb99 + +/* + * Atmel STK541 + */ +#define ATMEL_VID 0x03eb /* Vendor ID */ +#define STK541_PID 0x2109 /* Zigbee Controller */ + +/* + * Dresden Elektronic Sensor Terminal Board + */ +#define DE_VID 0x1cf1 /* Vendor ID */ +#define STB_PID 0x0001 /* Sensor Terminal Board */ +#define WHT_PID 0x0004 /* Wireless Handheld Terminal */ + +/* + * Blackfin gnICE JTAG + * http://docs.blackfin.uclinux.org/doku.php?id=hw:jtag:gnice + */ +#define ADI_VID 0x0456 +#define ADI_GNICE_PID 0xF000 +#define ADI_GNICEPLUS_PID 0xF001 + +/* + * JETI SPECTROMETER SPECBOS 1201 + * http://www.jeti.com/products/sys/scb/scb1201.php + */ +#define JETI_VID 0x0c6c +#define JETI_SPC1201_PID 0x04b2 + +/* + * Marvell SheevaPlug + */ +#define MARVELL_VID 0x9e88 +#define MARVELL_SHEEVAPLUG_PID 0x9e8f + +#define FTDI_TURTELIZER_PID 0xBDC8 /* JTAG/RS-232 adapter by egnite GmBH */ + +/* + * GN Otometrics (http://www.otometrics.com) + * Submitted by Ville Sundberg. + */ +#define GN_OTOMETRICS_VID 0x0c33 /* Vendor ID */ +#define AURICAL_USB_PID 0x0010 /* Aurical USB Audiometer */ + +/* + * Bayer Ascensia Contour blood glucose meter USB-converter cable. + * http://winglucofacts.com/cables/ + */ +#define BAYER_VID 0x1A79 +#define BAYER_CONTOUR_CABLE_PID 0x6001 + +/* + * Marvell OpenRD Base, Client + * http://www.open-rd.org + * OpenRD Base, Client use VID 0x0403 + */ +#define MARVELL_OPENRD_PID 0x9e90 + +/* + * Hameg HO820 and HO870 interface (using VID 0x0403) + */ +#define HAMEG_HO820_PID 0xed74 +#define HAMEG_HO870_PID 0xed71 + -- cgit v0.10.2 From 4e092d110fe931db3878865db185be1c9df3e182 Mon Sep 17 00:00:00 2001 From: Andreas Mohr Date: Thu, 17 Dec 2009 11:56:09 +0100 Subject: USB: ftdi_sio: sort PID/VID entries in new ftdi_sio_ids.h header This is a (almost) sort-only patch to sort FTDI device product ID definitions in new ftdi_sio_ids.h header. Advantage is that new device ID submissions will now have a specific (sorted) position - less future merge conflicts. Compile-tested, based on _current_ mainline git. Minor checkpatch.pl warnings were eliminated whereever it made sense, very minor text changes. Signed-off-by: Andreas Mohr Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index 2b5017b..da92b49 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h @@ -1,36 +1,85 @@ /* * vendor/product IDs (VID/PID) of devices using FTDI USB serial converters. + * Please keep numerically sorted within individual areas, thanks! * * Philipp Ghring - pg@futureware.at - added the Device ID of the USB relais * from Rudolf Gugler * */ + +/**********************************/ +/***** devices using FTDI VID *****/ +/**********************************/ + + #define FTDI_VID 0x0403 /* Vendor Id */ -#define FTDI_SIO_PID 0x8372 /* Product Id SIO application of 8U100AX */ + + +/*** "original" FTDI device PIDs ***/ + #define FTDI_8U232AM_PID 0x6001 /* Similar device to SIO above */ #define FTDI_8U232AM_ALT_PID 0x6006 /* FTDI's alternate PID for above */ #define FTDI_8U2232C_PID 0x6010 /* Dual channel device */ -#define FTDI_232RL_PID 0xFBFA /* Product ID for FT232RL */ #define FTDI_4232H_PID 0x6011 /* Quad channel hi-speed device */ -#define FTDI_RELAIS_PID 0xFA10 /* Relais device from Rudolf Gugler */ -#define FTDI_NF_RIC_VID 0x0DCD /* Vendor Id */ -#define FTDI_NF_RIC_PID 0x0001 /* Product Id */ -#define FTDI_USBX_707_PID 0xF857 /* ADSTech IR Blaster USBX-707 */ +#define FTDI_SIO_PID 0x8372 /* Product Id SIO application of 8U100AX */ +#define FTDI_232RL_PID 0xFBFA /* Product ID for FT232RL */ -/* Larsen and Brusgaard AltiTrack/USBtrack */ -#define LARSENBRUSGAARD_VID 0x0FD8 -#define LB_ALTITRACK_PID 0x0001 -/* www.canusb.com Lawicel CANUSB device */ -#define FTDI_CANUSB_PID 0xFFA8 /* Product Id */ +/*** third-party PIDs (using FTDI_VID) ***/ -/* AlphaMicro Components AMC-232USB01 device */ -#define FTDI_AMC232_PID 0xFF00 /* Product Id */ +/* + * Marvell OpenRD Base, Client + * http://www.open-rd.org + * OpenRD Base, Client use VID 0x0403 + */ +#define MARVELL_OPENRD_PID 0x9e90 /* www.candapter.com Ewert Energy Systems CANdapter device */ #define FTDI_CANDAPTER_PID 0x9F80 /* Product Id */ +/* OOCDlink by Joern Kaipf + * (http://www.joernonline.de/dw/doku.php?id=start&idx=projects:oocdlink) */ +#define FTDI_OOCDLINK_PID 0xbaf8 /* Amontec JTAGkey */ + +/* Luminary Micro Stellaris Boards, VID = FTDI_VID */ +/* FTDI 2332C Dual channel device, side A=245 FIFO (JTAG), Side B=RS232 UART */ +#define LMI_LM3S_DEVEL_BOARD_PID 0xbcd8 +#define LMI_LM3S_EVAL_BOARD_PID 0xbcd9 + +#define FTDI_TURTELIZER_PID 0xBDC8 /* JTAG/RS-232 adapter by egnite GmBH */ + +/* OpenDCC (www.opendcc.de) product id */ +#define FTDI_OPENDCC_PID 0xBFD8 +#define FTDI_OPENDCC_SNIFFER_PID 0xBFD9 +#define FTDI_OPENDCC_THROTTLE_PID 0xBFDA +#define FTDI_OPENDCC_GATEWAY_PID 0xBFDB + +/* + * RR-CirKits LocoBuffer USB (http://www.rr-cirkits.com) + */ +#define FTDI_RRCIRKITS_LOCOBUFFER_PID 0xc7d0 /* LocoBuffer USB */ + +/* DMX4ALL DMX Interfaces */ +#define FTDI_DMX4ALL 0xC850 + +/* + * ASK.fr devices + */ +#define FTDI_ASK_RDR400_PID 0xC991 /* ASK RDR 400 series card reader */ + +/* www.starting-point-systems.com Chameleon device */ +#define FTDI_MICRO_CHAMELEON_PID 0xCAA0 /* Product Id */ + +/* + * Tactrix OpenPort (ECU) devices. + * OpenPort 1.3M submitted by Donour Sizemore. + * OpenPort 1.3S and 1.3U submitted by Ian Abbott. + */ +#define FTDI_TACTRIX_OPENPORT_13M_PID 0xCC48 /* OpenPort 1.3 Mitsubishi */ +#define FTDI_TACTRIX_OPENPORT_13S_PID 0xCC49 /* OpenPort 1.3 Subaru */ +#define FTDI_TACTRIX_OPENPORT_13U_PID 0xCC4A /* OpenPort 1.3 Universal */ + /* SCS HF Radio Modems PID's (http://www.scs-ptc.com) */ /* the VID is the standard ftdi vid (FTDI_VID) */ #define FTDI_SCS_DEVICE_0_PID 0xD010 /* SCS PTC-IIusb */ @@ -42,523 +91,280 @@ #define FTDI_SCS_DEVICE_6_PID 0xD016 #define FTDI_SCS_DEVICE_7_PID 0xD017 -/* ACT Solutions HomePro ZWave interface (http://www.act-solutions.com/HomePro.htm) */ -#define FTDI_ACTZWAVE_PID 0xF2D0 +/* iPlus device */ +#define FTDI_IPLUS_PID 0xD070 /* Product Id */ +#define FTDI_IPLUS2_PID 0xD071 /* Product Id */ +/* + * Gamma Scout (http://gamma-scout.com/). Submitted by rsc@runtux.com. + */ +#define FTDI_GAMMA_SCOUT_PID 0xD678 /* Gamma Scout online */ -/* www.starting-point-systems.com Chameleon device */ -#define FTDI_MICRO_CHAMELEON_PID 0xCAA0 /* Product Id */ +/* Propox devices */ +#define FTDI_PROPOX_JTAGCABLEII_PID 0xD738 -/* www.irtrans.de device */ -#define FTDI_IRTRANS_PID 0xFC60 /* Product Id */ +/* + * Xsens Technologies BV products (http://www.xsens.com). + */ +#define XSENS_CONVERTER_0_PID 0xD388 +#define XSENS_CONVERTER_1_PID 0xD389 +#define XSENS_CONVERTER_2_PID 0xD38A +#define XSENS_CONVERTER_3_PID 0xD38B +#define XSENS_CONVERTER_4_PID 0xD38C +#define XSENS_CONVERTER_5_PID 0xD38D +#define XSENS_CONVERTER_6_PID 0xD38E +#define XSENS_CONVERTER_7_PID 0xD38F +/* + * NDI (www.ndigital.com) product ids + */ +#define FTDI_NDI_HUC_PID 0xDA70 /* NDI Host USB Converter */ +#define FTDI_NDI_SPECTRA_SCU_PID 0xDA71 /* NDI Spectra SCU */ +#define FTDI_NDI_FUTURE_2_PID 0xDA72 /* NDI future device #2 */ +#define FTDI_NDI_FUTURE_3_PID 0xDA73 /* NDI future device #3 */ +#define FTDI_NDI_AURORA_SCU_PID 0xDA74 /* NDI Aurora SCU */ -/* www.thoughttechnology.com/ TT-USB provide with procomp use ftdi_sio */ -#define FTDI_TTUSB_PID 0xFF20 /* Product Id */ +/* + * Westrex International devices submitted by Cory Lee + */ +#define FTDI_WESTREX_MODEL_777_PID 0xDC00 /* Model 777 */ +#define FTDI_WESTREX_MODEL_8900F_PID 0xDC01 /* Model 8900F */ -/* iPlus device */ -#define FTDI_IPLUS_PID 0xD070 /* Product Id */ -#define FTDI_IPLUS2_PID 0xD071 /* Product Id */ +/* + * ACG Identification Technologies GmbH products (http://www.acg.de/). + * Submitted by anton -at- goto10 -dot- org. + */ +#define FTDI_ACG_HFDUAL_PID 0xDD20 /* HF Dual ISO Reader (RFID) */ -/* DMX4ALL DMX Interfaces */ -#define FTDI_DMX4ALL 0xC850 +/* + * Definitions for Artemis astronomical USB based cameras + * Check it at http://www.artemisccd.co.uk/ + */ +#define FTDI_ARTEMIS_PID 0xDF28 /* All Artemis Cameras */ -/* OpenDCC (www.opendcc.de) product id */ -#define FTDI_OPENDCC_PID 0xBFD8 -#define FTDI_OPENDCC_SNIFFER_PID 0xBFD9 -#define FTDI_OPENDCC_THROTTLE_PID 0xBFDA -#define FTDI_OPENDCC_GATEWAY_PID 0xBFDB +/* + * Definitions for ATIK Instruments astronomical USB based cameras + * Check it at http://www.atik-instruments.com/ + */ +#define FTDI_ATIK_ATK16_PID 0xDF30 /* ATIK ATK-16 Grayscale Camera */ +#define FTDI_ATIK_ATK16C_PID 0xDF32 /* ATIK ATK-16C Colour Camera */ +#define FTDI_ATIK_ATK16HR_PID 0xDF31 /* ATIK ATK-16HR Grayscale Camera */ +#define FTDI_ATIK_ATK16HRC_PID 0xDF33 /* ATIK ATK-16HRC Colour Camera */ +#define FTDI_ATIK_ATK16IC_PID 0xDF35 /* ATIK ATK-16IC Grayscale Camera */ -/* Sprog II (Andrew Crosland's SprogII DCC interface) */ -#define FTDI_SPROG_II 0xF0C8 +/* + * Yost Engineering, Inc. products (www.yostengineering.com). + * PID 0xE050 submitted by Aaron Prose. + */ +#define FTDI_YEI_SERVOCENTER31_PID 0xE050 /* YEI ServoCenter3.1 USB */ -/* www.crystalfontz.com devices - thanx for providing free devices for evaluation ! */ -/* they use the ftdi chipset for the USB interface and the vendor id is the same */ -#define FTDI_XF_632_PID 0xFC08 /* 632: 16x2 Character Display */ -#define FTDI_XF_634_PID 0xFC09 /* 634: 20x4 Character Display */ -#define FTDI_XF_547_PID 0xFC0A /* 547: Two line Display */ -#define FTDI_XF_633_PID 0xFC0B /* 633: 16x2 Character Display with Keys */ -#define FTDI_XF_631_PID 0xFC0C /* 631: 20x2 Character Display */ -#define FTDI_XF_635_PID 0xFC0D /* 635: 20x4 Character Display */ -#define FTDI_XF_640_PID 0xFC0E /* 640: Two line Display */ -#define FTDI_XF_642_PID 0xFC0F /* 642: Two line Display */ +/* + * ELV USB devices submitted by Christian Abt of ELV (www.elv.de). + * All of these devices use FTDI's vendor ID (0x0403). + * + * The previously included PID for the UO 100 module was incorrect. + * In fact, that PID was for ELV's UR 100 USB-RS232 converter (0xFB58). + * + * Armin Laeuger originally sent the PID for the UM 100 module. + */ +#define FTDI_ELV_FHZ1300PC_PID 0xE0E8 /* FHZ 1300 PC */ +#define FTDI_ELV_WS500_PID 0xE0E9 /* PC-Wetterstation (WS 500) */ +#define FTDI_ELV_HS485_PID 0xE0EA /* USB to RS-485 adapter */ +#define FTDI_ELV_EM1010PC_PID 0xE0EF /* Engery monitor EM 1010 PC */ +#define FTDI_ELV_CSI8_PID 0xE0F0 /* Computer-Schalt-Interface (CSI 8) */ +#define FTDI_ELV_EM1000DL_PID 0xE0F1 /* PC-Datenlogger fuer Energiemonitor (EM 1000 DL) */ +#define FTDI_ELV_PCK100_PID 0xE0F2 /* PC-Kabeltester (PCK 100) */ +#define FTDI_ELV_RFP500_PID 0xE0F3 /* HF-Leistungsmesser (RFP 500) */ +#define FTDI_ELV_FS20SIG_PID 0xE0F4 /* Signalgeber (FS 20 SIG) */ +#define FTDI_ELV_WS300PC_PID 0xE0F6 /* PC-Wetterstation (WS 300 PC) */ +#define FTDI_PHI_FISCO_PID 0xE40B /* PHI Fisco USB to Serial cable */ +#define FTDI_ELV_UAD8_PID 0xF068 /* USB-AD-Wandler (UAD 8) */ +#define FTDI_ELV_UDA7_PID 0xF069 /* USB-DA-Wandler (UDA 7) */ +#define FTDI_ELV_USI2_PID 0xF06A /* USB-Schrittmotoren-Interface (USI 2) */ +#define FTDI_ELV_T1100_PID 0xF06B /* Thermometer (T 1100) */ +#define FTDI_ELV_PCD200_PID 0xF06C /* PC-Datenlogger (PCD 200) */ +#define FTDI_ELV_ULA200_PID 0xF06D /* USB-LCD-Ansteuerung (ULA 200) */ +#define FTDI_ELV_ALC8500_PID 0xF06E /* ALC 8500 Expert */ +#define FTDI_ELV_FHZ1000PC_PID 0xF06F /* FHZ 1000 PC */ +#define FTDI_ELV_UR100_PID 0xFB58 /* USB-RS232-Umsetzer (UR 100) */ +#define FTDI_ELV_UM100_PID 0xFB5A /* USB-Modul UM 100 */ +#define FTDI_ELV_UO100_PID 0xFB5B /* USB-Modul UO 100 */ +/* Additional ELV PIDs that default to using the FTDI D2XX drivers on + * MS Windows, rather than the FTDI Virtual Com Port drivers. + * Maybe these will be easier to use with the libftdi/libusb user-space + * drivers, or possibly the Comedi drivers in some cases. */ +#define FTDI_ELV_CLI7000_PID 0xFB59 /* Computer-Light-Interface (CLI 7000) */ +#define FTDI_ELV_PPS7330_PID 0xFB5C /* Processor-Power-Supply (PPS 7330) */ +#define FTDI_ELV_TFM100_PID 0xFB5D /* Temperartur-Feuchte Messgeraet (TFM 100) */ +#define FTDI_ELV_UDF77_PID 0xFB5E /* USB DCF Funkurh (UDF 77) */ +#define FTDI_ELV_UIO88_PID 0xFB5F /* USB-I/O Interface (UIO 88) */ -/* Video Networks Limited / Homechoice in the UK use an ftdi-based device for their 1Mb */ -/* broadband internet service. The following PID is exhibited by the usb device supplied */ -/* (the VID is the standard ftdi vid (FTDI_VID) */ -#define FTDI_VNHCPCUSB_D_PID 0xfe38 /* Product Id */ +/* + * EVER Eco Pro UPS (http://www.ever.com.pl/) + */ + +#define EVER_ECO_PRO_CDS 0xe520 /* RS-232 converter */ /* - * PCDJ use ftdi based dj-controllers. The following PID is for their DAC-2 device - * http://www.pcdjhardware.com/DAC2.asp (PID sent by Wouter Paesen) - * (the VID is the standard ftdi vid (FTDI_VID) */ -#define FTDI_PCDJ_DAC2_PID 0xFA88 + * Active Robots product ids. + */ +#define FTDI_ACTIVE_ROBOTS_PID 0xE548 /* USB comms board */ + +/* Pyramid Computer GmbH */ +#define FTDI_PYRAMID_PID 0xE6C8 /* Pyramid Appliance Display */ + +/* www.elsterelectricity.com Elster Unicom III Optical Probe */ +#define FTDI_ELSTER_UNICOM_PID 0xE700 /* Product Id */ /* - * The following are the values for the Matrix Orbital LCD displays, - * which are the FT232BM ( similar to the 8U232AM ) + * Gude Analog- und Digitalsysteme GmbH */ -#define FTDI_MTXORB_0_PID 0xFA00 /* Matrix Orbital Product Id */ -#define FTDI_MTXORB_1_PID 0xFA01 /* Matrix Orbital Product Id */ -#define FTDI_MTXORB_2_PID 0xFA02 /* Matrix Orbital Product Id */ -#define FTDI_MTXORB_3_PID 0xFA03 /* Matrix Orbital Product Id */ -#define FTDI_MTXORB_4_PID 0xFA04 /* Matrix Orbital Product Id */ -#define FTDI_MTXORB_5_PID 0xFA05 /* Matrix Orbital Product Id */ -#define FTDI_MTXORB_6_PID 0xFA06 /* Matrix Orbital Product Id */ +#define FTDI_GUDEADS_E808_PID 0xE808 +#define FTDI_GUDEADS_E809_PID 0xE809 +#define FTDI_GUDEADS_E80A_PID 0xE80A +#define FTDI_GUDEADS_E80B_PID 0xE80B +#define FTDI_GUDEADS_E80C_PID 0xE80C +#define FTDI_GUDEADS_E80D_PID 0xE80D +#define FTDI_GUDEADS_E80E_PID 0xE80E +#define FTDI_GUDEADS_E80F_PID 0xE80F +#define FTDI_GUDEADS_E888_PID 0xE888 /* Expert ISDN Control USB */ +#define FTDI_GUDEADS_E889_PID 0xE889 /* USB RS-232 OptoBridge */ +#define FTDI_GUDEADS_E88A_PID 0xE88A +#define FTDI_GUDEADS_E88B_PID 0xE88B +#define FTDI_GUDEADS_E88C_PID 0xE88C +#define FTDI_GUDEADS_E88D_PID 0xE88D +#define FTDI_GUDEADS_E88E_PID 0xE88E +#define FTDI_GUDEADS_E88F_PID 0xE88F -/* OOCDlink by Joern Kaipf - * (http://www.joernonline.de/dw/doku.php?id=start&idx=projects:oocdlink) */ -#define FTDI_OOCDLINK_PID 0xbaf8 /* Amontec JTAGkey */ +/* + * Eclo (http://www.eclo.pt/) product IDs. + * PID 0xEA90 submitted by Martin Grill. + */ +#define FTDI_ECLO_COM_1WIRE_PID 0xEA90 /* COM to 1-Wire USB adaptor */ + +/* TNC-X USB-to-packet-radio adapter, versions prior to 3.0 (DLP module) */ +#define FTDI_TNC_X_PID 0xEBE0 /* - * The following are the values for the Matrix Orbital FTDI Range - * Anything in this range will use an FT232RL. + * Teratronik product ids. + * Submitted by O. Wlfelschneider. */ -#define MTXORB_VID 0x1B3D -#define MTXORB_FTDI_RANGE_0100_PID 0x0100 -#define MTXORB_FTDI_RANGE_0101_PID 0x0101 -#define MTXORB_FTDI_RANGE_0102_PID 0x0102 -#define MTXORB_FTDI_RANGE_0103_PID 0x0103 -#define MTXORB_FTDI_RANGE_0104_PID 0x0104 -#define MTXORB_FTDI_RANGE_0105_PID 0x0105 -#define MTXORB_FTDI_RANGE_0106_PID 0x0106 -#define MTXORB_FTDI_RANGE_0107_PID 0x0107 -#define MTXORB_FTDI_RANGE_0108_PID 0x0108 -#define MTXORB_FTDI_RANGE_0109_PID 0x0109 -#define MTXORB_FTDI_RANGE_010A_PID 0x010A -#define MTXORB_FTDI_RANGE_010B_PID 0x010B -#define MTXORB_FTDI_RANGE_010C_PID 0x010C -#define MTXORB_FTDI_RANGE_010D_PID 0x010D -#define MTXORB_FTDI_RANGE_010E_PID 0x010E -#define MTXORB_FTDI_RANGE_010F_PID 0x010F -#define MTXORB_FTDI_RANGE_0110_PID 0x0110 -#define MTXORB_FTDI_RANGE_0111_PID 0x0111 -#define MTXORB_FTDI_RANGE_0112_PID 0x0112 -#define MTXORB_FTDI_RANGE_0113_PID 0x0113 -#define MTXORB_FTDI_RANGE_0114_PID 0x0114 -#define MTXORB_FTDI_RANGE_0115_PID 0x0115 -#define MTXORB_FTDI_RANGE_0116_PID 0x0116 -#define MTXORB_FTDI_RANGE_0117_PID 0x0117 -#define MTXORB_FTDI_RANGE_0118_PID 0x0118 -#define MTXORB_FTDI_RANGE_0119_PID 0x0119 -#define MTXORB_FTDI_RANGE_011A_PID 0x011A -#define MTXORB_FTDI_RANGE_011B_PID 0x011B -#define MTXORB_FTDI_RANGE_011C_PID 0x011C -#define MTXORB_FTDI_RANGE_011D_PID 0x011D -#define MTXORB_FTDI_RANGE_011E_PID 0x011E -#define MTXORB_FTDI_RANGE_011F_PID 0x011F -#define MTXORB_FTDI_RANGE_0120_PID 0x0120 -#define MTXORB_FTDI_RANGE_0121_PID 0x0121 -#define MTXORB_FTDI_RANGE_0122_PID 0x0122 -#define MTXORB_FTDI_RANGE_0123_PID 0x0123 -#define MTXORB_FTDI_RANGE_0124_PID 0x0124 -#define MTXORB_FTDI_RANGE_0125_PID 0x0125 -#define MTXORB_FTDI_RANGE_0126_PID 0x0126 -#define MTXORB_FTDI_RANGE_0127_PID 0x0127 -#define MTXORB_FTDI_RANGE_0128_PID 0x0128 -#define MTXORB_FTDI_RANGE_0129_PID 0x0129 -#define MTXORB_FTDI_RANGE_012A_PID 0x012A -#define MTXORB_FTDI_RANGE_012B_PID 0x012B -#define MTXORB_FTDI_RANGE_012C_PID 0x012C -#define MTXORB_FTDI_RANGE_012D_PID 0x012D -#define MTXORB_FTDI_RANGE_012E_PID 0x012E -#define MTXORB_FTDI_RANGE_012F_PID 0x012F -#define MTXORB_FTDI_RANGE_0130_PID 0x0130 -#define MTXORB_FTDI_RANGE_0131_PID 0x0131 -#define MTXORB_FTDI_RANGE_0132_PID 0x0132 -#define MTXORB_FTDI_RANGE_0133_PID 0x0133 -#define MTXORB_FTDI_RANGE_0134_PID 0x0134 -#define MTXORB_FTDI_RANGE_0135_PID 0x0135 -#define MTXORB_FTDI_RANGE_0136_PID 0x0136 -#define MTXORB_FTDI_RANGE_0137_PID 0x0137 -#define MTXORB_FTDI_RANGE_0138_PID 0x0138 -#define MTXORB_FTDI_RANGE_0139_PID 0x0139 -#define MTXORB_FTDI_RANGE_013A_PID 0x013A -#define MTXORB_FTDI_RANGE_013B_PID 0x013B -#define MTXORB_FTDI_RANGE_013C_PID 0x013C -#define MTXORB_FTDI_RANGE_013D_PID 0x013D -#define MTXORB_FTDI_RANGE_013E_PID 0x013E -#define MTXORB_FTDI_RANGE_013F_PID 0x013F -#define MTXORB_FTDI_RANGE_0140_PID 0x0140 -#define MTXORB_FTDI_RANGE_0141_PID 0x0141 -#define MTXORB_FTDI_RANGE_0142_PID 0x0142 -#define MTXORB_FTDI_RANGE_0143_PID 0x0143 -#define MTXORB_FTDI_RANGE_0144_PID 0x0144 -#define MTXORB_FTDI_RANGE_0145_PID 0x0145 -#define MTXORB_FTDI_RANGE_0146_PID 0x0146 -#define MTXORB_FTDI_RANGE_0147_PID 0x0147 -#define MTXORB_FTDI_RANGE_0148_PID 0x0148 -#define MTXORB_FTDI_RANGE_0149_PID 0x0149 -#define MTXORB_FTDI_RANGE_014A_PID 0x014A -#define MTXORB_FTDI_RANGE_014B_PID 0x014B -#define MTXORB_FTDI_RANGE_014C_PID 0x014C -#define MTXORB_FTDI_RANGE_014D_PID 0x014D -#define MTXORB_FTDI_RANGE_014E_PID 0x014E -#define MTXORB_FTDI_RANGE_014F_PID 0x014F -#define MTXORB_FTDI_RANGE_0150_PID 0x0150 -#define MTXORB_FTDI_RANGE_0151_PID 0x0151 -#define MTXORB_FTDI_RANGE_0152_PID 0x0152 -#define MTXORB_FTDI_RANGE_0153_PID 0x0153 -#define MTXORB_FTDI_RANGE_0154_PID 0x0154 -#define MTXORB_FTDI_RANGE_0155_PID 0x0155 -#define MTXORB_FTDI_RANGE_0156_PID 0x0156 -#define MTXORB_FTDI_RANGE_0157_PID 0x0157 -#define MTXORB_FTDI_RANGE_0158_PID 0x0158 -#define MTXORB_FTDI_RANGE_0159_PID 0x0159 -#define MTXORB_FTDI_RANGE_015A_PID 0x015A -#define MTXORB_FTDI_RANGE_015B_PID 0x015B -#define MTXORB_FTDI_RANGE_015C_PID 0x015C -#define MTXORB_FTDI_RANGE_015D_PID 0x015D -#define MTXORB_FTDI_RANGE_015E_PID 0x015E -#define MTXORB_FTDI_RANGE_015F_PID 0x015F -#define MTXORB_FTDI_RANGE_0160_PID 0x0160 -#define MTXORB_FTDI_RANGE_0161_PID 0x0161 -#define MTXORB_FTDI_RANGE_0162_PID 0x0162 -#define MTXORB_FTDI_RANGE_0163_PID 0x0163 -#define MTXORB_FTDI_RANGE_0164_PID 0x0164 -#define MTXORB_FTDI_RANGE_0165_PID 0x0165 -#define MTXORB_FTDI_RANGE_0166_PID 0x0166 -#define MTXORB_FTDI_RANGE_0167_PID 0x0167 -#define MTXORB_FTDI_RANGE_0168_PID 0x0168 -#define MTXORB_FTDI_RANGE_0169_PID 0x0169 -#define MTXORB_FTDI_RANGE_016A_PID 0x016A -#define MTXORB_FTDI_RANGE_016B_PID 0x016B -#define MTXORB_FTDI_RANGE_016C_PID 0x016C -#define MTXORB_FTDI_RANGE_016D_PID 0x016D -#define MTXORB_FTDI_RANGE_016E_PID 0x016E -#define MTXORB_FTDI_RANGE_016F_PID 0x016F -#define MTXORB_FTDI_RANGE_0170_PID 0x0170 -#define MTXORB_FTDI_RANGE_0171_PID 0x0171 -#define MTXORB_FTDI_RANGE_0172_PID 0x0172 -#define MTXORB_FTDI_RANGE_0173_PID 0x0173 -#define MTXORB_FTDI_RANGE_0174_PID 0x0174 -#define MTXORB_FTDI_RANGE_0175_PID 0x0175 -#define MTXORB_FTDI_RANGE_0176_PID 0x0176 -#define MTXORB_FTDI_RANGE_0177_PID 0x0177 -#define MTXORB_FTDI_RANGE_0178_PID 0x0178 -#define MTXORB_FTDI_RANGE_0179_PID 0x0179 -#define MTXORB_FTDI_RANGE_017A_PID 0x017A -#define MTXORB_FTDI_RANGE_017B_PID 0x017B -#define MTXORB_FTDI_RANGE_017C_PID 0x017C -#define MTXORB_FTDI_RANGE_017D_PID 0x017D -#define MTXORB_FTDI_RANGE_017E_PID 0x017E -#define MTXORB_FTDI_RANGE_017F_PID 0x017F -#define MTXORB_FTDI_RANGE_0180_PID 0x0180 -#define MTXORB_FTDI_RANGE_0181_PID 0x0181 -#define MTXORB_FTDI_RANGE_0182_PID 0x0182 -#define MTXORB_FTDI_RANGE_0183_PID 0x0183 -#define MTXORB_FTDI_RANGE_0184_PID 0x0184 -#define MTXORB_FTDI_RANGE_0185_PID 0x0185 -#define MTXORB_FTDI_RANGE_0186_PID 0x0186 -#define MTXORB_FTDI_RANGE_0187_PID 0x0187 -#define MTXORB_FTDI_RANGE_0188_PID 0x0188 -#define MTXORB_FTDI_RANGE_0189_PID 0x0189 -#define MTXORB_FTDI_RANGE_018A_PID 0x018A -#define MTXORB_FTDI_RANGE_018B_PID 0x018B -#define MTXORB_FTDI_RANGE_018C_PID 0x018C -#define MTXORB_FTDI_RANGE_018D_PID 0x018D -#define MTXORB_FTDI_RANGE_018E_PID 0x018E -#define MTXORB_FTDI_RANGE_018F_PID 0x018F -#define MTXORB_FTDI_RANGE_0190_PID 0x0190 -#define MTXORB_FTDI_RANGE_0191_PID 0x0191 -#define MTXORB_FTDI_RANGE_0192_PID 0x0192 -#define MTXORB_FTDI_RANGE_0193_PID 0x0193 -#define MTXORB_FTDI_RANGE_0194_PID 0x0194 -#define MTXORB_FTDI_RANGE_0195_PID 0x0195 -#define MTXORB_FTDI_RANGE_0196_PID 0x0196 -#define MTXORB_FTDI_RANGE_0197_PID 0x0197 -#define MTXORB_FTDI_RANGE_0198_PID 0x0198 -#define MTXORB_FTDI_RANGE_0199_PID 0x0199 -#define MTXORB_FTDI_RANGE_019A_PID 0x019A -#define MTXORB_FTDI_RANGE_019B_PID 0x019B -#define MTXORB_FTDI_RANGE_019C_PID 0x019C -#define MTXORB_FTDI_RANGE_019D_PID 0x019D -#define MTXORB_FTDI_RANGE_019E_PID 0x019E -#define MTXORB_FTDI_RANGE_019F_PID 0x019F -#define MTXORB_FTDI_RANGE_01A0_PID 0x01A0 -#define MTXORB_FTDI_RANGE_01A1_PID 0x01A1 -#define MTXORB_FTDI_RANGE_01A2_PID 0x01A2 -#define MTXORB_FTDI_RANGE_01A3_PID 0x01A3 -#define MTXORB_FTDI_RANGE_01A4_PID 0x01A4 -#define MTXORB_FTDI_RANGE_01A5_PID 0x01A5 -#define MTXORB_FTDI_RANGE_01A6_PID 0x01A6 -#define MTXORB_FTDI_RANGE_01A7_PID 0x01A7 -#define MTXORB_FTDI_RANGE_01A8_PID 0x01A8 -#define MTXORB_FTDI_RANGE_01A9_PID 0x01A9 -#define MTXORB_FTDI_RANGE_01AA_PID 0x01AA -#define MTXORB_FTDI_RANGE_01AB_PID 0x01AB -#define MTXORB_FTDI_RANGE_01AC_PID 0x01AC -#define MTXORB_FTDI_RANGE_01AD_PID 0x01AD -#define MTXORB_FTDI_RANGE_01AE_PID 0x01AE -#define MTXORB_FTDI_RANGE_01AF_PID 0x01AF -#define MTXORB_FTDI_RANGE_01B0_PID 0x01B0 -#define MTXORB_FTDI_RANGE_01B1_PID 0x01B1 -#define MTXORB_FTDI_RANGE_01B2_PID 0x01B2 -#define MTXORB_FTDI_RANGE_01B3_PID 0x01B3 -#define MTXORB_FTDI_RANGE_01B4_PID 0x01B4 -#define MTXORB_FTDI_RANGE_01B5_PID 0x01B5 -#define MTXORB_FTDI_RANGE_01B6_PID 0x01B6 -#define MTXORB_FTDI_RANGE_01B7_PID 0x01B7 -#define MTXORB_FTDI_RANGE_01B8_PID 0x01B8 -#define MTXORB_FTDI_RANGE_01B9_PID 0x01B9 -#define MTXORB_FTDI_RANGE_01BA_PID 0x01BA -#define MTXORB_FTDI_RANGE_01BB_PID 0x01BB -#define MTXORB_FTDI_RANGE_01BC_PID 0x01BC -#define MTXORB_FTDI_RANGE_01BD_PID 0x01BD -#define MTXORB_FTDI_RANGE_01BE_PID 0x01BE -#define MTXORB_FTDI_RANGE_01BF_PID 0x01BF -#define MTXORB_FTDI_RANGE_01C0_PID 0x01C0 -#define MTXORB_FTDI_RANGE_01C1_PID 0x01C1 -#define MTXORB_FTDI_RANGE_01C2_PID 0x01C2 -#define MTXORB_FTDI_RANGE_01C3_PID 0x01C3 -#define MTXORB_FTDI_RANGE_01C4_PID 0x01C4 -#define MTXORB_FTDI_RANGE_01C5_PID 0x01C5 -#define MTXORB_FTDI_RANGE_01C6_PID 0x01C6 -#define MTXORB_FTDI_RANGE_01C7_PID 0x01C7 -#define MTXORB_FTDI_RANGE_01C8_PID 0x01C8 -#define MTXORB_FTDI_RANGE_01C9_PID 0x01C9 -#define MTXORB_FTDI_RANGE_01CA_PID 0x01CA -#define MTXORB_FTDI_RANGE_01CB_PID 0x01CB -#define MTXORB_FTDI_RANGE_01CC_PID 0x01CC -#define MTXORB_FTDI_RANGE_01CD_PID 0x01CD -#define MTXORB_FTDI_RANGE_01CE_PID 0x01CE -#define MTXORB_FTDI_RANGE_01CF_PID 0x01CF -#define MTXORB_FTDI_RANGE_01D0_PID 0x01D0 -#define MTXORB_FTDI_RANGE_01D1_PID 0x01D1 -#define MTXORB_FTDI_RANGE_01D2_PID 0x01D2 -#define MTXORB_FTDI_RANGE_01D3_PID 0x01D3 -#define MTXORB_FTDI_RANGE_01D4_PID 0x01D4 -#define MTXORB_FTDI_RANGE_01D5_PID 0x01D5 -#define MTXORB_FTDI_RANGE_01D6_PID 0x01D6 -#define MTXORB_FTDI_RANGE_01D7_PID 0x01D7 -#define MTXORB_FTDI_RANGE_01D8_PID 0x01D8 -#define MTXORB_FTDI_RANGE_01D9_PID 0x01D9 -#define MTXORB_FTDI_RANGE_01DA_PID 0x01DA -#define MTXORB_FTDI_RANGE_01DB_PID 0x01DB -#define MTXORB_FTDI_RANGE_01DC_PID 0x01DC -#define MTXORB_FTDI_RANGE_01DD_PID 0x01DD -#define MTXORB_FTDI_RANGE_01DE_PID 0x01DE -#define MTXORB_FTDI_RANGE_01DF_PID 0x01DF -#define MTXORB_FTDI_RANGE_01E0_PID 0x01E0 -#define MTXORB_FTDI_RANGE_01E1_PID 0x01E1 -#define MTXORB_FTDI_RANGE_01E2_PID 0x01E2 -#define MTXORB_FTDI_RANGE_01E3_PID 0x01E3 -#define MTXORB_FTDI_RANGE_01E4_PID 0x01E4 -#define MTXORB_FTDI_RANGE_01E5_PID 0x01E5 -#define MTXORB_FTDI_RANGE_01E6_PID 0x01E6 -#define MTXORB_FTDI_RANGE_01E7_PID 0x01E7 -#define MTXORB_FTDI_RANGE_01E8_PID 0x01E8 -#define MTXORB_FTDI_RANGE_01E9_PID 0x01E9 -#define MTXORB_FTDI_RANGE_01EA_PID 0x01EA -#define MTXORB_FTDI_RANGE_01EB_PID 0x01EB -#define MTXORB_FTDI_RANGE_01EC_PID 0x01EC -#define MTXORB_FTDI_RANGE_01ED_PID 0x01ED -#define MTXORB_FTDI_RANGE_01EE_PID 0x01EE -#define MTXORB_FTDI_RANGE_01EF_PID 0x01EF -#define MTXORB_FTDI_RANGE_01F0_PID 0x01F0 -#define MTXORB_FTDI_RANGE_01F1_PID 0x01F1 -#define MTXORB_FTDI_RANGE_01F2_PID 0x01F2 -#define MTXORB_FTDI_RANGE_01F3_PID 0x01F3 -#define MTXORB_FTDI_RANGE_01F4_PID 0x01F4 -#define MTXORB_FTDI_RANGE_01F5_PID 0x01F5 -#define MTXORB_FTDI_RANGE_01F6_PID 0x01F6 -#define MTXORB_FTDI_RANGE_01F7_PID 0x01F7 -#define MTXORB_FTDI_RANGE_01F8_PID 0x01F8 -#define MTXORB_FTDI_RANGE_01F9_PID 0x01F9 -#define MTXORB_FTDI_RANGE_01FA_PID 0x01FA -#define MTXORB_FTDI_RANGE_01FB_PID 0x01FB -#define MTXORB_FTDI_RANGE_01FC_PID 0x01FC -#define MTXORB_FTDI_RANGE_01FD_PID 0x01FD -#define MTXORB_FTDI_RANGE_01FE_PID 0x01FE -#define MTXORB_FTDI_RANGE_01FF_PID 0x01FF - - - -/* Interbiometrics USB I/O Board */ -/* Developed for Interbiometrics by Rudolf Gugler */ -#define INTERBIOMETRICS_VID 0x1209 -#define INTERBIOMETRICS_IOBOARD_PID 0x1002 -#define INTERBIOMETRICS_MINI_IOBOARD_PID 0x1006 - -/* - * The following are the values for the Perle Systems - * UltraPort USB serial converters - */ -#define FTDI_PERLE_ULTRAPORT_PID 0xF0C0 /* Perle UltraPort Product Id */ - -/* - * The following are the values for the Sealevel SeaLINK+ adapters. - * (Original list sent by Tuan Hoang. Ian Abbott renamed the macros and - * removed some PIDs that don't seem to match any existing products.) - */ -#define SEALEVEL_VID 0x0c52 /* Sealevel Vendor ID */ -#define SEALEVEL_2101_PID 0x2101 /* SeaLINK+232 (2101/2105) */ -#define SEALEVEL_2102_PID 0x2102 /* SeaLINK+485 (2102) */ -#define SEALEVEL_2103_PID 0x2103 /* SeaLINK+232I (2103) */ -#define SEALEVEL_2104_PID 0x2104 /* SeaLINK+485I (2104) */ -#define SEALEVEL_2106_PID 0x9020 /* SeaLINK+422 (2106) */ -#define SEALEVEL_2201_1_PID 0x2211 /* SeaPORT+2/232 (2201) Port 1 */ -#define SEALEVEL_2201_2_PID 0x2221 /* SeaPORT+2/232 (2201) Port 2 */ -#define SEALEVEL_2202_1_PID 0x2212 /* SeaPORT+2/485 (2202) Port 1 */ -#define SEALEVEL_2202_2_PID 0x2222 /* SeaPORT+2/485 (2202) Port 2 */ -#define SEALEVEL_2203_1_PID 0x2213 /* SeaPORT+2 (2203) Port 1 */ -#define SEALEVEL_2203_2_PID 0x2223 /* SeaPORT+2 (2203) Port 2 */ -#define SEALEVEL_2401_1_PID 0x2411 /* SeaPORT+4/232 (2401) Port 1 */ -#define SEALEVEL_2401_2_PID 0x2421 /* SeaPORT+4/232 (2401) Port 2 */ -#define SEALEVEL_2401_3_PID 0x2431 /* SeaPORT+4/232 (2401) Port 3 */ -#define SEALEVEL_2401_4_PID 0x2441 /* SeaPORT+4/232 (2401) Port 4 */ -#define SEALEVEL_2402_1_PID 0x2412 /* SeaPORT+4/485 (2402) Port 1 */ -#define SEALEVEL_2402_2_PID 0x2422 /* SeaPORT+4/485 (2402) Port 2 */ -#define SEALEVEL_2402_3_PID 0x2432 /* SeaPORT+4/485 (2402) Port 3 */ -#define SEALEVEL_2402_4_PID 0x2442 /* SeaPORT+4/485 (2402) Port 4 */ -#define SEALEVEL_2403_1_PID 0x2413 /* SeaPORT+4 (2403) Port 1 */ -#define SEALEVEL_2403_2_PID 0x2423 /* SeaPORT+4 (2403) Port 2 */ -#define SEALEVEL_2403_3_PID 0x2433 /* SeaPORT+4 (2403) Port 3 */ -#define SEALEVEL_2403_4_PID 0x2443 /* SeaPORT+4 (2403) Port 4 */ -#define SEALEVEL_2801_1_PID 0X2811 /* SeaLINK+8/232 (2801) Port 1 */ -#define SEALEVEL_2801_2_PID 0X2821 /* SeaLINK+8/232 (2801) Port 2 */ -#define SEALEVEL_2801_3_PID 0X2831 /* SeaLINK+8/232 (2801) Port 3 */ -#define SEALEVEL_2801_4_PID 0X2841 /* SeaLINK+8/232 (2801) Port 4 */ -#define SEALEVEL_2801_5_PID 0X2851 /* SeaLINK+8/232 (2801) Port 5 */ -#define SEALEVEL_2801_6_PID 0X2861 /* SeaLINK+8/232 (2801) Port 6 */ -#define SEALEVEL_2801_7_PID 0X2871 /* SeaLINK+8/232 (2801) Port 7 */ -#define SEALEVEL_2801_8_PID 0X2881 /* SeaLINK+8/232 (2801) Port 8 */ -#define SEALEVEL_2802_1_PID 0X2812 /* SeaLINK+8/485 (2802) Port 1 */ -#define SEALEVEL_2802_2_PID 0X2822 /* SeaLINK+8/485 (2802) Port 2 */ -#define SEALEVEL_2802_3_PID 0X2832 /* SeaLINK+8/485 (2802) Port 3 */ -#define SEALEVEL_2802_4_PID 0X2842 /* SeaLINK+8/485 (2802) Port 4 */ -#define SEALEVEL_2802_5_PID 0X2852 /* SeaLINK+8/485 (2802) Port 5 */ -#define SEALEVEL_2802_6_PID 0X2862 /* SeaLINK+8/485 (2802) Port 6 */ -#define SEALEVEL_2802_7_PID 0X2872 /* SeaLINK+8/485 (2802) Port 7 */ -#define SEALEVEL_2802_8_PID 0X2882 /* SeaLINK+8/485 (2802) Port 8 */ -#define SEALEVEL_2803_1_PID 0X2813 /* SeaLINK+8 (2803) Port 1 */ -#define SEALEVEL_2803_2_PID 0X2823 /* SeaLINK+8 (2803) Port 2 */ -#define SEALEVEL_2803_3_PID 0X2833 /* SeaLINK+8 (2803) Port 3 */ -#define SEALEVEL_2803_4_PID 0X2843 /* SeaLINK+8 (2803) Port 4 */ -#define SEALEVEL_2803_5_PID 0X2853 /* SeaLINK+8 (2803) Port 5 */ -#define SEALEVEL_2803_6_PID 0X2863 /* SeaLINK+8 (2803) Port 6 */ -#define SEALEVEL_2803_7_PID 0X2873 /* SeaLINK+8 (2803) Port 7 */ -#define SEALEVEL_2803_8_PID 0X2883 /* SeaLINK+8 (2803) Port 8 */ +#define FTDI_TERATRONIK_VCP_PID 0xEC88 /* Teratronik device (preferring VCP driver on windows) */ +#define FTDI_TERATRONIK_D2XX_PID 0xEC89 /* Teratronik device (preferring D2XX driver on windows) */ -/* - * The following are the values for two KOBIL chipcard terminals. - */ -#define KOBIL_VID 0x0d46 /* KOBIL Vendor ID */ -#define KOBIL_CONV_B1_PID 0x2020 /* KOBIL Konverter for B1 */ -#define KOBIL_CONV_KAAN_PID 0x2021 /* KOBIL_Konverter for KAAN */ +/* Rig Expert Ukraine devices */ +#define FTDI_REU_TINY_PID 0xED22 /* RigExpert Tiny */ /* - * Icom ID-1 digital transceiver + * Hameg HO820 and HO870 interface (using VID 0x0403) */ - -#define ICOM_ID1_VID 0x0C26 -#define ICOM_ID1_PID 0x0004 +#define HAMEG_HO820_PID 0xed74 +#define HAMEG_HO870_PID 0xed71 /* - * ASK.fr devices + * MaxStream devices www.maxstream.net */ -#define FTDI_ASK_RDR400_PID 0xC991 /* ASK RDR 400 series card reader */ +#define FTDI_MAXSTREAM_PID 0xEE18 /* Xbee PKG-U Module */ /* - * FTDI USB UART chips used in construction projects from the - * Elektor Electronics magazine (http://elektor-electronics.co.uk) + * microHAM product IDs (http://www.microham.com). + * Submitted by Justin Burket (KL1RL) + * and Mike Studer (K6EEP) . + * Ian Abbott added a few more from the driver INF file. */ -#define ELEKTOR_VID 0x0C7D -#define ELEKTOR_FT323R_PID 0x0005 /* RFID-Reader, issue 09-2006 */ +#define FTDI_MHAM_KW_PID 0xEEE8 /* USB-KW interface */ +#define FTDI_MHAM_YS_PID 0xEEE9 /* USB-YS interface */ +#define FTDI_MHAM_Y6_PID 0xEEEA /* USB-Y6 interface */ +#define FTDI_MHAM_Y8_PID 0xEEEB /* USB-Y8 interface */ +#define FTDI_MHAM_IC_PID 0xEEEC /* USB-IC interface */ +#define FTDI_MHAM_DB9_PID 0xEEED /* USB-DB9 interface */ +#define FTDI_MHAM_RS232_PID 0xEEEE /* USB-RS232 interface */ +#define FTDI_MHAM_Y9_PID 0xEEEF /* USB-Y9 interface */ -/* - * DSS-20 Sync Station for Sony Ericsson P800 - */ -#define FTDI_DSS20_PID 0xFC82 +/* Domintell products http://www.domintell.com */ +#define FTDI_DOMINTELL_DGQG_PID 0xEF50 /* Master */ +#define FTDI_DOMINTELL_DUSB_PID 0xEF51 /* DUSB01 module */ /* - * Home Electronics (www.home-electro.com) USB gadgets + * The following are the values for the Perle Systems + * UltraPort USB serial converters */ -#define FTDI_HE_TIRA1_PID 0xFA78 /* Tira-1 IR transceiver */ +#define FTDI_PERLE_ULTRAPORT_PID 0xF0C0 /* Perle UltraPort Product Id */ -/* USB-UIRT - An infrared receiver and transmitter using the 8U232AM chip */ -/* http://home.earthlink.net/~jrhees/USBUIRT/index.htm */ -#define FTDI_USB_UIRT_PID 0xF850 /* Product Id */ +/* Sprog II (Andrew Crosland's SprogII DCC interface) */ +#define FTDI_SPROG_II 0xF0C8 -/* TNC-X USB-to-packet-radio adapter, versions prior to 3.0 (DLP module) */ +/* an infrared receiver for user access control with IR tags */ +#define FTDI_PIEGROUP_PID 0xF208 /* Product Id */ -#define FTDI_TNC_X_PID 0xEBE0 +/* ACT Solutions HomePro ZWave interface + (http://www.act-solutions.com/HomePro.htm) */ +#define FTDI_ACTZWAVE_PID 0xF2D0 -/* - * ELV USB devices submitted by Christian Abt of ELV (www.elv.de). - * All of these devices use FTDI's vendor ID (0x0403). - * - * The previously included PID for the UO 100 module was incorrect. - * In fact, that PID was for ELV's UR 100 USB-RS232 converter (0xFB58). - * - * Armin Laeuger originally sent the PID for the UM 100 module. - */ -#define FTDI_R2000KU_TRUE_RNG 0xFB80 /* R2000KU TRUE RNG */ -#define FTDI_ELV_UR100_PID 0xFB58 /* USB-RS232-Umsetzer (UR 100) */ -#define FTDI_ELV_UM100_PID 0xFB5A /* USB-Modul UM 100 */ -#define FTDI_ELV_UO100_PID 0xFB5B /* USB-Modul UO 100 */ -#define FTDI_ELV_ALC8500_PID 0xF06E /* ALC 8500 Expert */ -/* Additional ELV PIDs that default to using the FTDI D2XX drivers on - * MS Windows, rather than the FTDI Virtual Com Port drivers. - * Maybe these will be easier to use with the libftdi/libusb user-space - * drivers, or possibly the Comedi drivers in some cases. */ -#define FTDI_ELV_CLI7000_PID 0xFB59 /* Computer-Light-Interface (CLI 7000) */ -#define FTDI_ELV_PPS7330_PID 0xFB5C /* Processor-Power-Supply (PPS 7330) */ -#define FTDI_ELV_TFM100_PID 0xFB5D /* Temperartur-Feuchte Messgeraet (TFM 100) */ -#define FTDI_ELV_UDF77_PID 0xFB5E /* USB DCF Funkurh (UDF 77) */ -#define FTDI_ELV_UIO88_PID 0xFB5F /* USB-I/O Interface (UIO 88) */ -#define FTDI_ELV_UAD8_PID 0xF068 /* USB-AD-Wandler (UAD 8) */ -#define FTDI_ELV_UDA7_PID 0xF069 /* USB-DA-Wandler (UDA 7) */ -#define FTDI_ELV_USI2_PID 0xF06A /* USB-Schrittmotoren-Interface (USI 2) */ -#define FTDI_ELV_T1100_PID 0xF06B /* Thermometer (T 1100) */ -#define FTDI_ELV_PCD200_PID 0xF06C /* PC-Datenlogger (PCD 200) */ -#define FTDI_ELV_ULA200_PID 0xF06D /* USB-LCD-Ansteuerung (ULA 200) */ -#define FTDI_ELV_FHZ1000PC_PID 0xF06F /* FHZ 1000 PC */ -#define FTDI_ELV_CSI8_PID 0xE0F0 /* Computer-Schalt-Interface (CSI 8) */ -#define FTDI_ELV_EM1000DL_PID 0xE0F1 /* PC-Datenlogger fuer Energiemonitor (EM 1000 DL) */ -#define FTDI_ELV_PCK100_PID 0xE0F2 /* PC-Kabeltester (PCK 100) */ -#define FTDI_ELV_RFP500_PID 0xE0F3 /* HF-Leistungsmesser (RFP 500) */ -#define FTDI_ELV_FS20SIG_PID 0xE0F4 /* Signalgeber (FS 20 SIG) */ -#define FTDI_ELV_WS300PC_PID 0xE0F6 /* PC-Wetterstation (WS 300 PC) */ -#define FTDI_ELV_FHZ1300PC_PID 0xE0E8 /* FHZ 1300 PC */ -#define FTDI_ELV_WS500_PID 0xE0E9 /* PC-Wetterstation (WS 500) */ -#define FTDI_ELV_HS485_PID 0xE0EA /* USB to RS-485 adapter */ -#define FTDI_ELV_EM1010PC_PID 0xE0EF /* Engery monitor EM 1010 PC */ -#define FTDI_PHI_FISCO_PID 0xE40B /* PHI Fisco USB to Serial cable */ +/* + * 4N-GALAXY.DE PIDs for CAN-USB, USB-RS232, USB-RS422, USB-RS485, + * USB-TTY activ, USB-TTY passiv. Some PIDs are used by several devices + * and I'm not entirely sure which are used by which. + */ +#define FTDI_4N_GALAXY_DE_1_PID 0xF3C0 +#define FTDI_4N_GALAXY_DE_2_PID 0xF3C1 /* - * Definitions for ID TECH (www.idt-net.com) devices + * Linx Technologies product ids */ -#define IDTECH_VID 0x0ACD /* ID TECH Vendor ID */ -#define IDTECH_IDT1221U_PID 0x0300 /* IDT1221U USB to RS-232 adapter */ +#define LINX_SDMUSBQSS_PID 0xF448 /* Linx SDM-USB-QS-S */ +#define LINX_MASTERDEVEL2_PID 0xF449 /* Linx Master Development 2.0 */ +#define LINX_FUTURE_0_PID 0xF44A /* Linx future device */ +#define LINX_FUTURE_1_PID 0xF44B /* Linx future device */ +#define LINX_FUTURE_2_PID 0xF44C /* Linx future device */ /* - * Definitions for Omnidirectional Control Technology, Inc. devices + * Oceanic product ids */ -#define OCT_VID 0x0B39 /* OCT vendor ID */ -/* Note: OCT US101 is also rebadged as Dick Smith Electronics (NZ) XH6381 */ -/* Also rebadged as Dick Smith Electronics (Aus) XH6451 */ -/* Also rebadged as SIIG Inc. model US2308 hardware version 1 */ -#define OCT_US101_PID 0x0421 /* OCT US101 USB to RS-232 */ +#define FTDI_OCEANIC_PID 0xF460 /* Oceanic dive instrument */ -/* an infrared receiver for user access control with IR tags */ -#define FTDI_PIEGROUP_PID 0xF208 /* Product Id */ +/* + * SUUNTO product ids + */ +#define FTDI_SUUNTO_SPORTS_PID 0xF680 /* Suunto Sports instrument */ + +/* USB-UIRT - An infrared receiver and transmitter using the 8U232AM chip */ +/* http://home.earthlink.net/~jrhees/USBUIRT/index.htm */ +#define FTDI_USB_UIRT_PID 0xF850 /* Product Id */ + +/* CCS Inc. ICDU/ICDU40 product ID - + * the FT232BM is used in an in-circuit-debugger unit for PIC16's/PIC18's */ +#define FTDI_CCSICDU20_0_PID 0xF9D0 +#define FTDI_CCSICDU40_1_PID 0xF9D1 +#define FTDI_CCSMACHX_2_PID 0xF9D2 +#define FTDI_CCSLOAD_N_GO_3_PID 0xF9D3 +#define FTDI_CCSICDU64_4_PID 0xF9D4 +#define FTDI_CCSPRIME8_5_PID 0xF9D5 /* - * Definitions for Artemis astronomical USB based cameras - * Check it at http://www.artemisccd.co.uk/ + * The following are the values for the Matrix Orbital LCD displays, + * which are the FT232BM ( similar to the 8U232AM ) */ -#define FTDI_ARTEMIS_PID 0xDF28 /* All Artemis Cameras */ +#define FTDI_MTXORB_0_PID 0xFA00 /* Matrix Orbital Product Id */ +#define FTDI_MTXORB_1_PID 0xFA01 /* Matrix Orbital Product Id */ +#define FTDI_MTXORB_2_PID 0xFA02 /* Matrix Orbital Product Id */ +#define FTDI_MTXORB_3_PID 0xFA03 /* Matrix Orbital Product Id */ +#define FTDI_MTXORB_4_PID 0xFA04 /* Matrix Orbital Product Id */ +#define FTDI_MTXORB_5_PID 0xFA05 /* Matrix Orbital Product Id */ +#define FTDI_MTXORB_6_PID 0xFA06 /* Matrix Orbital Product Id */ /* - * Definitions for ATIK Instruments astronomical USB based cameras - * Check it at http://www.atik-instruments.com/ + * Home Electronics (www.home-electro.com) USB gadgets */ -#define FTDI_ATIK_ATK16_PID 0xDF30 /* ATIK ATK-16 Grayscale Camera */ -#define FTDI_ATIK_ATK16C_PID 0xDF32 /* ATIK ATK-16C Colour Camera */ -#define FTDI_ATIK_ATK16HR_PID 0xDF31 /* ATIK ATK-16HR Grayscale Camera */ -#define FTDI_ATIK_ATK16HRC_PID 0xDF33 /* ATIK ATK-16HRC Colour Camera */ -#define FTDI_ATIK_ATK16IC_PID 0xDF35 /* ATIK ATK-16IC Grayscale Camera */ +#define FTDI_HE_TIRA1_PID 0xFA78 /* Tira-1 IR transceiver */ + +/* Inside Accesso contactless reader (http://www.insidefr.com) */ +#define INSIDE_ACCESSO 0xFAD0 + +/* + * ThorLabs USB motor drivers + */ +#define FTDI_THORLABS_PID 0xfaf0 /* ThorLabs USB motor drivers */ /* * Protego product ids @@ -569,75 +375,106 @@ #define PROTEGO_SPECIAL_4 0xFC73 /* special/unknown device */ /* - * Gude Analog- und Digitalsysteme GmbH + * DSS-20 Sync Station for Sony Ericsson P800 */ -#define FTDI_GUDEADS_E808_PID 0xE808 -#define FTDI_GUDEADS_E809_PID 0xE809 -#define FTDI_GUDEADS_E80A_PID 0xE80A -#define FTDI_GUDEADS_E80B_PID 0xE80B -#define FTDI_GUDEADS_E80C_PID 0xE80C -#define FTDI_GUDEADS_E80D_PID 0xE80D -#define FTDI_GUDEADS_E80E_PID 0xE80E -#define FTDI_GUDEADS_E80F_PID 0xE80F -#define FTDI_GUDEADS_E888_PID 0xE888 /* Expert ISDN Control USB */ -#define FTDI_GUDEADS_E889_PID 0xE889 /* USB RS-232 OptoBridge */ -#define FTDI_GUDEADS_E88A_PID 0xE88A -#define FTDI_GUDEADS_E88B_PID 0xE88B -#define FTDI_GUDEADS_E88C_PID 0xE88C -#define FTDI_GUDEADS_E88D_PID 0xE88D -#define FTDI_GUDEADS_E88E_PID 0xE88E -#define FTDI_GUDEADS_E88F_PID 0xE88F +#define FTDI_DSS20_PID 0xFC82 + +/* www.irtrans.de device */ +#define FTDI_IRTRANS_PID 0xFC60 /* Product Id */ /* - * Linx Technologies product ids + * RM Michaelides CANview USB (http://www.rmcan.com) (FTDI_VID) + * CAN fieldbus interface adapter, added by port GmbH www.port.de) + * Ian Abbott changed the macro names for consistency. */ -#define LINX_SDMUSBQSS_PID 0xF448 /* Linx SDM-USB-QS-S */ -#define LINX_MASTERDEVEL2_PID 0xF449 /* Linx Master Development 2.0 */ -#define LINX_FUTURE_0_PID 0xF44A /* Linx future device */ -#define LINX_FUTURE_1_PID 0xF44B /* Linx future device */ -#define LINX_FUTURE_2_PID 0xF44C /* Linx future device */ +#define FTDI_RM_CANVIEW_PID 0xfd60 /* Product Id */ +/* www.thoughttechnology.com/ TT-USB provide with procomp use ftdi_sio */ +#define FTDI_TTUSB_PID 0xFF20 /* Product Id */ -/* CCS Inc. ICDU/ICDU40 product ID - the FT232BM is used in an in-circuit-debugger */ -/* unit for PIC16's/PIC18's */ -#define FTDI_CCSICDU20_0_PID 0xF9D0 -#define FTDI_CCSICDU40_1_PID 0xF9D1 -#define FTDI_CCSMACHX_2_PID 0xF9D2 -#define FTDI_CCSLOAD_N_GO_3_PID 0xF9D3 -#define FTDI_CCSICDU64_4_PID 0xF9D4 -#define FTDI_CCSPRIME8_5_PID 0xF9D5 +#define FTDI_USBX_707_PID 0xF857 /* ADSTech IR Blaster USBX-707 (FTDI_VID) */ -/* Inside Accesso contactless reader (http://www.insidefr.com) */ -#define INSIDE_ACCESSO 0xFAD0 +#define FTDI_RELAIS_PID 0xFA10 /* Relais device from Rudolf Gugler */ /* - * Intrepid Control Systems (http://www.intrepidcs.com/) ValueCAN and NeoVI + * PCDJ use ftdi based dj-controllers. The following PID is + * for their DAC-2 device http://www.pcdjhardware.com/DAC2.asp + * (the VID is the standard ftdi vid (FTDI_VID), PID sent by Wouter Paesen) */ -#define INTREPID_VID 0x093C -#define INTREPID_VALUECAN_PID 0x0601 -#define INTREPID_NEOVI_PID 0x0701 +#define FTDI_PCDJ_DAC2_PID 0xFA88 + +#define FTDI_R2000KU_TRUE_RNG 0xFB80 /* R2000KU TRUE RNG (FTDI_VID) */ /* - * Falcom Wireless Communications GmbH + * DIEBOLD BCS SE923 (FTDI_VID) */ -#define FALCOM_VID 0x0F94 /* Vendor Id */ -#define FALCOM_TWIST_PID 0x0001 /* Falcom Twist USB GPRS modem */ -#define FALCOM_SAMBA_PID 0x0005 /* Falcom Samba USB GPRS modem */ +#define DIEBOLD_BCS_SE923_PID 0xfb99 + +/* www.crystalfontz.com devices + * - thanx for providing free devices for evaluation ! + * they use the ftdi chipset for the USB interface + * and the vendor id is the same + */ +#define FTDI_XF_632_PID 0xFC08 /* 632: 16x2 Character Display */ +#define FTDI_XF_634_PID 0xFC09 /* 634: 20x4 Character Display */ +#define FTDI_XF_547_PID 0xFC0A /* 547: Two line Display */ +#define FTDI_XF_633_PID 0xFC0B /* 633: 16x2 Character Display with Keys */ +#define FTDI_XF_631_PID 0xFC0C /* 631: 20x2 Character Display */ +#define FTDI_XF_635_PID 0xFC0D /* 635: 20x4 Character Display */ +#define FTDI_XF_640_PID 0xFC0E /* 640: Two line Display */ +#define FTDI_XF_642_PID 0xFC0F /* 642: Two line Display */ /* - * SUUNTO product ids + * Video Networks Limited / Homechoice in the UK use an ftdi-based device + * for their 1Mb broadband internet service. The following PID is exhibited + * by the usb device supplied (the VID is the standard ftdi vid (FTDI_VID) */ -#define FTDI_SUUNTO_SPORTS_PID 0xF680 /* Suunto Sports instrument */ +#define FTDI_VNHCPCUSB_D_PID 0xfe38 /* Product Id */ + +/* AlphaMicro Components AMC-232USB01 device (FTDI_VID) */ +#define FTDI_AMC232_PID 0xFF00 /* Product Id */ /* - * Oceanic product ids + * IBS elektronik product ids (FTDI_VID) + * Submitted by Thomas Schleusener */ -#define FTDI_OCEANIC_PID 0xF460 /* Oceanic dive instrument */ +#define FTDI_IBS_US485_PID 0xff38 /* IBS US485 (USB<-->RS422/485 interface) */ +#define FTDI_IBS_PICPRO_PID 0xff39 /* IBS PIC-Programmer */ +#define FTDI_IBS_PCMCIA_PID 0xff3a /* IBS Card reader for PCMCIA SRAM-cards */ +#define FTDI_IBS_PK1_PID 0xff3b /* IBS PK1 - Particel counter */ +#define FTDI_IBS_RS232MON_PID 0xff3c /* IBS RS232 - Monitor */ +#define FTDI_IBS_APP70_PID 0xff3d /* APP 70 (dust monitoring system) */ +#define FTDI_IBS_PEDO_PID 0xff3e /* IBS PEDO-Modem (RF modem 868.35 MHz) */ +#define FTDI_IBS_PROD_PID 0xff3f /* future device */ +/* www.canusb.com Lawicel CANUSB device (FTDI_VID) */ +#define FTDI_CANUSB_PID 0xFFA8 /* Product Id */ + + + +/********************************/ +/** third-party VID/PID combos **/ +/********************************/ + + /* - * TTi (Thurlby Thandar Instruments) + * Atmel STK541 */ -#define TTI_VID 0x103E /* Vendor Id */ -#define TTI_QL355P_PID 0x03E8 /* TTi QL355P power supply */ +#define ATMEL_VID 0x03eb /* Vendor ID */ +#define STK541_PID 0x2109 /* Zigbee Controller */ + +/* + * Blackfin gnICE JTAG + * http://docs.blackfin.uclinux.org/doku.php?id=hw:jtag:gnice + */ +#define ADI_VID 0x0456 +#define ADI_GNICE_PID 0xF000 +#define ADI_GNICEPLUS_PID 0xF001 + +/* + * RATOC REX-USB60F + */ +#define RATOC_VENDOR_ID 0x0584 +#define RATOC_PRODUCT_ID_USB60F 0xb020 /* * Definitions for B&B Electronics products. @@ -662,141 +499,147 @@ #define BANDB_ZZ_PROG1_USB_PID 0xBA02 /* - * RM Michaelides CANview USB (http://www.rmcan.com) - * CAN fieldbus interface adapter, added by port GmbH www.port.de) - * Ian Abbott changed the macro names for consistency. - */ -#define FTDI_RM_CANVIEW_PID 0xfd60 /* Product Id */ - -/* - * EVER Eco Pro UPS (http://www.ever.com.pl/) - */ - -#define EVER_ECO_PRO_CDS 0xe520 /* RS-232 converter */ - -/* - * 4N-GALAXY.DE PIDs for CAN-USB, USB-RS232, USB-RS422, USB-RS485, - * USB-TTY activ, USB-TTY passiv. Some PIDs are used by several devices - * and I'm not entirely sure which are used by which. - */ -#define FTDI_4N_GALAXY_DE_1_PID 0xF3C0 -#define FTDI_4N_GALAXY_DE_2_PID 0xF3C1 - -/* - * Mobility Electronics products. - */ -#define MOBILITY_VID 0x1342 -#define MOBILITY_USB_SERIAL_PID 0x0202 /* EasiDock USB 200 serial */ - -/* - * microHAM product IDs (http://www.microham.com). - * Submitted by Justin Burket (KL1RL) - * and Mike Studer (K6EEP) . - * Ian Abbott added a few more from the driver INF file. - */ -#define FTDI_MHAM_KW_PID 0xEEE8 /* USB-KW interface */ -#define FTDI_MHAM_YS_PID 0xEEE9 /* USB-YS interface */ -#define FTDI_MHAM_Y6_PID 0xEEEA /* USB-Y6 interface */ -#define FTDI_MHAM_Y8_PID 0xEEEB /* USB-Y8 interface */ -#define FTDI_MHAM_IC_PID 0xEEEC /* USB-IC interface */ -#define FTDI_MHAM_DB9_PID 0xEEED /* USB-DB9 interface */ -#define FTDI_MHAM_RS232_PID 0xEEEE /* USB-RS232 interface */ -#define FTDI_MHAM_Y9_PID 0xEEEF /* USB-Y9 interface */ - -/* - * Active Robots product ids. - */ -#define FTDI_ACTIVE_ROBOTS_PID 0xE548 /* USB comms board */ - -/* - * Xsens Technologies BV products (http://www.xsens.com). + * Intrepid Control Systems (http://www.intrepidcs.com/) ValueCAN and NeoVI */ -#define XSENS_CONVERTER_0_PID 0xD388 -#define XSENS_CONVERTER_1_PID 0xD389 -#define XSENS_CONVERTER_2_PID 0xD38A -#define XSENS_CONVERTER_3_PID 0xD38B -#define XSENS_CONVERTER_4_PID 0xD38C -#define XSENS_CONVERTER_5_PID 0xD38D -#define XSENS_CONVERTER_6_PID 0xD38E -#define XSENS_CONVERTER_7_PID 0xD38F +#define INTREPID_VID 0x093C +#define INTREPID_VALUECAN_PID 0x0601 +#define INTREPID_NEOVI_PID 0x0701 /* - * Teratronik product ids. - * Submitted by O. Wlfelschneider. + * Definitions for ID TECH (www.idt-net.com) devices */ -#define FTDI_TERATRONIK_VCP_PID 0xEC88 /* Teratronik device (preferring VCP driver on windows) */ -#define FTDI_TERATRONIK_D2XX_PID 0xEC89 /* Teratronik device (preferring D2XX driver on windows) */ +#define IDTECH_VID 0x0ACD /* ID TECH Vendor ID */ +#define IDTECH_IDT1221U_PID 0x0300 /* IDT1221U USB to RS-232 adapter */ /* - * Evolution Robotics products (http://www.evolution.com/). - * Submitted by Shawn M. Lavelle. + * Definitions for Omnidirectional Control Technology, Inc. devices */ -#define EVOLUTION_VID 0xDEEE /* Vendor ID */ -#define EVOLUTION_ER1_PID 0x0300 /* ER1 Control Module */ -#define EVO_8U232AM_PID 0x02FF /* Evolution robotics RCM2 (FT232AM)*/ -#define EVO_HYBRID_PID 0x0302 /* Evolution robotics RCM4 PID (FT232BM)*/ -#define EVO_RCM4_PID 0x0303 /* Evolution robotics RCM4 PID */ - -/* Pyramid Computer GmbH */ -#define FTDI_PYRAMID_PID 0xE6C8 /* Pyramid Appliance Display */ +#define OCT_VID 0x0B39 /* OCT vendor ID */ +/* Note: OCT US101 is also rebadged as Dick Smith Electronics (NZ) XH6381 */ +/* Also rebadged as Dick Smith Electronics (Aus) XH6451 */ +/* Also rebadged as SIIG Inc. model US2308 hardware version 1 */ +#define OCT_US101_PID 0x0421 /* OCT US101 USB to RS-232 */ /* - * NDI (www.ndigital.com) product ids + * Icom ID-1 digital transceiver */ -#define FTDI_NDI_HUC_PID 0xDA70 /* NDI Host USB Converter */ -#define FTDI_NDI_SPECTRA_SCU_PID 0xDA71 /* NDI Spectra SCU */ -#define FTDI_NDI_FUTURE_2_PID 0xDA72 /* NDI future device #2 */ -#define FTDI_NDI_FUTURE_3_PID 0xDA73 /* NDI future device #3 */ -#define FTDI_NDI_AURORA_SCU_PID 0xDA74 /* NDI Aurora SCU */ + +#define ICOM_ID1_VID 0x0C26 +#define ICOM_ID1_PID 0x0004 /* - * Posiflex inc retail equipment (http://www.posiflex.com.tw) + * GN Otometrics (http://www.otometrics.com) + * Submitted by Ville Sundberg. */ -#define POSIFLEX_VID 0x0d3a /* Vendor ID */ -#define POSIFLEX_PP7000_PID 0x0300 /* PP-7000II thermal printer */ +#define GN_OTOMETRICS_VID 0x0c33 /* Vendor ID */ +#define AURICAL_USB_PID 0x0010 /* Aurical USB Audiometer */ /* - * Westrex International devices submitted by Cory Lee + * The following are the values for the Sealevel SeaLINK+ adapters. + * (Original list sent by Tuan Hoang. Ian Abbott renamed the macros and + * removed some PIDs that don't seem to match any existing products.) */ -#define FTDI_WESTREX_MODEL_777_PID 0xDC00 /* Model 777 */ -#define FTDI_WESTREX_MODEL_8900F_PID 0xDC01 /* Model 8900F */ +#define SEALEVEL_VID 0x0c52 /* Sealevel Vendor ID */ +#define SEALEVEL_2101_PID 0x2101 /* SeaLINK+232 (2101/2105) */ +#define SEALEVEL_2102_PID 0x2102 /* SeaLINK+485 (2102) */ +#define SEALEVEL_2103_PID 0x2103 /* SeaLINK+232I (2103) */ +#define SEALEVEL_2104_PID 0x2104 /* SeaLINK+485I (2104) */ +#define SEALEVEL_2106_PID 0x9020 /* SeaLINK+422 (2106) */ +#define SEALEVEL_2201_1_PID 0x2211 /* SeaPORT+2/232 (2201) Port 1 */ +#define SEALEVEL_2201_2_PID 0x2221 /* SeaPORT+2/232 (2201) Port 2 */ +#define SEALEVEL_2202_1_PID 0x2212 /* SeaPORT+2/485 (2202) Port 1 */ +#define SEALEVEL_2202_2_PID 0x2222 /* SeaPORT+2/485 (2202) Port 2 */ +#define SEALEVEL_2203_1_PID 0x2213 /* SeaPORT+2 (2203) Port 1 */ +#define SEALEVEL_2203_2_PID 0x2223 /* SeaPORT+2 (2203) Port 2 */ +#define SEALEVEL_2401_1_PID 0x2411 /* SeaPORT+4/232 (2401) Port 1 */ +#define SEALEVEL_2401_2_PID 0x2421 /* SeaPORT+4/232 (2401) Port 2 */ +#define SEALEVEL_2401_3_PID 0x2431 /* SeaPORT+4/232 (2401) Port 3 */ +#define SEALEVEL_2401_4_PID 0x2441 /* SeaPORT+4/232 (2401) Port 4 */ +#define SEALEVEL_2402_1_PID 0x2412 /* SeaPORT+4/485 (2402) Port 1 */ +#define SEALEVEL_2402_2_PID 0x2422 /* SeaPORT+4/485 (2402) Port 2 */ +#define SEALEVEL_2402_3_PID 0x2432 /* SeaPORT+4/485 (2402) Port 3 */ +#define SEALEVEL_2402_4_PID 0x2442 /* SeaPORT+4/485 (2402) Port 4 */ +#define SEALEVEL_2403_1_PID 0x2413 /* SeaPORT+4 (2403) Port 1 */ +#define SEALEVEL_2403_2_PID 0x2423 /* SeaPORT+4 (2403) Port 2 */ +#define SEALEVEL_2403_3_PID 0x2433 /* SeaPORT+4 (2403) Port 3 */ +#define SEALEVEL_2403_4_PID 0x2443 /* SeaPORT+4 (2403) Port 4 */ +#define SEALEVEL_2801_1_PID 0X2811 /* SeaLINK+8/232 (2801) Port 1 */ +#define SEALEVEL_2801_2_PID 0X2821 /* SeaLINK+8/232 (2801) Port 2 */ +#define SEALEVEL_2801_3_PID 0X2831 /* SeaLINK+8/232 (2801) Port 3 */ +#define SEALEVEL_2801_4_PID 0X2841 /* SeaLINK+8/232 (2801) Port 4 */ +#define SEALEVEL_2801_5_PID 0X2851 /* SeaLINK+8/232 (2801) Port 5 */ +#define SEALEVEL_2801_6_PID 0X2861 /* SeaLINK+8/232 (2801) Port 6 */ +#define SEALEVEL_2801_7_PID 0X2871 /* SeaLINK+8/232 (2801) Port 7 */ +#define SEALEVEL_2801_8_PID 0X2881 /* SeaLINK+8/232 (2801) Port 8 */ +#define SEALEVEL_2802_1_PID 0X2812 /* SeaLINK+8/485 (2802) Port 1 */ +#define SEALEVEL_2802_2_PID 0X2822 /* SeaLINK+8/485 (2802) Port 2 */ +#define SEALEVEL_2802_3_PID 0X2832 /* SeaLINK+8/485 (2802) Port 3 */ +#define SEALEVEL_2802_4_PID 0X2842 /* SeaLINK+8/485 (2802) Port 4 */ +#define SEALEVEL_2802_5_PID 0X2852 /* SeaLINK+8/485 (2802) Port 5 */ +#define SEALEVEL_2802_6_PID 0X2862 /* SeaLINK+8/485 (2802) Port 6 */ +#define SEALEVEL_2802_7_PID 0X2872 /* SeaLINK+8/485 (2802) Port 7 */ +#define SEALEVEL_2802_8_PID 0X2882 /* SeaLINK+8/485 (2802) Port 8 */ +#define SEALEVEL_2803_1_PID 0X2813 /* SeaLINK+8 (2803) Port 1 */ +#define SEALEVEL_2803_2_PID 0X2823 /* SeaLINK+8 (2803) Port 2 */ +#define SEALEVEL_2803_3_PID 0X2833 /* SeaLINK+8 (2803) Port 3 */ +#define SEALEVEL_2803_4_PID 0X2843 /* SeaLINK+8 (2803) Port 4 */ +#define SEALEVEL_2803_5_PID 0X2853 /* SeaLINK+8 (2803) Port 5 */ +#define SEALEVEL_2803_6_PID 0X2863 /* SeaLINK+8 (2803) Port 6 */ +#define SEALEVEL_2803_7_PID 0X2873 /* SeaLINK+8 (2803) Port 7 */ +#define SEALEVEL_2803_8_PID 0X2883 /* SeaLINK+8 (2803) Port 8 */ /* - * RR-CirKits LocoBuffer USB (http://www.rr-cirkits.com) + * JETI SPECTROMETER SPECBOS 1201 + * http://www.jeti.com/products/sys/scb/scb1201.php */ -#define FTDI_RRCIRKITS_LOCOBUFFER_PID 0xc7d0 /* LocoBuffer USB */ +#define JETI_VID 0x0c6c +#define JETI_SPC1201_PID 0x04b2 /* - * Eclo (http://www.eclo.pt/) product IDs. - * PID 0xEA90 submitted by Martin Grill. + * FTDI USB UART chips used in construction projects from the + * Elektor Electronics magazine (http://elektor-electronics.co.uk) */ -#define FTDI_ECLO_COM_1WIRE_PID 0xEA90 /* COM to 1-Wire USB adaptor */ +#define ELEKTOR_VID 0x0C7D +#define ELEKTOR_FT323R_PID 0x0005 /* RFID-Reader, issue 09-2006 */ /* - * Papouch products (http://www.papouch.com/) - * Submitted by Folkert van Heusden + * Posiflex inc retail equipment (http://www.posiflex.com.tw) */ - -#define PAPOUCH_VID 0x5050 /* Vendor ID */ -#define PAPOUCH_TMU_PID 0x0400 /* TMU USB Thermometer */ -#define PAPOUCH_QUIDO4x4_PID 0x0900 /* Quido 4/4 Module */ +#define POSIFLEX_VID 0x0d3a /* Vendor ID */ +#define POSIFLEX_PP7000_PID 0x0300 /* PP-7000II thermal printer */ /* - * ACG Identification Technologies GmbH products (http://www.acg.de/). - * Submitted by anton -at- goto10 -dot- org. + * The following are the values for two KOBIL chipcard terminals. */ -#define FTDI_ACG_HFDUAL_PID 0xDD20 /* HF Dual ISO Reader (RFID) */ +#define KOBIL_VID 0x0d46 /* KOBIL Vendor ID */ +#define KOBIL_CONV_B1_PID 0x2020 /* KOBIL Konverter for B1 */ +#define KOBIL_CONV_KAAN_PID 0x2021 /* KOBIL_Konverter for KAAN */ + +#define FTDI_NF_RIC_VID 0x0DCD /* Vendor Id */ +#define FTDI_NF_RIC_PID 0x0001 /* Product Id */ /* - * Yost Engineering, Inc. products (www.yostengineering.com). - * PID 0xE050 submitted by Aaron Prose. + * Falcom Wireless Communications GmbH */ -#define FTDI_YEI_SERVOCENTER31_PID 0xE050 /* YEI ServoCenter3.1 USB */ +#define FALCOM_VID 0x0F94 /* Vendor Id */ +#define FALCOM_TWIST_PID 0x0001 /* Falcom Twist USB GPRS modem */ +#define FALCOM_SAMBA_PID 0x0005 /* Falcom Samba USB GPRS modem */ + +/* Larsen and Brusgaard AltiTrack/USBtrack */ +#define LARSENBRUSGAARD_VID 0x0FD8 +#define LB_ALTITRACK_PID 0x0001 /* - * ThorLabs USB motor drivers + * TTi (Thurlby Thandar Instruments) */ -#define FTDI_THORLABS_PID 0xfaf0 /* ThorLabs USB motor drivers */ +#define TTI_VID 0x103E /* Vendor Id */ +#define TTI_QL355P_PID 0x03E8 /* TTi QL355P power supply */ + +/* Interbiometrics USB I/O Board */ +/* Developed for Interbiometrics by Rudolf Gugler */ +#define INTERBIOMETRICS_VID 0x1209 +#define INTERBIOMETRICS_IOBOARD_PID 0x1002 +#define INTERBIOMETRICS_MINI_IOBOARD_PID 0x1006 /* * Testo products (http://www.testo.com/) @@ -806,18 +649,21 @@ #define TESTO_USB_INTERFACE_PID 0x0001 /* - * Gamma Scout (http://gamma-scout.com/). Submitted by rsc@runtux.com. + * Mobility Electronics products. */ -#define FTDI_GAMMA_SCOUT_PID 0xD678 /* Gamma Scout online */ +#define MOBILITY_VID 0x1342 +#define MOBILITY_USB_SERIAL_PID 0x0202 /* EasiDock USB 200 serial */ /* - * Tactrix OpenPort (ECU) devices. - * OpenPort 1.3M submitted by Donour Sizemore. - * OpenPort 1.3S and 1.3U submitted by Ian Abbott. + * FIC / OpenMoko, Inc. http://wiki.openmoko.org/wiki/Neo1973_Debug_Board_v3 + * Submitted by Harald Welte */ -#define FTDI_TACTRIX_OPENPORT_13M_PID 0xCC48 /* OpenPort 1.3 Mitsubishi */ -#define FTDI_TACTRIX_OPENPORT_13S_PID 0xCC49 /* OpenPort 1.3 Subaru */ -#define FTDI_TACTRIX_OPENPORT_13U_PID 0xCC4A /* OpenPort 1.3 Universal */ +#define FIC_VID 0x1457 +#define FIC_NEO1973_DEBUG_PID 0x5118 + +/* Olimex */ +#define OLIMEX_VID 0x15BA +#define OLIMEX_ARM_USB_OCD_PID 0x0003 /* * Telldus Technologies @@ -826,34 +672,275 @@ #define TELLDUS_TELLSTICK_PID 0x0C30 /* RF control dongle 433 MHz using FT232RL */ /* - * IBS elektronik product ids - * Submitted by Thomas Schleusener + * Bayer Ascensia Contour blood glucose meter USB-converter cable. + * http://winglucofacts.com/cables/ */ -#define FTDI_IBS_US485_PID 0xff38 /* IBS US485 (USB<-->RS422/485 interface) */ -#define FTDI_IBS_PICPRO_PID 0xff39 /* IBS PIC-Programmer */ -#define FTDI_IBS_PCMCIA_PID 0xff3a /* IBS Card reader for PCMCIA SRAM-cards */ -#define FTDI_IBS_PK1_PID 0xff3b /* IBS PK1 - Particel counter */ -#define FTDI_IBS_RS232MON_PID 0xff3c /* IBS RS232 - Monitor */ -#define FTDI_IBS_APP70_PID 0xff3d /* APP 70 (dust monitoring system) */ -#define FTDI_IBS_PEDO_PID 0xff3e /* IBS PEDO-Modem (RF modem 868.35 MHz) */ -#define FTDI_IBS_PROD_PID 0xff3f /* future device */ +#define BAYER_VID 0x1A79 +#define BAYER_CONTOUR_CABLE_PID 0x6001 /* - * MaxStream devices www.maxstream.net + * The following are the values for the Matrix Orbital FTDI Range + * Anything in this range will use an FT232RL. */ -#define FTDI_MAXSTREAM_PID 0xEE18 /* Xbee PKG-U Module */ - -/* Olimex */ -#define OLIMEX_VID 0x15BA -#define OLIMEX_ARM_USB_OCD_PID 0x0003 +#define MTXORB_VID 0x1B3D +#define MTXORB_FTDI_RANGE_0100_PID 0x0100 +#define MTXORB_FTDI_RANGE_0101_PID 0x0101 +#define MTXORB_FTDI_RANGE_0102_PID 0x0102 +#define MTXORB_FTDI_RANGE_0103_PID 0x0103 +#define MTXORB_FTDI_RANGE_0104_PID 0x0104 +#define MTXORB_FTDI_RANGE_0105_PID 0x0105 +#define MTXORB_FTDI_RANGE_0106_PID 0x0106 +#define MTXORB_FTDI_RANGE_0107_PID 0x0107 +#define MTXORB_FTDI_RANGE_0108_PID 0x0108 +#define MTXORB_FTDI_RANGE_0109_PID 0x0109 +#define MTXORB_FTDI_RANGE_010A_PID 0x010A +#define MTXORB_FTDI_RANGE_010B_PID 0x010B +#define MTXORB_FTDI_RANGE_010C_PID 0x010C +#define MTXORB_FTDI_RANGE_010D_PID 0x010D +#define MTXORB_FTDI_RANGE_010E_PID 0x010E +#define MTXORB_FTDI_RANGE_010F_PID 0x010F +#define MTXORB_FTDI_RANGE_0110_PID 0x0110 +#define MTXORB_FTDI_RANGE_0111_PID 0x0111 +#define MTXORB_FTDI_RANGE_0112_PID 0x0112 +#define MTXORB_FTDI_RANGE_0113_PID 0x0113 +#define MTXORB_FTDI_RANGE_0114_PID 0x0114 +#define MTXORB_FTDI_RANGE_0115_PID 0x0115 +#define MTXORB_FTDI_RANGE_0116_PID 0x0116 +#define MTXORB_FTDI_RANGE_0117_PID 0x0117 +#define MTXORB_FTDI_RANGE_0118_PID 0x0118 +#define MTXORB_FTDI_RANGE_0119_PID 0x0119 +#define MTXORB_FTDI_RANGE_011A_PID 0x011A +#define MTXORB_FTDI_RANGE_011B_PID 0x011B +#define MTXORB_FTDI_RANGE_011C_PID 0x011C +#define MTXORB_FTDI_RANGE_011D_PID 0x011D +#define MTXORB_FTDI_RANGE_011E_PID 0x011E +#define MTXORB_FTDI_RANGE_011F_PID 0x011F +#define MTXORB_FTDI_RANGE_0120_PID 0x0120 +#define MTXORB_FTDI_RANGE_0121_PID 0x0121 +#define MTXORB_FTDI_RANGE_0122_PID 0x0122 +#define MTXORB_FTDI_RANGE_0123_PID 0x0123 +#define MTXORB_FTDI_RANGE_0124_PID 0x0124 +#define MTXORB_FTDI_RANGE_0125_PID 0x0125 +#define MTXORB_FTDI_RANGE_0126_PID 0x0126 +#define MTXORB_FTDI_RANGE_0127_PID 0x0127 +#define MTXORB_FTDI_RANGE_0128_PID 0x0128 +#define MTXORB_FTDI_RANGE_0129_PID 0x0129 +#define MTXORB_FTDI_RANGE_012A_PID 0x012A +#define MTXORB_FTDI_RANGE_012B_PID 0x012B +#define MTXORB_FTDI_RANGE_012C_PID 0x012C +#define MTXORB_FTDI_RANGE_012D_PID 0x012D +#define MTXORB_FTDI_RANGE_012E_PID 0x012E +#define MTXORB_FTDI_RANGE_012F_PID 0x012F +#define MTXORB_FTDI_RANGE_0130_PID 0x0130 +#define MTXORB_FTDI_RANGE_0131_PID 0x0131 +#define MTXORB_FTDI_RANGE_0132_PID 0x0132 +#define MTXORB_FTDI_RANGE_0133_PID 0x0133 +#define MTXORB_FTDI_RANGE_0134_PID 0x0134 +#define MTXORB_FTDI_RANGE_0135_PID 0x0135 +#define MTXORB_FTDI_RANGE_0136_PID 0x0136 +#define MTXORB_FTDI_RANGE_0137_PID 0x0137 +#define MTXORB_FTDI_RANGE_0138_PID 0x0138 +#define MTXORB_FTDI_RANGE_0139_PID 0x0139 +#define MTXORB_FTDI_RANGE_013A_PID 0x013A +#define MTXORB_FTDI_RANGE_013B_PID 0x013B +#define MTXORB_FTDI_RANGE_013C_PID 0x013C +#define MTXORB_FTDI_RANGE_013D_PID 0x013D +#define MTXORB_FTDI_RANGE_013E_PID 0x013E +#define MTXORB_FTDI_RANGE_013F_PID 0x013F +#define MTXORB_FTDI_RANGE_0140_PID 0x0140 +#define MTXORB_FTDI_RANGE_0141_PID 0x0141 +#define MTXORB_FTDI_RANGE_0142_PID 0x0142 +#define MTXORB_FTDI_RANGE_0143_PID 0x0143 +#define MTXORB_FTDI_RANGE_0144_PID 0x0144 +#define MTXORB_FTDI_RANGE_0145_PID 0x0145 +#define MTXORB_FTDI_RANGE_0146_PID 0x0146 +#define MTXORB_FTDI_RANGE_0147_PID 0x0147 +#define MTXORB_FTDI_RANGE_0148_PID 0x0148 +#define MTXORB_FTDI_RANGE_0149_PID 0x0149 +#define MTXORB_FTDI_RANGE_014A_PID 0x014A +#define MTXORB_FTDI_RANGE_014B_PID 0x014B +#define MTXORB_FTDI_RANGE_014C_PID 0x014C +#define MTXORB_FTDI_RANGE_014D_PID 0x014D +#define MTXORB_FTDI_RANGE_014E_PID 0x014E +#define MTXORB_FTDI_RANGE_014F_PID 0x014F +#define MTXORB_FTDI_RANGE_0150_PID 0x0150 +#define MTXORB_FTDI_RANGE_0151_PID 0x0151 +#define MTXORB_FTDI_RANGE_0152_PID 0x0152 +#define MTXORB_FTDI_RANGE_0153_PID 0x0153 +#define MTXORB_FTDI_RANGE_0154_PID 0x0154 +#define MTXORB_FTDI_RANGE_0155_PID 0x0155 +#define MTXORB_FTDI_RANGE_0156_PID 0x0156 +#define MTXORB_FTDI_RANGE_0157_PID 0x0157 +#define MTXORB_FTDI_RANGE_0158_PID 0x0158 +#define MTXORB_FTDI_RANGE_0159_PID 0x0159 +#define MTXORB_FTDI_RANGE_015A_PID 0x015A +#define MTXORB_FTDI_RANGE_015B_PID 0x015B +#define MTXORB_FTDI_RANGE_015C_PID 0x015C +#define MTXORB_FTDI_RANGE_015D_PID 0x015D +#define MTXORB_FTDI_RANGE_015E_PID 0x015E +#define MTXORB_FTDI_RANGE_015F_PID 0x015F +#define MTXORB_FTDI_RANGE_0160_PID 0x0160 +#define MTXORB_FTDI_RANGE_0161_PID 0x0161 +#define MTXORB_FTDI_RANGE_0162_PID 0x0162 +#define MTXORB_FTDI_RANGE_0163_PID 0x0163 +#define MTXORB_FTDI_RANGE_0164_PID 0x0164 +#define MTXORB_FTDI_RANGE_0165_PID 0x0165 +#define MTXORB_FTDI_RANGE_0166_PID 0x0166 +#define MTXORB_FTDI_RANGE_0167_PID 0x0167 +#define MTXORB_FTDI_RANGE_0168_PID 0x0168 +#define MTXORB_FTDI_RANGE_0169_PID 0x0169 +#define MTXORB_FTDI_RANGE_016A_PID 0x016A +#define MTXORB_FTDI_RANGE_016B_PID 0x016B +#define MTXORB_FTDI_RANGE_016C_PID 0x016C +#define MTXORB_FTDI_RANGE_016D_PID 0x016D +#define MTXORB_FTDI_RANGE_016E_PID 0x016E +#define MTXORB_FTDI_RANGE_016F_PID 0x016F +#define MTXORB_FTDI_RANGE_0170_PID 0x0170 +#define MTXORB_FTDI_RANGE_0171_PID 0x0171 +#define MTXORB_FTDI_RANGE_0172_PID 0x0172 +#define MTXORB_FTDI_RANGE_0173_PID 0x0173 +#define MTXORB_FTDI_RANGE_0174_PID 0x0174 +#define MTXORB_FTDI_RANGE_0175_PID 0x0175 +#define MTXORB_FTDI_RANGE_0176_PID 0x0176 +#define MTXORB_FTDI_RANGE_0177_PID 0x0177 +#define MTXORB_FTDI_RANGE_0178_PID 0x0178 +#define MTXORB_FTDI_RANGE_0179_PID 0x0179 +#define MTXORB_FTDI_RANGE_017A_PID 0x017A +#define MTXORB_FTDI_RANGE_017B_PID 0x017B +#define MTXORB_FTDI_RANGE_017C_PID 0x017C +#define MTXORB_FTDI_RANGE_017D_PID 0x017D +#define MTXORB_FTDI_RANGE_017E_PID 0x017E +#define MTXORB_FTDI_RANGE_017F_PID 0x017F +#define MTXORB_FTDI_RANGE_0180_PID 0x0180 +#define MTXORB_FTDI_RANGE_0181_PID 0x0181 +#define MTXORB_FTDI_RANGE_0182_PID 0x0182 +#define MTXORB_FTDI_RANGE_0183_PID 0x0183 +#define MTXORB_FTDI_RANGE_0184_PID 0x0184 +#define MTXORB_FTDI_RANGE_0185_PID 0x0185 +#define MTXORB_FTDI_RANGE_0186_PID 0x0186 +#define MTXORB_FTDI_RANGE_0187_PID 0x0187 +#define MTXORB_FTDI_RANGE_0188_PID 0x0188 +#define MTXORB_FTDI_RANGE_0189_PID 0x0189 +#define MTXORB_FTDI_RANGE_018A_PID 0x018A +#define MTXORB_FTDI_RANGE_018B_PID 0x018B +#define MTXORB_FTDI_RANGE_018C_PID 0x018C +#define MTXORB_FTDI_RANGE_018D_PID 0x018D +#define MTXORB_FTDI_RANGE_018E_PID 0x018E +#define MTXORB_FTDI_RANGE_018F_PID 0x018F +#define MTXORB_FTDI_RANGE_0190_PID 0x0190 +#define MTXORB_FTDI_RANGE_0191_PID 0x0191 +#define MTXORB_FTDI_RANGE_0192_PID 0x0192 +#define MTXORB_FTDI_RANGE_0193_PID 0x0193 +#define MTXORB_FTDI_RANGE_0194_PID 0x0194 +#define MTXORB_FTDI_RANGE_0195_PID 0x0195 +#define MTXORB_FTDI_RANGE_0196_PID 0x0196 +#define MTXORB_FTDI_RANGE_0197_PID 0x0197 +#define MTXORB_FTDI_RANGE_0198_PID 0x0198 +#define MTXORB_FTDI_RANGE_0199_PID 0x0199 +#define MTXORB_FTDI_RANGE_019A_PID 0x019A +#define MTXORB_FTDI_RANGE_019B_PID 0x019B +#define MTXORB_FTDI_RANGE_019C_PID 0x019C +#define MTXORB_FTDI_RANGE_019D_PID 0x019D +#define MTXORB_FTDI_RANGE_019E_PID 0x019E +#define MTXORB_FTDI_RANGE_019F_PID 0x019F +#define MTXORB_FTDI_RANGE_01A0_PID 0x01A0 +#define MTXORB_FTDI_RANGE_01A1_PID 0x01A1 +#define MTXORB_FTDI_RANGE_01A2_PID 0x01A2 +#define MTXORB_FTDI_RANGE_01A3_PID 0x01A3 +#define MTXORB_FTDI_RANGE_01A4_PID 0x01A4 +#define MTXORB_FTDI_RANGE_01A5_PID 0x01A5 +#define MTXORB_FTDI_RANGE_01A6_PID 0x01A6 +#define MTXORB_FTDI_RANGE_01A7_PID 0x01A7 +#define MTXORB_FTDI_RANGE_01A8_PID 0x01A8 +#define MTXORB_FTDI_RANGE_01A9_PID 0x01A9 +#define MTXORB_FTDI_RANGE_01AA_PID 0x01AA +#define MTXORB_FTDI_RANGE_01AB_PID 0x01AB +#define MTXORB_FTDI_RANGE_01AC_PID 0x01AC +#define MTXORB_FTDI_RANGE_01AD_PID 0x01AD +#define MTXORB_FTDI_RANGE_01AE_PID 0x01AE +#define MTXORB_FTDI_RANGE_01AF_PID 0x01AF +#define MTXORB_FTDI_RANGE_01B0_PID 0x01B0 +#define MTXORB_FTDI_RANGE_01B1_PID 0x01B1 +#define MTXORB_FTDI_RANGE_01B2_PID 0x01B2 +#define MTXORB_FTDI_RANGE_01B3_PID 0x01B3 +#define MTXORB_FTDI_RANGE_01B4_PID 0x01B4 +#define MTXORB_FTDI_RANGE_01B5_PID 0x01B5 +#define MTXORB_FTDI_RANGE_01B6_PID 0x01B6 +#define MTXORB_FTDI_RANGE_01B7_PID 0x01B7 +#define MTXORB_FTDI_RANGE_01B8_PID 0x01B8 +#define MTXORB_FTDI_RANGE_01B9_PID 0x01B9 +#define MTXORB_FTDI_RANGE_01BA_PID 0x01BA +#define MTXORB_FTDI_RANGE_01BB_PID 0x01BB +#define MTXORB_FTDI_RANGE_01BC_PID 0x01BC +#define MTXORB_FTDI_RANGE_01BD_PID 0x01BD +#define MTXORB_FTDI_RANGE_01BE_PID 0x01BE +#define MTXORB_FTDI_RANGE_01BF_PID 0x01BF +#define MTXORB_FTDI_RANGE_01C0_PID 0x01C0 +#define MTXORB_FTDI_RANGE_01C1_PID 0x01C1 +#define MTXORB_FTDI_RANGE_01C2_PID 0x01C2 +#define MTXORB_FTDI_RANGE_01C3_PID 0x01C3 +#define MTXORB_FTDI_RANGE_01C4_PID 0x01C4 +#define MTXORB_FTDI_RANGE_01C5_PID 0x01C5 +#define MTXORB_FTDI_RANGE_01C6_PID 0x01C6 +#define MTXORB_FTDI_RANGE_01C7_PID 0x01C7 +#define MTXORB_FTDI_RANGE_01C8_PID 0x01C8 +#define MTXORB_FTDI_RANGE_01C9_PID 0x01C9 +#define MTXORB_FTDI_RANGE_01CA_PID 0x01CA +#define MTXORB_FTDI_RANGE_01CB_PID 0x01CB +#define MTXORB_FTDI_RANGE_01CC_PID 0x01CC +#define MTXORB_FTDI_RANGE_01CD_PID 0x01CD +#define MTXORB_FTDI_RANGE_01CE_PID 0x01CE +#define MTXORB_FTDI_RANGE_01CF_PID 0x01CF +#define MTXORB_FTDI_RANGE_01D0_PID 0x01D0 +#define MTXORB_FTDI_RANGE_01D1_PID 0x01D1 +#define MTXORB_FTDI_RANGE_01D2_PID 0x01D2 +#define MTXORB_FTDI_RANGE_01D3_PID 0x01D3 +#define MTXORB_FTDI_RANGE_01D4_PID 0x01D4 +#define MTXORB_FTDI_RANGE_01D5_PID 0x01D5 +#define MTXORB_FTDI_RANGE_01D6_PID 0x01D6 +#define MTXORB_FTDI_RANGE_01D7_PID 0x01D7 +#define MTXORB_FTDI_RANGE_01D8_PID 0x01D8 +#define MTXORB_FTDI_RANGE_01D9_PID 0x01D9 +#define MTXORB_FTDI_RANGE_01DA_PID 0x01DA +#define MTXORB_FTDI_RANGE_01DB_PID 0x01DB +#define MTXORB_FTDI_RANGE_01DC_PID 0x01DC +#define MTXORB_FTDI_RANGE_01DD_PID 0x01DD +#define MTXORB_FTDI_RANGE_01DE_PID 0x01DE +#define MTXORB_FTDI_RANGE_01DF_PID 0x01DF +#define MTXORB_FTDI_RANGE_01E0_PID 0x01E0 +#define MTXORB_FTDI_RANGE_01E1_PID 0x01E1 +#define MTXORB_FTDI_RANGE_01E2_PID 0x01E2 +#define MTXORB_FTDI_RANGE_01E3_PID 0x01E3 +#define MTXORB_FTDI_RANGE_01E4_PID 0x01E4 +#define MTXORB_FTDI_RANGE_01E5_PID 0x01E5 +#define MTXORB_FTDI_RANGE_01E6_PID 0x01E6 +#define MTXORB_FTDI_RANGE_01E7_PID 0x01E7 +#define MTXORB_FTDI_RANGE_01E8_PID 0x01E8 +#define MTXORB_FTDI_RANGE_01E9_PID 0x01E9 +#define MTXORB_FTDI_RANGE_01EA_PID 0x01EA +#define MTXORB_FTDI_RANGE_01EB_PID 0x01EB +#define MTXORB_FTDI_RANGE_01EC_PID 0x01EC +#define MTXORB_FTDI_RANGE_01ED_PID 0x01ED +#define MTXORB_FTDI_RANGE_01EE_PID 0x01EE +#define MTXORB_FTDI_RANGE_01EF_PID 0x01EF +#define MTXORB_FTDI_RANGE_01F0_PID 0x01F0 +#define MTXORB_FTDI_RANGE_01F1_PID 0x01F1 +#define MTXORB_FTDI_RANGE_01F2_PID 0x01F2 +#define MTXORB_FTDI_RANGE_01F3_PID 0x01F3 +#define MTXORB_FTDI_RANGE_01F4_PID 0x01F4 +#define MTXORB_FTDI_RANGE_01F5_PID 0x01F5 +#define MTXORB_FTDI_RANGE_01F6_PID 0x01F6 +#define MTXORB_FTDI_RANGE_01F7_PID 0x01F7 +#define MTXORB_FTDI_RANGE_01F8_PID 0x01F8 +#define MTXORB_FTDI_RANGE_01F9_PID 0x01F9 +#define MTXORB_FTDI_RANGE_01FA_PID 0x01FA +#define MTXORB_FTDI_RANGE_01FB_PID 0x01FB +#define MTXORB_FTDI_RANGE_01FC_PID 0x01FC +#define MTXORB_FTDI_RANGE_01FD_PID 0x01FD +#define MTXORB_FTDI_RANGE_01FE_PID 0x01FE +#define MTXORB_FTDI_RANGE_01FF_PID 0x01FF -/* Luminary Micro Stellaris Boards, VID = FTDI_VID */ -/* FTDI 2332C Dual channel device, side A=245 FIFO (JTAG), Side B=RS232 UART */ -#define LMI_LM3S_DEVEL_BOARD_PID 0xbcd8 -#define LMI_LM3S_EVAL_BOARD_PID 0xbcd9 -/* www.elsterelectricity.com Elster Unicom III Optical Probe */ -#define FTDI_ELSTER_UNICOM_PID 0xE700 /* Product Id */ /* * The Mobility Lab (TML) @@ -862,45 +949,11 @@ #define TML_VID 0x1B91 /* Vendor ID */ #define TML_USB_SERIAL_PID 0x0064 /* USB - Serial Converter */ -/* Propox devices */ -#define FTDI_PROPOX_JTAGCABLEII_PID 0xD738 - -/* Rig Expert Ukraine devices */ -#define FTDI_REU_TINY_PID 0xED22 /* RigExpert Tiny */ - -/* Domintell products http://www.domintell.com */ -#define FTDI_DOMINTELL_DGQG_PID 0xEF50 /* Master */ -#define FTDI_DOMINTELL_DUSB_PID 0xEF51 /* DUSB01 module */ - /* Alti-2 products http://www.alti-2.com */ #define ALTI2_VID 0x1BC9 #define ALTI2_N3_PID 0x6001 /* Neptune 3 */ /* - * FIC / OpenMoko, Inc. http://wiki.openmoko.org/wiki/Neo1973_Debug_Board_v3 - * Submitted by Harald Welte - */ -#define FIC_VID 0x1457 -#define FIC_NEO1973_DEBUG_PID 0x5118 - -/* - * RATOC REX-USB60F - */ -#define RATOC_VENDOR_ID 0x0584 -#define RATOC_PRODUCT_ID_USB60F 0xb020 - -/* - * DIEBOLD BCS SE923 - */ -#define DIEBOLD_BCS_SE923_PID 0xfb99 - -/* - * Atmel STK541 - */ -#define ATMEL_VID 0x03eb /* Vendor ID */ -#define STK541_PID 0x2109 /* Zigbee Controller */ - -/* * Dresden Elektronic Sensor Terminal Board */ #define DE_VID 0x1cf1 /* Vendor ID */ @@ -908,19 +961,13 @@ #define WHT_PID 0x0004 /* Wireless Handheld Terminal */ /* - * Blackfin gnICE JTAG - * http://docs.blackfin.uclinux.org/doku.php?id=hw:jtag:gnice + * Papouch products (http://www.papouch.com/) + * Submitted by Folkert van Heusden */ -#define ADI_VID 0x0456 -#define ADI_GNICE_PID 0xF000 -#define ADI_GNICEPLUS_PID 0xF001 -/* - * JETI SPECTROMETER SPECBOS 1201 - * http://www.jeti.com/products/sys/scb/scb1201.php - */ -#define JETI_VID 0x0c6c -#define JETI_SPC1201_PID 0x04b2 +#define PAPOUCH_VID 0x5050 /* Vendor ID */ +#define PAPOUCH_TMU_PID 0x0400 /* TMU USB Thermometer */ +#define PAPOUCH_QUIDO4x4_PID 0x0900 /* Quido 4/4 Module */ /* * Marvell SheevaPlug @@ -928,32 +975,12 @@ #define MARVELL_VID 0x9e88 #define MARVELL_SHEEVAPLUG_PID 0x9e8f -#define FTDI_TURTELIZER_PID 0xBDC8 /* JTAG/RS-232 adapter by egnite GmBH */ - /* - * GN Otometrics (http://www.otometrics.com) - * Submitted by Ville Sundberg. - */ -#define GN_OTOMETRICS_VID 0x0c33 /* Vendor ID */ -#define AURICAL_USB_PID 0x0010 /* Aurical USB Audiometer */ - -/* - * Bayer Ascensia Contour blood glucose meter USB-converter cable. - * http://winglucofacts.com/cables/ - */ -#define BAYER_VID 0x1A79 -#define BAYER_CONTOUR_CABLE_PID 0x6001 - -/* - * Marvell OpenRD Base, Client - * http://www.open-rd.org - * OpenRD Base, Client use VID 0x0403 - */ -#define MARVELL_OPENRD_PID 0x9e90 - -/* - * Hameg HO820 and HO870 interface (using VID 0x0403) + * Evolution Robotics products (http://www.evolution.com/). + * Submitted by Shawn M. Lavelle. */ -#define HAMEG_HO820_PID 0xed74 -#define HAMEG_HO870_PID 0xed71 - +#define EVOLUTION_VID 0xDEEE /* Vendor ID */ +#define EVOLUTION_ER1_PID 0x0300 /* ER1 Control Module */ +#define EVO_8U232AM_PID 0x02FF /* Evolution robotics RCM2 (FT232AM)*/ +#define EVO_HYBRID_PID 0x0302 /* Evolution robotics RCM4 PID (FT232BM)*/ +#define EVO_RCM4_PID 0x0303 /* Evolution robotics RCM4 PID */ -- cgit v0.10.2 From 95962a773ca5c1e52305fd1003d3bda59abbf371 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Wed, 16 Dec 2009 20:38:31 +0300 Subject: USB: musb_gadget: fix kernel oops in txstate() Commit 7723de7e19b744144975a09c81777ec0f14ac5b3 (USB: musb_gadget: remove pointless loop) included uncalled for (and incorrect) optimization that might cause a kernel oops in txstate() -- undo it. Signed-off-by: Sergei Shtylyov Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index c49b9ba..4dea146 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -515,12 +515,12 @@ void musb_g_tx(struct musb *musb, u8 epnum) if (csr & MUSB_TXCSR_FIFONOTEMPTY) return; - if (!musb_ep->desc) { + request = musb_ep->desc ? next_request(musb_ep) : NULL; + if (!request) { DBG(4, "%s idle now\n", musb_ep->end_point.name); return; - } else - request = next_request(musb_ep); + } } txstate(musb, to_musb_request(request)); -- cgit v0.10.2 From e3060b175c1bd60586f51482464530dd1b37f3cf Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 15 Dec 2009 11:08:41 +0200 Subject: USB: musb: move musb_remove to __exit probe() already was on __init, so moving remove() to __exit. Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index bfe08f4..1041bb7 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -2139,7 +2139,7 @@ static int __init musb_probe(struct platform_device *pdev) return musb_init_controller(dev, irq, base); } -static int __devexit musb_remove(struct platform_device *pdev) +static int __exit musb_remove(struct platform_device *pdev) { struct musb *musb = dev_to_musb(&pdev->dev); void __iomem *ctrl_base = musb->ctrl_base; @@ -2231,7 +2231,7 @@ static struct platform_driver musb_driver = { .owner = THIS_MODULE, .pm = MUSB_DEV_PM_OPS, }, - .remove = __devexit_p(musb_remove), + .remove = __exit_p(musb_remove), .shutdown = musb_shutdown, }; -- cgit v0.10.2 From f95c4c0186aa94ad41681d8f0ecd79cc45f92bda Mon Sep 17 00:00:00 2001 From: Cliff Cai Date: Tue, 15 Dec 2009 11:08:44 +0200 Subject: USB: musb: fix compiling warning with min() macro Current musb gadget dma code produces the warning: drivers/usb/musb/musb_gadget.c: In function 'txstate': drivers/usb/musb/musb_gadget.c:312: warning: comparison of distinct pointer types lacks a cast So switch to min_t(size_t, ...). Signed-off-by: Cliff Cai Signed-off-by: Mike Frysinger Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 4dea146..0c36925 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -309,7 +309,7 @@ static void txstate(struct musb *musb, struct musb_request *req) size_t request_size; /* setup DMA, then program endpoint CSR */ - request_size = min(request->length, + request_size = min_t(size_t, request->length, musb_ep->dma->max_len); if (request_size < musb_ep->packet_sz) musb_ep->dma->desired_mode = 0; -- cgit v0.10.2 From 8a700f3d0d34a79c9cb25f2c66552c181f9c5737 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 15 Dec 2009 11:08:45 +0200 Subject: USB: musb: MAINTAINERS: Fix my tree's address The tree is now on a new address. Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman diff --git a/MAINTAINERS b/MAINTAINERS index d5244f1..745643b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3679,7 +3679,7 @@ F: include/linux/isicom.h MUSB MULTIPOINT HIGH SPEED DUAL-ROLE CONTROLLER M: Felipe Balbi L: linux-usb@vger.kernel.org -T: git git://gitorious.org/musb/mainline.git +T: git git://gitorious.org/usb/usb.git S: Maintained F: drivers/usb/musb/ -- cgit v0.10.2 From a2396a32b848a9864f933ced860192c72c769aca Mon Sep 17 00:00:00 2001 From: Swaminathan S Date: Tue, 15 Dec 2009 13:29:57 +0200 Subject: USB: musb: Populate the VBUS GPIO with the correct GPIO number This fixes a null-pointer dereference bug. Signed-off-by: Swaminathan S Cc: David Brownell Acked-by: Sergei Shtylyov Acked-by: Anand Gadiyar Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index e16ff60..6691381 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c @@ -42,7 +42,7 @@ #include "musb_core.h" #ifdef CONFIG_MACH_DAVINCI_EVM -#define GPIO_nVBUS_DRV 144 +#define GPIO_nVBUS_DRV 160 #endif #include "davinci.h" -- cgit v0.10.2 From d4c433fe6f04195a1a0d2146d9f11ad45eecef86 Mon Sep 17 00:00:00 2001 From: Arnaud Mandy Date: Tue, 15 Dec 2009 13:29:58 +0200 Subject: USB: musb: gadget: set otg tranceiver to idle when registering gadget When registering gadget driver, the state of the transceiver must be set from undefined (no gadget) to b_idle. Module unload sets the transceiver state to undefined state. After the first load/unload pair, the reset irq will be lost. Signed-off-by: Arnaud Mandy Signed-off-by: Felipe Balbi Cc: David Brownell Acked-by: Anand Gadiyar Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 0c36925..e164999 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -1731,6 +1731,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) spin_lock_irqsave(&musb->lock, flags); otg_set_peripheral(musb->xceiv, &musb->g); + musb->xceiv->state = OTG_STATE_B_IDLE; musb->is_active = 1; /* FIXME this ignores the softconnect flag. Drivers are -- cgit v0.10.2 From cd42fef0a0b061817904fd6feb0de66830794857 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 15 Dec 2009 13:47:30 +0200 Subject: USB: musb: do not work if no gadget driver is loaded On OTG and gadget-only configurations, we need a gadget driver in order to work properly, so avoid changing operation modes when there's no gadget driver loaded. Signed-off-by: Felipe Balbi Cc: David Brownell Acked-by: Anand Gadiyar Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 1041bb7..24ff097 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1521,6 +1521,14 @@ irqreturn_t musb_interrupt(struct musb *musb) (devctl & MUSB_DEVCTL_HM) ? "host" : "peripheral", musb->int_usb, musb->int_tx, musb->int_rx); +#ifdef CONFIG_USB_GADGET_MUSB_HDRC + if (is_otg_enabled(musb) || is_peripheral_enabled(musb)) + if (!musb->gadget_driver) { + DBG(5, "No gadget driver loaded\n"); + return IRQ_HANDLED; + } +#endif + /* the core can interrupt us for multiple reasons; docs have * a generic interrupt flowchart to follow */ -- cgit v0.10.2 From 93aa3dab008421789aa0f8865a62a52ae13269a3 Mon Sep 17 00:00:00 2001 From: Swaminathan S Date: Tue, 15 Dec 2009 13:30:00 +0200 Subject: USB: musb: fix for crash in DM646x USB when (CPPI)DMA is enabled Race condition exists between the cppi_interrupt handler and davinci_interrupt handler w.r.t completing a TX IO. Since DM646x has seperate DMA and USB endpoint interrupts cppi_interrupt handler needs to hold the lock while operating on the endpoint. Update over previous patch to avoid taking the lock if already taken. Tested on DM644x, DM355 and DM646x platforms. Signed-off-by: Swaminathan S Acked-by: Sergei Shtylyov Acked-by: Anand Gadiyar Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/musb/cppi_dma.c b/drivers/usb/musb/cppi_dma.c index ef2332a..a44a450 100644 --- a/drivers/usb/musb/cppi_dma.c +++ b/drivers/usb/musb/cppi_dma.c @@ -1154,8 +1154,11 @@ irqreturn_t cppi_interrupt(int irq, void *dev_id) struct musb_hw_ep *hw_ep = NULL; u32 rx, tx; int i, index; + unsigned long flags; cppi = container_of(musb->dma_controller, struct cppi, controller); + if (cppi->irq) + spin_lock_irqsave(&musb->lock, flags); tibase = musb->ctrl_base; @@ -1285,6 +1288,9 @@ irqreturn_t cppi_interrupt(int irq, void *dev_id) /* write to CPPI EOI register to re-enable interrupts */ musb_writel(tibase, DAVINCI_CPPI_EOI_REG, 0); + if (cppi->irq) + spin_unlock_irqrestore(&musb->lock, flags); + return IRQ_HANDLED; } -- cgit v0.10.2 From 17be5c5f5ef99c94374e07f71effa78e93a20eda Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Tue, 15 Dec 2009 13:30:01 +0200 Subject: USB: musb: gadget_ep0: avoid SetupEnd interrupt Gadget stalling a zero-length SETUP request results in this error message: SetupEnd came in a wrong ep0stage idle In order to avoid it, always set the CSR0.DataEnd bit after detecting a zero- length request. Add the missing '\n' to the error message itself as well... Signed-off-by: Sergei Shtylyov Acked-by: Anand Gadiyar Cc: stable Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/musb/musb_gadget_ep0.c b/drivers/usb/musb/musb_gadget_ep0.c index 8fba3f1..53d0645 100644 --- a/drivers/usb/musb/musb_gadget_ep0.c +++ b/drivers/usb/musb/musb_gadget_ep0.c @@ -664,7 +664,7 @@ irqreturn_t musb_g_ep0_irq(struct musb *musb) musb->ep0_state = MUSB_EP0_STAGE_STATUSIN; break; default: - ERR("SetupEnd came in a wrong ep0stage %s", + ERR("SetupEnd came in a wrong ep0stage %s\n", decode_ep0stage(musb->ep0_state)); } csr = musb_readw(regs, MUSB_CSR0); @@ -787,12 +787,18 @@ setup: handled = service_zero_data_request( musb, &setup); + /* + * We're expecting no data in any case, so + * always set the DATAEND bit -- doing this + * here helps avoid SetupEnd interrupt coming + * in the idle stage when we're stalling... + */ + musb->ackpend |= MUSB_CSR0_P_DATAEND; + /* status stage might be immediate */ - if (handled > 0) { - musb->ackpend |= MUSB_CSR0_P_DATAEND; + if (handled > 0) musb->ep0_state = MUSB_EP0_STAGE_STATUSIN; - } break; /* sequence #1 (IN to host), includes GET_STATUS -- cgit v0.10.2 From 796a83fa039de50133171221ac102a2310e81ffd Mon Sep 17 00:00:00 2001 From: Cliff Cai Date: Mon, 21 Dec 2009 21:18:02 -0500 Subject: USB: musb: correct DMA address for tx Since a DMA transfer may need to be kicked off several times to complete, the DMA start must include the length that has already been transferred. Signed-off-by: Cliff Cai Signed-off-by: Mike Frysinger Cc: Felipe Balbi Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index e164999..ac30698 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -319,7 +319,7 @@ static void txstate(struct musb *musb, struct musb_request *req) use_dma = use_dma && c->channel_program( musb_ep->dma, musb_ep->packet_sz, musb_ep->dma->desired_mode, - request->dma, request_size); + request->dma + request->actual, request_size); if (use_dma) { if (musb_ep->dma->desired_mode == 0) { /* -- cgit v0.10.2 From 0abdc36f066ae20521b8c8d306725dd59a0d50aa Mon Sep 17 00:00:00 2001 From: Maulik Mankad Date: Tue, 22 Dec 2009 16:18:19 +0530 Subject: USB: musb: Fix null pointer dereference issue This patch fixes the following NULL pointer dereference issue. Pointer 'request' returned from call to function 'next_request' at line 748 may be NULL and may be dereferenced at line 792. ============ Code Snippet ============ 748: request = next_request(musb_ep); 785: if (dma && (csr & MUSB_RXCSR_DMAENAB)) { csr &= ~(MUSB_RXCSR_AUTOCLEAR | MUSB_RXCSR_DMAENAB | MUSB_RXCSR_DMAMODE); musb_writew(epio, MUSB_RXCSR, MUSB_RXCSR_P_WZC_BITS | csr); 792: request->actual += musb_ep->dma->actual_len; Signed-off-by: Maulik Mankad Cc: Felipe Balbi Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index ac30698..cbcf14a2 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -746,6 +746,8 @@ void musb_g_rx(struct musb *musb, u8 epnum) musb_ep_select(mbase, epnum); request = next_request(musb_ep); + if (!request) + return; csr = musb_readw(epio, MUSB_RXCSR); dma = is_dma_capable() ? musb_ep->dma : NULL; -- cgit v0.10.2 From 0ea52ff44f7a30781881ca2debf35e47b2676171 Mon Sep 17 00:00:00 2001 From: Maulik Mankad Date: Tue, 22 Dec 2009 16:19:53 +0530 Subject: USB: musb: Fix array index out of bounds issue This patch fixes the below array index out of bounds issue. Buffer overflow, array index of 'aInfo' may be out of bounds. Array 'aInfo' of size 78 may use index value(s) 6..84 The data stored in 'aInfo' array exceeds the array size of 78. This patch increases the size of this array to hold the string correctly without any memory corruption. This issue was reported by Klockwork tool. Signed-off-by: Maulik Mankad Cc: Felipe Balbi Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 24ff097..5eb9318 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1319,7 +1319,7 @@ static int __init musb_core_init(u16 musb_type, struct musb *musb) #endif u8 reg; char *type; - char aInfo[78], aRevision[32], aDate[12]; + char aInfo[90], aRevision[32], aDate[12]; void __iomem *mbase = musb->mregs; int status = 0; int i; -- cgit v0.10.2 From 1c4bdc01b8a5cf6c54e5eb8bf9a727e38f0176cc Mon Sep 17 00:00:00 2001 From: Bryan Wu Date: Mon, 21 Dec 2009 09:49:52 -0500 Subject: USB: musb: workaround Blackfin FIFO anomalies Some of these workarounds are already in place, but labeled as affecting all BF52x parts. Since we have official anomaly numbers now, use those defines. And since writing to the FIFO has a similar hang issue as reading from the FIFO, implement the workaround there too when necessary. Signed-off-by: Bryan Wu Signed-off-by: Cliff Cai Signed-off-by: Mike Frysinger Cc: Felipe Balbi Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index fe4934d..ad26e65 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c @@ -29,6 +29,8 @@ void musb_write_fifo(struct musb_hw_ep *hw_ep, u16 len, const u8 *src) { void __iomem *fifo = hw_ep->fifo; void __iomem *epio = hw_ep->regs; + u8 epnum = hw_ep->epnum; + u16 dma_reg = 0; prefetch((u8 *)src); @@ -39,67 +41,113 @@ void musb_write_fifo(struct musb_hw_ep *hw_ep, u16 len, const u8 *src) dump_fifo_data(src, len); - if (unlikely((unsigned long)src & 0x01)) - outsw_8((unsigned long)fifo, src, - len & 0x01 ? (len >> 1) + 1 : len >> 1); - else - outsw((unsigned long)fifo, src, - len & 0x01 ? (len >> 1) + 1 : len >> 1); -} + if (!ANOMALY_05000380 && epnum != 0) { + flush_dcache_range((unsigned int)src, + (unsigned int)(src + len)); + + /* Setup DMA address register */ + dma_reg = (u16) ((u32) src & 0xFFFF); + bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_LOW), dma_reg); + SSYNC(); + + dma_reg = (u16) (((u32) src >> 16) & 0xFFFF); + bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_HIGH), dma_reg); + SSYNC(); + + /* Setup DMA count register */ + bfin_write16(USB_DMA_REG(epnum, USB_DMAx_COUNT_LOW), len); + bfin_write16(USB_DMA_REG(epnum, USB_DMAx_COUNT_HIGH), 0); + SSYNC(); + + /* Enable the DMA */ + dma_reg = (epnum << 4) | DMA_ENA | INT_ENA | DIRECTION; + bfin_write16(USB_DMA_REG(epnum, USB_DMAx_CTRL), dma_reg); + SSYNC(); + + /* Wait for compelete */ + while (!(bfin_read_USB_DMA_INTERRUPT() & (1 << epnum))) + cpu_relax(); + + /* acknowledge dma interrupt */ + bfin_write_USB_DMA_INTERRUPT(1 << epnum); + SSYNC(); + + /* Reset DMA */ + bfin_write16(USB_DMA_REG(epnum, USB_DMAx_CTRL), 0); + SSYNC(); + } else { + SSYNC(); + + if (unlikely((unsigned long)src & 0x01)) + outsw_8((unsigned long)fifo, src, + len & 0x01 ? (len >> 1) + 1 : len >> 1); + else + outsw((unsigned long)fifo, src, + len & 0x01 ? (len >> 1) + 1 : len >> 1); + } +} /* * Unload an endpoint's FIFO */ void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst) { void __iomem *fifo = hw_ep->fifo; - -#ifdef CONFIG_BF52x u8 epnum = hw_ep->epnum; u16 dma_reg = 0; - invalidate_dcache_range((unsigned int)dst, - (unsigned int)(dst + len)); + if (ANOMALY_05000467 && epnum != 0) { - /* Setup DMA address register */ - dma_reg = (u16) ((u32) dst & 0xFFFF); - bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_LOW), dma_reg); - SSYNC(); + invalidate_dcache_range((unsigned int)dst, + (unsigned int)(dst + len)); - dma_reg = (u16) (((u32) dst >> 16) & 0xFFFF); - bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_HIGH), dma_reg); - SSYNC(); + /* Setup DMA address register */ + dma_reg = (u16) ((u32) dst & 0xFFFF); + bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_LOW), dma_reg); + SSYNC(); - /* Setup DMA count register */ - bfin_write16(USB_DMA_REG(epnum, USB_DMAx_COUNT_LOW), len); - bfin_write16(USB_DMA_REG(epnum, USB_DMAx_COUNT_HIGH), 0); - SSYNC(); + dma_reg = (u16) (((u32) dst >> 16) & 0xFFFF); + bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_HIGH), dma_reg); + SSYNC(); - /* Enable the DMA */ - dma_reg = (epnum << 4) | DMA_ENA | INT_ENA; - bfin_write16(USB_DMA_REG(epnum, USB_DMAx_CTRL), dma_reg); - SSYNC(); + /* Setup DMA count register */ + bfin_write16(USB_DMA_REG(epnum, USB_DMAx_COUNT_LOW), len); + bfin_write16(USB_DMA_REG(epnum, USB_DMAx_COUNT_HIGH), 0); + SSYNC(); - /* Wait for compelete */ - while (!(bfin_read_USB_DMA_INTERRUPT() & (1 << epnum))) - cpu_relax(); + /* Enable the DMA */ + dma_reg = (epnum << 4) | DMA_ENA | INT_ENA; + bfin_write16(USB_DMA_REG(epnum, USB_DMAx_CTRL), dma_reg); + SSYNC(); - /* acknowledge dma interrupt */ - bfin_write_USB_DMA_INTERRUPT(1 << epnum); - SSYNC(); + /* Wait for compelete */ + while (!(bfin_read_USB_DMA_INTERRUPT() & (1 << epnum))) + cpu_relax(); - /* Reset DMA */ - bfin_write16(USB_DMA_REG(epnum, USB_DMAx_CTRL), 0); - SSYNC(); -#else - if (unlikely((unsigned long)dst & 0x01)) - insw_8((unsigned long)fifo, dst, - len & 0x01 ? (len >> 1) + 1 : len >> 1); - else - insw((unsigned long)fifo, dst, - len & 0x01 ? (len >> 1) + 1 : len >> 1); -#endif + /* acknowledge dma interrupt */ + bfin_write_USB_DMA_INTERRUPT(1 << epnum); + SSYNC(); + /* Reset DMA */ + bfin_write16(USB_DMA_REG(epnum, USB_DMAx_CTRL), 0); + SSYNC(); + } else { + SSYNC(); + /* Read the last byte of packet with odd size from address fifo + 4 + * to trigger 1 byte access to EP0 FIFO. + */ + if (len == 1) + *dst = (u8)inw((unsigned long)fifo + 4); + else { + if (unlikely((unsigned long)dst & 0x01)) + insw_8((unsigned long)fifo, dst, len >> 1); + else + insw((unsigned long)fifo, dst, len >> 1); + + if (len & 0x01) + *(dst + len - 1) = (u8)inw((unsigned long)fifo + 4); + } + } DBG(4, "%cX ep%d fifo %p count %d buf %p\n", 'R', hw_ep->epnum, fifo, len, dst); diff --git a/drivers/usb/musb/blackfin.h b/drivers/usb/musb/blackfin.h index 10b7d75..bd9352a 100644 --- a/drivers/usb/musb/blackfin.h +++ b/drivers/usb/musb/blackfin.h @@ -69,7 +69,6 @@ static void dump_fifo_data(u8 *buf, u16 len) #define dump_fifo_data(buf, len) do {} while (0) #endif -#ifdef CONFIG_BF52x #define USB_DMA_BASE USB_DMA_INTERRUPT #define USB_DMAx_CTRL 0x04 @@ -79,7 +78,6 @@ static void dump_fifo_data(u8 *buf, u16 len) #define USB_DMAx_COUNT_HIGH 0x14 #define USB_DMA_REG(ep, reg) (USB_DMA_BASE + 0x20 * ep + reg) -#endif /* Almost 1 second */ #define TIMER_DELAY (1 * HZ) -- cgit v0.10.2 From 465f8294eea1ea206e3a008e7bfe0e8fd53991fc Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 15 Dec 2009 23:19:52 +0200 Subject: usb: otg: isp1301_omap: fix compile error commit 91c8a5a9985d5bf9c55f6f82f183f57b050b2a3a broke compilation of this driver after it introduced otg_init() as a static inline in Reported-by: Tony Lindgren Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/otg/isp1301_omap.c b/drivers/usb/otg/isp1301_omap.c index d54460a..78a2097 100644 --- a/drivers/usb/otg/isp1301_omap.c +++ b/drivers/usb/otg/isp1301_omap.c @@ -843,7 +843,7 @@ static irqreturn_t omap_otg_irq(int irq, void *_isp) static struct platform_device *otg_dev; -static int otg_init(struct isp1301 *isp) +static int isp1301_otg_init(struct isp1301 *isp) { u32 l; @@ -1275,7 +1275,7 @@ static int __exit isp1301_remove(struct i2c_client *i2c) static int isp1301_otg_enable(struct isp1301 *isp) { power_up(isp); - otg_init(isp); + isp1301_otg_init(isp); /* NOTE: since we don't change this, this provides * a few more interrupts than are strictly needed. -- cgit v0.10.2 From d16f172622a7941c4fca09724ce16df5348af5fb Mon Sep 17 00:00:00 2001 From: Cliff Cai Date: Wed, 9 Dec 2009 22:21:12 -0500 Subject: USB: audio gadget: fix wTotalLength calculation The wTotalLength should contain the sum of the interface and unit descriptor sizes per the Audio Device Class specification 1.0. Reported-by: Sergey Lapin Signed-off-by: Cliff Cai Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/gadget/f_audio.c b/drivers/usb/gadget/f_audio.c index 0f2eee1..1ff420b 100644 --- a/drivers/usb/gadget/f_audio.c +++ b/drivers/usb/gadget/f_audio.c @@ -56,13 +56,16 @@ static struct usb_interface_descriptor ac_interface_desc __initdata = { DECLARE_UAC_AC_HEADER_DESCRIPTOR(2); #define UAC_DT_AC_HEADER_LENGTH UAC_DT_AC_HEADER_SIZE(F_AUDIO_NUM_INTERFACES) +/* 1 input terminal, 1 output terminal and 1 feature unit */ +#define UAC_DT_TOTAL_LENGTH (UAC_DT_AC_HEADER_LENGTH + UAC_DT_INPUT_TERMINAL_SIZE \ + + UAC_DT_OUTPUT_TERMINAL_SIZE + UAC_DT_FEATURE_UNIT_SIZE(0)) /* B.3.2 Class-Specific AC Interface Descriptor */ static struct uac_ac_header_descriptor_2 ac_header_desc = { .bLength = UAC_DT_AC_HEADER_LENGTH, .bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorSubtype = UAC_HEADER, .bcdADC = __constant_cpu_to_le16(0x0100), - .wTotalLength = __constant_cpu_to_le16(UAC_DT_AC_HEADER_LENGTH), + .wTotalLength = __constant_cpu_to_le16(UAC_DT_TOTAL_LENGTH), .bInCollection = F_AUDIO_NUM_INTERFACES, .baInterfaceNr = { [0] = F_AUDIO_AC_INTERFACE, -- cgit v0.10.2 From feef1d952ee1e9ac074640d7029dbbe8501725c2 Mon Sep 17 00:00:00 2001 From: Cliff Cai Date: Wed, 9 Dec 2009 22:28:39 -0500 Subject: USB: audio gadget: free alsa devices when unloading Signed-off-by: Cliff Cai Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/gadget/audio.c b/drivers/usb/gadget/audio.c index 58f2203..a62af7b 100644 --- a/drivers/usb/gadget/audio.c +++ b/drivers/usb/gadget/audio.c @@ -158,6 +158,7 @@ fail: static int __exit audio_unbind(struct usb_composite_dev *cdev) { + gaudio_cleanup(); return 0; } diff --git a/drivers/usb/gadget/f_audio.c b/drivers/usb/gadget/f_audio.c index 1ff420b..df77f61 100644 --- a/drivers/usb/gadget/f_audio.c +++ b/drivers/usb/gadget/f_audio.c @@ -792,7 +792,7 @@ int __init audio_bind_config(struct usb_configuration *c) return status; add_fail: - gaudio_cleanup(&audio->card); + gaudio_cleanup(); setup_fail: kfree(audio); return status; diff --git a/drivers/usb/gadget/u_audio.c b/drivers/usb/gadget/u_audio.c index 8252595d..35e0930 100644 --- a/drivers/usb/gadget/u_audio.c +++ b/drivers/usb/gadget/u_audio.c @@ -288,6 +288,7 @@ static int gaudio_close_snd_dev(struct gaudio *gau) return 0; } +static struct gaudio *the_card; /** * gaudio_setup - setup ALSA interface and preparing for USB transfer * @@ -303,6 +304,9 @@ int __init gaudio_setup(struct gaudio *card) if (ret) ERROR(card, "we need at least one control device\n"); + if (!the_card) + the_card = card; + return ret; } @@ -312,9 +316,11 @@ int __init gaudio_setup(struct gaudio *card) * * This is called to free all resources allocated by @gaudio_setup(). */ -void gaudio_cleanup(struct gaudio *card) +void gaudio_cleanup(void) { - if (card) - gaudio_close_snd_dev(card); + if (the_card) { + gaudio_close_snd_dev(the_card); + the_card = NULL; + } } diff --git a/drivers/usb/gadget/u_audio.h b/drivers/usb/gadget/u_audio.h index cc8d159..08ffce3 100644 --- a/drivers/usb/gadget/u_audio.h +++ b/drivers/usb/gadget/u_audio.h @@ -51,6 +51,6 @@ struct gaudio { }; int gaudio_setup(struct gaudio *card); -void gaudio_cleanup(struct gaudio *card); +void gaudio_cleanup(void); #endif /* __U_AUDIO_H */ -- cgit v0.10.2 From c983202bd03eb82394ef1dce5906702fcbc7bb80 Mon Sep 17 00:00:00 2001 From: Donny Kurnia Date: Wed, 23 Dec 2009 19:03:12 +0700 Subject: USB: option: support hi speed for modem Haier CE100 I made this patch for usbserial driver to add the support for EVDO modem Haier CE100. The bugs report for this is here: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/490068 This patch based on these post: http://blankblondtank.wordpress.com/2009/09/04/mengoptimalkan-koneksi-modem-haier-ce-100-cdma-di-linux/ http://tantos.web.id/blogs/how-to-internet-connection-using-cdma-evdo-modem-and-karmic-koala-ubuntu-9-10 I hope this patch can help other that have the Haier C100 modem, mostly in my country, Indonesia. Signed-off-by: Donny Kurnia Cc: stable Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 9a2b903..6e94a67 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -340,6 +340,10 @@ static int option_resume(struct usb_serial *serial); #define FOUR_G_SYSTEMS_VENDOR_ID 0x1c9e #define FOUR_G_SYSTEMS_PRODUCT_W14 0x9603 +/* Haier products */ +#define HAIER_VENDOR_ID 0x201e +#define HAIER_PRODUCT_CE100 0x2009 + static struct usb_device_id option_ids[] = { { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, @@ -641,6 +645,7 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) }, { USB_DEVICE(TLAYTECH_VENDOR_ID, TLAYTECH_PRODUCT_TEU800) }, { USB_DEVICE(FOUR_G_SYSTEMS_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W14) }, + { USB_DEVICE(HAIER_VENDOR_ID, HAIER_PRODUCT_CE100) }, { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, option_ids); -- cgit v0.10.2 From 37e9066b2f85480d99d3795373f5ef0b00ac1189 Mon Sep 17 00:00:00 2001 From: pancho horrillo Date: Wed, 23 Dec 2009 11:09:13 +0100 Subject: USB: Fix a bug on appledisplay.c regarding signedness brightness status is reported by the Apple Cinema Displays as an 'unsigned char' (u8) value, but the code used 'char' instead. Note that he driver was developed on the PowerPC architecture, where the two types are synonymous, which is not always the case. Fixed that. Otherwise the driver will interpret brightness levels > 127 as negative, and fail to load. Signed-off-by: pancho horrillo Cc: stable Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/misc/appledisplay.c b/drivers/usb/misc/appledisplay.c index 8dc4afa..1eb9e41 100644 --- a/drivers/usb/misc/appledisplay.c +++ b/drivers/usb/misc/appledisplay.c @@ -73,8 +73,8 @@ struct appledisplay { struct usb_device *udev; /* usb device */ struct urb *urb; /* usb request block */ struct backlight_device *bd; /* backlight device */ - char *urbdata; /* interrupt URB data buffer */ - char *msgdata; /* control message data buffer */ + u8 *urbdata; /* interrupt URB data buffer */ + u8 *msgdata; /* control message data buffer */ struct delayed_work work; int button_pressed; -- cgit v0.10.2 From 4946f8353da9d3038e2a9d0295d5dfeee4cee5c5 Mon Sep 17 00:00:00 2001 From: Imre Kaloz Date: Mon, 7 Dec 2009 20:42:26 +0100 Subject: [WATCHDOG] iTCO_wdt: add PCI ID for the Intel EP80579 (Tolapai) SoC add PCI ID for the Intel EP80579 (Tolapai) SoC Signed-off-by: Imre Kaloz Signed-off-by: Wim Van Sebroeck diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c index e44fbb3..c8a3bec 100644 --- a/drivers/watchdog/iTCO_wdt.c +++ b/drivers/watchdog/iTCO_wdt.c @@ -30,6 +30,7 @@ * document number 316972-004, 316973-012: 82801I (ICH9) * document number 319973-002, 319974-002: 82801J (ICH10) * document number 322169-001, 322170-001: 5 Series, 3400 Series (PCH) + * document number 320066-003, 320257-008: EP80597 (IICH) */ /* @@ -100,6 +101,7 @@ enum iTCO_chipsets { TCO_PCH, /* PCH Desktop Full Featured */ TCO_PCHM, /* PCH Mobile Full Featured */ TCO_PCHMSFF, /* PCH Mobile SFF Full Featured */ + TCO_EP80579, /* EP80579 */ }; static struct { @@ -143,6 +145,7 @@ static struct { {"PCH Desktop Full Featured", 2}, {"PCH Mobile Full Featured", 2}, {"PCH Mobile SFF Full Featured", 2}, + {"EP80579", 2}, {NULL, 0} }; @@ -214,6 +217,7 @@ static struct pci_device_id iTCO_wdt_pci_tbl[] = { { ITCO_PCI_DEVICE(0x3b00, TCO_PCH)}, { ITCO_PCI_DEVICE(0x3b01, TCO_PCHM)}, { ITCO_PCI_DEVICE(0x3b0d, TCO_PCHMSFF)}, + { ITCO_PCI_DEVICE(0x5031, TCO_EP80579)}, { 0, }, /* End of list */ }; MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl); -- cgit v0.10.2 From b782a563758ac963c794d9fbaaff494140c28fd6 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 4 Dec 2009 12:24:04 -0500 Subject: [WATCHDOG] use resource_size() Use resource_size(). Signed-off-by: H Hartley Sweeten Cc: Kevin Hilman Cc: Kevin Hilman Cc: Ulrik Bech Hald Cc: Henrique de Moraes Holschuh Cc: Ming Lei Cc: Vincent Sanders Acked-by: Thierry Reding Signed-off-by: Wim Van Sebroeck Signed-off-by: Andrew Morton diff --git a/drivers/watchdog/adx_wdt.c b/drivers/watchdog/adx_wdt.c index 9c65944..9d7d155 100644 --- a/drivers/watchdog/adx_wdt.c +++ b/drivers/watchdog/adx_wdt.c @@ -242,14 +242,14 @@ static int __devinit adx_wdt_probe(struct platform_device *pdev) } res = devm_request_mem_region(&pdev->dev, res->start, - res->end - res->start + 1, res->name); + resource_size(res), res->name); if (!res) { dev_err(&pdev->dev, "cannot request I/O memory region\n"); return -ENXIO; } wdt->base = devm_ioremap_nocache(&pdev->dev, res->start, - res->end - res->start + 1); + resource_size(res)); if (!wdt->base) { dev_err(&pdev->dev, "cannot remap I/O memory region\n"); return -ENXIO; diff --git a/drivers/watchdog/at32ap700x_wdt.c b/drivers/watchdog/at32ap700x_wdt.c index e8ae638..0378479 100644 --- a/drivers/watchdog/at32ap700x_wdt.c +++ b/drivers/watchdog/at32ap700x_wdt.c @@ -326,7 +326,7 @@ static int __init at32_wdt_probe(struct platform_device *pdev) return -ENOMEM; } - wdt->regs = ioremap(regs->start, regs->end - regs->start + 1); + wdt->regs = ioremap(regs->start, resource_size(regs)); if (!wdt->regs) { ret = -ENOMEM; dev_dbg(&pdev->dev, "could not map I/O memory\n"); diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c index 9d7520f..887136d 100644 --- a/drivers/watchdog/davinci_wdt.c +++ b/drivers/watchdog/davinci_wdt.c @@ -221,7 +221,7 @@ static int __devinit davinci_wdt_probe(struct platform_device *pdev) return -ENOENT; } - size = res->end - res->start + 1; + size = resource_size(res); wdt_mem = request_mem_region(res->start, size, pdev->name); if (wdt_mem == NULL) { diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c index 83fa34b..a2dc07c 100644 --- a/drivers/watchdog/mpcore_wdt.c +++ b/drivers/watchdog/mpcore_wdt.c @@ -350,7 +350,7 @@ static int __devinit mpcore_wdt_probe(struct platform_device *dev) ret = -ENXIO; goto err_free; } - wdt->base = ioremap(res->start, res->end - res->start + 1); + wdt->base = ioremap(res->start, resource_size(res)); if (!wdt->base) { ret = -ENOMEM; goto err_free; diff --git a/drivers/watchdog/mv64x60_wdt.c b/drivers/watchdog/mv64x60_wdt.c index acf589d..a51dbe4 100644 --- a/drivers/watchdog/mv64x60_wdt.c +++ b/drivers/watchdog/mv64x60_wdt.c @@ -275,7 +275,7 @@ static int __devinit mv64x60_wdt_probe(struct platform_device *dev) if (!r) return -ENODEV; - mv64x60_wdt_regs = ioremap(r->start, r->end - r->start + 1); + mv64x60_wdt_regs = ioremap(r->start, resource_size(r)); if (mv64x60_wdt_regs == NULL) return -ENOMEM; diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c index 429ea99..c6aaf28 100644 --- a/drivers/watchdog/omap_wdt.c +++ b/drivers/watchdog/omap_wdt.c @@ -277,8 +277,7 @@ static int __devinit omap_wdt_probe(struct platform_device *pdev) goto err_busy; } - mem = request_mem_region(res->start, res->end - res->start + 1, - pdev->name); + mem = request_mem_region(res->start, resource_size(res), pdev->name); if (!mem) { ret = -EBUSY; goto err_busy; @@ -306,7 +305,7 @@ static int __devinit omap_wdt_probe(struct platform_device *pdev) goto err_clk; } - wdev->base = ioremap(res->start, res->end - res->start + 1); + wdev->base = ioremap(res->start, resource_size(res)); if (!wdev->base) { ret = -ENOMEM; goto err_ioremap; @@ -358,7 +357,7 @@ err_clk: kfree(wdev); err_kzalloc: - release_mem_region(res->start, res->end - res->start + 1); + release_mem_region(res->start, resource_size(res)); err_busy: err_get_resource: @@ -383,7 +382,7 @@ static int __devexit omap_wdt_remove(struct platform_device *pdev) return -ENOENT; misc_deregister(&(wdev->omap_wdt_miscdev)); - release_mem_region(res->start, res->end - res->start + 1); + release_mem_region(res->start, resource_size(res)); platform_set_drvdata(pdev, NULL); clk_put(wdev->ick); diff --git a/drivers/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c index 4d227b15..430a584 100644 --- a/drivers/watchdog/pnx4008_wdt.c +++ b/drivers/watchdog/pnx4008_wdt.c @@ -264,7 +264,7 @@ static int __devinit pnx4008_wdt_probe(struct platform_device *pdev) return -ENOENT; } - size = res->end - res->start + 1; + size = resource_size(res); wdt_mem = request_mem_region(res->start, size, pdev->name); if (wdt_mem == NULL) { diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c index 85b93e1..8760a26 100644 --- a/drivers/watchdog/s3c2410_wdt.c +++ b/drivers/watchdog/s3c2410_wdt.c @@ -421,7 +421,7 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev) return -ENOENT; } - size = (res->end - res->start) + 1; + size = resource_size(res); wdt_mem = request_mem_region(res->start, size, pdev->name); if (wdt_mem == NULL) { dev_err(dev, "failed to get memory region\n"); diff --git a/drivers/watchdog/txx9wdt.c b/drivers/watchdog/txx9wdt.c index 6adab77..d635566 100644 --- a/drivers/watchdog/txx9wdt.c +++ b/drivers/watchdog/txx9wdt.c @@ -214,12 +214,10 @@ static int __init txx9wdt_probe(struct platform_device *dev) res = platform_get_resource(dev, IORESOURCE_MEM, 0); if (!res) goto exit_busy; - if (!devm_request_mem_region(&dev->dev, - res->start, res->end - res->start + 1, + if (!devm_request_mem_region(&dev->dev, res->start, resource_size(res), "txx9wdt")) goto exit_busy; - txx9wdt_reg = devm_ioremap(&dev->dev, - res->start, res->end - res->start + 1); + txx9wdt_reg = devm_ioremap(&dev->dev, res->start, resource_size(res)); if (!txx9wdt_reg) goto exit_busy; -- cgit v0.10.2 From 52e8bfd81af5492a14cc3a4641d4c80d05b66bdb Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 23 Dec 2009 19:54:31 +0000 Subject: ARM: Fix wrong shared bit for CPU write buffer bug test It is unpredictable to have the same memory mapped using different shared bit settings for ARMv6 and ARMv7 CPUs. Fix this for the CPU write buffer bug test. Signed-off-by: Russell King diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c index 7296022..56ee153 100644 --- a/arch/arm/mm/fault-armv.c +++ b/arch/arm/mm/fault-armv.c @@ -207,9 +207,8 @@ void __init check_writebuffer_bugs(void) page = alloc_page(GFP_KERNEL); if (page) { unsigned long *p1, *p2; - pgprot_t prot = __pgprot(L_PTE_PRESENT|L_PTE_YOUNG| - L_PTE_DIRTY|L_PTE_WRITE| - L_PTE_MT_BUFFERABLE); + pgprot_t prot = __pgprot_modify(PAGE_KERNEL, + L_PTE_MT_MASK, L_PTE_MT_BUFFERABLE); p1 = vmap(&page, 1, VM_IOREMAP, prot); p2 = vmap(&page, 1, VM_IOREMAP, prot); -- cgit v0.10.2 From 4440095c8268c1a5e11577097d2be429cec036ca Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 23 Dec 2009 21:00:20 +0100 Subject: SYSCTL: Print binary sysctl warnings (nearly) only once When printing legacy sysctls print the warning message for each of them only once. This way there is a guarantee the syslog won't be flooded for any sane program. The original attempt at this made the tables non const and stored the flag inline. Linus suggested using a separate hash table for this, this is based on a code snippet from him. The hash implies this is not exact and can sometimes not print a new sysctl due to a hash collision, but in practice this should not be a problem I used a FNV32 hash over the binary string with a 32byte bitmap. This gives relatively little collisions when all the predefined binary sysctls are hashed: size 256 bucket length number 0: [25] 1: [67] 2: [88] 3: [47] 4: [22] 5: [6] 6: [1] The worst case is a single collision of 6 hash values. Signed-off-by: Andi Kleen diff --git a/kernel/sysctl_binary.c b/kernel/sysctl_binary.c index 112533d..8f5d16e 100644 --- a/kernel/sysctl_binary.c +++ b/kernel/sysctl_binary.c @@ -1417,6 +1417,35 @@ static void deprecated_sysctl_warning(const int *name, int nlen) return; } +#define WARN_ONCE_HASH_BITS 8 +#define WARN_ONCE_HASH_SIZE (1< Date: Wed, 23 Dec 2009 21:00:47 +0100 Subject: SYSCTL: Add a mutex to the page_alloc zone order sysctl The zone list code clearly cannot tolerate concurrent writers (I couldn't find any locks for that), so simply add a global mutex. No need for RCU in this case. Signed-off-by: Andi Kleen diff --git a/mm/page_alloc.c b/mm/page_alloc.c index d79b925..4e9f5cc 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -2402,13 +2402,14 @@ int numa_zonelist_order_handler(ctl_table *table, int write, { char saved_string[NUMA_ZONELIST_ORDER_LEN]; int ret; + static DEFINE_MUTEX(zl_order_mutex); + mutex_lock(&zl_order_mutex); if (write) - strncpy(saved_string, (char*)table->data, - NUMA_ZONELIST_ORDER_LEN); + strcpy(saved_string, (char*)table->data); ret = proc_dostring(table, write, buffer, length, ppos); if (ret) - return ret; + goto out; if (write) { int oldval = user_zonelist_order; if (__parse_numa_zonelist_order((char*)table->data)) { @@ -2421,7 +2422,9 @@ int numa_zonelist_order_handler(ctl_table *table, int write, } else if (oldval != user_zonelist_order) build_all_zonelists(); } - return 0; +out: + mutex_unlock(&zl_order_mutex); + return ret; } -- cgit v0.10.2 From 2b542a13a94f310e718f2ed57b0f712b9ddbbbef Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Wed, 23 Dec 2009 20:34:29 +0000 Subject: ARM: S3C: Fix NAND device registration by s3c_nand_set_platdata(). Fix two bugs in s3c_nand_set_platdata() where thet device's platform data was not set, and the wrong error check was being performed on the return of s3c_nand_copy_set(). Fixes the following OOPS: Unable to handle kernel NULL pointer dereference at virtual address 00000004 PC is at s3c24xx_nand_probe+0x234/0x594 Signed-off-by: Ben Dooks diff --git a/arch/arm/plat-s3c/dev-nand.c b/arch/arm/plat-s3c/dev-nand.c index e771e77..84808cc 100644 --- a/arch/arm/plat-s3c/dev-nand.c +++ b/arch/arm/plat-s3c/dev-nand.c @@ -114,7 +114,7 @@ void __init s3c_nand_set_platdata(struct s3c2410_platform_nand *nand) for (i = 0; i < npd->nr_sets; i++) { ret = s3c_nand_copy_set(to); - if (!ret) { + if (ret) { printk(KERN_ERR "%s: failed to copy set %d\n", __func__, i); return; @@ -122,6 +122,8 @@ void __init s3c_nand_set_platdata(struct s3c2410_platform_nand *nand) to++; } } + + s3c_device_nand.dev.platform_data = npd; } EXPORT_SYMBOL_GPL(s3c_nand_set_platdata); -- cgit v0.10.2 From 9dc130fccb874f2959ef313d7922d306dc6d4f75 Mon Sep 17 00:00:00 2001 From: Shaohua Li Date: Wed, 23 Dec 2009 17:04:11 +0800 Subject: ACPI: fix OSC regression that caused aer and pciehp not to load Executing _OSC returns a buffer, which has an acpi object in it. Don't directly returns the buffer, instead, we return the acpi object's buffer. This fixes a regression since caller of acpi_run_osc expects an acpi object's buffer returned. Tested-by: Yinghai Lu Signed-off-by: Shaohua Li Signed-off-by: Len Brown diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 65f7e33..0c1ad31 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -397,6 +397,7 @@ acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context) union acpi_object *out_obj; u8 uuid[16]; u32 errors; + struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL}; if (!context) return AE_ERROR; @@ -419,16 +420,16 @@ acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context) in_params[3].buffer.length = context->cap.length; in_params[3].buffer.pointer = context->cap.pointer; - status = acpi_evaluate_object(handle, "_OSC", &input, &context->ret); + status = acpi_evaluate_object(handle, "_OSC", &input, &output); if (ACPI_FAILURE(status)) return status; - /* return buffer should have the same length as cap buffer */ - if (context->ret.length != context->cap.length) + if (!output.length) return AE_NULL_OBJECT; - out_obj = context->ret.pointer; - if (out_obj->type != ACPI_TYPE_BUFFER) { + out_obj = output.pointer; + if (out_obj->type != ACPI_TYPE_BUFFER + || out_obj->buffer.length != context->cap.length) { acpi_print_osc_error(handle, context, "_OSC evaluation returned wrong type"); status = AE_TYPE; @@ -457,11 +458,20 @@ acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context) goto out_kfree; } out_success: - return AE_OK; + context->ret.length = out_obj->buffer.length; + context->ret.pointer = kmalloc(context->ret.length, GFP_KERNEL); + if (!context->ret.pointer) { + status = AE_NO_MEMORY; + goto out_kfree; + } + memcpy(context->ret.pointer, out_obj->buffer.pointer, + context->ret.length); + status = AE_OK; out_kfree: - kfree(context->ret.pointer); - context->ret.pointer = NULL; + kfree(output.pointer); + if (status != AE_OK) + context->ret.pointer = NULL; return status; } EXPORT_SYMBOL(acpi_run_osc); -- cgit v0.10.2 From 2f99f5c8f05e02f3df1bb4d93b6704e6f5972872 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Wed, 23 Dec 2009 15:04:53 -0800 Subject: Revert "x86, ucode-amd: Ensure ucode update on suspend/resume after CPU off/online cycle" This reverts commit 9f15226e75583547aaf542c6be4bdac1060dd425. It's just wrong, and broke resume for Rafael even on a non-AMD CPU. As Rafael says: "... it causes microcode_init_cpu() to be called during resume even for CPUs for which there's no microcode to apply. That, in turn, results in executing request_firmware() (on Intel CPUs at least) which doesn't work at this stage of resume (we have device interrupts disabled, I/O devices are still suspended and so on). If I'm not mistaken, the "if (uci->valid)" logic means "if that CPU is known to us" , so before commit 9f15226e755 microcode_resume_cpu() was called for all CPUs already in the system during suspend, which was the right thing to do. The commit changed it so that the CPUs without microcode to apply are now treated as "unknown", which is not quite right. The problem this commit attempted to solve has to be handled differently." Bisected-and -requested-by: Rafael J. Wysocki Signed-off-by: Linus Torvalds diff --git a/arch/x86/kernel/microcode_core.c b/arch/x86/kernel/microcode_core.c index 844c02c..0c86324 100644 --- a/arch/x86/kernel/microcode_core.c +++ b/arch/x86/kernel/microcode_core.c @@ -394,7 +394,7 @@ static enum ucode_state microcode_update_cpu(int cpu) struct ucode_cpu_info *uci = ucode_cpu_info + cpu; enum ucode_state ustate; - if (uci->valid && uci->mc) + if (uci->valid) ustate = microcode_resume_cpu(cpu); else ustate = microcode_init_cpu(cpu); -- cgit v0.10.2 From ac07fb4dc1908d300f50fa711982c9d750eb59f7 Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Mon, 21 Dec 2009 09:28:30 -0500 Subject: i2c-bfin-twi: fix CLKDIV calculation Calculation of the CLKDIV speed setting should be done using base 10 math rather than base 2. We also avoid exceeding the spec due to integer truncation and a 50% duty cycle. Signed-off-by: Sonic Zhang Signed-off-by: Mike Frysinger Signed-off-by: Ben Dooks diff --git a/drivers/i2c/busses/i2c-bfin-twi.c b/drivers/i2c/busses/i2c-bfin-twi.c index b309ac2..fe3fb56 100644 --- a/drivers/i2c/busses/i2c-bfin-twi.c +++ b/drivers/i2c/busses/i2c-bfin-twi.c @@ -693,13 +693,13 @@ static int i2c_bfin_twi_probe(struct platform_device *pdev) } /* Set TWI internal clock as 10MHz */ - write_CONTROL(iface, ((get_sclk() / 1024 / 1024 + 5) / 10) & 0x7F); + write_CONTROL(iface, ((get_sclk() / 1000 / 1000 + 5) / 10) & 0x7F); /* * We will not end up with a CLKDIV=0 because no one will specify - * 20kHz SCL or less in Kconfig now. (5 * 1024 / 20 = 0x100) + * 20kHz SCL or less in Kconfig now. (5 * 1000 / 20 = 250) */ - clkhilow = 5 * 1024 / CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ; + clkhilow = ((10 * 1000 / CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ) + 1) / 2; /* Set Twi interface clock as specified */ write_CLKDIV(iface, (clkhilow << 8) | clkhilow); -- cgit v0.10.2 From 07ac31f6f4cd558e53f6705dbe3033a7f0237eb8 Mon Sep 17 00:00:00 2001 From: Cory Maccarrone Date: Tue, 22 Dec 2009 18:06:13 -0700 Subject: i2c-omap: Don't write IE state in unidle if 0 Commit ef871432... (i2c-omap: OMAP3: PM: (re)init for every transfer to support off-mode) introduced a change which make the dev->iestate contents be written to the OMAP_I2C_IE_REG every time omap_i2c_unidle is called. Previously, the state was only written if it wasn't equal to zero. In omap_i2c_probe, omap_i2c_unidle() is called prior to omap_i2c_init(), in which case dev->iestate has not yet been initialized and will be set to zero. Having this value written to the registers causes deadlock while booting. As such, this change restores the original functionality. Signed-off-by: Cory Maccarrone Signed-off-by: Ben Dooks diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 75bf3ad..a64a192 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -247,7 +247,13 @@ static void omap_i2c_unidle(struct omap_i2c_dev *dev) omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN); } dev->idle = 0; - omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate); + + /* + * Don't write to this register if the IE state is 0 as it can + * cause deadlock. + */ + if (dev->iestate) + omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate); } static void omap_i2c_idle(struct omap_i2c_dev *dev) -- cgit v0.10.2 From 57eb81b14e35a14df64ac3597bc90c26ce04a9b4 Mon Sep 17 00:00:00 2001 From: Manjunatha GK Date: Fri, 11 Dec 2009 11:09:08 +0530 Subject: i2c-omap: OMAP3: Fix I2C lockup during timeout/error cases Current OMAP3 I2C driver code does not follow the correct sequence for soft reset. Due to this, lock up issues are reported during timeout/error cases. This patch fixes above issue by disabling I2C controller as per OMAP3430 TRM for soft reset. As per TRM, I2C controller needs to be disabled as a first step during soft reset. Here is correct soft reset sequence: a. Ensure that the module is disabled (clear the I2Ci.I2C_CON[15] I2C_EN bit to 0). b. Set the I2Ci.I2C_SYSC[1] SRST bit to 1. c. Enable the module by setting I2Ci.I2C_CON[15] I2C_EN bit to 1. d. Check the I2Ci.I2C_SYSS[0] RDONE bit until it is set to 1 to indicate the software reset is complete. Tested on Zoom2, Zoom3, 3430SDP and 3630SDP Signed-off-by: Manjunatha GK Signed-off-by: George, Harith Acked-by: Varadarajan, Charu Latha Signed-off-by: Ben Dooks diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index a64a192..0037e31 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -286,6 +286,11 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) unsigned long internal_clk = 0; if (dev->rev >= OMAP_I2C_REV_2) { + /* Disable I2C controller before soft reset */ + omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, + omap_i2c_read_reg(dev, OMAP_I2C_CON_REG) & + ~(OMAP_I2C_CON_EN)); + omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG, SYSC_SOFTRESET_MASK); /* For some reason we need to set the EN bit before the * reset done bit gets set. */ -- cgit v0.10.2 From 86239d59e268a35a49a00fce9c8512a506267f5c Mon Sep 17 00:00:00 2001 From: Tristan Ye Date: Tue, 22 Dec 2009 09:11:58 +0800 Subject: Ocfs2: Let ocfs2 support fiemap for symlink and fast symlink. For fast symlink, it can be treated the same as inlined files since the data extent we want to return of both case all were stored in metadata block. For symlink, it can be simply treated the same as we did for regular files. Signed-off-by: Tristan Ye Acked-by: Sunil Mushran Signed-off-by: Joel Becker diff --git a/fs/ocfs2/extent_map.c b/fs/ocfs2/extent_map.c index cdce5f8..d35a27f 100644 --- a/fs/ocfs2/extent_map.c +++ b/fs/ocfs2/extent_map.c @@ -37,6 +37,7 @@ #include "extent_map.h" #include "inode.h" #include "super.h" +#include "symlink.h" #include "buffer_head_io.h" @@ -703,6 +704,12 @@ out: return ret; } +/* + * The ocfs2_fiemap_inline() may be a little bit misleading, since + * it not only handles the fiemap for inlined files, but also deals + * with the fast symlink, cause they have no difference for extent + * mapping per se. + */ static int ocfs2_fiemap_inline(struct inode *inode, struct buffer_head *di_bh, struct fiemap_extent_info *fieinfo, u64 map_start) @@ -715,11 +722,18 @@ static int ocfs2_fiemap_inline(struct inode *inode, struct buffer_head *di_bh, struct ocfs2_inode_info *oi = OCFS2_I(inode); di = (struct ocfs2_dinode *)di_bh->b_data; - id_count = le16_to_cpu(di->id2.i_data.id_count); + if (ocfs2_inode_is_fast_symlink(inode)) + id_count = ocfs2_fast_symlink_chars(inode->i_sb); + else + id_count = le16_to_cpu(di->id2.i_data.id_count); if (map_start < id_count) { phys = oi->ip_blkno << inode->i_sb->s_blocksize_bits; - phys += offsetof(struct ocfs2_dinode, id2.i_data.id_data); + if (ocfs2_inode_is_fast_symlink(inode)) + phys += offsetof(struct ocfs2_dinode, id2.i_symlink); + else + phys += offsetof(struct ocfs2_dinode, + id2.i_data.id_data); ret = fiemap_fill_next_extent(fieinfo, 0, phys, id_count, flags); @@ -756,9 +770,10 @@ int ocfs2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, down_read(&OCFS2_I(inode)->ip_alloc_sem); /* - * Handle inline-data separately. + * Handle inline-data and fast symlink separately. */ - if (OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) { + if ((OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) || + ocfs2_inode_is_fast_symlink(inode)) { ret = ocfs2_fiemap_inline(inode, di_bh, fieinfo, map_start); goto out_unlock; } diff --git a/fs/ocfs2/symlink.c b/fs/ocfs2/symlink.c index e342103..49b133c 100644 --- a/fs/ocfs2/symlink.c +++ b/fs/ocfs2/symlink.c @@ -163,6 +163,7 @@ const struct inode_operations ocfs2_symlink_inode_operations = { .getxattr = generic_getxattr, .listxattr = ocfs2_listxattr, .removexattr = generic_removexattr, + .fiemap = ocfs2_fiemap, }; const struct inode_operations ocfs2_fast_symlink_inode_operations = { .readlink = ocfs2_readlink, @@ -174,4 +175,5 @@ const struct inode_operations ocfs2_fast_symlink_inode_operations = { .getxattr = generic_getxattr, .listxattr = ocfs2_listxattr, .removexattr = generic_removexattr, + .fiemap = ocfs2_fiemap, }; -- cgit v0.10.2 From b31d308ddcfb73349582a0196b5f65dad3cf5d17 Mon Sep 17 00:00:00 2001 From: Tao Ma Date: Tue, 22 Dec 2009 10:32:15 +0800 Subject: ocfs2/trivial: Use proper mask for 2 places in hearbeat.c I just noticed today that there are 2 places of "mlog(0,...)" in fs/ocfs2/cluster/heartbeat.c, but actually have no default mask prefix in that file. So change them to mlog(ML_HEARTBEAT,...). Signed-off-by: Tao Ma Signed-off-by: Joel Becker diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c index c452d11..eda5b8b 100644 --- a/fs/ocfs2/cluster/heartbeat.c +++ b/fs/ocfs2/cluster/heartbeat.c @@ -176,7 +176,8 @@ static void o2hb_write_timeout(struct work_struct *work) static void o2hb_arm_write_timeout(struct o2hb_region *reg) { - mlog(0, "Queue write timeout for %u ms\n", O2HB_MAX_WRITE_TIMEOUT_MS); + mlog(ML_HEARTBEAT, "Queue write timeout for %u ms\n", + O2HB_MAX_WRITE_TIMEOUT_MS); cancel_delayed_work(®->hr_write_timeout_work); reg->hr_last_timeout_start = jiffies; @@ -874,7 +875,8 @@ static int o2hb_thread(void *data) do_gettimeofday(&after_hb); elapsed_msec = o2hb_elapsed_msecs(&before_hb, &after_hb); - mlog(0, "start = %lu.%lu, end = %lu.%lu, msec = %u\n", + mlog(ML_HEARTBEAT, + "start = %lu.%lu, end = %lu.%lu, msec = %u\n", before_hb.tv_sec, (unsigned long) before_hb.tv_usec, after_hb.tv_sec, (unsigned long) after_hb.tv_usec, elapsed_msec); -- cgit v0.10.2 From 8ff6af881deccca4f88e03f2fdadb1aac42e9489 Mon Sep 17 00:00:00 2001 From: Tao Ma Date: Wed, 23 Dec 2009 14:31:15 +0800 Subject: ocfs2/trivial: Use le16_to_cpu for a disk value in xattr.c In ocfs2_value_metas_in_xattr_header, we should Use le16_to_cpu for ocfs2_extent_list.l_next_free_rec. Signed-off-by: Tao Ma Signed-off-by: Joel Becker diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c index 923e950e..932c077 100644 --- a/fs/ocfs2/xattr.c +++ b/fs/ocfs2/xattr.c @@ -6062,7 +6062,7 @@ static int ocfs2_value_metas_in_xattr_header(struct super_block *sb, * to the extent block, so just calculate a maximum record num. */ if (!xv->xr_list.l_tree_depth) - *num_recs += xv->xr_list.l_next_free_rec; + *num_recs += le16_to_cpu(xv->xr_list.l_next_free_rec); else *num_recs += ocfs2_clusters_for_bytes(sb, XATTR_SIZE_MAX); -- cgit v0.10.2 From ff3b00a0fcaab89ff885e9f0f4ad83c4ced788f4 Mon Sep 17 00:00:00 2001 From: Steve Hodgson Date: Wed, 23 Dec 2009 13:46:36 +0000 Subject: sfc: Move PHY software state initialisation from init() into probe() This prevents efx->link_advertising from being blatted during a reset. The phy_short_reach sysfs node is now destroyed later in the port shutdown process, so check for STATE_RUNNING after acquiring the rtnl_lock (just like in set_phy_flash_cfg). Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index f983e3b..103e8b0 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c @@ -741,14 +741,14 @@ static int efx_probe_port(struct efx_nic *efx) EFX_LOG(efx, "create port\n"); + if (phy_flash_cfg) + efx->phy_mode = PHY_MODE_SPECIAL; + /* Connect up MAC/PHY operations table */ rc = efx->type->probe_port(efx); if (rc) goto err; - if (phy_flash_cfg) - efx->phy_mode = PHY_MODE_SPECIAL; - /* Sanity check MAC address */ if (is_valid_ether_addr(efx->mac_address)) { memcpy(efx->net_dev->dev_addr, efx->mac_address, ETH_ALEN); diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 17afcd2..9d009c4 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -925,6 +925,7 @@ static int falcon_probe_port(struct efx_nic *efx) static void falcon_remove_port(struct efx_nic *efx) { + efx->phy_op->remove(efx); efx_nic_free_buffer(efx, &efx->stats_buffer); } diff --git a/drivers/net/sfc/mcdi_phy.c b/drivers/net/sfc/mcdi_phy.c index 0e1bcc5..eb694af 100644 --- a/drivers/net/sfc/mcdi_phy.c +++ b/drivers/net/sfc/mcdi_phy.c @@ -304,31 +304,47 @@ static u32 mcdi_to_ethtool_media(u32 media) static int efx_mcdi_phy_probe(struct efx_nic *efx) { - struct efx_mcdi_phy_cfg *phy_cfg; + struct efx_mcdi_phy_cfg *phy_data; + u8 outbuf[MC_CMD_GET_LINK_OUT_LEN]; + u32 caps; int rc; - /* TODO: Move phy_data initialisation to - * phy_op->probe/remove, rather than init/fini */ - phy_cfg = kzalloc(sizeof(*phy_cfg), GFP_KERNEL); - if (phy_cfg == NULL) { - rc = -ENOMEM; - goto fail_alloc; - } - rc = efx_mcdi_get_phy_cfg(efx, phy_cfg); + /* Initialise and populate phy_data */ + phy_data = kzalloc(sizeof(*phy_data), GFP_KERNEL); + if (phy_data == NULL) + return -ENOMEM; + + rc = efx_mcdi_get_phy_cfg(efx, phy_data); if (rc != 0) goto fail; - efx->phy_type = phy_cfg->type; + /* Read initial link advertisement */ + BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0); + rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0, + outbuf, sizeof(outbuf), NULL); + if (rc) + goto fail; + + /* Fill out nic state */ + efx->phy_data = phy_data; + efx->phy_type = phy_data->type; - efx->mdio_bus = phy_cfg->channel; - efx->mdio.prtad = phy_cfg->port; - efx->mdio.mmds = phy_cfg->mmd_mask & ~(1 << MC_CMD_MMD_CLAUSE22); + efx->mdio_bus = phy_data->channel; + efx->mdio.prtad = phy_data->port; + efx->mdio.mmds = phy_data->mmd_mask & ~(1 << MC_CMD_MMD_CLAUSE22); efx->mdio.mode_support = 0; - if (phy_cfg->mmd_mask & (1 << MC_CMD_MMD_CLAUSE22)) + if (phy_data->mmd_mask & (1 << MC_CMD_MMD_CLAUSE22)) efx->mdio.mode_support |= MDIO_SUPPORTS_C22; - if (phy_cfg->mmd_mask & ~(1 << MC_CMD_MMD_CLAUSE22)) + if (phy_data->mmd_mask & ~(1 << MC_CMD_MMD_CLAUSE22)) efx->mdio.mode_support |= MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22; + caps = MCDI_DWORD(outbuf, GET_LINK_OUT_CAP); + if (caps & (1 << MC_CMD_PHY_CAP_AN_LBN)) + efx->link_advertising = + mcdi_to_ethtool_cap(phy_data->media, caps); + else + phy_data->forced_cap = caps; + /* Assert that we can map efx -> mcdi loopback modes */ BUILD_BUG_ON(LOOPBACK_NONE != MC_CMD_LOOPBACK_NONE); BUILD_BUG_ON(LOOPBACK_DATA != MC_CMD_LOOPBACK_DATA); @@ -365,46 +381,6 @@ static int efx_mcdi_phy_probe(struct efx_nic *efx) * but by convention we don't */ efx->loopback_modes &= ~(1 << LOOPBACK_NONE); - kfree(phy_cfg); - - return 0; - -fail: - kfree(phy_cfg); -fail_alloc: - return rc; -} - -static int efx_mcdi_phy_init(struct efx_nic *efx) -{ - struct efx_mcdi_phy_cfg *phy_data; - u8 outbuf[MC_CMD_GET_LINK_OUT_LEN]; - u32 caps; - int rc; - - phy_data = kzalloc(sizeof(*phy_data), GFP_KERNEL); - if (phy_data == NULL) - return -ENOMEM; - - rc = efx_mcdi_get_phy_cfg(efx, phy_data); - if (rc != 0) - goto fail; - - efx->phy_data = phy_data; - - BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0); - rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0, - outbuf, sizeof(outbuf), NULL); - if (rc) - goto fail; - - caps = MCDI_DWORD(outbuf, GET_LINK_OUT_CAP); - if (caps & (1 << MC_CMD_PHY_CAP_AN_LBN)) - efx->link_advertising = - mcdi_to_ethtool_cap(phy_data->media, caps); - else - phy_data->forced_cap = caps; - return 0; fail: @@ -504,7 +480,7 @@ static bool efx_mcdi_phy_poll(struct efx_nic *efx) return !efx_link_state_equal(&efx->link_state, &old_state); } -static void efx_mcdi_phy_fini(struct efx_nic *efx) +static void efx_mcdi_phy_remove(struct efx_nic *efx) { struct efx_mcdi_phy_data *phy_data = efx->phy_data; @@ -586,10 +562,11 @@ static int efx_mcdi_phy_set_settings(struct efx_nic *efx, struct ethtool_cmd *ec struct efx_phy_operations efx_mcdi_phy_ops = { .probe = efx_mcdi_phy_probe, - .init = efx_mcdi_phy_init, + .init = efx_port_dummy_op_int, .reconfigure = efx_mcdi_phy_reconfigure, .poll = efx_mcdi_phy_poll, - .fini = efx_mcdi_phy_fini, + .fini = efx_port_dummy_op_void, + .remove = efx_mcdi_phy_remove, .get_settings = efx_mcdi_phy_get_settings, .set_settings = efx_mcdi_phy_set_settings, .run_tests = NULL, diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 34c381f..d5aab5b 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -524,6 +524,7 @@ struct efx_phy_operations { int (*probe) (struct efx_nic *efx); int (*init) (struct efx_nic *efx); void (*fini) (struct efx_nic *efx); + void (*remove) (struct efx_nic *efx); int (*reconfigure) (struct efx_nic *efx); bool (*poll) (struct efx_nic *efx); void (*get_settings) (struct efx_nic *efx, diff --git a/drivers/net/sfc/qt202x_phy.c b/drivers/net/sfc/qt202x_phy.c index 3800fc7..7450e3a 100644 --- a/drivers/net/sfc/qt202x_phy.c +++ b/drivers/net/sfc/qt202x_phy.c @@ -137,6 +137,14 @@ static int qt202x_reset_phy(struct efx_nic *efx) static int qt202x_phy_probe(struct efx_nic *efx) { + struct qt202x_phy_data *phy_data; + + phy_data = kzalloc(sizeof(struct qt202x_phy_data), GFP_KERNEL); + if (!phy_data) + return -ENOMEM; + efx->phy_data = phy_data; + phy_data->phy_mode = efx->phy_mode; + efx->mdio.mmds = QT202X_REQUIRED_DEVS; efx->mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22; efx->loopback_modes = QT202X_LOOPBACKS | FALCON_XMAC_LOOPBACKS; @@ -145,7 +153,6 @@ static int qt202x_phy_probe(struct efx_nic *efx) static int qt202x_phy_init(struct efx_nic *efx) { - struct qt202x_phy_data *phy_data; u32 devid; int rc; @@ -155,17 +162,11 @@ static int qt202x_phy_init(struct efx_nic *efx) return rc; } - phy_data = kzalloc(sizeof(struct qt202x_phy_data), GFP_KERNEL); - if (!phy_data) - return -ENOMEM; - efx->phy_data = phy_data; - devid = efx_mdio_read_id(efx, MDIO_MMD_PHYXS); EFX_INFO(efx, "PHY ID reg %x (OUI %06x model %02x revision %x)\n", devid, efx_mdio_id_oui(devid), efx_mdio_id_model(devid), efx_mdio_id_rev(devid)); - phy_data->phy_mode = efx->phy_mode; return 0; } @@ -224,7 +225,7 @@ static void qt202x_phy_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecm mdio45_ethtool_gset(&efx->mdio, ecmd); } -static void qt202x_phy_fini(struct efx_nic *efx) +static void qt202x_phy_remove(struct efx_nic *efx) { /* Free the context block */ kfree(efx->phy_data); @@ -236,7 +237,8 @@ struct efx_phy_operations falcon_qt202x_phy_ops = { .init = qt202x_phy_init, .reconfigure = qt202x_phy_reconfigure, .poll = qt202x_phy_poll, - .fini = qt202x_phy_fini, + .fini = efx_port_dummy_op_void, + .remove = qt202x_phy_remove, .get_settings = qt202x_phy_get_settings, .set_settings = efx_mdio_set_settings, }; diff --git a/drivers/net/sfc/siena.c b/drivers/net/sfc/siena.c index de07a4f..f8c6771 100644 --- a/drivers/net/sfc/siena.c +++ b/drivers/net/sfc/siena.c @@ -133,6 +133,7 @@ static int siena_probe_port(struct efx_nic *efx) void siena_remove_port(struct efx_nic *efx) { + efx->phy_op->remove(efx); efx_nic_free_buffer(efx, &efx->stats_buffer); } diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c index ca11572..3009c29 100644 --- a/drivers/net/sfc/tenxpress.c +++ b/drivers/net/sfc/tenxpress.c @@ -202,10 +202,14 @@ static ssize_t set_phy_short_reach(struct device *dev, int rc; rtnl_lock(); - efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, MDIO_PMA_10GBT_TXPWR, - MDIO_PMA_10GBT_TXPWR_SHORT, - count != 0 && *buf != '0'); - rc = efx_reconfigure_port(efx); + if (efx->state != STATE_RUNNING) { + rc = -EBUSY; + } else { + efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, MDIO_PMA_10GBT_TXPWR, + MDIO_PMA_10GBT_TXPWR_SHORT, + count != 0 && *buf != '0'); + rc = efx_reconfigure_port(efx); + } rtnl_unlock(); return rc < 0 ? rc : (ssize_t)count; @@ -298,36 +302,62 @@ static int tenxpress_init(struct efx_nic *efx) return 0; } -static int sfx7101_phy_probe(struct efx_nic *efx) +static int tenxpress_phy_probe(struct efx_nic *efx) { - efx->mdio.mmds = TENXPRESS_REQUIRED_DEVS; - efx->mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22; - efx->loopback_modes = SFX7101_LOOPBACKS | FALCON_XMAC_LOOPBACKS; - return 0; -} + struct tenxpress_phy_data *phy_data; + int rc; + + /* Allocate phy private storage */ + phy_data = kzalloc(sizeof(*phy_data), GFP_KERNEL); + if (!phy_data) + return -ENOMEM; + efx->phy_data = phy_data; + phy_data->phy_mode = efx->phy_mode; + + /* Create any special files */ + if (efx->phy_type == PHY_TYPE_SFT9001B) { + rc = device_create_file(&efx->pci_dev->dev, + &dev_attr_phy_short_reach); + if (rc) + goto fail; + } + + if (efx->phy_type == PHY_TYPE_SFX7101) { + efx->mdio.mmds = TENXPRESS_REQUIRED_DEVS; + efx->mdio.mode_support = MDIO_SUPPORTS_C45; + + efx->loopback_modes = SFX7101_LOOPBACKS | FALCON_XMAC_LOOPBACKS; + + efx->link_advertising = (ADVERTISED_TP | ADVERTISED_Autoneg | + ADVERTISED_10000baseT_Full); + } else { + efx->mdio.mmds = TENXPRESS_REQUIRED_DEVS; + efx->mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22; + + efx->loopback_modes = (SFT9001_LOOPBACKS | + FALCON_XMAC_LOOPBACKS | + FALCON_GMAC_LOOPBACKS); + + efx->link_advertising = (ADVERTISED_TP | ADVERTISED_Autoneg | + ADVERTISED_10000baseT_Full | + ADVERTISED_1000baseT_Full | + ADVERTISED_100baseT_Full); + } -static int sft9001_phy_probe(struct efx_nic *efx) -{ - efx->mdio.mmds = TENXPRESS_REQUIRED_DEVS; - efx->mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22; - efx->loopback_modes = (SFT9001_LOOPBACKS | FALCON_XMAC_LOOPBACKS | - FALCON_GMAC_LOOPBACKS); return 0; + +fail: + kfree(efx->phy_data); + efx->phy_data = NULL; + return rc; } static int tenxpress_phy_init(struct efx_nic *efx) { - struct tenxpress_phy_data *phy_data; - int rc = 0; + int rc; falcon_board(efx)->type->init_phy(efx); - phy_data = kzalloc(sizeof(*phy_data), GFP_KERNEL); - if (!phy_data) - return -ENOMEM; - efx->phy_data = phy_data; - phy_data->phy_mode = efx->phy_mode; - if (!(efx->phy_mode & PHY_MODE_SPECIAL)) { if (efx->phy_type == PHY_TYPE_SFT9001A) { int reg; @@ -341,44 +371,27 @@ static int tenxpress_phy_init(struct efx_nic *efx) rc = efx_mdio_wait_reset_mmds(efx, TENXPRESS_REQUIRED_DEVS); if (rc < 0) - goto fail; + return rc; rc = efx_mdio_check_mmds(efx, TENXPRESS_REQUIRED_DEVS, 0); if (rc < 0) - goto fail; + return rc; } rc = tenxpress_init(efx); if (rc < 0) - goto fail; + return rc; - /* Initialise advertising flags */ - efx->link_advertising = (ADVERTISED_TP | ADVERTISED_Autoneg | - ADVERTISED_10000baseT_Full); - if (efx->phy_type != PHY_TYPE_SFX7101) - efx->link_advertising |= (ADVERTISED_1000baseT_Full | - ADVERTISED_100baseT_Full); + /* Reinitialise flow control settings */ efx_link_set_wanted_fc(efx, efx->wanted_fc); efx_mdio_an_reconfigure(efx); - if (efx->phy_type == PHY_TYPE_SFT9001B) { - rc = device_create_file(&efx->pci_dev->dev, - &dev_attr_phy_short_reach); - if (rc) - goto fail; - } - schedule_timeout_uninterruptible(HZ / 5); /* 200ms */ /* Let XGXS and SerDes out of reset */ falcon_reset_xaui(efx); return 0; - - fail: - kfree(efx->phy_data); - efx->phy_data = NULL; - return rc; } /* Perform a "special software reset" on the PHY. The caller is @@ -589,25 +602,26 @@ static bool tenxpress_phy_poll(struct efx_nic *efx) return !efx_link_state_equal(&efx->link_state, &old_state); } -static void tenxpress_phy_fini(struct efx_nic *efx) +static void sfx7101_phy_fini(struct efx_nic *efx) { int reg; + /* Power down the LNPGA */ + reg = (1 << PMA_PMD_LNPGA_POWERDOWN_LBN); + efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG, reg); + + /* Waiting here ensures that the board fini, which can turn + * off the power to the PHY, won't get run until the LNPGA + * powerdown has been given long enough to complete. */ + schedule_timeout_uninterruptible(LNPGA_PDOWN_WAIT); /* 200 ms */ +} + +static void tenxpress_phy_remove(struct efx_nic *efx) +{ if (efx->phy_type == PHY_TYPE_SFT9001B) device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_short_reach); - if (efx->phy_type == PHY_TYPE_SFX7101) { - /* Power down the LNPGA */ - reg = (1 << PMA_PMD_LNPGA_POWERDOWN_LBN); - efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG, reg); - - /* Waiting here ensures that the board fini, which can turn - * off the power to the PHY, won't get run until the LNPGA - * powerdown has been given long enough to complete. */ - schedule_timeout_uninterruptible(LNPGA_PDOWN_WAIT); /* 200 ms */ - } - kfree(efx->phy_data); efx->phy_data = NULL; } @@ -819,11 +833,12 @@ static void sft9001_set_npage_adv(struct efx_nic *efx, u32 advertising) } struct efx_phy_operations falcon_sfx7101_phy_ops = { - .probe = sfx7101_phy_probe, + .probe = tenxpress_phy_probe, .init = tenxpress_phy_init, .reconfigure = tenxpress_phy_reconfigure, .poll = tenxpress_phy_poll, - .fini = tenxpress_phy_fini, + .fini = sfx7101_phy_fini, + .remove = tenxpress_phy_remove, .get_settings = tenxpress_get_settings, .set_settings = tenxpress_set_settings, .set_npage_adv = sfx7101_set_npage_adv, @@ -832,11 +847,12 @@ struct efx_phy_operations falcon_sfx7101_phy_ops = { }; struct efx_phy_operations falcon_sft9001_phy_ops = { - .probe = sft9001_phy_probe, + .probe = tenxpress_phy_probe, .init = tenxpress_phy_init, .reconfigure = tenxpress_phy_reconfigure, .poll = tenxpress_phy_poll, - .fini = tenxpress_phy_fini, + .fini = efx_port_dummy_op_void, + .remove = tenxpress_phy_remove, .get_settings = tenxpress_get_settings, .set_settings = tenxpress_set_settings, .set_npage_adv = sft9001_set_npage_adv, -- cgit v0.10.2 From a355020af415947c7dee7e00a91360d11b6a9b47 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 23 Dec 2009 13:46:47 +0000 Subject: sfc: Include XGXS in XMAC link status check except in XGMII loopback The XGXS block may not get a link immediately in XGXS or XAUI loopback modes, so we still need to check it. Split falcon_xaui_link_ok() into falcon_xgxs_link_ok(), which checks only the Falcon XGXS block, and falcon_xmac_link_ok(), which checks one or both sides of the link as appropriate. Also rename falcon_check_xaui_link() to falcon_xmac_link_ok_retry(). Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller diff --git a/drivers/net/sfc/falcon_xmac.c b/drivers/net/sfc/falcon_xmac.c index 3da933f..8ccab2c 100644 --- a/drivers/net/sfc/falcon_xmac.c +++ b/drivers/net/sfc/falcon_xmac.c @@ -111,16 +111,12 @@ static void falcon_mask_status_intr(struct efx_nic *efx, bool enable) efx_writeo(efx, ®, FR_AB_XM_MGT_INT_MASK); } -/* Get status of XAUI link */ -static bool falcon_xaui_link_ok(struct efx_nic *efx) +static bool falcon_xgxs_link_ok(struct efx_nic *efx) { efx_oword_t reg; bool align_done, link_ok = false; int sync_status; - if (LOOPBACK_INTERNAL(efx)) - return true; - /* Read link status */ efx_reado(efx, ®, FR_AB_XX_CORE_STAT); @@ -135,14 +131,24 @@ static bool falcon_xaui_link_ok(struct efx_nic *efx) EFX_SET_OWORD_FIELD(reg, FRF_AB_XX_DISPERR, FFE_AB_XX_STAT_ALL_LANES); efx_writeo(efx, ®, FR_AB_XX_CORE_STAT); - /* If the link is up, then check the phy side of the xaui link */ - if (efx->link_state.up && link_ok) - if (efx->mdio.mmds & (1 << MDIO_MMD_PHYXS)) - link_ok = efx_mdio_phyxgxs_lane_sync(efx); - return link_ok; } +static bool falcon_xmac_link_ok(struct efx_nic *efx) +{ + /* + * Check MAC's XGXS link status except when using XGMII loopback + * which bypasses the XGXS block. + * If possible, check PHY's XGXS link status except when using + * MAC loopback. + */ + return (efx->loopback_mode == LOOPBACK_XGMII || + falcon_xgxs_link_ok(efx)) && + (!(efx->mdio.mmds & (1 << MDIO_MMD_PHYXS)) || + LOOPBACK_INTERNAL(efx) || + efx_mdio_phyxgxs_lane_sync(efx)); +} + void falcon_reconfigure_xmac_core(struct efx_nic *efx) { unsigned int max_frame_len; @@ -245,9 +251,9 @@ static void falcon_reconfigure_xgxs_core(struct efx_nic *efx) /* Try to bring up the Falcon side of the Falcon-Phy XAUI link */ -static bool falcon_check_xaui_link_up(struct efx_nic *efx, int tries) +static bool falcon_xmac_link_ok_retry(struct efx_nic *efx, int tries) { - bool mac_up = falcon_xaui_link_ok(efx); + bool mac_up = falcon_xmac_link_ok(efx); if (LOOPBACK_MASK(efx) & LOOPBACKS_EXTERNAL(efx) & LOOPBACKS_WS || efx_phy_mode_disabled(efx->phy_mode)) @@ -261,7 +267,7 @@ static bool falcon_check_xaui_link_up(struct efx_nic *efx, int tries) falcon_reset_xaui(efx); udelay(200); - mac_up = falcon_xaui_link_ok(efx); + mac_up = falcon_xmac_link_ok(efx); --tries; } @@ -272,7 +278,7 @@ static bool falcon_check_xaui_link_up(struct efx_nic *efx, int tries) static bool falcon_xmac_check_fault(struct efx_nic *efx) { - return !falcon_check_xaui_link_up(efx, 5); + return !falcon_xmac_link_ok_retry(efx, 5); } static int falcon_reconfigure_xmac(struct efx_nic *efx) @@ -284,7 +290,7 @@ static int falcon_reconfigure_xmac(struct efx_nic *efx) falcon_reconfigure_mac_wrapper(efx); - efx->xmac_poll_required = !falcon_check_xaui_link_up(efx, 5); + efx->xmac_poll_required = !falcon_xmac_link_ok_retry(efx, 5); falcon_mask_status_intr(efx, true); return 0; @@ -357,7 +363,7 @@ void falcon_poll_xmac(struct efx_nic *efx) return; falcon_mask_status_intr(efx, false); - efx->xmac_poll_required = !falcon_check_xaui_link_up(efx, 1); + efx->xmac_poll_required = !falcon_xmac_link_ok_retry(efx, 1); falcon_mask_status_intr(efx, true); } -- cgit v0.10.2 From a7ebd27a13757248863cd61e541af7fa9e7727ee Mon Sep 17 00:00:00 2001 From: Neil Turton Date: Wed, 23 Dec 2009 13:47:13 +0000 Subject: sfc: Fix DMA mapping cleanup in case of an error in TSO We need buffer->len to remain valid to work out the correct address to be unmapped. We therefore need to clear buffer->len after the unmap operation. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller diff --git a/drivers/net/sfc/tx.c b/drivers/net/sfc/tx.c index e669f94..a8b70ef 100644 --- a/drivers/net/sfc/tx.c +++ b/drivers/net/sfc/tx.c @@ -821,8 +821,6 @@ static void efx_enqueue_unwind(struct efx_tx_queue *tx_queue) EFX_TXQ_MASK]; efx_tsoh_free(tx_queue, buffer); EFX_BUG_ON_PARANOID(buffer->skb); - buffer->len = 0; - buffer->continuation = true; if (buffer->unmap_len) { unmap_addr = (buffer->dma_addr + buffer->len - buffer->unmap_len); @@ -836,6 +834,8 @@ static void efx_enqueue_unwind(struct efx_tx_queue *tx_queue) PCI_DMA_TODEVICE); buffer->unmap_len = 0; } + buffer->len = 0; + buffer->continuation = true; } } -- cgit v0.10.2 From 17d6aeafe9d8268612d91edc0102659edb382282 Mon Sep 17 00:00:00 2001 From: Matthew Slattery Date: Wed, 23 Dec 2009 13:47:37 +0000 Subject: sfc: QT2025C: Work around PHY bug If we see the PHY remaining stuck in a link-down state due to PCS being down while PMA/PMD is up, we briefly switch to PMA/PMD loopback and back, which usually unsticks it. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller diff --git a/drivers/net/sfc/qt202x_phy.c b/drivers/net/sfc/qt202x_phy.c index 7450e3a..e4590fb 100644 --- a/drivers/net/sfc/qt202x_phy.c +++ b/drivers/net/sfc/qt202x_phy.c @@ -52,11 +52,15 @@ void falcon_qt202x_set_led(struct efx_nic *p, int led, int mode) struct qt202x_phy_data { enum efx_phy_mode phy_mode; + bool bug17190_in_bad_state; + unsigned long bug17190_timer; }; #define QT2022C2_MAX_RESET_TIME 500 #define QT2022C2_RESET_WAIT 10 +#define BUG17190_INTERVAL (2 * HZ) + static int qt2025c_wait_reset(struct efx_nic *efx) { unsigned long timeout = jiffies + 10 * HZ; @@ -96,6 +100,39 @@ static int qt2025c_wait_reset(struct efx_nic *efx) return 0; } +static void qt2025c_bug17190_workaround(struct efx_nic *efx) +{ + struct qt202x_phy_data *phy_data = efx->phy_data; + + /* The PHY can get stuck in a state where it reports PHY_XS and PMA/PMD + * layers up, but PCS down (no block_lock). If we notice this state + * persisting for a couple of seconds, we switch PMA/PMD loopback + * briefly on and then off again, which is normally sufficient to + * recover it. + */ + if (efx->link_state.up || + !efx_mdio_links_ok(efx, MDIO_DEVS_PMAPMD | MDIO_DEVS_PHYXS)) { + phy_data->bug17190_in_bad_state = false; + return; + } + + if (!phy_data->bug17190_in_bad_state) { + phy_data->bug17190_in_bad_state = true; + phy_data->bug17190_timer = jiffies + BUG17190_INTERVAL; + return; + } + + if (time_after_eq(jiffies, phy_data->bug17190_timer)) { + EFX_LOG(efx, "bashing QT2025C PMA/PMD\n"); + efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, MDIO_CTRL1, + MDIO_PMA_CTRL1_LOOPBACK, true); + msleep(100); + efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, MDIO_CTRL1, + MDIO_PMA_CTRL1_LOOPBACK, false); + phy_data->bug17190_timer = jiffies + BUG17190_INTERVAL; + } +} + static int qt202x_reset_phy(struct efx_nic *efx) { int rc; @@ -144,6 +181,8 @@ static int qt202x_phy_probe(struct efx_nic *efx) return -ENOMEM; efx->phy_data = phy_data; phy_data->phy_mode = efx->phy_mode; + phy_data->bug17190_in_bad_state = false; + phy_data->bug17190_timer = 0; efx->mdio.mmds = QT202X_REQUIRED_DEVS; efx->mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22; @@ -184,6 +223,9 @@ static bool qt202x_phy_poll(struct efx_nic *efx) efx->link_state.fd = true; efx->link_state.fc = efx->wanted_fc; + if (efx->phy_type == PHY_TYPE_QT2025C) + qt2025c_bug17190_workaround(efx); + return efx->link_state.up != was_up; } -- cgit v0.10.2 From 0d83b2f64c330ee3892cb3117ac5d56e97185ecf Mon Sep 17 00:00:00 2001 From: Matthew Slattery Date: Wed, 23 Dec 2009 13:48:04 +0000 Subject: sfc: QT2025C: Switch into self-configure mode when not in loopback The PHY boots in a mode which is not necessarily optimal. This change switches it to self-configure mode (except when in loopback, which won't work in that mode if an SFP+ module is not present) by rebooting the PHY's microcontroller, and replicating the sequence of configuration writes from the boot EEPROM with the appropriate changes. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller diff --git a/drivers/net/sfc/qt202x_phy.c b/drivers/net/sfc/qt202x_phy.c index e4590fb..0cd6eed0 100644 --- a/drivers/net/sfc/qt202x_phy.c +++ b/drivers/net/sfc/qt202x_phy.c @@ -33,6 +33,9 @@ #define PCS_FW_HEARTBEAT_REG 0xd7ee #define PCS_FW_HEARTB_LBN 0 #define PCS_FW_HEARTB_WIDTH 8 +#define PCS_FW_PRODUCT_CODE_1 0xd7f0 +#define PCS_FW_VERSION_1 0xd7f3 +#define PCS_FW_BUILD_1 0xd7f6 #define PCS_UC8051_STATUS_REG 0xd7fd #define PCS_UC_STATUS_LBN 0 #define PCS_UC_STATUS_WIDTH 8 @@ -54,6 +57,7 @@ struct qt202x_phy_data { enum efx_phy_mode phy_mode; bool bug17190_in_bad_state; unsigned long bug17190_timer; + u32 firmware_ver; }; #define QT2022C2_MAX_RESET_TIME 500 @@ -100,6 +104,25 @@ static int qt2025c_wait_reset(struct efx_nic *efx) return 0; } +static void qt2025c_firmware_id(struct efx_nic *efx) +{ + struct qt202x_phy_data *phy_data = efx->phy_data; + u8 firmware_id[9]; + size_t i; + + for (i = 0; i < sizeof(firmware_id); i++) + firmware_id[i] = efx_mdio_read(efx, MDIO_MMD_PCS, + PCS_FW_PRODUCT_CODE_1 + i); + EFX_INFO(efx, "QT2025C firmware %xr%d v%d.%d.%d.%d [20%02d-%02d-%02d]\n", + (firmware_id[0] << 8) | firmware_id[1], firmware_id[2], + firmware_id[3] >> 4, firmware_id[3] & 0xf, + firmware_id[4], firmware_id[5], + firmware_id[6], firmware_id[7], firmware_id[8]); + phy_data->firmware_ver = ((firmware_id[3] & 0xf0) << 20) | + ((firmware_id[3] & 0x0f) << 16) | + (firmware_id[4] << 8) | firmware_id[5]; +} + static void qt2025c_bug17190_workaround(struct efx_nic *efx) { struct qt202x_phy_data *phy_data = efx->phy_data; @@ -133,6 +156,95 @@ static void qt2025c_bug17190_workaround(struct efx_nic *efx) } } +static int qt2025c_select_phy_mode(struct efx_nic *efx) +{ + struct qt202x_phy_data *phy_data = efx->phy_data; + struct falcon_board *board = falcon_board(efx); + int reg, rc, i; + uint16_t phy_op_mode; + + /* Only 2.0.1.0+ PHY firmware supports the more optimal SFP+ + * Self-Configure mode. Don't attempt any switching if we encounter + * older firmware. */ + if (phy_data->firmware_ver < 0x02000100) + return 0; + + /* In general we will get optimal behaviour in "SFP+ Self-Configure" + * mode; however, that powers down most of the PHY when no module is + * present, so we must use a different mode (any fixed mode will do) + * to be sure that loopbacks will work. */ + phy_op_mode = (efx->loopback_mode == LOOPBACK_NONE) ? 0x0038 : 0x0020; + + /* Only change mode if really necessary */ + reg = efx_mdio_read(efx, 1, 0xc319); + if ((reg & 0x0038) == phy_op_mode) + return 0; + EFX_LOG(efx, "Switching PHY to mode 0x%04x\n", phy_op_mode); + + /* This sequence replicates the register writes configured in the boot + * EEPROM (including the differences between board revisions), except + * that the operating mode is changed, and the PHY is prevented from + * unnecessarily reloading the main firmware image again. */ + efx_mdio_write(efx, 1, 0xc300, 0x0000); + /* (Note: this portion of the boot EEPROM sequence, which bit-bashes 9 + * STOPs onto the firmware/module I2C bus to reset it, varies across + * board revisions, as the bus is connected to different GPIO/LED + * outputs on the PHY.) */ + if (board->major == 0 && board->minor < 2) { + efx_mdio_write(efx, 1, 0xc303, 0x4498); + for (i = 0; i < 9; i++) { + efx_mdio_write(efx, 1, 0xc303, 0x4488); + efx_mdio_write(efx, 1, 0xc303, 0x4480); + efx_mdio_write(efx, 1, 0xc303, 0x4490); + efx_mdio_write(efx, 1, 0xc303, 0x4498); + } + } else { + efx_mdio_write(efx, 1, 0xc303, 0x0920); + efx_mdio_write(efx, 1, 0xd008, 0x0004); + for (i = 0; i < 9; i++) { + efx_mdio_write(efx, 1, 0xc303, 0x0900); + efx_mdio_write(efx, 1, 0xd008, 0x0005); + efx_mdio_write(efx, 1, 0xc303, 0x0920); + efx_mdio_write(efx, 1, 0xd008, 0x0004); + } + efx_mdio_write(efx, 1, 0xc303, 0x4900); + } + efx_mdio_write(efx, 1, 0xc303, 0x4900); + efx_mdio_write(efx, 1, 0xc302, 0x0004); + efx_mdio_write(efx, 1, 0xc316, 0x0013); + efx_mdio_write(efx, 1, 0xc318, 0x0054); + efx_mdio_write(efx, 1, 0xc319, phy_op_mode); + efx_mdio_write(efx, 1, 0xc31a, 0x0098); + efx_mdio_write(efx, 3, 0x0026, 0x0e00); + efx_mdio_write(efx, 3, 0x0027, 0x0013); + efx_mdio_write(efx, 3, 0x0028, 0xa528); + efx_mdio_write(efx, 1, 0xd006, 0x000a); + efx_mdio_write(efx, 1, 0xd007, 0x0009); + efx_mdio_write(efx, 1, 0xd008, 0x0004); + /* This additional write is not present in the boot EEPROM. It + * prevents the PHY's internal boot ROM doing another pointless (and + * slow) reload of the firmware image (the microcontroller's code + * memory is not affected by the microcontroller reset). */ + efx_mdio_write(efx, 1, 0xc317, 0x00ff); + efx_mdio_write(efx, 1, 0xc300, 0x0002); + msleep(20); + + /* Restart microcontroller execution from RAM */ + efx_mdio_write(efx, 3, 0xe854, 0x00c0); + efx_mdio_write(efx, 3, 0xe854, 0x0040); + msleep(50); + + /* Wait for the microcontroller to be ready again */ + rc = qt2025c_wait_reset(efx); + if (rc < 0) { + EFX_ERR(efx, "PHY microcontroller reset during mode switch " + "timed out\n"); + return rc; + } + + return 0; +} + static int qt202x_reset_phy(struct efx_nic *efx) { int rc; @@ -206,6 +318,9 @@ static int qt202x_phy_init(struct efx_nic *efx) devid, efx_mdio_id_oui(devid), efx_mdio_id_model(devid), efx_mdio_id_rev(devid)); + if (efx->phy_type == PHY_TYPE_QT2025C) + qt2025c_firmware_id(efx); + return 0; } @@ -234,6 +349,10 @@ static int qt202x_phy_reconfigure(struct efx_nic *efx) struct qt202x_phy_data *phy_data = efx->phy_data; if (efx->phy_type == PHY_TYPE_QT2025C) { + int rc = qt2025c_select_phy_mode(efx); + if (rc) + return rc; + /* There are several different register bits which can * disable TX (and save power) on direct-attach cables * or optical transceivers, varying somewhat between -- cgit v0.10.2 From 1a1284ef97ca79ba747d211b697e996a248a8555 Mon Sep 17 00:00:00 2001 From: Matthew Slattery Date: Wed, 23 Dec 2009 13:48:32 +0000 Subject: sfc: QT2025C: Work around PHY firmware initialisation bug The PHY's firmware very occasionally appears to lock up very early, but with the heartbeat update still running. Rebooting the microcontroller core seems to be sufficient to recover. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller diff --git a/drivers/net/sfc/qt202x_phy.c b/drivers/net/sfc/qt202x_phy.c index 0cd6eed0..326ffa4 100644 --- a/drivers/net/sfc/qt202x_phy.c +++ b/drivers/net/sfc/qt202x_phy.c @@ -63,11 +63,16 @@ struct qt202x_phy_data { #define QT2022C2_MAX_RESET_TIME 500 #define QT2022C2_RESET_WAIT 10 +#define QT2025C_MAX_HEARTB_TIME (5 * HZ) +#define QT2025C_HEARTB_WAIT 100 +#define QT2025C_MAX_FWSTART_TIME (25 * HZ / 10) +#define QT2025C_FWSTART_WAIT 100 + #define BUG17190_INTERVAL (2 * HZ) -static int qt2025c_wait_reset(struct efx_nic *efx) +static int qt2025c_wait_heartbeat(struct efx_nic *efx) { - unsigned long timeout = jiffies + 10 * HZ; + unsigned long timeout = jiffies + QT2025C_MAX_HEARTB_TIME; int reg, old_counter = 0; /* Wait for firmware heartbeat to start */ @@ -84,9 +89,17 @@ static int qt2025c_wait_reset(struct efx_nic *efx) break; if (time_after(jiffies, timeout)) return -ETIMEDOUT; - msleep(10); + msleep(QT2025C_HEARTB_WAIT); } + return 0; +} + +static int qt2025c_wait_fw_status_good(struct efx_nic *efx) +{ + unsigned long timeout = jiffies + QT2025C_MAX_FWSTART_TIME; + int reg; + /* Wait for firmware status to look good */ for (;;) { reg = efx_mdio_read(efx, MDIO_MMD_PCS, PCS_UC8051_STATUS_REG); @@ -98,12 +111,44 @@ static int qt2025c_wait_reset(struct efx_nic *efx) break; if (time_after(jiffies, timeout)) return -ETIMEDOUT; - msleep(100); + msleep(QT2025C_FWSTART_WAIT); } return 0; } +static void qt2025c_restart_firmware(struct efx_nic *efx) +{ + /* Restart microcontroller execution of firmware from RAM */ + efx_mdio_write(efx, 3, 0xe854, 0x00c0); + efx_mdio_write(efx, 3, 0xe854, 0x0040); + msleep(50); +} + +static int qt2025c_wait_reset(struct efx_nic *efx) +{ + int rc; + + rc = qt2025c_wait_heartbeat(efx); + if (rc != 0) + return rc; + + rc = qt2025c_wait_fw_status_good(efx); + if (rc == -ETIMEDOUT) { + /* Bug 17689: occasionally heartbeat starts but firmware status + * code never progresses beyond 0x00. Try again, once, after + * restarting execution of the firmware image. */ + EFX_LOG(efx, "bashing QT2025C microcontroller\n"); + qt2025c_restart_firmware(efx); + rc = qt2025c_wait_heartbeat(efx); + if (rc != 0) + return rc; + rc = qt2025c_wait_fw_status_good(efx); + } + + return rc; +} + static void qt2025c_firmware_id(struct efx_nic *efx) { struct qt202x_phy_data *phy_data = efx->phy_data; @@ -229,10 +274,8 @@ static int qt2025c_select_phy_mode(struct efx_nic *efx) efx_mdio_write(efx, 1, 0xc300, 0x0002); msleep(20); - /* Restart microcontroller execution from RAM */ - efx_mdio_write(efx, 3, 0xe854, 0x00c0); - efx_mdio_write(efx, 3, 0xe854, 0x0040); - msleep(50); + /* Restart microcontroller execution of firmware from RAM */ + qt2025c_restart_firmware(efx); /* Wait for the microcontroller to be ready again */ rc = qt2025c_wait_reset(efx); -- cgit v0.10.2 From 50d6ec552bdd4d9227fe9ed2bac819eced3170ac Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 23 Dec 2009 13:48:42 +0000 Subject: sfc: QT2025C: Add error message for suspected bad SFP+ cables Some cables have EEPROMs that conflict with the PHY's on-board EEPROM so it cannot load firmware. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller diff --git a/drivers/net/sfc/qt202x_phy.c b/drivers/net/sfc/qt202x_phy.c index 326ffa4..ff8f0a4 100644 --- a/drivers/net/sfc/qt202x_phy.c +++ b/drivers/net/sfc/qt202x_phy.c @@ -87,8 +87,14 @@ static int qt2025c_wait_heartbeat(struct efx_nic *efx) old_counter = counter; else if (counter != old_counter) break; - if (time_after(jiffies, timeout)) + if (time_after(jiffies, timeout)) { + /* Some cables have EEPROMs that conflict with the + * PHY's on-board EEPROM so it cannot load firmware */ + EFX_ERR(efx, "If an SFP+ direct attach cable is" + " connected, please check that it complies" + " with the SFP+ specification\n"); return -ETIMEDOUT; + } msleep(QT2025C_HEARTB_WAIT); } -- cgit v0.10.2 From 286d47ba90315a871f77351f7f61b7e4a96476a9 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 23 Dec 2009 13:49:13 +0000 Subject: sfc: Disable TX descriptor prefetch watchdog This hardware watchdog can misfire, so it does more harm than good. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller diff --git a/drivers/net/sfc/nic.c b/drivers/net/sfc/nic.c index a577be2..db44224 100644 --- a/drivers/net/sfc/nic.c +++ b/drivers/net/sfc/nic.c @@ -1576,6 +1576,8 @@ void efx_nic_init_common(struct efx_nic *efx) EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_SOFT_EVT_EN, 1); /* Prefetch threshold 2 => fetch when descriptor cache half empty */ EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_PREF_THRESHOLD, 2); + /* Disable hardware watchdog which can misfire */ + EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_PREF_WD_TMR, 0x3fffff); /* Squash TX of packets of 16 bytes or less */ if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) EFX_SET_OWORD_FIELD(temp, FRF_BZ_TX_FLUSH_MIN_LEN_EN, 1); -- cgit v0.10.2 From d5a664a311c1957a75bec1808cae0f10d606c378 Mon Sep 17 00:00:00 2001 From: Mattia Dongili Date: Thu, 17 Dec 2009 00:08:35 +0900 Subject: sony-laptop: rfkill support for newer models Vaio Type X and possibly other new models use F135 as the radio frequency controlling function attached to the SNC device. In the indexed table this corresponds to 0x0135 (surpise!). Signed-off-by: Mattia Dongili Signed-off-by: Len Brown diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index 9710f70..1144686 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c @@ -131,6 +131,7 @@ enum sony_nc_rfkill { N_SONY_RFKILL, }; +static int sony_rfkill_handle; static struct rfkill *sony_rfkill_devices[N_SONY_RFKILL]; static int sony_rfkill_address[N_SONY_RFKILL] = {0x300, 0x500, 0x700, 0x900}; static void sony_nc_rfkill_update(void); @@ -965,7 +966,7 @@ static void sony_nc_notify(struct acpi_device *device, u32 event) else sony_laptop_report_input_event(ev); } - } else if (sony_find_snc_handle(0x124) == ev) { + } else if (sony_find_snc_handle(sony_rfkill_handle) == ev) { sony_nc_rfkill_update(); return; } @@ -1071,7 +1072,7 @@ static int sony_nc_rfkill_set(void *data, bool blocked) if (!blocked) argument |= 0xff0000; - return sony_call_snc_handle(0x124, argument, &result); + return sony_call_snc_handle(sony_rfkill_handle, argument, &result); } static const struct rfkill_ops sony_rfkill_ops = { @@ -1114,7 +1115,7 @@ static int sony_nc_setup_rfkill(struct acpi_device *device, if (!rfk) return -ENOMEM; - sony_call_snc_handle(0x124, 0x200, &result); + sony_call_snc_handle(sony_rfkill_handle, 0x200, &result); hwblock = !(result & 0x1); rfkill_set_hw_state(rfk, hwblock); @@ -1133,7 +1134,7 @@ static void sony_nc_rfkill_update() int result; bool hwblock; - sony_call_snc_handle(0x124, 0x200, &result); + sony_call_snc_handle(sony_rfkill_handle, 0x200, &result); hwblock = !(result & 0x1); for (i = 0; i < N_SONY_RFKILL; i++) { @@ -1149,7 +1150,7 @@ static void sony_nc_rfkill_update() continue; } - sony_call_snc_handle(0x124, argument, &result); + sony_call_snc_handle(sony_rfkill_handle, argument, &result); rfkill_set_states(sony_rfkill_devices[i], !(result & 0xf), false); } @@ -1159,10 +1160,15 @@ static int sony_nc_rfkill_setup(struct acpi_device *device) { int result, ret; - if (sony_find_snc_handle(0x124) == -1) - return -1; + if (sony_find_snc_handle(0x124) == -1) { + if (sony_find_snc_handle(0x135) == -1) + return -1; + else + sony_rfkill_handle = 0x135; + } else + sony_rfkill_handle = 0x124; - ret = sony_call_snc_handle(0x124, 0xb00, &result); + ret = sony_call_snc_handle(sony_rfkill_handle, 0xb00, &result); if (ret) { printk(KERN_INFO DRV_PFX "Unable to enumerate rfkill devices: %x\n", ret); -- cgit v0.10.2 From 528809c35faebd8c50a4722c85ab8610725875cc Mon Sep 17 00:00:00 2001 From: Mattia Dongili Date: Thu, 17 Dec 2009 00:08:36 +0900 Subject: sony-laptop: enumerate rfkill devices using SN06 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SN06 makes sure we get back a longer buffer which seems to be necessary going forward as the SNC devices describes more and more devices (or features more precisely). Moreover SN06 should be called with only the descriptor offset to make sure we hit the rfkill controlling function (F124 or F135) with a 0 argument to get a full list of features. Signed-off-by: Mattia Dongili Tested-by: Miguel Rodríguez Pérez Signed-off-by: Len Brown diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index 1144686..49f3fe0 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c @@ -1156,35 +1156,73 @@ static void sony_nc_rfkill_update() } } -static int sony_nc_rfkill_setup(struct acpi_device *device) +static void sony_nc_rfkill_setup(struct acpi_device *device) { - int result, ret; + int offset; + u8 dev_code, i; + acpi_status status; + struct acpi_object_list params; + union acpi_object in_obj; + union acpi_object *device_enum; + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; - if (sony_find_snc_handle(0x124) == -1) { - if (sony_find_snc_handle(0x135) == -1) - return -1; + offset = sony_find_snc_handle(0x124); + if (offset == -1) { + offset = sony_find_snc_handle(0x135); + if (offset == -1) + return; else sony_rfkill_handle = 0x135; } else sony_rfkill_handle = 0x124; + dprintk("Found rkfill handle: 0x%.4x\n", sony_rfkill_handle); - ret = sony_call_snc_handle(sony_rfkill_handle, 0xb00, &result); - if (ret) { - printk(KERN_INFO DRV_PFX - "Unable to enumerate rfkill devices: %x\n", ret); - return ret; + /* need to read the whole buffer returned by the acpi call to SN06 + * here otherwise we may miss some features + */ + params.count = 1; + params.pointer = &in_obj; + in_obj.type = ACPI_TYPE_INTEGER; + in_obj.integer.value = offset; + status = acpi_evaluate_object(sony_nc_acpi_handle, "SN06", ¶ms, + &buffer); + if (ACPI_FAILURE(status)) { + dprintk("Radio device enumeration failed\n"); + return; } - if (result & 0x1) - sony_nc_setup_rfkill(device, SONY_WIFI); - if (result & 0x2) - sony_nc_setup_rfkill(device, SONY_BLUETOOTH); - if (result & 0x1c) - sony_nc_setup_rfkill(device, SONY_WWAN); - if (result & 0x20) - sony_nc_setup_rfkill(device, SONY_WIMAX); + device_enum = (union acpi_object *) buffer.pointer; + if (!device_enum || device_enum->type != ACPI_TYPE_BUFFER) { + printk(KERN_ERR "Invalid SN06 return object 0x%.2x\n", + device_enum->type); + goto out_no_enum; + } - return 0; + /* the buffer is filled with magic numbers describing the devices + * available, 0xff terminates the enumeration + */ + while ((dev_code = *(device_enum->buffer.pointer + i)) != 0xff && + i < device_enum->buffer.length) { + i++; + dprintk("Radio devices, looking at 0x%.2x\n", dev_code); + + if (dev_code == 0 && !sony_rfkill_devices[SONY_WIFI]) + sony_nc_setup_rfkill(device, SONY_WIFI); + + if (dev_code == 0x10 && !sony_rfkill_devices[SONY_BLUETOOTH]) + sony_nc_setup_rfkill(device, SONY_BLUETOOTH); + + if ((0xf0 & dev_code) == 0x20 && + !sony_rfkill_devices[SONY_WWAN]) + sony_nc_setup_rfkill(device, SONY_WWAN); + + if (dev_code == 0x30 && !sony_rfkill_devices[SONY_WIMAX]) + sony_nc_setup_rfkill(device, SONY_WIMAX); + } + +out_no_enum: + kfree(buffer.pointer); + return; } static int sony_nc_add(struct acpi_device *device) -- cgit v0.10.2 From d68caec645b4b92f6a81985265b024bc94bce41f Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Wed, 23 Dec 2009 13:20:47 +0000 Subject: igb: do not force pcs link when in KX mode We were forcing the PCS link up in error when we are in KX mode. We should only be disabling autoneg, not forcing the link up. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c index e8e9e91..c505b50 100644 --- a/drivers/net/igb/e1000_82575.c +++ b/drivers/net/igb/e1000_82575.c @@ -1096,9 +1096,7 @@ static s32 igb_setup_serdes_link_82575(struct e1000_hw *hw) hw_dbg("Configuring Autoneg:PCS_LCTL=0x%08X\n", reg); } else { /* Set PCS register for forced link */ - reg |= E1000_PCS_LCTL_FSD | /* Force Speed */ - E1000_PCS_LCTL_FORCE_LINK | /* Force Link */ - E1000_PCS_LCTL_FLV_LINK_UP; /* Force link value up */ + reg |= E1000_PCS_LCTL_FSD; /* Force Speed */ hw_dbg("Configuring Forced Link:PCS_LCTL=0x%08X\n", reg); } -- cgit v0.10.2 From 8c6af2995c14e71558c312b86955ae32272a03d8 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Wed, 23 Dec 2009 13:21:07 +0000 Subject: igb: do not force retry count to 1 on 82580 phy This change resolves an issue seen in some configurations where the link may drop to 100Mb/s even though the link itself supports 1000Mb/s. The issue was root caused to the fact that we were only trying the link once. Now instead we will try up to 5 attempts on a faulty cable before downshifting to 100Mb/s. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller diff --git a/drivers/net/igb/e1000_phy.c b/drivers/net/igb/e1000_phy.c index 5c9d73e..3670a66 100644 --- a/drivers/net/igb/e1000_phy.c +++ b/drivers/net/igb/e1000_phy.c @@ -457,15 +457,6 @@ s32 igb_copper_link_setup_82580(struct e1000_hw *hw) phy_data |= I82580_CFG_ENABLE_DOWNSHIFT; ret_val = phy->ops.write_reg(hw, I82580_CFG_REG, phy_data); - if (ret_val) - goto out; - - /* Set number of link attempts before downshift */ - ret_val = phy->ops.read_reg(hw, I82580_CTRL_REG, &phy_data); - if (ret_val) - goto out; - phy_data &= ~I82580_CTRL_DOWNSHIFT_MASK; - ret_val = phy->ops.write_reg(hw, I82580_CTRL_REG, phy_data); out: return ret_val; -- cgit v0.10.2 From d405ea3ef2499eb46834418a643973c884ff7f30 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Wed, 23 Dec 2009 13:21:27 +0000 Subject: igb: correctly offset 82575 flow control watermarks by 16 bytes The watermark values for the 82575 were not being set correctly. As a result the high and low watermark values were set to the same value which can lead to excess xon/xoff packets being generated. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 78963a0..933c64f 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -1306,13 +1306,8 @@ void igb_reset(struct igb_adapter *adapter) hwm = min(((pba << 10) * 9 / 10), ((pba << 10) - 2 * adapter->max_frame_size)); - if (mac->type < e1000_82576) { - fc->high_water = hwm & 0xFFF8; /* 8-byte granularity */ - fc->low_water = fc->high_water - 8; - } else { - fc->high_water = hwm & 0xFFF0; /* 16-byte granularity */ - fc->low_water = fc->high_water - 16; - } + fc->high_water = hwm & 0xFFF0; /* 16-byte granularity */ + fc->low_water = fc->high_water - 16; fc->pause_time = 0xFFFF; fc->send_xon = 1; fc->current_mode = fc->requested_mode; -- cgit v0.10.2 From 58b8b042509f53955ba660a4245e221c5405f124 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Wed, 23 Dec 2009 13:21:46 +0000 Subject: igb: check both function bits in status register in wol exception The ethtool code for enabling Wake on Lan was not correctly checking the status register bits so as a result ports 0 and 2 were both being allowed to set WOL to enabled even though it is only supported on the first port for our adapters. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c index ac9d527..f771a6c 100644 --- a/drivers/net/igb/igb_ethtool.c +++ b/drivers/net/igb/igb_ethtool.c @@ -1795,7 +1795,7 @@ static int igb_wol_exclusion(struct igb_adapter *adapter, /* dual port cards only support WoL on port A from now on * unless it was enabled in the eeprom for port B * so exclude FUNC_1 ports from having WoL enabled */ - if (rd32(E1000_STATUS) & E1000_STATUS_FUNC_1 && + if ((rd32(E1000_STATUS) & E1000_STATUS_FUNC_MASK) && !adapter->eeprom_wol) { wol->supported = 0; break; -- cgit v0.10.2 From 1242b6f31e1d0688f1eb1dc78036dbd975bd6140 Mon Sep 17 00:00:00 2001 From: "Williams, Mitch A" Date: Wed, 23 Dec 2009 13:22:43 +0000 Subject: igbvf: Make igbvf error message more informative Signed-off-by: Mitch Williams Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c index e9dd95f..0dbd032 100644 --- a/drivers/net/igbvf/netdev.c +++ b/drivers/net/igbvf/netdev.c @@ -2763,7 +2763,8 @@ static int __devinit igbvf_probe(struct pci_dev *pdev, err = hw->mac.ops.reset_hw(hw); if (err) { dev_info(&pdev->dev, - "PF still in reset state, assigning new address\n"); + "PF still in reset state, assigning new address." + " Is the PF interface up?\n"); random_ether_addr(hw->mac.addr); } else { err = hw->mac.ops.read_mac_addr(hw); -- cgit v0.10.2 From d7b901418250f00eaaa18f9135d09ba61b72a5bc Mon Sep 17 00:00:00 2001 From: Sarveshwar Bandi Date: Wed, 23 Dec 2009 04:40:36 +0000 Subject: be2net: Bug fix to avoid soft lockup in loopback test. This change ensures that loopback test command gives up after 4 seconds when the hardware is not responsive. This could happen if the ports are connected properly in loopback mode. Signed-off-by: Sarveshwar Bandi Signed-off-by: David S. Miller diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index 1b68bd9..a27fdb3 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -1501,6 +1501,7 @@ int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num, be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_LOWLEVEL, OPCODE_LOWLEVEL_LOOPBACK_TEST, sizeof(*req)); + req->hdr.timeout = 4; req->pattern = cpu_to_le64(pattern); req->src_port = cpu_to_le32(port_num); -- cgit v0.10.2 From fced9999ed7f6975fbb2350a73048918ba60a773 Mon Sep 17 00:00:00 2001 From: Sarveshwar Bandi Date: Wed, 23 Dec 2009 04:41:44 +0000 Subject: be2net: Bug fix to config NIC appropriately before loopback test NIC controller has to be set to an appropriate mode before doing a loopback test. Test will fail otherwise. Signed-off-by: Sarveshwar Bandi Signed-off-by: David S. Miller diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index a27fdb3..102ade1 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -1479,6 +1479,41 @@ err: return status; } +int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num, + u8 loopback_type, u8 enable) +{ + struct be_mcc_wrb *wrb; + struct be_cmd_req_set_lmode *req; + int status; + + spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + if (!wrb) { + status = -EBUSY; + goto err; + } + + req = embedded_payload(wrb); + + be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0, + OPCODE_LOWLEVEL_SET_LOOPBACK_MODE); + + be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_LOWLEVEL, + OPCODE_LOWLEVEL_SET_LOOPBACK_MODE, + sizeof(*req)); + + req->src_port = port_num; + req->dest_port = port_num; + req->loopback_type = loopback_type; + req->loopback_state = enable; + + status = be_mcc_notify_wait(adapter); +err: + spin_unlock_bh(&adapter->mcc_lock); + return status; +} + int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num, u32 loopback_type, u32 pkt_size, u32 num_pkts, u64 pattern) { diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h index 92b87ef..c002b83 100644 --- a/drivers/net/benet/be_cmds.h +++ b/drivers/net/benet/be_cmds.h @@ -155,6 +155,7 @@ struct be_mcc_mailbox { #define OPCODE_LOWLEVEL_HOST_DDR_DMA 17 #define OPCODE_LOWLEVEL_LOOPBACK_TEST 18 +#define OPCODE_LOWLEVEL_SET_LOOPBACK_MODE 19 struct be_cmd_req_hdr { u8 opcode; /* dword 0 */ @@ -821,6 +822,19 @@ struct be_cmd_resp_loopback_test { u32 ticks_compl; }; +struct be_cmd_req_set_lmode { + struct be_cmd_req_hdr hdr; + u8 src_port; + u8 dest_port; + u8 loopback_type; + u8 loopback_state; +}; + +struct be_cmd_resp_set_lmode { + struct be_cmd_resp_hdr resp_hdr; + u8 rsvd0[4]; +}; + /********************** DDR DMA test *********************/ struct be_cmd_req_ddrdma_test { struct be_cmd_req_hdr hdr; @@ -912,3 +926,5 @@ extern int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num, u32 num_pkts, u64 pattern); extern int be_cmd_ddr_dma_test(struct be_adapter *adapter, u64 pattern, u32 byte_cnt, struct be_dma_mem *cmd); +extern int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num, + u8 loopback_type, u8 enable); diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c index 298b92c..da66d15 100644 --- a/drivers/net/benet/be_ethtool.c +++ b/drivers/net/benet/be_ethtool.c @@ -118,6 +118,7 @@ static const char et_self_tests[][ETH_GSTRING_LEN] = { #define BE_MAC_LOOPBACK 0x0 #define BE_PHY_LOOPBACK 0x1 #define BE_ONE_PORT_EXT_LOOPBACK 0x2 +#define BE_NO_LOOPBACK 0xff static void be_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo) @@ -489,6 +490,19 @@ err: return ret; } +static u64 be_loopback_test(struct be_adapter *adapter, u8 loopback_type, + u64 *status) +{ + be_cmd_set_loopback(adapter, adapter->port_num, + loopback_type, 1); + *status = be_cmd_loopback_test(adapter, adapter->port_num, + loopback_type, 1500, + 2, 0xabc); + be_cmd_set_loopback(adapter, adapter->port_num, + BE_NO_LOOPBACK, 1); + return *status; +} + static void be_self_test(struct net_device *netdev, struct ethtool_test *test, u64 *data) { @@ -497,23 +511,18 @@ be_self_test(struct net_device *netdev, struct ethtool_test *test, u64 *data) memset(data, 0, sizeof(u64) * ETHTOOL_TESTS_NUM); if (test->flags & ETH_TEST_FL_OFFLINE) { - data[0] = be_cmd_loopback_test(adapter, adapter->port_num, - BE_MAC_LOOPBACK, 1500, - 2, 0xabc); - if (data[0] != 0) + if (be_loopback_test(adapter, BE_MAC_LOOPBACK, + &data[0]) != 0) { test->flags |= ETH_TEST_FL_FAILED; - - data[1] = be_cmd_loopback_test(adapter, adapter->port_num, - BE_PHY_LOOPBACK, 1500, - 2, 0xabc); - if (data[1] != 0) + } + if (be_loopback_test(adapter, BE_PHY_LOOPBACK, + &data[1]) != 0) { test->flags |= ETH_TEST_FL_FAILED; - - data[2] = be_cmd_loopback_test(adapter, adapter->port_num, - BE_ONE_PORT_EXT_LOOPBACK, - 1500, 2, 0xabc); - if (data[2] != 0) + } + if (be_loopback_test(adapter, BE_ONE_PORT_EXT_LOOPBACK, + &data[2]) != 0) { test->flags |= ETH_TEST_FL_FAILED; + } data[3] = be_test_ddr_dma(adapter); if (data[3] != 0) -- cgit v0.10.2 From 16c02145902d8597841a25e8443cfb082898a2d7 Mon Sep 17 00:00:00 2001 From: Sarveshwar Bandi Date: Wed, 23 Dec 2009 04:42:51 +0000 Subject: be2net: Bug fix to return correct values in ethtool get_settings. Changes to return correct values for transceiver and supported in ethtool get_settings function. Signed-off-by: Sarveshwar Bandi Signed-off-by: David S. Miller diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index 9e56014..9fd8e5e 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -275,6 +275,7 @@ struct be_adapter { u32 tx_fc; /* Tx flow control */ int link_speed; u8 port_type; + u8 transceiver; }; extern const struct ethtool_ops be_ethtool_ops; diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c index da66d15..5d001c4 100644 --- a/drivers/net/benet/be_ethtool.c +++ b/drivers/net/benet/be_ethtool.c @@ -340,28 +340,50 @@ static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) status = be_cmd_read_port_type(adapter, adapter->port_num, &connector); - switch (connector) { - case 7: - ecmd->port = PORT_FIBRE; - break; - default: - ecmd->port = PORT_TP; - break; + if (!status) { + switch (connector) { + case 7: + ecmd->port = PORT_FIBRE; + ecmd->transceiver = XCVR_EXTERNAL; + break; + case 0: + ecmd->port = PORT_TP; + ecmd->transceiver = XCVR_EXTERNAL; + break; + default: + ecmd->port = PORT_TP; + ecmd->transceiver = XCVR_INTERNAL; + break; + } + } else { + ecmd->port = PORT_AUI; + ecmd->transceiver = XCVR_INTERNAL; } /* Save for future use */ adapter->link_speed = ecmd->speed; adapter->port_type = ecmd->port; + adapter->transceiver = ecmd->transceiver; } else { ecmd->speed = adapter->link_speed; ecmd->port = adapter->port_type; + ecmd->transceiver = adapter->transceiver; } ecmd->duplex = DUPLEX_FULL; ecmd->autoneg = AUTONEG_DISABLE; - ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_TP); ecmd->phy_address = adapter->port_num; - ecmd->transceiver = XCVR_INTERNAL; + switch (ecmd->port) { + case PORT_FIBRE: + ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE); + break; + case PORT_TP: + ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_TP); + break; + case PORT_AUI: + ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_AUI); + break; + } return 0; } -- cgit v0.10.2 From 2370b5ed03030d554adb345778d5edecab7a510c Mon Sep 17 00:00:00 2001 From: "Carlos R. Mafra" Date: Tue, 22 Dec 2009 13:45:39 -0800 Subject: ACPI: do not select ACPI_DOCK from ATA_ACPI In March 2008 commit 0ac4a3c2fbbcadc3e96e4dc47d4ae802d66e6f67 ("ACPI: fix ATA_ACPI build") made CONFIG_ACPI_DOCK be selected by CONFIG_ATA_ACPI because of a build error when CONFIG_ATA_ACPI=y and CONFIG_ACPI_DOCK=m. However, in September 2008 commit 898b054f3eec5921320ae8614b5bdd7b07ea5b43 ("dock: make dock driver not a module") removed the possibility of having CONFIG_ACPI_DOCK=m and therefore there is no need for selecting it when CONFIG_ATA_ACPI=y. This makes the kernel ~5 Kb smaller for people who don't have a dock by allowing them to not have ACPI_DOCK compiled-in because of ATA_ACPI=y. Signed-off-by: Carlos R. Mafra Cc: Shaohua Li Signed-off-by: Andrew Morton Signed-off-by: Len Brown diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 85844d0..56c6374 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -40,7 +40,6 @@ config ATA_VERBOSE_ERROR config ATA_ACPI bool "ATA ACPI Support" depends on ACPI && PCI - select ACPI_DOCK default y help This option adds support for ATA-related ACPI objects. -- cgit v0.10.2 From ff93be5dea548f16dcfe7b73ce5df7666efba92d Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Mon, 21 Dec 2009 16:20:01 -0800 Subject: asus_acpi: convert to seq_file Signed-off-by: Alexey Dobriyan Cc: Corentin Chary Cc: Karol Kozimor Signed-off-by: Andrew Morton Signed-off-by: Len Brown diff --git a/drivers/platform/x86/asus_acpi.c b/drivers/platform/x86/asus_acpi.c index 0c9c531..c1d2aee 100644 --- a/drivers/platform/x86/asus_acpi.c +++ b/drivers/platform/x86/asus_acpi.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -513,26 +514,12 @@ static int read_acpi_int(acpi_handle handle, const char *method, int *val) return (status == AE_OK) && (out_obj.type == ACPI_TYPE_INTEGER); } -/* - * We write our info in page, we begin at offset off and cannot write more - * than count bytes. We set eof to 1 if we handle those 2 values. We return the - * number of bytes written in page - */ -static int -proc_read_info(char *page, char **start, off_t off, int count, int *eof, - void *data) +static int asus_info_proc_show(struct seq_file *m, void *v) { - int len = 0; int temp; - char buf[16]; /* enough for all info */ - /* - * We use the easy way, we don't care of off and count, - * so we don't set eof to 1 - */ - len += sprintf(page, ACPI_HOTK_NAME " " ASUS_ACPI_VERSION "\n"); - len += sprintf(page + len, "Model reference : %s\n", - hotk->methods->name); + seq_printf(m, ACPI_HOTK_NAME " " ASUS_ACPI_VERSION "\n"); + seq_printf(m, "Model reference : %s\n", hotk->methods->name); /* * The SFUN method probably allows the original driver to get the list * of features supported by a given model. For now, 0x0100 or 0x0800 @@ -540,8 +527,7 @@ proc_read_info(char *page, char **start, off_t off, int count, int *eof, * The significance of others is yet to be found. */ if (read_acpi_int(hotk->handle, "SFUN", &temp)) - len += - sprintf(page + len, "SFUN value : 0x%04x\n", temp); + seq_printf(m, "SFUN value : 0x%04x\n", temp); /* * Another value for userspace: the ASYM method returns 0x02 for * battery low and 0x04 for battery critical, its readings tend to be @@ -550,30 +536,34 @@ proc_read_info(char *page, char **start, off_t off, int count, int *eof, * silently ignored. */ if (read_acpi_int(hotk->handle, "ASYM", &temp)) - len += - sprintf(page + len, "ASYM value : 0x%04x\n", temp); + seq_printf(m, "ASYM value : 0x%04x\n", temp); if (asus_info) { - snprintf(buf, 16, "%d", asus_info->length); - len += sprintf(page + len, "DSDT length : %s\n", buf); - snprintf(buf, 16, "%d", asus_info->checksum); - len += sprintf(page + len, "DSDT checksum : %s\n", buf); - snprintf(buf, 16, "%d", asus_info->revision); - len += sprintf(page + len, "DSDT revision : %s\n", buf); - snprintf(buf, 7, "%s", asus_info->oem_id); - len += sprintf(page + len, "OEM id : %s\n", buf); - snprintf(buf, 9, "%s", asus_info->oem_table_id); - len += sprintf(page + len, "OEM table id : %s\n", buf); - snprintf(buf, 16, "%x", asus_info->oem_revision); - len += sprintf(page + len, "OEM revision : 0x%s\n", buf); - snprintf(buf, 5, "%s", asus_info->asl_compiler_id); - len += sprintf(page + len, "ASL comp vendor id : %s\n", buf); - snprintf(buf, 16, "%x", asus_info->asl_compiler_revision); - len += sprintf(page + len, "ASL comp revision : 0x%s\n", buf); + seq_printf(m, "DSDT length : %d\n", asus_info->length); + seq_printf(m, "DSDT checksum : %d\n", asus_info->checksum); + seq_printf(m, "DSDT revision : %d\n", asus_info->revision); + seq_printf(m, "OEM id : %.*s\n", ACPI_OEM_ID_SIZE, asus_info->oem_id); + seq_printf(m, "OEM table id : %.*s\n", ACPI_OEM_TABLE_ID_SIZE, asus_info->oem_table_id); + seq_printf(m, "OEM revision : 0x%x\n", asus_info->oem_revision); + seq_printf(m, "ASL comp vendor id : %.*s\n", ACPI_NAME_SIZE, asus_info->asl_compiler_id); + seq_printf(m, "ASL comp revision : 0x%x\n", asus_info->asl_compiler_revision); } - return len; + return 0; +} + +static int asus_info_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, asus_info_proc_show, NULL); } +static const struct file_operations asus_info_proc_fops = { + .owner = THIS_MODULE, + .open = asus_info_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + /* * /proc handlers * We write our info in page, we begin at offset off and cannot write more @@ -639,34 +629,48 @@ write_led(const char __user *buffer, unsigned long count, /* * Proc handlers for MLED */ -static int -proc_read_mled(char *page, char **start, off_t off, int count, int *eof, - void *data) +static int mled_proc_show(struct seq_file *m, void *v) { - return sprintf(page, "%d\n", - read_led(hotk->methods->mled_status, MLED_ON)); + seq_printf(m, "%d\n", read_led(hotk->methods->mled_status, MLED_ON)); + return 0; } -static int -proc_write_mled(struct file *file, const char __user *buffer, - unsigned long count, void *data) +static int mled_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, mled_proc_show, NULL); +} + +static ssize_t mled_proc_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) { return write_led(buffer, count, hotk->methods->mt_mled, MLED_ON, 1); } +static const struct file_operations mled_proc_fops = { + .owner = THIS_MODULE, + .open = mled_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = mled_proc_write, +}; + /* * Proc handlers for LED display */ -static int -proc_read_ledd(char *page, char **start, off_t off, int count, int *eof, - void *data) +static int ledd_proc_show(struct seq_file *m, void *v) { - return sprintf(page, "0x%08x\n", hotk->ledd_status); + seq_printf(m, "0x%08x\n", hotk->ledd_status); + return 0; } -static int -proc_write_ledd(struct file *file, const char __user *buffer, - unsigned long count, void *data) +static int ledd_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, ledd_proc_show, NULL); +} + +static ssize_t ledd_proc_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) { int rv, value; @@ -682,61 +686,104 @@ proc_write_ledd(struct file *file, const char __user *buffer, return rv; } +static const struct file_operations ledd_proc_fops = { + .owner = THIS_MODULE, + .open = ledd_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = ledd_proc_write, +}; + /* * Proc handlers for WLED */ -static int -proc_read_wled(char *page, char **start, off_t off, int count, int *eof, - void *data) +static int wled_proc_show(struct seq_file *m, void *v) { - return sprintf(page, "%d\n", - read_led(hotk->methods->wled_status, WLED_ON)); + seq_printf(m, "%d\n", read_led(hotk->methods->wled_status, WLED_ON)); + return 0; } -static int -proc_write_wled(struct file *file, const char __user *buffer, - unsigned long count, void *data) +static int wled_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, wled_proc_show, NULL); +} + +static ssize_t wled_proc_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) { return write_led(buffer, count, hotk->methods->mt_wled, WLED_ON, 0); } +static const struct file_operations wled_proc_fops = { + .owner = THIS_MODULE, + .open = wled_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = wled_proc_write, +}; + /* * Proc handlers for Bluetooth */ -static int -proc_read_bluetooth(char *page, char **start, off_t off, int count, int *eof, - void *data) +static int bluetooth_proc_show(struct seq_file *m, void *v) { - return sprintf(page, "%d\n", read_led(hotk->methods->bt_status, BT_ON)); + seq_printf(m, "%d\n", read_led(hotk->methods->bt_status, BT_ON)); + return 0; } -static int -proc_write_bluetooth(struct file *file, const char __user *buffer, - unsigned long count, void *data) +static int bluetooth_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, bluetooth_proc_show, NULL); +} + +static ssize_t bluetooth_proc_write(struct file *file, + const char __user *buffer, size_t count, loff_t *pos) { /* Note: mt_bt_switch controls both internal Bluetooth adapter's presence and its LED */ return write_led(buffer, count, hotk->methods->mt_bt_switch, BT_ON, 0); } +static const struct file_operations bluetooth_proc_fops = { + .owner = THIS_MODULE, + .open = bluetooth_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = bluetooth_proc_write, +}; + /* * Proc handlers for TLED */ -static int -proc_read_tled(char *page, char **start, off_t off, int count, int *eof, - void *data) +static int tled_proc_show(struct seq_file *m, void *v) { - return sprintf(page, "%d\n", - read_led(hotk->methods->tled_status, TLED_ON)); + seq_printf(m, "%d\n", read_led(hotk->methods->tled_status, TLED_ON)); + return 0; } -static int -proc_write_tled(struct file *file, const char __user *buffer, - unsigned long count, void *data) +static int tled_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, tled_proc_show, NULL); +} + +static ssize_t tled_proc_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) { return write_led(buffer, count, hotk->methods->mt_tled, TLED_ON, 0); } +static const struct file_operations tled_proc_fops = { + .owner = THIS_MODULE, + .open = tled_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = tled_proc_write, +}; + static int get_lcd_state(void) { int lcd = 0; @@ -829,16 +876,19 @@ static int set_lcd_state(int value) } -static int -proc_read_lcd(char *page, char **start, off_t off, int count, int *eof, - void *data) +static int lcd_proc_show(struct seq_file *m, void *v) { - return sprintf(page, "%d\n", get_lcd_state()); + seq_printf(m, "%d\n", get_lcd_state()); + return 0; } -static int -proc_write_lcd(struct file *file, const char __user *buffer, - unsigned long count, void *data) +static int lcd_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, lcd_proc_show, NULL); +} + +static ssize_t lcd_proc_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) { int rv, value; @@ -848,6 +898,15 @@ proc_write_lcd(struct file *file, const char __user *buffer, return rv; } +static const struct file_operations lcd_proc_fops = { + .owner = THIS_MODULE, + .open = lcd_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = lcd_proc_write, +}; + static int read_brightness(struct backlight_device *bd) { int value; @@ -907,16 +966,19 @@ static int set_brightness_status(struct backlight_device *bd) return set_brightness(bd->props.brightness); } -static int -proc_read_brn(char *page, char **start, off_t off, int count, int *eof, - void *data) +static int brn_proc_show(struct seq_file *m, void *v) { - return sprintf(page, "%d\n", read_brightness(NULL)); + seq_printf(m, "%d\n", read_brightness(NULL)); + return 0; } -static int -proc_write_brn(struct file *file, const char __user *buffer, - unsigned long count, void *data) +static int brn_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, brn_proc_show, NULL); +} + +static ssize_t brn_proc_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) { int rv, value; @@ -929,6 +991,15 @@ proc_write_brn(struct file *file, const char __user *buffer, return rv; } +static const struct file_operations brn_proc_fops = { + .owner = THIS_MODULE, + .open = brn_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = brn_proc_write, +}; + static void set_display(int value) { /* no sanity check needed for now */ @@ -942,9 +1013,7 @@ static void set_display(int value) * Now, *this* one could be more user-friendly, but so far, no-one has * complained. The significance of bits is the same as in proc_write_disp() */ -static int -proc_read_disp(char *page, char **start, off_t off, int count, int *eof, - void *data) +static int disp_proc_show(struct seq_file *m, void *v) { int value = 0; @@ -952,7 +1021,13 @@ proc_read_disp(char *page, char **start, off_t off, int count, int *eof, printk(KERN_WARNING "Asus ACPI: Error reading display status\n"); value &= 0x07; /* needed for some models, shouldn't hurt others */ - return sprintf(page, "%d\n", value); + seq_printf(m, "%d\n", value); + return 0; +} + +static int disp_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, disp_proc_show, NULL); } /* @@ -961,9 +1036,8 @@ proc_read_disp(char *page, char **start, off_t off, int count, int *eof, * (bitwise) of these will suffice. I never actually tested 3 displays hooked * up simultaneously, so be warned. See the acpi4asus README for more info. */ -static int -proc_write_disp(struct file *file, const char __user *buffer, - unsigned long count, void *data) +static ssize_t disp_proc_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) { int rv, value; @@ -973,25 +1047,27 @@ proc_write_disp(struct file *file, const char __user *buffer, return rv; } -typedef int (proc_readfunc) (char *page, char **start, off_t off, int count, - int *eof, void *data); -typedef int (proc_writefunc) (struct file *file, const char __user *buffer, - unsigned long count, void *data); +static const struct file_operations disp_proc_fops = { + .owner = THIS_MODULE, + .open = disp_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = disp_proc_write, +}; static int -asus_proc_add(char *name, proc_writefunc *writefunc, - proc_readfunc *readfunc, mode_t mode, +asus_proc_add(char *name, const struct file_operations *proc_fops, mode_t mode, struct acpi_device *device) { - struct proc_dir_entry *proc = - create_proc_entry(name, mode, acpi_device_dir(device)); + struct proc_dir_entry *proc; + + proc = proc_create_data(name, mode, acpi_device_dir(device), + proc_fops, acpi_driver_data(device)); if (!proc) { printk(KERN_WARNING " Unable to create %s fs entry\n", name); return -1; } - proc->write_proc = writefunc; - proc->read_proc = readfunc; - proc->data = acpi_driver_data(device); proc->uid = asus_uid; proc->gid = asus_gid; return 0; @@ -1020,10 +1096,9 @@ static int asus_hotk_add_fs(struct acpi_device *device) if (!acpi_device_dir(device)) return -ENODEV; - proc = create_proc_entry(PROC_INFO, mode, acpi_device_dir(device)); + proc = proc_create(PROC_INFO, mode, acpi_device_dir(device), + &asus_info_proc_fops); if (proc) { - proc->read_proc = proc_read_info; - proc->data = acpi_driver_data(device); proc->uid = asus_uid; proc->gid = asus_gid; } else { @@ -1032,28 +1107,23 @@ static int asus_hotk_add_fs(struct acpi_device *device) } if (hotk->methods->mt_wled) { - asus_proc_add(PROC_WLED, &proc_write_wled, &proc_read_wled, - mode, device); + asus_proc_add(PROC_WLED, &wled_proc_fops, mode, device); } if (hotk->methods->mt_ledd) { - asus_proc_add(PROC_LEDD, &proc_write_ledd, &proc_read_ledd, - mode, device); + asus_proc_add(PROC_LEDD, &ledd_proc_fops, mode, device); } if (hotk->methods->mt_mled) { - asus_proc_add(PROC_MLED, &proc_write_mled, &proc_read_mled, - mode, device); + asus_proc_add(PROC_MLED, &mled_proc_fops, mode, device); } if (hotk->methods->mt_tled) { - asus_proc_add(PROC_TLED, &proc_write_tled, &proc_read_tled, - mode, device); + asus_proc_add(PROC_TLED, &tled_proc_fops, mode, device); } if (hotk->methods->mt_bt_switch) { - asus_proc_add(PROC_BT, &proc_write_bluetooth, - &proc_read_bluetooth, mode, device); + asus_proc_add(PROC_BT, &bluetooth_proc_fops, mode, device); } /* @@ -1061,19 +1131,16 @@ static int asus_hotk_add_fs(struct acpi_device *device) * accessible from the keyboard */ if (hotk->methods->mt_lcd_switch && hotk->methods->lcd_status) { - asus_proc_add(PROC_LCD, &proc_write_lcd, &proc_read_lcd, mode, - device); + asus_proc_add(PROC_LCD, &lcd_proc_fops, mode, device); } if ((hotk->methods->brightness_up && hotk->methods->brightness_down) || (hotk->methods->brightness_get && hotk->methods->brightness_set)) { - asus_proc_add(PROC_BRN, &proc_write_brn, &proc_read_brn, mode, - device); + asus_proc_add(PROC_BRN, &brn_proc_fops, mode, device); } if (hotk->methods->display_set) { - asus_proc_add(PROC_DISP, &proc_write_disp, &proc_read_disp, - mode, device); + asus_proc_add(PROC_DISP, &disp_proc_fops, mode, device); } return 0; -- cgit v0.10.2 From 936c8bcd7f5b418d0e040be539ceb4d2ac3bc0b8 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Mon, 21 Dec 2009 16:20:02 -0800 Subject: toshiba_acpi: convert to seq_file Signed-off-by: Alexey Dobriyan Cc: John W. Linville Cc: Johannes Berg Signed-off-by: Andrew Morton Signed-off-by: Len Brown diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index 51c0a8b..77bf5d8 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -357,63 +358,6 @@ static int force_fan; static int last_key_event; static int key_event_valid; -typedef struct _ProcItem { - const char *name; - char *(*read_func) (char *); - unsigned long (*write_func) (const char *, unsigned long); -} ProcItem; - -/* proc file handlers - */ - -static int -dispatch_read(char *page, char **start, off_t off, int count, int *eof, - ProcItem * item) -{ - char *p = page; - int len; - - if (off == 0) - p = item->read_func(p); - - /* ISSUE: I don't understand this code */ - len = (p - page); - if (len <= off + count) - *eof = 1; - *start = page + off; - len -= off; - if (len > count) - len = count; - if (len < 0) - len = 0; - return len; -} - -static int -dispatch_write(struct file *file, const char __user * buffer, - unsigned long count, ProcItem * item) -{ - int result; - char *tmp_buffer; - - /* Arg buffer points to userspace memory, which can't be accessed - * directly. Since we're making a copy, zero-terminate the - * destination so that sscanf can be used on it safely. - */ - tmp_buffer = kmalloc(count + 1, GFP_KERNEL); - if (!tmp_buffer) - return -ENOMEM; - - if (copy_from_user(tmp_buffer, buffer, count)) { - result = -EFAULT; - } else { - tmp_buffer[count] = 0; - result = item->write_func(tmp_buffer, count); - } - kfree(tmp_buffer); - return result; -} - static int get_lcd(struct backlight_device *bd) { u32 hci_result; @@ -426,19 +370,24 @@ static int get_lcd(struct backlight_device *bd) return -EFAULT; } -static char *read_lcd(char *p) +static int lcd_proc_show(struct seq_file *m, void *v) { int value = get_lcd(NULL); if (value >= 0) { - p += sprintf(p, "brightness: %d\n", value); - p += sprintf(p, "brightness_levels: %d\n", + seq_printf(m, "brightness: %d\n", value); + seq_printf(m, "brightness_levels: %d\n", HCI_LCD_BRIGHTNESS_LEVELS); } else { printk(MY_ERR "Error reading LCD brightness\n"); } - return p; + return 0; +} + +static int lcd_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, lcd_proc_show, NULL); } static int set_lcd(int value) @@ -458,12 +407,20 @@ static int set_lcd_status(struct backlight_device *bd) return set_lcd(bd->props.brightness); } -static unsigned long write_lcd(const char *buffer, unsigned long count) +static ssize_t lcd_proc_write(struct file *file, const char __user *buf, + size_t count, loff_t *pos) { + char cmd[42]; + size_t len; int value; int ret; - if (sscanf(buffer, " brightness : %i", &value) == 1 && + len = min(count, sizeof(cmd) - 1); + if (copy_from_user(cmd, buf, len)) + return -EFAULT; + cmd[len] = '\0'; + + if (sscanf(cmd, " brightness : %i", &value) == 1 && value >= 0 && value < HCI_LCD_BRIGHTNESS_LEVELS) { ret = set_lcd(value); if (ret == 0) @@ -474,7 +431,16 @@ static unsigned long write_lcd(const char *buffer, unsigned long count) return ret; } -static char *read_video(char *p) +static const struct file_operations lcd_proc_fops = { + .owner = THIS_MODULE, + .open = lcd_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = lcd_proc_write, +}; + +static int video_proc_show(struct seq_file *m, void *v) { u32 hci_result; u32 value; @@ -484,18 +450,25 @@ static char *read_video(char *p) int is_lcd = (value & HCI_VIDEO_OUT_LCD) ? 1 : 0; int is_crt = (value & HCI_VIDEO_OUT_CRT) ? 1 : 0; int is_tv = (value & HCI_VIDEO_OUT_TV) ? 1 : 0; - p += sprintf(p, "lcd_out: %d\n", is_lcd); - p += sprintf(p, "crt_out: %d\n", is_crt); - p += sprintf(p, "tv_out: %d\n", is_tv); + seq_printf(m, "lcd_out: %d\n", is_lcd); + seq_printf(m, "crt_out: %d\n", is_crt); + seq_printf(m, "tv_out: %d\n", is_tv); } else { printk(MY_ERR "Error reading video out status\n"); } - return p; + return 0; } -static unsigned long write_video(const char *buffer, unsigned long count) +static int video_proc_open(struct inode *inode, struct file *file) { + return single_open(file, video_proc_show, NULL); +} + +static ssize_t video_proc_write(struct file *file, const char __user *buf, + size_t count, loff_t *pos) +{ + char *cmd, *buffer; int value; int remain = count; int lcd_out = -1; @@ -504,6 +477,17 @@ static unsigned long write_video(const char *buffer, unsigned long count) u32 hci_result; u32 video_out; + cmd = kmalloc(count + 1, GFP_KERNEL); + if (!cmd) + return -ENOMEM; + if (copy_from_user(cmd, buf, count)) { + kfree(cmd); + return -EFAULT; + } + cmd[count] = '\0'; + + buffer = cmd; + /* scan expression. Multiple expressions may be delimited with ; * * NOTE: to keep scanning simple, invalid fields are ignored @@ -523,6 +507,8 @@ static unsigned long write_video(const char *buffer, unsigned long count) while (remain && *(buffer - 1) != ';'); } + kfree(cmd); + hci_read1(HCI_VIDEO_OUT, &video_out, &hci_result); if (hci_result == HCI_SUCCESS) { unsigned int new_video_out = video_out; @@ -543,28 +529,50 @@ static unsigned long write_video(const char *buffer, unsigned long count) return count; } -static char *read_fan(char *p) +static const struct file_operations video_proc_fops = { + .owner = THIS_MODULE, + .open = video_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = video_proc_write, +}; + +static int fan_proc_show(struct seq_file *m, void *v) { u32 hci_result; u32 value; hci_read1(HCI_FAN, &value, &hci_result); if (hci_result == HCI_SUCCESS) { - p += sprintf(p, "running: %d\n", (value > 0)); - p += sprintf(p, "force_on: %d\n", force_fan); + seq_printf(m, "running: %d\n", (value > 0)); + seq_printf(m, "force_on: %d\n", force_fan); } else { printk(MY_ERR "Error reading fan status\n"); } - return p; + return 0; +} + +static int fan_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, fan_proc_show, NULL); } -static unsigned long write_fan(const char *buffer, unsigned long count) +static ssize_t fan_proc_write(struct file *file, const char __user *buf, + size_t count, loff_t *pos) { + char cmd[42]; + size_t len; int value; u32 hci_result; - if (sscanf(buffer, " force_on : %i", &value) == 1 && + len = min(count, sizeof(cmd) - 1); + if (copy_from_user(cmd, buf, len)) + return -EFAULT; + cmd[len] = '\0'; + + if (sscanf(cmd, " force_on : %i", &value) == 1 && value >= 0 && value <= 1) { hci_write1(HCI_FAN, value, &hci_result); if (hci_result != HCI_SUCCESS) @@ -578,7 +586,16 @@ static unsigned long write_fan(const char *buffer, unsigned long count) return count; } -static char *read_keys(char *p) +static const struct file_operations fan_proc_fops = { + .owner = THIS_MODULE, + .open = fan_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = fan_proc_write, +}; + +static int keys_proc_show(struct seq_file *m, void *v) { u32 hci_result; u32 value; @@ -602,18 +619,30 @@ static char *read_keys(char *p) } } - p += sprintf(p, "hotkey_ready: %d\n", key_event_valid); - p += sprintf(p, "hotkey: 0x%04x\n", last_key_event); + seq_printf(m, "hotkey_ready: %d\n", key_event_valid); + seq_printf(m, "hotkey: 0x%04x\n", last_key_event); +end: + return 0; +} - end: - return p; +static int keys_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, keys_proc_show, NULL); } -static unsigned long write_keys(const char *buffer, unsigned long count) +static ssize_t keys_proc_write(struct file *file, const char __user *buf, + size_t count, loff_t *pos) { + char cmd[42]; + size_t len; int value; - if (sscanf(buffer, " hotkey_ready : %i", &value) == 1 && value == 0) { + len = min(count, sizeof(cmd) - 1); + if (copy_from_user(cmd, buf, len)) + return -EFAULT; + cmd[len] = '\0'; + + if (sscanf(cmd, " hotkey_ready : %i", &value) == 1 && value == 0) { key_event_valid = 0; } else { return -EINVAL; @@ -622,52 +651,58 @@ static unsigned long write_keys(const char *buffer, unsigned long count) return count; } -static char *read_version(char *p) +static const struct file_operations keys_proc_fops = { + .owner = THIS_MODULE, + .open = keys_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = keys_proc_write, +}; + +static int version_proc_show(struct seq_file *m, void *v) { - p += sprintf(p, "driver: %s\n", TOSHIBA_ACPI_VERSION); - p += sprintf(p, "proc_interface: %d\n", - PROC_INTERFACE_VERSION); - return p; + seq_printf(m, "driver: %s\n", TOSHIBA_ACPI_VERSION); + seq_printf(m, "proc_interface: %d\n", PROC_INTERFACE_VERSION); + return 0; } +static int version_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, version_proc_show, PDE(inode)->data); +} + +static const struct file_operations version_proc_fops = { + .owner = THIS_MODULE, + .open = version_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + /* proc and module init */ #define PROC_TOSHIBA "toshiba" -static ProcItem proc_items[] = { - {"lcd", read_lcd, write_lcd}, - {"video", read_video, write_video}, - {"fan", read_fan, write_fan}, - {"keys", read_keys, write_keys}, - {"version", read_version, NULL}, - {NULL} -}; - static acpi_status __init add_device(void) { - struct proc_dir_entry *proc; - ProcItem *item; - - for (item = proc_items; item->name; ++item) { - proc = create_proc_read_entry(item->name, - S_IFREG | S_IRUGO | S_IWUSR, - toshiba_proc_dir, - (read_proc_t *) dispatch_read, - item); - if (proc && item->write_func) - proc->write_proc = (write_proc_t *) dispatch_write; - } + proc_create("lcd", S_IRUGO | S_IWUSR, toshiba_proc_dir, &lcd_proc_fops); + proc_create("video", S_IRUGO | S_IWUSR, toshiba_proc_dir, &video_proc_fops); + proc_create("fan", S_IRUGO | S_IWUSR, toshiba_proc_dir, &fan_proc_fops); + proc_create("keys", S_IRUGO | S_IWUSR, toshiba_proc_dir, &keys_proc_fops); + proc_create("version", S_IRUGO, toshiba_proc_dir, &version_proc_fops); return AE_OK; } static acpi_status remove_device(void) { - ProcItem *item; - - for (item = proc_items; item->name; ++item) - remove_proc_entry(item->name, toshiba_proc_dir); + remove_proc_entry("lcd", toshiba_proc_dir); + remove_proc_entry("video", toshiba_proc_dir); + remove_proc_entry("fan", toshiba_proc_dir); + remove_proc_entry("keys", toshiba_proc_dir); + remove_proc_entry("version", toshiba_proc_dir); return AE_OK; } -- cgit v0.10.2 From bdc731bc5fcd1794e9ac8ac80c389d302381c123 Mon Sep 17 00:00:00 2001 From: Stefan Bader Date: Mon, 21 Dec 2009 16:20:04 -0800 Subject: acerhdf: limit modalias matching to supported BugLink: https://bugs.launchpad.net/ubuntu/+bug/435958 The module alias currently matches any Acer computer but when loaded the BIOS checks will only succeed on Aspire One models. This causes a invalid BIOS warning for all other models (seen on Aspire 4810T). This is not fatal but worries users that see this message. Limiting the moule alias to models starting with AOA or DOA for Packard Bell. Signed-off-by: Stefan Bader Acked-by: Borislav Petkov Acked-by: Peter Feuerer Cc: Signed-off-by: Andrew Morton Signed-off-by: Len Brown diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c index 79b15b9..007bc55 100644 --- a/drivers/platform/x86/acerhdf.c +++ b/drivers/platform/x86/acerhdf.c @@ -640,9 +640,10 @@ static void __exit acerhdf_exit(void) MODULE_LICENSE("GPL"); MODULE_AUTHOR("Peter Feuerer"); MODULE_DESCRIPTION("Aspire One temperature and fan driver"); -MODULE_ALIAS("dmi:*:*Acer*:*:"); -MODULE_ALIAS("dmi:*:*Gateway*:*:"); -MODULE_ALIAS("dmi:*:*Packard Bell*:*:"); +MODULE_ALIAS("dmi:*:*Acer*:pnAOA*:"); +MODULE_ALIAS("dmi:*:*Gateway*:pnAOA*:"); +MODULE_ALIAS("dmi:*:*Packard Bell*:pnAOA*:"); +MODULE_ALIAS("dmi:*:*Packard Bell*:pnDOA*:"); module_init(acerhdf_init); module_exit(acerhdf_exit); -- cgit v0.10.2 From 94219d798e65dff1dac5f8f36f03a9bdb3105f91 Mon Sep 17 00:00:00 2001 From: Peter Feuerer Date: Mon, 21 Dec 2009 16:20:05 -0800 Subject: acerhdf: add new BIOS versions Add new BIOS versions for following netbooks: Aspire 1810xx, Packard Bell DOTMU. Signed-off-by: Peter Feuerer Cc: Borislav Petkov Cc: Andreas Mohr Signed-off-by: Andrew Morton Signed-off-by: Len Brown diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c index 007bc55..a97fc4a 100644 --- a/drivers/platform/x86/acerhdf.c +++ b/drivers/platform/x86/acerhdf.c @@ -52,7 +52,7 @@ */ #undef START_IN_KERNEL_MODE -#define DRV_VER "0.5.20" +#define DRV_VER "0.5.21" /* * According to the Atom N270 datasheet, @@ -156,7 +156,13 @@ static const struct bios_settings_t bios_tbl[] = { {"Acer", "AOA150", "v0.3310", 0x55, 0x58, {0x20, 0x20, 0x00} }, /* Acer 1410 */ {"Acer", "Aspire 1410", "v0.3120", 0x55, 0x58, {0x9e, 0x9e, 0x00} }, - /* special BIOS / other */ + {"Acer", "Aspire 1410", "v1.3303", 0x55, 0x58, {0x9e, 0x9e, 0x00} }, + /* Acer 1810xx */ + {"Acer", "Aspire 1810TZ", "v0.3120", 0x55, 0x58, {0x9e, 0x9e, 0x00} }, + {"Acer", "Aspire 1810T", "v0.3120", 0x55, 0x58, {0x9e, 0x9e, 0x00} }, + {"Acer", "Aspire 1810T", "v1.3303", 0x55, 0x58, {0x9e, 0x9e, 0x00} }, + {"Acer", "Aspire 1810TZ", "v1.3303", 0x55, 0x58, {0x9e, 0x9e, 0x00} }, + /* Gateway */ {"Gateway", "AOA110", "v0.3103", 0x55, 0x58, {0x21, 0x21, 0x00} }, {"Gateway", "AOA150", "v0.3103", 0x55, 0x58, {0x20, 0x20, 0x00} }, {"Gateway ", "LT31 ", "v1.3103 ", 0x55, 0x58, @@ -165,10 +171,13 @@ static const struct bios_settings_t bios_tbl[] = { {0x10, 0x0f, 0x00} }, {"Gateway ", "LT31 ", "v1.3302 ", 0x55, 0x58, {0x10, 0x0f, 0x00} }, + /* Packard Bell */ {"Packard Bell", "DOA150", "v0.3104", 0x55, 0x58, {0x21, 0x21, 0x00} }, {"Packard Bell", "DOA150", "v0.3105", 0x55, 0x58, {0x20, 0x20, 0x00} }, {"Packard Bell", "AOA110", "v0.3105", 0x55, 0x58, {0x21, 0x21, 0x00} }, {"Packard Bell", "AOA150", "v0.3105", 0x55, 0x58, {0x20, 0x20, 0x00} }, + {"Packard Bell", "DOTMU", "v1.3303", 0x55, 0x58, {0x9e, 0x9e, 0x00} }, + {"Packard Bell", "DOTMU", "v0.3120", 0x55, 0x58, {0x9e, 0x9e, 0x00} }, /* pewpew-terminator */ {"", "", "", 0, 0, {0, 0, 0} } }; @@ -641,9 +650,13 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Peter Feuerer"); MODULE_DESCRIPTION("Aspire One temperature and fan driver"); MODULE_ALIAS("dmi:*:*Acer*:pnAOA*:"); +MODULE_ALIAS("dmi:*:*Acer*:pnAspire 1410*:"); +MODULE_ALIAS("dmi:*:*Acer*:pnAspire 1810*:"); MODULE_ALIAS("dmi:*:*Gateway*:pnAOA*:"); +MODULE_ALIAS("dmi:*:*Gateway*:pnLT31*:"); MODULE_ALIAS("dmi:*:*Packard Bell*:pnAOA*:"); MODULE_ALIAS("dmi:*:*Packard Bell*:pnDOA*:"); +MODULE_ALIAS("dmi:*:*Packard Bell*:pnDOTMU*:"); module_init(acerhdf_init); module_exit(acerhdf_exit); -- cgit v0.10.2 From dcbfb8156a2149fd6358a377aa9400e28ef43800 Mon Sep 17 00:00:00 2001 From: Peter Feuerer Date: Mon, 21 Dec 2009 16:20:06 -0800 Subject: drivers/platform/x86/acerhdf.c: check BIOS information whether it begins with string of table BIOS information is now checked whether it begins with the strings stored in the BIOS table. Previous method did a strcmp, what lead to problems if BIOS information has appended whitespaces. Signed-off-by: Peter Feuerer Cc: Borislav Petkov Cc: Andreas Mohr Cc: Ingo Molnar Cc: Thomas Gleixner Cc: "H. Peter Anvin" Signed-off-by: Andrew Morton Signed-off-by: Len Brown diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c index a97fc4a..7b2384d 100644 --- a/drivers/platform/x86/acerhdf.c +++ b/drivers/platform/x86/acerhdf.c @@ -52,7 +52,7 @@ */ #undef START_IN_KERNEL_MODE -#define DRV_VER "0.5.21" +#define DRV_VER "0.5.22" /* * According to the Atom N270 datasheet, @@ -165,12 +165,9 @@ static const struct bios_settings_t bios_tbl[] = { /* Gateway */ {"Gateway", "AOA110", "v0.3103", 0x55, 0x58, {0x21, 0x21, 0x00} }, {"Gateway", "AOA150", "v0.3103", 0x55, 0x58, {0x20, 0x20, 0x00} }, - {"Gateway ", "LT31 ", "v1.3103 ", 0x55, 0x58, - {0x10, 0x0f, 0x00} }, - {"Gateway ", "LT31 ", "v1.3201 ", 0x55, 0x58, - {0x10, 0x0f, 0x00} }, - {"Gateway ", "LT31 ", "v1.3302 ", 0x55, 0x58, - {0x10, 0x0f, 0x00} }, + {"Gateway", "LT31", "v1.3103", 0x55, 0x58, {0x10, 0x0f, 0x00} }, + {"Gateway", "LT31", "v1.3201", 0x55, 0x58, {0x10, 0x0f, 0x00} }, + {"Gateway", "LT31", "v1.3302", 0x55, 0x58, {0x10, 0x0f, 0x00} }, /* Packard Bell */ {"Packard Bell", "DOA150", "v0.3104", 0x55, 0x58, {0x21, 0x21, 0x00} }, {"Packard Bell", "DOA150", "v0.3105", 0x55, 0x58, {0x20, 0x20, 0x00} }, @@ -495,13 +492,26 @@ static struct platform_driver acerhdf_driver = { .remove = acerhdf_remove, }; +/* checks if str begins with start */ +static int str_starts_with(const char *str, const char *start) +{ + unsigned long str_len = 0, start_len = 0; + + str_len = strlen(str); + start_len = strlen(start); + + if (str_len >= start_len && + !strncmp(str, start, start_len)) + return 1; + + return 0; +} /* check hardware */ static int acerhdf_check_hardware(void) { char const *vendor, *version, *product; - int i; - unsigned long prod_len = 0; + const struct bios_settings_t *bt = NULL; /* get BIOS data */ vendor = dmi_get_system_info(DMI_SYS_VENDOR); @@ -523,20 +533,20 @@ static int acerhdf_check_hardware(void) kernelmode = 0; } - prod_len = strlen(product); - if (verbose) pr_info("BIOS info: %s %s, product: %s\n", vendor, version, product); /* search BIOS version and vendor in BIOS settings table */ - for (i = 0; bios_tbl[i].version[0]; i++) { - if (strlen(bios_tbl[i].product) >= prod_len && - !strncmp(bios_tbl[i].product, product, - strlen(bios_tbl[i].product)) && - !strcmp(bios_tbl[i].vendor, vendor) && - !strcmp(bios_tbl[i].version, version)) { - bios_cfg = &bios_tbl[i]; + for (bt = bios_tbl; bt->vendor[0]; bt++) { + /* + * check if actual hardware BIOS vendor, product and version + * IDs start with the strings of BIOS table entry + */ + if (str_starts_with(vendor, bt->vendor) && + str_starts_with(product, bt->product) && + str_starts_with(version, bt->version)) { + bios_cfg = bt; break; } } -- cgit v0.10.2 From 656ab8172a49d3931e64f866c080260be638c8a9 Mon Sep 17 00:00:00 2001 From: Don Skidmore Date: Wed, 23 Dec 2009 21:19:19 -0800 Subject: ixgbe: fix Need to call pci_save_state after pci_restore_state This patch adds a pci_save_state() call in ixgbe_resume() after pci_restore_state(). A similar change was made in ixgbe_io_slot_reset() that accommodates pci_restore_state() new behavior. This change makes pci_restore_state() clear the saved_state flag This is necessary due to a resent kernel change to pci_restore_state() so that it now clears the saved_state flag of the device right after the device.s standard configuration registers have been poplulated with the previously saved values. Signed-off-by: Don Skidmore Acked-by: Peter P Waskiewicz Jr Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index bd64387..1a2ea62 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -4373,6 +4373,11 @@ static int ixgbe_resume(struct pci_dev *pdev) pci_set_power_state(pdev, PCI_D0); pci_restore_state(pdev); + /* + * pci_restore_state clears dev->state_saved so call + * pci_save_state to restore it. + */ + pci_save_state(pdev); err = pci_enable_device_mem(pdev); if (err) { -- cgit v0.10.2 From 3e9b988e4edf065d39c1343937f717319b1c1065 Mon Sep 17 00:00:00 2001 From: Anisse Astier Date: Fri, 4 Dec 2009 10:10:09 +0100 Subject: wmi: Free the allocated acpi objects through wmi_get_event_data These function allocate an acpi object by calling wmi_get_event_data, which then calls acpi_evaluate_object, and it is not freed afterwards. And kernel doc is fixed for parameters of wmi_get_event_data. Signed-off-by: Anisse Astier Acked-by: Randy Dunlap Acked-by: Carlos Corbacho Signed-off-by: Len Brown diff --git a/drivers/platform/x86/dell-wmi.c b/drivers/platform/x86/dell-wmi.c index 67f3fe7..6561dfc 100644 --- a/drivers/platform/x86/dell-wmi.c +++ b/drivers/platform/x86/dell-wmi.c @@ -238,6 +238,7 @@ static void dell_wmi_notify(u32 value, void *context) input_sync(dell_wmi_input_dev); } } + kfree(obj); } diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c index 63c3e65..db10c5d 100644 --- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c @@ -381,6 +381,8 @@ static void hp_wmi_notify(u32 value, void *context) } else printk(KERN_INFO "HP WMI: Unknown key pressed - %x\n", eventcode); + + kfree(obj); } static int __init hp_wmi_input_setup(void) diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c index e425a86..9f93d6c 100644 --- a/drivers/platform/x86/wmi.c +++ b/drivers/platform/x86/wmi.c @@ -540,8 +540,8 @@ EXPORT_SYMBOL_GPL(wmi_remove_notify_handler); /** * wmi_get_event_data - Get WMI data associated with an event * - * @event - Event to find - * &out - Buffer to hold event data + * @event: Event to find + * @out: Buffer to hold event data. out->pointer should be freed with kfree() * * Returns extra data associated with an event in WMI. */ -- cgit v0.10.2 From 1fdd407f4e3f2ecb453954cbebb6c22491c61853 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 17 Dec 2009 22:19:42 -0800 Subject: dell-wmi: do not keep driver loaded on unsupported boxes There is no point in having the driver loaded in memory if we fail to locate particular WMI GUID. Signed-off-by: Dmitry Torokhov Acked-by: Matthew Garrett Signed-off-by: Len Brown diff --git a/drivers/platform/x86/dell-wmi.c b/drivers/platform/x86/dell-wmi.c index 6561dfc..916ccb2 100644 --- a/drivers/platform/x86/dell-wmi.c +++ b/drivers/platform/x86/dell-wmi.c @@ -325,37 +325,34 @@ static int __init dell_wmi_init(void) int err; if (wmi_has_guid(DELL_EVENT_GUID)) { + printk(KERN_WARNING "dell-wmi: No known WMI GUID found\n"); + return -ENODEV; + } - dmi_walk(find_hk_type, NULL); - - err = dell_wmi_input_setup(); - - if (err) - return err; - - err = wmi_install_notify_handler(DELL_EVENT_GUID, - dell_wmi_notify, NULL); - if (err) { - input_unregister_device(dell_wmi_input_dev); - printk(KERN_ERR "dell-wmi: Unable to register" - " notify handler - %d\n", err); - return err; - } + dmi_walk(find_hk_type, NULL); + acpi_video = acpi_video_backlight_support(); - acpi_video = acpi_video_backlight_support(); + err = dell_wmi_input_setup(); + if (err) + return err; - } else - printk(KERN_WARNING "dell-wmi: No known WMI GUID found\n"); + err = wmi_install_notify_handler(DELL_EVENT_GUID, + dell_wmi_notify, NULL); + if (err) { + input_unregister_device(dell_wmi_input_dev); + printk(KERN_ERR + "dell-wmi: Unable to register notify handler - %d\n", + err); + return err; + } return 0; } static void __exit dell_wmi_exit(void) { - if (wmi_has_guid(DELL_EVENT_GUID)) { - wmi_remove_notify_handler(DELL_EVENT_GUID); - input_unregister_device(dell_wmi_input_dev); - } + wmi_remove_notify_handler(DELL_EVENT_GUID); + input_unregister_device(dell_wmi_input_dev); } module_init(dell_wmi_init); -- cgit v0.10.2 From 4d5f177caf1ef78f5e7eaee75b66b4d534445682 Mon Sep 17 00:00:00 2001 From: Thomas Renninger Date: Fri, 18 Dec 2009 15:29:22 +0100 Subject: acer-wmi, msi-wmi: Remove needless DMI MODULE_ALIAS Now that we have WMI autoloading the DMI matching is not needed anymore. Signed-off-by: Thomas Renninger Acked-by: Carlos Corbacho Acked-by: Anisse Astier Signed-off-by: Len Brown diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index 454970d..07d14df 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c @@ -96,9 +96,6 @@ struct acer_quirks { MODULE_ALIAS("wmi:67C3371D-95A3-4C37-BB61-DD47B491DAAB"); MODULE_ALIAS("wmi:6AF4F258-B401-42fd-BE91-3D4AC2D7C0D3"); -/* Temporary workaround until the WMI sysfs interface goes in */ -MODULE_ALIAS("dmi:*:*Acer*:*:"); - /* * Interface capability flags */ diff --git a/drivers/platform/x86/msi-wmi.c b/drivers/platform/x86/msi-wmi.c index 0c8fe14..7f77f90 100644 --- a/drivers/platform/x86/msi-wmi.c +++ b/drivers/platform/x86/msi-wmi.c @@ -34,16 +34,6 @@ MODULE_LICENSE("GPL"); MODULE_ALIAS("wmi:551A1F84-FBDD-4125-91DB-3EA8F44F1D45"); MODULE_ALIAS("wmi:B6F3EEF2-3D2F-49DC-9DE3-85BCE18C62F2"); -/* Temporary workaround until the WMI sysfs interface goes in - { "svn", DMI_SYS_VENDOR }, - { "pn", DMI_PRODUCT_NAME }, - { "pvr", DMI_PRODUCT_VERSION }, - { "rvn", DMI_BOARD_VENDOR }, - { "rn", DMI_BOARD_NAME }, -*/ - -MODULE_ALIAS("dmi:*:svnMICRO-STARINTERNATIONAL*:pnMS-6638:*"); - #define DRV_NAME "msi-wmi" #define DRV_PFX DRV_NAME ": " -- cgit v0.10.2 From 154280fd0e890814a249bf4a79b4340fb367f1a7 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 22 Dec 2009 03:37:28 +0000 Subject: serial: sh-sci: earlyprintk zero uartclk fix This establishes a sensible max baud rate for the earlyprintk cases where the port's uartclk has not yet been determined. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 68c7f6c..a886990 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c @@ -897,11 +897,21 @@ static void sci_shutdown(struct uart_port *port) static void sci_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { - unsigned int status, baud, smr_val; + unsigned int status, baud, smr_val, max_baud; int t = -1; - baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); - if (likely(baud)) + /* + * earlyprintk comes here early on with port->uartclk set to zero. + * the clock framework is not up and running at this point so here + * we assume that 115200 is the maximum baud rate. please note that + * the baud rate is not programmed during earlyprintk - it is assumed + * that the previous boot loader has enabled required clocks and + * setup the baud rate generator hardware for us already. + */ + max_baud = port->uartclk ? port->uartclk / 16 : 115200; + + baud = uart_get_baud_rate(port, termios, old, 0, max_baud); + if (likely(baud && port->uartclk)) t = SCBRR_VALUE(baud, port->uartclk); do { -- cgit v0.10.2 From 32b53076c31ce9159740b744d5eb5d9505312add Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 24 Dec 2009 14:52:43 +0900 Subject: serial: sh-sci: Convert tremaining ctrl_xxx I/O routines to __raw_xxx. ctrl_xxx() is an antiquated SH interface, while __raw_xxx is the standard API that accomplishes the same thing. As such, this converts the remaining sh-sci straggles over, which enables the driver to be wired up for ARM SH-Mobile CPUs as well. Signed-off-by: Paul Mundt diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index a886990..37f0de9 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c @@ -222,9 +222,9 @@ static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) Set SCP6MD1,0 = {01} (output) */ __raw_writew((data & 0x0fcf) | 0x1000, SCPCR); - data = ctrl_inb(SCPDR); + data = __raw_readb(SCPDR); /* Set /RTS2 (bit6) = 0 */ - ctrl_outb(data & 0xbf, SCPDR); + __raw_writeb(data & 0xbf, SCPDR); } } #elif defined(CONFIG_CPU_SUBTYPE_SH7722) diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h index a32094ee..0efcded 100644 --- a/drivers/serial/sh-sci.h +++ b/drivers/serial/sh-sci.h @@ -517,20 +517,20 @@ static const struct __attribute__((packed)) { static inline int sci_rxd_in(struct uart_port *port) { if (port->mapbase == 0xfffffe80) - return ctrl_inb(SCPDR)&0x01 ? 1 : 0; /* SCI */ + return __raw_readb(SCPDR)&0x01 ? 1 : 0; /* SCI */ if (port->mapbase == 0xa4000150) - return ctrl_inb(SCPDR)&0x10 ? 1 : 0; /* SCIF */ + return __raw_readb(SCPDR)&0x10 ? 1 : 0; /* SCIF */ if (port->mapbase == 0xa4000140) - return ctrl_inb(SCPDR)&0x04 ? 1 : 0; /* IRDA */ + return __raw_readb(SCPDR)&0x04 ? 1 : 0; /* IRDA */ return 1; } #elif defined(CONFIG_CPU_SUBTYPE_SH7705) static inline int sci_rxd_in(struct uart_port *port) { if (port->mapbase == SCIF0) - return ctrl_inb(SCPDR)&0x04 ? 1 : 0; /* IRDA */ + return __raw_readb(SCPDR)&0x04 ? 1 : 0; /* IRDA */ if (port->mapbase == SCIF2) - return ctrl_inb(SCPDR)&0x10 ? 1 : 0; /* SCIF */ + return __raw_readb(SCPDR)&0x10 ? 1 : 0; /* SCIF */ return 1; } #elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) @@ -557,68 +557,68 @@ static inline int sci_rxd_in(struct uart_port *port) static inline int sci_rxd_in(struct uart_port *port) { if (port->mapbase == 0xffe00000) - return ctrl_inb(SCSPTR1)&0x01 ? 1 : 0; /* SCI */ + return __raw_readb(SCSPTR1)&0x01 ? 1 : 0; /* SCI */ if (port->mapbase == 0xffe80000) - return ctrl_inw(SCSPTR2)&0x0001 ? 1 : 0; /* SCIF */ + return __raw_readw(SCSPTR2)&0x0001 ? 1 : 0; /* SCIF */ return 1; } #elif defined(CONFIG_CPU_SUBTYPE_SH4_202) static inline int sci_rxd_in(struct uart_port *port) { if (port->mapbase == 0xffe80000) - return ctrl_inw(SCSPTR2)&0x0001 ? 1 : 0; /* SCIF */ + return __raw_readw(SCSPTR2)&0x0001 ? 1 : 0; /* SCIF */ return 1; } #elif defined(CONFIG_CPU_SUBTYPE_SH7757) static inline int sci_rxd_in(struct uart_port *port) { if (port->mapbase == 0xfe4b0000) - return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; + return __raw_readw(SCSPTR0) & 0x0001 ? 1 : 0; if (port->mapbase == 0xfe4c0000) - return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; + return __raw_readw(SCSPTR1) & 0x0001 ? 1 : 0; if (port->mapbase == 0xfe4d0000) - return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; + return __raw_readw(SCSPTR2) & 0x0001 ? 1 : 0; } #elif defined(CONFIG_CPU_SUBTYPE_SH7760) static inline int sci_rxd_in(struct uart_port *port) { if (port->mapbase == 0xfe600000) - return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ + return __raw_readw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ if (port->mapbase == 0xfe610000) - return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ + return __raw_readw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ if (port->mapbase == 0xfe620000) - return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ + return __raw_readw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ return 1; } #elif defined(CONFIG_CPU_SUBTYPE_SH7343) static inline int sci_rxd_in(struct uart_port *port) { if (port->mapbase == 0xffe00000) - return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ + return __raw_readw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ if (port->mapbase == 0xffe10000) - return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ + return __raw_readw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ if (port->mapbase == 0xffe20000) - return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ + return __raw_readw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ if (port->mapbase == 0xffe30000) - return ctrl_inw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */ + return __raw_readw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */ return 1; } #elif defined(CONFIG_CPU_SUBTYPE_SH7366) static inline int sci_rxd_in(struct uart_port *port) { if (port->mapbase == 0xffe00000) - return ctrl_inb(SCPDR0) & 0x0001 ? 1 : 0; /* SCIF0 */ + return __raw_readb(SCPDR0) & 0x0001 ? 1 : 0; /* SCIF0 */ return 1; } #elif defined(CONFIG_CPU_SUBTYPE_SH7722) static inline int sci_rxd_in(struct uart_port *port) { if (port->mapbase == 0xffe00000) - return ctrl_inb(PSDR) & 0x02 ? 1 : 0; /* SCIF0 */ + return __raw_readb(PSDR) & 0x02 ? 1 : 0; /* SCIF0 */ if (port->mapbase == 0xffe10000) - return ctrl_inb(PADR) & 0x40 ? 1 : 0; /* SCIF1 */ + return __raw_readb(PADR) & 0x40 ? 1 : 0; /* SCIF1 */ if (port->mapbase == 0xffe20000) - return ctrl_inb(PWDR) & 0x04 ? 1 : 0; /* SCIF2 */ + return __raw_readb(PWDR) & 0x04 ? 1 : 0; /* SCIF2 */ return 1; } @@ -626,17 +626,17 @@ static inline int sci_rxd_in(struct uart_port *port) static inline int sci_rxd_in(struct uart_port *port) { if (port->mapbase == 0xffe00000) - return ctrl_inb(SCSPTR0) & 0x0008 ? 1 : 0; /* SCIF0 */ + return __raw_readb(SCSPTR0) & 0x0008 ? 1 : 0; /* SCIF0 */ if (port->mapbase == 0xffe10000) - return ctrl_inb(SCSPTR1) & 0x0020 ? 1 : 0; /* SCIF1 */ + return __raw_readb(SCSPTR1) & 0x0020 ? 1 : 0; /* SCIF1 */ if (port->mapbase == 0xffe20000) - return ctrl_inb(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF2 */ + return __raw_readb(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF2 */ if (port->mapbase == 0xa4e30000) - return ctrl_inb(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF3 */ + return __raw_readb(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF3 */ if (port->mapbase == 0xa4e40000) - return ctrl_inb(SCSPTR4) & 0x0001 ? 1 : 0; /* SCIF4 */ + return __raw_readb(SCSPTR4) & 0x0001 ? 1 : 0; /* SCIF4 */ if (port->mapbase == 0xa4e50000) - return ctrl_inb(SCSPTR5) & 0x0008 ? 1 : 0; /* SCIF5 */ + return __raw_readb(SCSPTR5) & 0x0008 ? 1 : 0; /* SCIF5 */ return 1; } #elif defined(CONFIG_CPU_SUBTYPE_SH7724) @@ -645,9 +645,9 @@ static inline int sci_rxd_in(struct uart_port *port) static inline int sci_rxd_in(struct uart_port *port) { if (port->type == PORT_SCIF) - return ctrl_inw((port->mapbase + SCFSR)) & SCIF_BRK ? 1 : 0; + return __raw_readw((port->mapbase + SCFSR)) & SCIF_BRK ? 1 : 0; if (port->type == PORT_SCIFA) - return ctrl_inw((port->mapbase + SCASSR)) & SCIF_BRK ? 1 : 0; + return __raw_readw((port->mapbase + SCASSR)) & SCIF_BRK ? 1 : 0; return 1; } #elif defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103) @@ -665,11 +665,11 @@ static inline int sci_rxd_in(struct uart_port *port) static inline int sci_rxd_in(struct uart_port *port) { if (port->mapbase == 0xffe00000) - return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ + return __raw_readw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ if (port->mapbase == 0xffe08000) - return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ + return __raw_readw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ if (port->mapbase == 0xffe10000) - return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF/IRDA */ + return __raw_readw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF/IRDA */ return 1; } @@ -677,20 +677,20 @@ static inline int sci_rxd_in(struct uart_port *port) static inline int sci_rxd_in(struct uart_port *port) { if (port->mapbase == 0xff923000) - return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ + return __raw_readw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ if (port->mapbase == 0xff924000) - return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ + return __raw_readw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ if (port->mapbase == 0xff925000) - return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ + return __raw_readw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ return 1; } #elif defined(CONFIG_CPU_SUBTYPE_SH7780) static inline int sci_rxd_in(struct uart_port *port) { if (port->mapbase == 0xffe00000) - return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ + return __raw_readw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ if (port->mapbase == 0xffe10000) - return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ + return __raw_readw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ return 1; } #elif defined(CONFIG_CPU_SUBTYPE_SH7785) || \ @@ -698,17 +698,17 @@ static inline int sci_rxd_in(struct uart_port *port) static inline int sci_rxd_in(struct uart_port *port) { if (port->mapbase == 0xffea0000) - return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ + return __raw_readw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ if (port->mapbase == 0xffeb0000) - return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ + return __raw_readw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ if (port->mapbase == 0xffec0000) - return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ + return __raw_readw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ if (port->mapbase == 0xffed0000) - return ctrl_inw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */ + return __raw_readw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */ if (port->mapbase == 0xffee0000) - return ctrl_inw(SCSPTR4) & 0x0001 ? 1 : 0; /* SCIF */ + return __raw_readw(SCSPTR4) & 0x0001 ? 1 : 0; /* SCIF */ if (port->mapbase == 0xffef0000) - return ctrl_inw(SCSPTR5) & 0x0001 ? 1 : 0; /* SCIF */ + return __raw_readw(SCSPTR5) & 0x0001 ? 1 : 0; /* SCIF */ return 1; } #elif defined(CONFIG_CPU_SUBTYPE_SH7201) || \ @@ -718,22 +718,22 @@ static inline int sci_rxd_in(struct uart_port *port) static inline int sci_rxd_in(struct uart_port *port) { if (port->mapbase == 0xfffe8000) - return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ + return __raw_readw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ if (port->mapbase == 0xfffe8800) - return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ + return __raw_readw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ if (port->mapbase == 0xfffe9000) - return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ + return __raw_readw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ if (port->mapbase == 0xfffe9800) - return ctrl_inw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */ + return __raw_readw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */ #if defined(CONFIG_CPU_SUBTYPE_SH7201) if (port->mapbase == 0xfffeA000) - return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ + return __raw_readw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ if (port->mapbase == 0xfffeA800) - return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ + return __raw_readw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ if (port->mapbase == 0xfffeB000) - return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ + return __raw_readw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ if (port->mapbase == 0xfffeB800) - return ctrl_inw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */ + return __raw_readw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */ #endif return 1; } @@ -741,24 +741,24 @@ static inline int sci_rxd_in(struct uart_port *port) static inline int sci_rxd_in(struct uart_port *port) { if (port->mapbase == 0xf8400000) - return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ + return __raw_readw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ if (port->mapbase == 0xf8410000) - return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ + return __raw_readw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ if (port->mapbase == 0xf8420000) - return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ + return __raw_readw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ return 1; } #elif defined(CONFIG_CPU_SUBTYPE_SHX3) static inline int sci_rxd_in(struct uart_port *port) { if (port->mapbase == 0xffc30000) - return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ + return __raw_readw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ if (port->mapbase == 0xffc40000) - return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ + return __raw_readw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ if (port->mapbase == 0xffc50000) - return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ + return __raw_readw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ if (port->mapbase == 0xffc60000) - return ctrl_inw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */ + return __raw_readw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */ return 1; } #endif -- cgit v0.10.2 From c0d7a0212becebe11ffe6979ee3d6f1c4104568d Mon Sep 17 00:00:00 2001 From: Jarek Poplawski Date: Wed, 23 Dec 2009 21:54:29 -0800 Subject: net/via-rhine: Fix scheduling while atomic bugs There are BUGs "scheduling while atomic" triggered by the timer rhine_tx_timeout(). They are caused by calling napi_disable() (with msleep()). This patch fixes it by moving most of the timer content to the workqueue function (similarly to other drivers, like tg3), with spin_lock() changed to BH version. Additionally, there is spin_lock_irq() moved in rhine_close() to exclude napi_disable() etc., also tg3's way. Reported-by: Andrey Rahmatullin Tested-by: Andrey Rahmatullin Signed-off-by: Jarek Poplawski Signed-off-by: David S. Miller diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c index 593e01f..611b804 100644 --- a/drivers/net/via-rhine.c +++ b/drivers/net/via-rhine.c @@ -102,6 +102,7 @@ static const int multicast_filter_limit = 32; #include #include #include +#include #include /* Processor type for cache alignment. */ #include #include @@ -389,6 +390,7 @@ struct rhine_private { struct net_device *dev; struct napi_struct napi; spinlock_t lock; + struct work_struct reset_task; /* Frequently used values: keep some adjacent for cache effect. */ u32 quirks; @@ -407,6 +409,7 @@ struct rhine_private { static int mdio_read(struct net_device *dev, int phy_id, int location); static void mdio_write(struct net_device *dev, int phy_id, int location, int value); static int rhine_open(struct net_device *dev); +static void rhine_reset_task(struct work_struct *work); static void rhine_tx_timeout(struct net_device *dev); static netdev_tx_t rhine_start_tx(struct sk_buff *skb, struct net_device *dev); @@ -775,6 +778,8 @@ static int __devinit rhine_init_one(struct pci_dev *pdev, dev->irq = pdev->irq; spin_lock_init(&rp->lock); + INIT_WORK(&rp->reset_task, rhine_reset_task); + rp->mii_if.dev = dev; rp->mii_if.mdio_read = mdio_read; rp->mii_if.mdio_write = mdio_write; @@ -1179,22 +1184,18 @@ static int rhine_open(struct net_device *dev) return 0; } -static void rhine_tx_timeout(struct net_device *dev) +static void rhine_reset_task(struct work_struct *work) { - struct rhine_private *rp = netdev_priv(dev); - void __iomem *ioaddr = rp->base; - - printk(KERN_WARNING "%s: Transmit timed out, status %4.4x, PHY status " - "%4.4x, resetting...\n", - dev->name, ioread16(ioaddr + IntrStatus), - mdio_read(dev, rp->mii_if.phy_id, MII_BMSR)); + struct rhine_private *rp = container_of(work, struct rhine_private, + reset_task); + struct net_device *dev = rp->dev; /* protect against concurrent rx interrupts */ disable_irq(rp->pdev->irq); napi_disable(&rp->napi); - spin_lock(&rp->lock); + spin_lock_bh(&rp->lock); /* clear all descriptors */ free_tbufs(dev); @@ -1206,7 +1207,7 @@ static void rhine_tx_timeout(struct net_device *dev) rhine_chip_reset(dev); init_registers(dev); - spin_unlock(&rp->lock); + spin_unlock_bh(&rp->lock); enable_irq(rp->pdev->irq); dev->trans_start = jiffies; @@ -1214,6 +1215,19 @@ static void rhine_tx_timeout(struct net_device *dev) netif_wake_queue(dev); } +static void rhine_tx_timeout(struct net_device *dev) +{ + struct rhine_private *rp = netdev_priv(dev); + void __iomem *ioaddr = rp->base; + + printk(KERN_WARNING "%s: Transmit timed out, status %4.4x, PHY status " + "%4.4x, resetting...\n", + dev->name, ioread16(ioaddr + IntrStatus), + mdio_read(dev, rp->mii_if.phy_id, MII_BMSR)); + + schedule_work(&rp->reset_task); +} + static netdev_tx_t rhine_start_tx(struct sk_buff *skb, struct net_device *dev) { @@ -1830,10 +1844,11 @@ static int rhine_close(struct net_device *dev) struct rhine_private *rp = netdev_priv(dev); void __iomem *ioaddr = rp->base; - spin_lock_irq(&rp->lock); - - netif_stop_queue(dev); napi_disable(&rp->napi); + cancel_work_sync(&rp->reset_task); + netif_stop_queue(dev); + + spin_lock_irq(&rp->lock); if (debug > 1) printk(KERN_DEBUG "%s: Shutting down ethercard, " -- cgit v0.10.2 From 44ef00e6482e755f36629773abc2aee83a6f53e3 Mon Sep 17 00:00:00 2001 From: Thomas Renninger Date: Fri, 18 Dec 2009 15:29:23 +0100 Subject: hp-wmi: Fix two memleaks Signed-off-by: Thomas Renninger Signed-off-by: Len Brown diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c index db10c5d..8781d8fa 100644 --- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c @@ -134,10 +134,15 @@ static int hp_wmi_perform_query(int query, int write, int value) obj = output.pointer; - if (!obj || obj->type != ACPI_TYPE_BUFFER) + if (!obj) return -EINVAL; + else if (obj->type != ACPI_TYPE_BUFFER) { + kfree(obj); + return -EINVAL; + } bios_return = *((struct bios_return *)obj->buffer.pointer); + kfree(obj); if (bios_return.return_code > 0) return bios_return.return_code * -1; else @@ -340,10 +345,12 @@ static void hp_wmi_notify(u32 value, void *context) if (!obj || obj->type != ACPI_TYPE_BUFFER || obj->buffer.length != 8) { printk(KERN_INFO "HP WMI: Unknown response received\n"); + kfree(obj); return; } eventcode = *((u8 *) obj->buffer.pointer); + kfree(obj); if (eventcode == 0x4) eventcode = hp_wmi_perform_query(HPWMI_HOTKEY_QUERY, 0, 0); -- cgit v0.10.2 From 9503e891d28e91961026c778ec251dfe886626fb Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 24 Dec 2009 05:27:47 +0000 Subject: sh: mach-ecovec24: setup.c detailed correction o remove unused define o add device name comment Signed-off-by: Kuninori Morimoto Signed-off-by: Paul Mundt diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c index 194aaca..6a8861b 100644 --- a/arch/sh/boards/mach-ecovec24/setup.c +++ b/arch/sh/boards/mach-ecovec24/setup.c @@ -128,8 +128,6 @@ static struct platform_device nor_flash_device = { /* SH Eth */ #define SH_ETH_ADDR (0xA4600000) -#define SH_ETH_MAHR (SH_ETH_ADDR + 0x1C0) -#define SH_ETH_MALR (SH_ETH_ADDR + 0x1C8) static struct resource sh_eth_resources[] = { [0] = { .start = SH_ETH_ADDR, @@ -509,6 +507,7 @@ static struct platform_device sdhi1_device = { #else +/* MMC SPI */ static int mmc_spi_get_ro(struct device *dev) { return gpio_get_value(GPIO_PTY6); @@ -542,6 +541,7 @@ static struct spi_board_info spi_bus[] = { }, }; +/* MSIOF0 */ static struct sh_msiof_spi_info msiof0_data = { .num_chipselect = 1, }; -- cgit v0.10.2 From f466dba1832f05006cf6caa9be41fb98d11cb848 Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Wed, 23 Dec 2009 22:02:57 -0800 Subject: pktgen: ndo_start_xmit can return NET_XMIT_xxx values This updates pktgen so that it does not decrement skb->users when it receives valid NET_XMIT_xxx values. These are now valid return values from ndo_start_xmit in net-next-2.6. They also indicate the skb has been consumed. This fixes pktgen to work correctly with vlan devices. Signed-off-by: John Fastabend Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller diff --git a/net/core/pktgen.c b/net/core/pktgen.c index a23b45f..de0c2c7 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -250,8 +250,7 @@ struct pktgen_dev { __u64 count; /* Default No packets to send */ __u64 sofar; /* How many pkts we've sent so far */ __u64 tx_bytes; /* How many bytes we've transmitted */ - __u64 errors; /* Errors when trying to transmit, - pkts will be re-sent */ + __u64 errors; /* Errors when trying to transmit, */ /* runtime counters relating to clone_skb */ @@ -3465,6 +3464,12 @@ static void pktgen_xmit(struct pktgen_dev *pkt_dev) pkt_dev->seq_num++; pkt_dev->tx_bytes += pkt_dev->last_pkt_size; break; + case NET_XMIT_DROP: + case NET_XMIT_CN: + case NET_XMIT_POLICED: + /* skb has been consumed */ + pkt_dev->errors++; + break; default: /* Drivers are not supposed to return other values! */ if (net_ratelimit()) pr_info("pktgen: %s xmit error: %d\n", -- cgit v0.10.2 From 76382b5bdb77c29ab430e1b82ef1c604c8dd113b Mon Sep 17 00:00:00 2001 From: Markus Pietrek Date: Thu, 24 Dec 2009 15:12:02 +0900 Subject: sh: Ensure all PG_dcache_dirty pages are written back. With some of the cache rework an address aliasing optimization was added, but this managed to fail on certain mappings resulting in pages with PG_dcache_dirty set never writing back their dcache lines. This patch reverts to the earlier behaviour of simply always writing back when the dirty bit is set. Signed-off-by: Markus Pietrek Signed-off-by: Paul Mundt diff --git a/arch/sh/mm/cache.c b/arch/sh/mm/cache.c index e9415d3..b8607fa 100644 --- a/arch/sh/mm/cache.c +++ b/arch/sh/mm/cache.c @@ -133,12 +133,8 @@ void __update_cache(struct vm_area_struct *vma, page = pfn_to_page(pfn); if (pfn_valid(pfn)) { int dirty = test_and_clear_bit(PG_dcache_dirty, &page->flags); - if (dirty) { - unsigned long addr = (unsigned long)page_address(page); - - if (pages_do_alias(addr, address & PAGE_MASK)) - __flush_purge_region((void *)addr, PAGE_SIZE); - } + if (dirty) + __flush_purge_region(page_address(page), PAGE_SIZE); } } -- cgit v0.10.2 From 529aa8cb0a59367d08883f818e8c47028e819d0d Mon Sep 17 00:00:00 2001 From: Thadeu Lima de Souza Cascardo Date: Mon, 21 Dec 2009 16:20:01 -0800 Subject: classmate-laptop: add support for Classmate PC ACPI devices This add supports for devices like keyboard, backlight, tablet and accelerometer. This work is supported by International Syst S/A. [randy.dunlap@oracle.com: cmpc_acpi: depends on ACPI] [akpm@linux-foundation.org: readability tweaks] [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Thadeu Lima de Souza Cascardo Signed-off-by: Andrew Morton Signed-off-by: Len Brown diff --git a/MAINTAINERS b/MAINTAINERS index efd2ef2..9ddfc97 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1470,6 +1470,12 @@ L: linux-scsi@vger.kernel.org S: Supported F: drivers/scsi/fnic/ +CMPC ACPI DRIVER +M: Thadeu Lima de Souza Cascardo +M: Daniel Oliveira Nascimento +S: Supported +F: drivers/platform/x86/classmate-laptop.c + CODA FILE SYSTEM M: Jan Harkes M: coda@cs.cmu.edu diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index fc5bf9d..ec4faff 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -464,4 +464,16 @@ config TOSHIBA_BT_RFKILL If you have a modern Toshiba laptop with a Bluetooth and an RFKill switch (such as the Portege R500), say Y. + +config ACPI_CMPC + tristate "CMPC Laptop Extras" + depends on X86 && ACPI + select INPUT + select BACKLIGHT_CLASS_DEVICE + default n + help + Support for Intel Classmate PC ACPI devices, including some + keys as input device, backlight device, tablet and accelerometer + devices. + endif # X86_PLATFORM_DEVICES diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile index b7474b6..9cd9fa0 100644 --- a/drivers/platform/x86/Makefile +++ b/drivers/platform/x86/Makefile @@ -5,6 +5,7 @@ obj-$(CONFIG_ASUS_LAPTOP) += asus-laptop.o obj-$(CONFIG_EEEPC_LAPTOP) += eeepc-laptop.o obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o +obj-$(CONFIG_ACPI_CMPC) += classmate-laptop.o obj-$(CONFIG_COMPAL_LAPTOP) += compal-laptop.o obj-$(CONFIG_DELL_LAPTOP) += dell-laptop.o obj-$(CONFIG_DELL_WMI) += dell-wmi.o diff --git a/drivers/platform/x86/classmate-laptop.c b/drivers/platform/x86/classmate-laptop.c new file mode 100644 index 0000000..ed90082 --- /dev/null +++ b/drivers/platform/x86/classmate-laptop.c @@ -0,0 +1,609 @@ +/* + * Copyright (C) 2009 Thadeu Lima de Souza Cascardo + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + + +#include +#include +#include +#include +#include +#include + +MODULE_LICENSE("GPL"); + + +struct cmpc_accel { + int sensitivity; +}; + +#define CMPC_ACCEL_SENSITIVITY_DEFAULT 5 + + +/* + * Generic input device code. + */ + +typedef void (*input_device_init)(struct input_dev *dev); + +static int cmpc_add_acpi_notify_device(struct acpi_device *acpi, char *name, + input_device_init idev_init) +{ + struct input_dev *inputdev; + int error; + + inputdev = input_allocate_device(); + if (!inputdev) + return -ENOMEM; + inputdev->name = name; + inputdev->dev.parent = &acpi->dev; + idev_init(inputdev); + error = input_register_device(inputdev); + if (error) { + input_free_device(inputdev); + return error; + } + dev_set_drvdata(&acpi->dev, inputdev); + return 0; +} + +static int cmpc_remove_acpi_notify_device(struct acpi_device *acpi) +{ + struct input_dev *inputdev = dev_get_drvdata(&acpi->dev); + input_unregister_device(inputdev); + return 0; +} + +/* + * Accelerometer code. + */ +static acpi_status cmpc_start_accel(acpi_handle handle) +{ + union acpi_object param[2]; + struct acpi_object_list input; + acpi_status status; + + param[0].type = ACPI_TYPE_INTEGER; + param[0].integer.value = 0x3; + param[1].type = ACPI_TYPE_INTEGER; + input.count = 2; + input.pointer = param; + status = acpi_evaluate_object(handle, "ACMD", &input, NULL); + return status; +} + +static acpi_status cmpc_stop_accel(acpi_handle handle) +{ + union acpi_object param[2]; + struct acpi_object_list input; + acpi_status status; + + param[0].type = ACPI_TYPE_INTEGER; + param[0].integer.value = 0x4; + param[1].type = ACPI_TYPE_INTEGER; + input.count = 2; + input.pointer = param; + status = acpi_evaluate_object(handle, "ACMD", &input, NULL); + return status; +} + +static acpi_status cmpc_accel_set_sensitivity(acpi_handle handle, int val) +{ + union acpi_object param[2]; + struct acpi_object_list input; + + param[0].type = ACPI_TYPE_INTEGER; + param[0].integer.value = 0x02; + param[1].type = ACPI_TYPE_INTEGER; + param[1].integer.value = val; + input.count = 2; + input.pointer = param; + return acpi_evaluate_object(handle, "ACMD", &input, NULL); +} + +static acpi_status cmpc_get_accel(acpi_handle handle, + unsigned char *x, + unsigned char *y, + unsigned char *z) +{ + union acpi_object param[2]; + struct acpi_object_list input; + struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, 0 }; + unsigned char *locs; + acpi_status status; + + param[0].type = ACPI_TYPE_INTEGER; + param[0].integer.value = 0x01; + param[1].type = ACPI_TYPE_INTEGER; + input.count = 2; + input.pointer = param; + status = acpi_evaluate_object(handle, "ACMD", &input, &output); + if (ACPI_SUCCESS(status)) { + union acpi_object *obj; + obj = output.pointer; + locs = obj->buffer.pointer; + *x = locs[0]; + *y = locs[1]; + *z = locs[2]; + kfree(output.pointer); + } + return status; +} + +static void cmpc_accel_handler(struct acpi_device *dev, u32 event) +{ + if (event == 0x81) { + unsigned char x, y, z; + acpi_status status; + + status = cmpc_get_accel(dev->handle, &x, &y, &z); + if (ACPI_SUCCESS(status)) { + struct input_dev *inputdev = dev_get_drvdata(&dev->dev); + + input_report_abs(inputdev, ABS_X, x); + input_report_abs(inputdev, ABS_Y, y); + input_report_abs(inputdev, ABS_Z, z); + input_sync(inputdev); + } + } +} + +static ssize_t cmpc_accel_sensitivity_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct acpi_device *acpi; + struct input_dev *inputdev; + struct cmpc_accel *accel; + + acpi = to_acpi_device(dev); + inputdev = dev_get_drvdata(&acpi->dev); + accel = dev_get_drvdata(&inputdev->dev); + + return sprintf(buf, "%d\n", accel->sensitivity); +} + +static ssize_t cmpc_accel_sensitivity_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct acpi_device *acpi; + struct input_dev *inputdev; + struct cmpc_accel *accel; + unsigned long sensitivity; + int r; + + acpi = to_acpi_device(dev); + inputdev = dev_get_drvdata(&acpi->dev); + accel = dev_get_drvdata(&inputdev->dev); + + r = strict_strtoul(buf, 0, &sensitivity); + if (r) + return r; + + accel->sensitivity = sensitivity; + cmpc_accel_set_sensitivity(acpi->handle, sensitivity); + + return strnlen(buf, count); +} + +struct device_attribute cmpc_accel_sensitivity_attr = { + .attr = { .name = "sensitivity", .mode = 0660 }, + .show = cmpc_accel_sensitivity_show, + .store = cmpc_accel_sensitivity_store +}; + +static int cmpc_accel_open(struct input_dev *input) +{ + struct acpi_device *acpi; + + acpi = to_acpi_device(input->dev.parent); + if (ACPI_SUCCESS(cmpc_start_accel(acpi->handle))) + return 0; + return -EIO; +} + +static void cmpc_accel_close(struct input_dev *input) +{ + struct acpi_device *acpi; + + acpi = to_acpi_device(input->dev.parent); + cmpc_stop_accel(acpi->handle); +} + +static void cmpc_accel_idev_init(struct input_dev *inputdev) +{ + set_bit(EV_ABS, inputdev->evbit); + input_set_abs_params(inputdev, ABS_X, 0, 255, 8, 0); + input_set_abs_params(inputdev, ABS_Y, 0, 255, 8, 0); + input_set_abs_params(inputdev, ABS_Z, 0, 255, 8, 0); + inputdev->open = cmpc_accel_open; + inputdev->close = cmpc_accel_close; +} + +static int cmpc_accel_add(struct acpi_device *acpi) +{ + int error; + struct input_dev *inputdev; + struct cmpc_accel *accel; + + accel = kmalloc(sizeof(*accel), GFP_KERNEL); + if (!accel) + return -ENOMEM; + + accel->sensitivity = CMPC_ACCEL_SENSITIVITY_DEFAULT; + cmpc_accel_set_sensitivity(acpi->handle, accel->sensitivity); + + error = device_create_file(&acpi->dev, &cmpc_accel_sensitivity_attr); + if (error) + goto failed_file; + + error = cmpc_add_acpi_notify_device(acpi, "cmpc_accel", + cmpc_accel_idev_init); + if (error) + goto failed_input; + + inputdev = dev_get_drvdata(&acpi->dev); + dev_set_drvdata(&inputdev->dev, accel); + + return 0; + +failed_input: + device_remove_file(&acpi->dev, &cmpc_accel_sensitivity_attr); +failed_file: + kfree(accel); + return error; +} + +static int cmpc_accel_remove(struct acpi_device *acpi, int type) +{ + struct input_dev *inputdev; + struct cmpc_accel *accel; + + inputdev = dev_get_drvdata(&acpi->dev); + accel = dev_get_drvdata(&inputdev->dev); + + device_remove_file(&acpi->dev, &cmpc_accel_sensitivity_attr); + return cmpc_remove_acpi_notify_device(acpi); +} + +static const struct acpi_device_id cmpc_accel_device_ids[] = { + {"ACCE0000", 0}, + {"", 0} +}; +MODULE_DEVICE_TABLE(acpi, cmpc_accel_device_ids); + +static struct acpi_driver cmpc_accel_acpi_driver = { + .owner = THIS_MODULE, + .name = "cmpc_accel", + .class = "cmpc_accel", + .ids = cmpc_accel_device_ids, + .ops = { + .add = cmpc_accel_add, + .remove = cmpc_accel_remove, + .notify = cmpc_accel_handler, + } +}; + + +/* + * Tablet mode code. + */ +static acpi_status cmpc_get_tablet(acpi_handle handle, + unsigned long long *value) +{ + union acpi_object param; + struct acpi_object_list input; + unsigned long long output; + acpi_status status; + + param.type = ACPI_TYPE_INTEGER; + param.integer.value = 0x01; + input.count = 1; + input.pointer = ¶m; + status = acpi_evaluate_integer(handle, "TCMD", &input, &output); + if (ACPI_SUCCESS(status)) + *value = output; + return status; +} + +static void cmpc_tablet_handler(struct acpi_device *dev, u32 event) +{ + unsigned long long val = 0; + struct input_dev *inputdev = dev_get_drvdata(&dev->dev); + + if (event == 0x81) { + if (ACPI_SUCCESS(cmpc_get_tablet(dev->handle, &val))) + input_report_switch(inputdev, SW_TABLET_MODE, !val); + } +} + +static void cmpc_tablet_idev_init(struct input_dev *inputdev) +{ + unsigned long long val = 0; + struct acpi_device *acpi; + + set_bit(EV_SW, inputdev->evbit); + set_bit(SW_TABLET_MODE, inputdev->swbit); + + acpi = to_acpi_device(inputdev->dev.parent); + if (ACPI_SUCCESS(cmpc_get_tablet(acpi->handle, &val))) + input_report_switch(inputdev, SW_TABLET_MODE, !val); +} + +static int cmpc_tablet_add(struct acpi_device *acpi) +{ + return cmpc_add_acpi_notify_device(acpi, "cmpc_tablet", + cmpc_tablet_idev_init); +} + +static int cmpc_tablet_remove(struct acpi_device *acpi, int type) +{ + return cmpc_remove_acpi_notify_device(acpi); +} + +static int cmpc_tablet_resume(struct acpi_device *acpi) +{ + struct input_dev *inputdev = dev_get_drvdata(&acpi->dev); + unsigned long long val = 0; + if (ACPI_SUCCESS(cmpc_get_tablet(acpi->handle, &val))) + input_report_switch(inputdev, SW_TABLET_MODE, !val); + return 0; +} + +static const struct acpi_device_id cmpc_tablet_device_ids[] = { + {"TBLT0000", 0}, + {"", 0} +}; +MODULE_DEVICE_TABLE(acpi, cmpc_tablet_device_ids); + +static struct acpi_driver cmpc_tablet_acpi_driver = { + .owner = THIS_MODULE, + .name = "cmpc_tablet", + .class = "cmpc_tablet", + .ids = cmpc_tablet_device_ids, + .ops = { + .add = cmpc_tablet_add, + .remove = cmpc_tablet_remove, + .resume = cmpc_tablet_resume, + .notify = cmpc_tablet_handler, + } +}; + + +/* + * Backlight code. + */ + +static acpi_status cmpc_get_brightness(acpi_handle handle, + unsigned long long *value) +{ + union acpi_object param; + struct acpi_object_list input; + unsigned long long output; + acpi_status status; + + param.type = ACPI_TYPE_INTEGER; + param.integer.value = 0xC0; + input.count = 1; + input.pointer = ¶m; + status = acpi_evaluate_integer(handle, "GRDI", &input, &output); + if (ACPI_SUCCESS(status)) + *value = output; + return status; +} + +static acpi_status cmpc_set_brightness(acpi_handle handle, + unsigned long long value) +{ + union acpi_object param[2]; + struct acpi_object_list input; + acpi_status status; + unsigned long long output; + + param[0].type = ACPI_TYPE_INTEGER; + param[0].integer.value = 0xC0; + param[1].type = ACPI_TYPE_INTEGER; + param[1].integer.value = value; + input.count = 2; + input.pointer = param; + status = acpi_evaluate_integer(handle, "GWRI", &input, &output); + return status; +} + +static int cmpc_bl_get_brightness(struct backlight_device *bd) +{ + acpi_status status; + acpi_handle handle; + unsigned long long brightness; + + handle = bl_get_data(bd); + status = cmpc_get_brightness(handle, &brightness); + if (ACPI_SUCCESS(status)) + return brightness; + else + return -1; +} + +static int cmpc_bl_update_status(struct backlight_device *bd) +{ + acpi_status status; + acpi_handle handle; + + handle = bl_get_data(bd); + status = cmpc_set_brightness(handle, bd->props.brightness); + if (ACPI_SUCCESS(status)) + return 0; + else + return -1; +} + +static struct backlight_ops cmpc_bl_ops = { + .get_brightness = cmpc_bl_get_brightness, + .update_status = cmpc_bl_update_status +}; + +static int cmpc_bl_add(struct acpi_device *acpi) +{ + struct backlight_device *bd; + + bd = backlight_device_register("cmpc_bl", &acpi->dev, + acpi->handle, &cmpc_bl_ops); + bd->props.max_brightness = 7; + dev_set_drvdata(&acpi->dev, bd); + return 0; +} + +static int cmpc_bl_remove(struct acpi_device *acpi, int type) +{ + struct backlight_device *bd; + + bd = dev_get_drvdata(&acpi->dev); + backlight_device_unregister(bd); + return 0; +} + +static const struct acpi_device_id cmpc_device_ids[] = { + {"IPML200", 0}, + {"", 0} +}; +MODULE_DEVICE_TABLE(acpi, cmpc_device_ids); + +static struct acpi_driver cmpc_bl_acpi_driver = { + .owner = THIS_MODULE, + .name = "cmpc", + .class = "cmpc", + .ids = cmpc_device_ids, + .ops = { + .add = cmpc_bl_add, + .remove = cmpc_bl_remove + } +}; + + +/* + * Extra keys code. + */ +static int cmpc_keys_codes[] = { + KEY_UNKNOWN, + KEY_WLAN, + KEY_SWITCHVIDEOMODE, + KEY_BRIGHTNESSDOWN, + KEY_BRIGHTNESSUP, + KEY_VENDOR, + KEY_MAX +}; + +static void cmpc_keys_handler(struct acpi_device *dev, u32 event) +{ + struct input_dev *inputdev; + int code = KEY_MAX; + + if ((event & 0x0F) < ARRAY_SIZE(cmpc_keys_codes)) + code = cmpc_keys_codes[event & 0x0F]; + inputdev = dev_get_drvdata(&dev->dev);; + input_report_key(inputdev, code, !(event & 0x10)); +} + +static void cmpc_keys_idev_init(struct input_dev *inputdev) +{ + int i; + + set_bit(EV_KEY, inputdev->evbit); + for (i = 0; cmpc_keys_codes[i] != KEY_MAX; i++) + set_bit(cmpc_keys_codes[i], inputdev->keybit); +} + +static int cmpc_keys_add(struct acpi_device *acpi) +{ + return cmpc_add_acpi_notify_device(acpi, "cmpc_keys", + cmpc_keys_idev_init); +} + +static int cmpc_keys_remove(struct acpi_device *acpi, int type) +{ + return cmpc_remove_acpi_notify_device(acpi); +} + +static const struct acpi_device_id cmpc_keys_device_ids[] = { + {"FnBT0000", 0}, + {"", 0} +}; +MODULE_DEVICE_TABLE(acpi, cmpc_keys_device_ids); + +static struct acpi_driver cmpc_keys_acpi_driver = { + .owner = THIS_MODULE, + .name = "cmpc_keys", + .class = "cmpc_keys", + .ids = cmpc_keys_device_ids, + .ops = { + .add = cmpc_keys_add, + .remove = cmpc_keys_remove, + .notify = cmpc_keys_handler, + } +}; + + +/* + * General init/exit code. + */ + +static int cmpc_init(void) +{ + int r; + + r = acpi_bus_register_driver(&cmpc_keys_acpi_driver); + if (r) + goto failed_keys; + + r = acpi_bus_register_driver(&cmpc_bl_acpi_driver); + if (r) + goto failed_bl; + + r = acpi_bus_register_driver(&cmpc_tablet_acpi_driver); + if (r) + goto failed_tablet; + + r = acpi_bus_register_driver(&cmpc_accel_acpi_driver); + if (r) + goto failed_accel; + + return r; + +failed_accel: + acpi_bus_unregister_driver(&cmpc_tablet_acpi_driver); + +failed_tablet: + acpi_bus_unregister_driver(&cmpc_bl_acpi_driver); + +failed_bl: + acpi_bus_unregister_driver(&cmpc_keys_acpi_driver); + +failed_keys: + return r; +} + +static void cmpc_exit(void) +{ + acpi_bus_unregister_driver(&cmpc_accel_acpi_driver); + acpi_bus_unregister_driver(&cmpc_tablet_acpi_driver); + acpi_bus_unregister_driver(&cmpc_bl_acpi_driver); + acpi_bus_unregister_driver(&cmpc_keys_acpi_driver); +} + +module_init(cmpc_init); +module_exit(cmpc_exit); -- cgit v0.10.2 From 603adaf6b3e37450235f0ddb5986b961b3146a79 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Mon, 21 Dec 2009 14:52:53 +0100 Subject: amd64_edac: fix K8 chip select reporting Fix the case when amd64_debug_display_dimm_sizes() reports only half the amount of DRAM on it because it doesn't account for when the single DCT operates in 128-bit mode and merges chip selects from different DIMMs. Reported-by: Johannes Hirte LKML-Reference: <200912112202.48173.johannes.hirte@fem.tu-ilmenau.de> Signed-off-by: Borislav Petkov diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index df5b684..784cc5a 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c @@ -1700,11 +1700,14 @@ static void f10_map_sysaddr_to_csrow(struct mem_ctl_info *mci, */ static void amd64_debug_display_dimm_sizes(int ctrl, struct amd64_pvt *pvt) { - int dimm, size0, size1; + int dimm, size0, size1, factor = 0; u32 dbam; u32 *dcsb; if (boot_cpu_data.x86 == 0xf) { + if (pvt->dclr0 & F10_WIDTH_128) + factor = 1; + /* K8 families < revF not supported yet */ if (pvt->ext_model < K8_REV_F) return; @@ -1732,7 +1735,8 @@ static void amd64_debug_display_dimm_sizes(int ctrl, struct amd64_pvt *pvt) size1 = pvt->ops->dbam_to_cs(pvt, DBAM_DIMM(dimm, dbam)); edac_printk(KERN_DEBUG, EDAC_MC, " %d: %5dMB %d: %5dMB\n", - dimm * 2, size0, dimm * 2 + 1, size1); + dimm * 2, size0 << factor, + dimm * 2 + 1, size1 << factor); } } -- cgit v0.10.2 From 8f68ed9728193b1f2fb53ba06031b06bd8b3d1b4 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Mon, 21 Dec 2009 15:15:59 +0100 Subject: amd64_edac: fix driver instance freeing Fix use-after-free errors by pushing all memory-freeing calls to the end of amd64_remove_one_instance(). Reported-by: Darren Jenkins LKML-Reference: <1261370306.11354.52.camel@ICE-BOX> Signed-off-by: Borislav Petkov diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index 784cc5a..fb0d36b 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c @@ -2929,16 +2929,15 @@ static void __devexit amd64_remove_one_instance(struct pci_dev *pdev) amd64_free_mc_sibling_devices(pvt); - kfree(pvt); - mci->pvt_info = NULL; - - mci_lookup[pvt->mc_node_id] = NULL; - /* unregister from EDAC MCE */ amd_report_gart_errors(false); amd_unregister_ecc_decoder(amd64_decode_bus_error); /* Free the EDAC CORE resources */ + mci->pvt_info = NULL; + mci_lookup[pvt->mc_node_id] = NULL; + + kfree(pvt); edac_mc_free(mci); } -- cgit v0.10.2 From 56b34b91e22313294154cee0c16e294cf8a45b61 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Mon, 21 Dec 2009 18:13:01 +0100 Subject: amd64_edac: make driver loading more robust Currently, the module does not initialize fully when the DIMMs aren't ECC but remains still loaded. Propagate the error when no instance of the driver is properly initialized and prevent further loading. Reorganize and polish error handling in amd64_edac_init() while at it. Signed-off-by: Borislav Petkov diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index fb0d36b..a8af27a 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c @@ -3014,25 +3014,29 @@ static void amd64_setup_pci_device(void) static int __init amd64_edac_init(void) { int nb, err = -ENODEV; + bool load_ok = false; edac_printk(KERN_INFO, EDAC_MOD_STR, EDAC_AMD64_VERSION "\n"); opstate_init(); if (cache_k8_northbridges() < 0) - return err; + goto err_ret; msrs = msrs_alloc(); + if (!msrs) + goto err_ret; err = pci_register_driver(&amd64_pci_driver); if (err) - return err; + goto err_pci; /* * At this point, the array 'pvt_lookup[]' contains pointers to alloc'd * amd64_pvt structs. These will be used in the 2nd stage init function * to finish initialization of the MC instances. */ + err = -ENODEV; for (nb = 0; nb < num_k8_northbridges; nb++) { if (!pvt_lookup[nb]) continue; @@ -3040,16 +3044,21 @@ static int __init amd64_edac_init(void) err = amd64_init_2nd_stage(pvt_lookup[nb]); if (err) goto err_2nd_stage; - } - amd64_setup_pci_device(); + load_ok = true; + } - return 0; + if (load_ok) { + amd64_setup_pci_device(); + return 0; + } err_2nd_stage: - debugf0("2nd stage failed\n"); pci_unregister_driver(&amd64_pci_driver); - +err_pci: + msrs_free(msrs); + msrs = NULL; +err_ret: return err; } -- cgit v0.10.2 From 43f5e68733cfe8bed3c30b5c14c4993dffb29766 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Mon, 21 Dec 2009 18:55:18 +0100 Subject: amd64_edac: fix forcing module load/unload Clear the override flag after force-loading the module. Signed-off-by: Borislav Petkov diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index a8af27a..63c04d3 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c @@ -2690,9 +2690,8 @@ static int amd64_check_ecc_enabled(struct amd64_pvt *pvt) amd64_printk(KERN_WARNING, "%s", ecc_warning); return -ENODEV; } - } else - /* CLEAR the override, since BIOS controlled it */ ecc_enable_override = 0; + } return 0; } -- cgit v0.10.2 From 92389102b6832fc779f5c37f1d9e3eaadea6e059 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Mon, 21 Dec 2009 19:21:41 +0100 Subject: amd64_edac: restrict PCI config space access Do not access F2x19[0,4] on K8 since they're undefined there. Signed-off-by: Borislav Petkov diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index 63c04d3..c5facd9 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c @@ -2349,7 +2349,7 @@ static void amd64_read_mc_registers(struct amd64_pvt *pvt) amd64_read_pci_cfg(pvt->dram_f2_ctl, F10_DCLR_0, &pvt->dclr0); amd64_read_pci_cfg(pvt->dram_f2_ctl, F10_DCHR_0, &pvt->dchr0); - if (!dct_ganging_enabled(pvt)) { + if (!dct_ganging_enabled(pvt) && boot_cpu_data.x86 >= 0x10) { amd64_read_pci_cfg(pvt->dram_f2_ctl, F10_DCLR_1, &pvt->dclr1); amd64_read_pci_cfg(pvt->dram_f2_ctl, F10_DCHR_1, &pvt->dchr1); } -- cgit v0.10.2 From 5213c32f9d56db6a5e3ae8d2977a3961e98211fd Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Mon, 21 Dec 2009 19:11:12 +0100 Subject: edac, pci: remove pesky debug printk Do not spam the logs needlessly with the sole info that edac_pci_dev_parity_clear is being called. Signed-off-by: Borislav Petkov diff --git a/drivers/edac/edac_pci_sysfs.c b/drivers/edac/edac_pci_sysfs.c index 422728c..fb60a87 100644 --- a/drivers/edac/edac_pci_sysfs.c +++ b/drivers/edac/edac_pci_sysfs.c @@ -534,8 +534,6 @@ static void edac_pci_dev_parity_clear(struct pci_dev *dev) { u8 header_type; - debugf0("%s()\n", __func__); - get_pci_parity_status(dev, 0); /* read the device TYPE, looking for bridges */ -- cgit v0.10.2 From 6dc995a3da9adfa83d61ccf06aa1afa5f6ab764f Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 24 Dec 2009 10:16:21 +0000 Subject: ARM: fix PAGE_KERNEL PAGE_KERNEL should not be executable; any area marked executable can be prefetched into the instruction cache. We don't want vmalloc areas to be read in this way. Signed-off-by: Russell King diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 8c7fbd1..1708da8 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -453,8 +453,7 @@ static void __init build_mem_type_table(void) pgprot_user = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | user_pgprot); pgprot_kernel = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | - L_PTE_DIRTY | L_PTE_WRITE | - L_PTE_EXEC | kern_pgprot); + L_PTE_DIRTY | L_PTE_WRITE | kern_pgprot); mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask; mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask; -- cgit v0.10.2 From 18f98ab54735f66ea84bf679b70fcec5e8b3df66 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 14 Dec 2009 13:22:04 +0900 Subject: ASoC: fsi-ak4642: Remove ak4642_add_i2c_device I2C devices should be registered when platform board setting in latest ASoC. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown diff --git a/sound/soc/sh/fsi-ak4642.c b/sound/soc/sh/fsi-ak4642.c index c7af097..5263ab1 100644 --- a/sound/soc/sh/fsi-ak4642.c +++ b/sound/soc/sh/fsi-ak4642.c @@ -42,42 +42,12 @@ static struct snd_soc_device fsi_snd_devdata = { .codec_dev = &soc_codec_dev_ak4642, }; -#define AK4642_BUS 0 -#define AK4642_ADR 0x12 -static int ak4642_add_i2c_device(void) -{ - struct i2c_board_info info; - struct i2c_adapter *adapter; - struct i2c_client *client; - - memset(&info, 0, sizeof(struct i2c_board_info)); - info.addr = AK4642_ADR; - strlcpy(info.type, "ak4642", I2C_NAME_SIZE); - - adapter = i2c_get_adapter(AK4642_BUS); - if (!adapter) { - printk(KERN_DEBUG "can't get i2c adapter\n"); - return -ENODEV; - } - - client = i2c_new_device(adapter, &info); - i2c_put_adapter(adapter); - if (!client) { - printk(KERN_DEBUG "can't add i2c device\n"); - return -ENODEV; - } - - return 0; -} - static struct platform_device *fsi_snd_device; static int __init fsi_ak4642_init(void) { int ret = -ENOMEM; - ak4642_add_i2c_device(); - fsi_snd_device = platform_device_alloc("soc-audio", -1); if (!fsi_snd_device) goto out; -- cgit v0.10.2 From b3172f222ab5afdc91ea058bd11c42cf169728f3 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 24 Dec 2009 01:13:51 +0100 Subject: ASoC: fix params_rate() macro use in several codecs Sevelar ASoC codec drivers wrongly assume, that the params_rate() macro returns one of SNDRV_PCM_RATE_* defines instead of the actual numerical sampling rate. Fix them. Signed-off-by: Guennadi Liakhovetski Acked-by: Liam Girdwood Signed-off-by: Mark Brown Cc: stable@kernel.org diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c index 265e68c..af8cb69 100644 --- a/sound/soc/codecs/wm8510.c +++ b/sound/soc/codecs/wm8510.c @@ -424,23 +424,23 @@ static int wm8510_pcm_hw_params(struct snd_pcm_substream *substream, /* filter coefficient */ switch (params_rate(params)) { - case SNDRV_PCM_RATE_8000: + case 8000: adn |= 0x5 << 1; break; - case SNDRV_PCM_RATE_11025: + case 11025: adn |= 0x4 << 1; break; - case SNDRV_PCM_RATE_16000: + case 16000: adn |= 0x3 << 1; break; - case SNDRV_PCM_RATE_22050: + case 22050: adn |= 0x2 << 1; break; - case SNDRV_PCM_RATE_32000: + case 32000: adn |= 0x1 << 1; break; - case SNDRV_PCM_RATE_44100: - case SNDRV_PCM_RATE_48000: + case 44100: + case 48000: break; } diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c index 3d850b9..31e39ff 100644 --- a/sound/soc/codecs/wm8940.c +++ b/sound/soc/codecs/wm8940.c @@ -378,23 +378,23 @@ static int wm8940_i2s_hw_params(struct snd_pcm_substream *substream, iface |= (1 << 9); switch (params_rate(params)) { - case SNDRV_PCM_RATE_8000: + case 8000: addcntrl |= (0x5 << 1); break; - case SNDRV_PCM_RATE_11025: + case 11025: addcntrl |= (0x4 << 1); break; - case SNDRV_PCM_RATE_16000: + case 16000: addcntrl |= (0x3 << 1); break; - case SNDRV_PCM_RATE_22050: + case 22050: addcntrl |= (0x2 << 1); break; - case SNDRV_PCM_RATE_32000: + case 32000: addcntrl |= (0x1 << 1); break; - case SNDRV_PCM_RATE_44100: - case SNDRV_PCM_RATE_48000: + case 44100: + case 48000: break; } ret = snd_soc_write(codec, WM8940_ADDCNTRL, addcntrl); diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c index a808675..8812751 100644 --- a/sound/soc/codecs/wm8974.c +++ b/sound/soc/codecs/wm8974.c @@ -482,23 +482,23 @@ static int wm8974_pcm_hw_params(struct snd_pcm_substream *substream, /* filter coefficient */ switch (params_rate(params)) { - case SNDRV_PCM_RATE_8000: + case 8000: adn |= 0x5 << 1; break; - case SNDRV_PCM_RATE_11025: + case 11025: adn |= 0x4 << 1; break; - case SNDRV_PCM_RATE_16000: + case 16000: adn |= 0x3 << 1; break; - case SNDRV_PCM_RATE_22050: + case 22050: adn |= 0x2 << 1; break; - case SNDRV_PCM_RATE_32000: + case 32000: adn |= 0x1 << 1; break; - case SNDRV_PCM_RATE_44100: - case SNDRV_PCM_RATE_48000: + case 44100: + case 48000: break; } -- cgit v0.10.2 From 382b4480ff832e472d76c99f3f75fffb30e118c0 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 24 Dec 2009 12:52:44 +0000 Subject: ARM: footbridge: trim down old ISA rtc setup This fixes a "start_kernel(): bug: interrupts were enabled early". rtc_cmos now takes care of initializing the ISA RTC and reading the current time and date from it; there's no need to repeat that here, thereby causing interrupts to be enabled too early. Signed-off-by: Russell King diff --git a/arch/arm/mach-footbridge/Makefile b/arch/arm/mach-footbridge/Makefile index 32f8609..3afb1b2 100644 --- a/arch/arm/mach-footbridge/Makefile +++ b/arch/arm/mach-footbridge/Makefile @@ -4,7 +4,7 @@ # Object file lists. -obj-y := common.o dc21285.o dma.o isa-irq.o time.o +obj-y := common.o dc21285.o dma.o isa-irq.o obj-m := obj-n := obj- := @@ -25,4 +25,4 @@ obj-$(CONFIG_ARCH_PERSONAL_SERVER) += personal.o dc21285-timer.o obj-$(CONFIG_PCI) +=$(pci-y) obj-$(CONFIG_LEDS) +=$(leds-y) -obj-$(CONFIG_ISA) += isa.o +obj-$(CONFIG_ISA) += isa.o isa-rtc.o diff --git a/arch/arm/mach-footbridge/dc21285-timer.c b/arch/arm/mach-footbridge/dc21285-timer.c index da35bc5..bc5e83f 100644 --- a/arch/arm/mach-footbridge/dc21285-timer.c +++ b/arch/arm/mach-footbridge/dc21285-timer.c @@ -56,8 +56,6 @@ static void __init footbridge_timer_init(void) *CSR_TIMER1_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_AUTORELOAD | TIMER_CNTL_DIV16; setup_irq(IRQ_TIMER1, &footbridge_timer_irq); - - isa_rtc_init(); } struct sys_timer footbridge_timer = { diff --git a/arch/arm/mach-footbridge/isa-rtc.c b/arch/arm/mach-footbridge/isa-rtc.c new file mode 100644 index 0000000..07fde40 --- /dev/null +++ b/arch/arm/mach-footbridge/isa-rtc.c @@ -0,0 +1,57 @@ +/* + * arch/arm/mach-footbridge/isa-rtc.c + * + * Copyright (C) 1998 Russell King. + * Copyright (C) 1998 Phil Blundell + * + * CATS has a real-time clock, though the evaluation board doesn't. + * + * Changelog: + * 21-Mar-1998 RMK Created + * 27-Aug-1998 PJB CATS support + * 28-Dec-1998 APH Made leds optional + * 20-Jan-1999 RMK Started merge of EBSA285, CATS and NetWinder + * 16-Mar-1999 RMK More support for EBSA285-like machines with RTCs in + */ + +#define RTC_PORT(x) (0x70+(x)) +#define RTC_ALWAYS_BCD 0 + +#include +#include +#include +#include + +#include "common.h" + +void __init isa_rtc_init(void) +{ + int reg_d, reg_b; + + /* + * Probe for the RTC. + */ + reg_d = CMOS_READ(RTC_REG_D); + + /* + * make sure the divider is set + */ + CMOS_WRITE(RTC_REF_CLCK_32KHZ, RTC_REG_A); + + /* + * Set control reg B + * (24 hour mode, update enabled) + */ + reg_b = CMOS_READ(RTC_REG_B) & 0x7f; + reg_b |= 2; + CMOS_WRITE(reg_b, RTC_REG_B); + + if ((CMOS_READ(RTC_REG_A) & 0x7f) == RTC_REF_CLCK_32KHZ && + CMOS_READ(RTC_REG_B) == reg_b) { + /* + * We have a RTC. Check the battery + */ + if ((reg_d & 0x80) == 0) + printk(KERN_WARNING "RTC: *** warning: CMOS battery bad\n"); + } +} diff --git a/arch/arm/mach-footbridge/isa-timer.c b/arch/arm/mach-footbridge/isa-timer.c index 0c83900..f488fa2 100644 --- a/arch/arm/mach-footbridge/isa-timer.c +++ b/arch/arm/mach-footbridge/isa-timer.c @@ -76,8 +76,6 @@ static struct irqaction isa_timer_irq = { static void __init isa_timer_init(void) { - isa_rtc_init(); - /* enable PIT timer */ /* set for periodic (4) and LSB/MSB write (0x30) */ outb(0x34, 0x43); diff --git a/arch/arm/mach-footbridge/isa.c b/arch/arm/mach-footbridge/isa.c index 725a219..4d9276c 100644 --- a/arch/arm/mach-footbridge/isa.c +++ b/arch/arm/mach-footbridge/isa.c @@ -11,6 +11,9 @@ #include #include +#include + +#include "common.h" static struct resource rtc_resources[] = { [0] = { @@ -77,11 +80,18 @@ static struct platform_device serial_device = { static int __init footbridge_isa_init(void) { - int err; + int err = 0; - err = platform_device_register(&rtc_device); - if (err) - printk(KERN_ERR "Unable to register RTC device: %d\n", err); + if (!footbridge_cfn_mode()) + return 0; + + /* Personal server doesn't have RTC */ + if (!machine_is_personal_server()) { + isa_rtc_init(); + err = platform_device_register(&rtc_device); + if (err) + printk(KERN_ERR "Unable to register RTC device: %d\n", err); + } err = platform_device_register(&serial_device); if (err) printk(KERN_ERR "Unable to register serial device: %d\n", err); diff --git a/arch/arm/mach-footbridge/time.c b/arch/arm/mach-footbridge/time.c deleted file mode 100644 index cd1b54f..0000000 --- a/arch/arm/mach-footbridge/time.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * arch/arm/mach-footbridge/include/mach/time.h - * - * Copyright (C) 1998 Russell King. - * Copyright (C) 1998 Phil Blundell - * - * CATS has a real-time clock, though the evaluation board doesn't. - * - * Changelog: - * 21-Mar-1998 RMK Created - * 27-Aug-1998 PJB CATS support - * 28-Dec-1998 APH Made leds optional - * 20-Jan-1999 RMK Started merge of EBSA285, CATS and NetWinder - * 16-Mar-1999 RMK More support for EBSA285-like machines with RTCs in - */ - -#define RTC_PORT(x) (rtc_base+(x)) -#define RTC_ALWAYS_BCD 0 - -#include -#include -#include -#include -#include -#include - -#include - -#include -#include "common.h" - -static int rtc_base; - -static unsigned long __init get_isa_cmos_time(void) -{ - unsigned int year, mon, day, hour, min, sec; - - // check to see if the RTC makes sense..... - if ((CMOS_READ(RTC_VALID) & RTC_VRT) == 0) - return mktime(1970, 1, 1, 0, 0, 0); - - do { - sec = CMOS_READ(RTC_SECONDS); - min = CMOS_READ(RTC_MINUTES); - hour = CMOS_READ(RTC_HOURS); - day = CMOS_READ(RTC_DAY_OF_MONTH); - mon = CMOS_READ(RTC_MONTH); - year = CMOS_READ(RTC_YEAR); - } while (sec != CMOS_READ(RTC_SECONDS)); - - if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { - sec = bcd2bin(sec); - min = bcd2bin(min); - hour = bcd2bin(hour); - day = bcd2bin(day); - mon = bcd2bin(mon); - year = bcd2bin(year); - } - if ((year += 1900) < 1970) - year += 100; - return mktime(year, mon, day, hour, min, sec); -} - -static int set_isa_cmos_time(void) -{ - int retval = 0; - int real_seconds, real_minutes, cmos_minutes; - unsigned char save_control, save_freq_select; - unsigned long nowtime = xtime.tv_sec; - - save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */ - CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL); - - save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */ - CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); - - cmos_minutes = CMOS_READ(RTC_MINUTES); - if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) - cmos_minutes = bcd2bin(cmos_minutes); - - /* - * since we're only adjusting minutes and seconds, - * don't interfere with hour overflow. This avoids - * messing with unknown time zones but requires your - * RTC not to be off by more than 15 minutes - */ - real_seconds = nowtime % 60; - real_minutes = nowtime / 60; - if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1) - real_minutes += 30; /* correct for half hour time zone */ - real_minutes %= 60; - - if (abs(real_minutes - cmos_minutes) < 30) { - if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { - real_seconds = bin2bcd(real_seconds); - real_minutes = bin2bcd(real_minutes); - } - CMOS_WRITE(real_seconds,RTC_SECONDS); - CMOS_WRITE(real_minutes,RTC_MINUTES); - } else - retval = -1; - - /* The following flags have to be released exactly in this order, - * otherwise the DS12887 (popular MC146818A clone with integrated - * battery and quartz) will not reset the oscillator and will not - * update precisely 500 ms later. You won't find this mentioned in - * the Dallas Semiconductor data sheets, but who believes data - * sheets anyway ... -- Markus Kuhn - */ - CMOS_WRITE(save_control, RTC_CONTROL); - CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); - - return retval; -} - -void __init isa_rtc_init(void) -{ - if (machine_is_personal_server()) - /* - * Add-in 21285s shouldn't access the RTC - */ - rtc_base = 0; - else - rtc_base = 0x70; - - if (rtc_base) { - int reg_d, reg_b; - - /* - * Probe for the RTC. - */ - reg_d = CMOS_READ(RTC_REG_D); - - /* - * make sure the divider is set - */ - CMOS_WRITE(RTC_REF_CLCK_32KHZ, RTC_REG_A); - - /* - * Set control reg B - * (24 hour mode, update enabled) - */ - reg_b = CMOS_READ(RTC_REG_B) & 0x7f; - reg_b |= 2; - CMOS_WRITE(reg_b, RTC_REG_B); - - if ((CMOS_READ(RTC_REG_A) & 0x7f) == RTC_REF_CLCK_32KHZ && - CMOS_READ(RTC_REG_B) == reg_b) { - struct timespec tv; - - /* - * We have a RTC. Check the battery - */ - if ((reg_d & 0x80) == 0) - printk(KERN_WARNING "RTC: *** warning: CMOS battery bad\n"); - - tv.tv_nsec = 0; - tv.tv_sec = get_isa_cmos_time(); - do_settimeofday(&tv); - set_rtc = set_isa_cmos_time; - } else - rtc_base = 0; - } -} -- cgit v0.10.2 From e8b8f5ef90b934bc9eaef7c8960ecd9dda9f7a62 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 24 Dec 2009 14:45:39 +0000 Subject: ARM: dma-isa: request cascade channel after registering it We can't request the cascade channel before it's been registered, so move it afterwards. Signed-off-by: Russell King diff --git a/arch/arm/kernel/dma-isa.c b/arch/arm/kernel/dma-isa.c index 0e88e46..360bb6d 100644 --- a/arch/arm/kernel/dma-isa.c +++ b/arch/arm/kernel/dma-isa.c @@ -207,8 +207,6 @@ void __init isa_init_dma(void) outb(0x32, 0x4d6); outb(0x33, 0x4d6); - request_dma(DMA_ISA_CASCADE, "cascade"); - for (i = 0; i < ARRAY_SIZE(dma_resources); i++) request_resource(&ioport_resource, dma_resources + i); @@ -218,5 +216,7 @@ void __init isa_init_dma(void) printk(KERN_ERR "ISADMA%u: unable to register: %d\n", chan, ret); } + + request_dma(DMA_ISA_CASCADE, "cascade"); } } -- cgit v0.10.2 From ed5a35acbb48d512332a53565e6341c65eecfa29 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 24 Dec 2009 13:36:21 +0000 Subject: VIDEO: cyberpro: pci_request_regions needs a persistent name Don't pass a name pointer from the kernel stack, it will not survive and will result in corrupted /proc/iomem output. Signed-off-by: Russell King diff --git a/drivers/video/cyber2000fb.c b/drivers/video/cyber2000fb.c index da7c01b..3a561df2 100644 --- a/drivers/video/cyber2000fb.c +++ b/drivers/video/cyber2000fb.c @@ -1573,15 +1573,15 @@ cyberpro_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) if (err) return err; - err = pci_request_regions(dev, name); - if (err) - return err; - err = -ENOMEM; cfb = cyberpro_alloc_fb_info(id->driver_data, name); if (!cfb) goto failed_release; + err = pci_request_regions(dev, cfb->fb.fix.id); + if (err) + goto failed_regions; + cfb->dev = dev; cfb->region = pci_ioremap_bar(dev, 0); if (!cfb->region) @@ -1633,10 +1633,10 @@ cyberpro_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) failed: iounmap(cfb->region); failed_ioremap: + pci_release_regions(dev); +failed_regions: cyberpro_free_fb_info(cfb); failed_release: - pci_release_regions(dev); - return err; } -- cgit v0.10.2 From 6b7b284958d47b77d06745b36bc7f36dab769d9b Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 24 Dec 2009 13:09:41 -0800 Subject: Linux 2.6.33-rc2 diff --git a/Makefile b/Makefile index e6b06cb..c628a5c 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 33 -EXTRAVERSION = -rc1 +EXTRAVERSION = -rc2 NAME = Man-Eating Seals of Antiquity # *DOCUMENTATION* -- cgit v0.10.2 From 6d3b82f2d31f22085e5711b28dddcb9fb3d97a25 Mon Sep 17 00:00:00 2001 From: Fang Wenqi Date: Thu, 24 Dec 2009 17:51:42 -0500 Subject: ext4: Update documentation to correct the inode_readahead_blks option name Per commit 240799cd, the option name for readahead should be inode_readahead_blks, not inode_readahead. Signed-off-by: Fang Wenqi Signed-off-by: "Theodore Ts'o" diff --git a/Documentation/filesystems/ext4.txt b/Documentation/filesystems/ext4.txt index af6885c..e1def17 100644 --- a/Documentation/filesystems/ext4.txt +++ b/Documentation/filesystems/ext4.txt @@ -196,7 +196,7 @@ nobarrier This also requires an IO stack which can support also be used to enable or disable barriers, for consistency with other ext4 mount options. -inode_readahead=n This tuning parameter controls the maximum +inode_readahead_blks=n This tuning parameter controls the maximum number of inode table blocks that ext4's inode table readahead algorithm will pre-read into the buffer cache. The default value is 32 blocks. -- cgit v0.10.2 From 5ee581483246e832ca5a9fc1ac669bba0b6ec468 Mon Sep 17 00:00:00 2001 From: Jiro SEKIBA Date: Sun, 6 Dec 2009 15:43:56 +0900 Subject: nilfs2: trivial coding style fix This is a trivial style fix patch to mend errors/warnings reported by "checkpatch.pl --file". Signed-off-by: Jiro SEKIBA Signed-off-by: Ryusuke Konishi diff --git a/fs/nilfs2/bmap.c b/fs/nilfs2/bmap.c index f4a14ea..effdbdb 100644 --- a/fs/nilfs2/bmap.c +++ b/fs/nilfs2/bmap.c @@ -417,8 +417,8 @@ __u64 nilfs_bmap_data_get_key(const struct nilfs_bmap *bmap, key = page_index(bh->b_page) << (PAGE_CACHE_SHIFT - bmap->b_inode->i_blkbits); - for (pbh = page_buffers(bh->b_page); pbh != bh; - pbh = pbh->b_this_page, key++); + for (pbh = page_buffers(bh->b_page); pbh != bh; pbh = pbh->b_this_page) + key++; return key; } diff --git a/fs/nilfs2/cpfile.c b/fs/nilfs2/cpfile.c index d5ad54e..1873781 100644 --- a/fs/nilfs2/cpfile.c +++ b/fs/nilfs2/cpfile.c @@ -328,19 +328,24 @@ int nilfs_cpfile_delete_checkpoints(struct inode *cpfile, tnicps += nicps; nilfs_mdt_mark_buffer_dirty(cp_bh); nilfs_mdt_mark_dirty(cpfile); - if (!nilfs_cpfile_is_in_first(cpfile, cno) && - (count = nilfs_cpfile_block_sub_valid_checkpoints( - cpfile, cp_bh, kaddr, nicps)) == 0) { - /* make hole */ - kunmap_atomic(kaddr, KM_USER0); - brelse(cp_bh); - ret = nilfs_cpfile_delete_checkpoint_block( - cpfile, cno); - if (ret == 0) - continue; - printk(KERN_ERR "%s: cannot delete block\n", - __func__); - break; + if (!nilfs_cpfile_is_in_first(cpfile, cno)) { + count = + nilfs_cpfile_block_sub_valid_checkpoints( + cpfile, cp_bh, kaddr, nicps); + if (count == 0) { + /* make hole */ + kunmap_atomic(kaddr, KM_USER0); + brelse(cp_bh); + ret = + nilfs_cpfile_delete_checkpoint_block( + cpfile, cno); + if (ret == 0) + continue; + printk(KERN_ERR + "%s: cannot delete block\n", + __func__); + break; + } } } diff --git a/fs/nilfs2/direct.c b/fs/nilfs2/direct.c index d369ac7..236753d 100644 --- a/fs/nilfs2/direct.c +++ b/fs/nilfs2/direct.c @@ -51,11 +51,11 @@ static int nilfs_direct_lookup(const struct nilfs_bmap *bmap, struct nilfs_direct *direct; __u64 ptr; - direct = (struct nilfs_direct *)bmap; - if ((key > NILFS_DIRECT_KEY_MAX) || - (level != 1) || /* XXX: use macro for level 1 */ - ((ptr = nilfs_direct_get_ptr(direct, key)) == - NILFS_BMAP_INVALID_PTR)) + direct = (struct nilfs_direct *)bmap; /* XXX: use macro for level 1 */ + if (key > NILFS_DIRECT_KEY_MAX || level != 1) + return -ENOENT; + ptr = nilfs_direct_get_ptr(direct, key); + if (ptr == NILFS_BMAP_INVALID_PTR) return -ENOENT; if (ptrp != NULL) @@ -73,9 +73,10 @@ static int nilfs_direct_lookup_contig(const struct nilfs_bmap *bmap, sector_t blocknr; int ret, cnt; - if (key > NILFS_DIRECT_KEY_MAX || - (ptr = nilfs_direct_get_ptr(direct, key)) == - NILFS_BMAP_INVALID_PTR) + if (key > NILFS_DIRECT_KEY_MAX) + return -ENOENT; + ptr = nilfs_direct_get_ptr(direct, key); + if (ptr == NILFS_BMAP_INVALID_PTR) return -ENOENT; if (NILFS_BMAP_USE_VBN(bmap)) { -- cgit v0.10.2 From 33e189bd5754dead3ece130da8e62f470f526f36 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Wed, 23 Dec 2009 13:57:47 +0100 Subject: nilfs2: Storage class should be before const qualifier The C99 specification states in section 6.11.5: The placement of a storage-class specifier other than at the beginning of the declaration specifiers in a declaration is an obsolescent feature. Signed-off-by: Tobias Klauser Signed-off-by: Ryusuke Konishi diff --git a/fs/nilfs2/ioctl.c b/fs/nilfs2/ioctl.c index f6af760..d6b2b83 100644 --- a/fs/nilfs2/ioctl.c +++ b/fs/nilfs2/ioctl.c @@ -480,7 +480,7 @@ static int nilfs_ioctl_clean_segments(struct inode *inode, struct file *filp, unsigned int cmd, void __user *argp) { struct nilfs_argv argv[5]; - const static size_t argsz[5] = { + static const size_t argsz[5] = { sizeof(struct nilfs_vdesc), sizeof(struct nilfs_period), sizeof(__u64), -- cgit v0.10.2 From 4a299bf591bc5bef3bde8316e603b9eaec5a7696 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 24 Dec 2009 21:40:24 -0800 Subject: Input: speed up suspend/shutdown for PS/2 mice and keyboards Instead of doing full-blown reset while suspending or shutting down the box use lighter form of reset that should take less time. Tested-by: Alan Stern Tested-by: Rafael J. Wysocki Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index a357357..1f5e2ce 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c @@ -134,7 +134,8 @@ static const unsigned short atkbd_unxlate_table[128] = { #define ATKBD_CMD_GETID 0x02f2 #define ATKBD_CMD_SETREP 0x10f3 #define ATKBD_CMD_ENABLE 0x00f4 -#define ATKBD_CMD_RESET_DIS 0x00f5 +#define ATKBD_CMD_RESET_DIS 0x00f5 /* Reset to defaults and disable */ +#define ATKBD_CMD_RESET_DEF 0x00f6 /* Reset to defaults */ #define ATKBD_CMD_SETALL_MBR 0x00fa #define ATKBD_CMD_RESET_BAT 0x02ff #define ATKBD_CMD_RESEND 0x00fe @@ -836,7 +837,7 @@ static void atkbd_cleanup(struct serio *serio) struct atkbd *atkbd = serio_get_drvdata(serio); atkbd_disable(atkbd); - ps2_command(&atkbd->ps2dev, NULL, ATKBD_CMD_RESET_BAT); + ps2_command(&atkbd->ps2dev, NULL, ATKBD_CMD_RESET_DEF); } diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index fd0bc09..401ac6b 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c @@ -1137,7 +1137,10 @@ static void psmouse_cleanup(struct serio *serio) if (psmouse->cleanup) psmouse->cleanup(psmouse); - psmouse_reset(psmouse); +/* + * Reset the mouse to defaults (bare PS/2 protocol). + */ + ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS); /* * Some boxes, such as HP nx7400, get terribly confused if mouse -- cgit v0.10.2 From ea486e681188d64c6a101d8d06414aef0f9f0cd3 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 24 Dec 2009 21:40:43 -0800 Subject: Input: serio - do not mark kseriod freezable anymore We used to make kseriod freezable to prevent unnecessary attempts at resuming keyboard and mouse before taking hibernation image when suspend and hibernation were sharing PM operations. Now that they are separated and we don't risk resuming during 'thaw' we don't need to freeze kseriod anymore. This will allow us to start resetting mouse and keyboard a bit earlier, before rest of the userspace comes back up. Acked-by: Rafael J. Wysocki Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index 0236f0d..e0f3018 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c @@ -284,13 +284,7 @@ static void serio_handle_event(void) mutex_lock(&serio_mutex); - /* - * Note that we handle only one event here to give swsusp - * a chance to freeze kseriod thread. Serio events should - * be pretty rare so we are not concerned about taking - * performance hit. - */ - if ((event = serio_get_event())) { + while ((event = serio_get_event())) { switch (event->type) { case SERIO_REGISTER_PORT: @@ -380,10 +374,9 @@ static struct serio *serio_get_pending_child(struct serio *parent) static int serio_thread(void *nothing) { - set_freezable(); do { serio_handle_event(); - wait_event_freezable(serio_wait, + wait_event_interruptible(serio_wait, kthread_should_stop() || !list_empty(&serio_event_list)); } while (!kthread_should_stop()); -- cgit v0.10.2 From 25ae08317647c68ed9276f7bdc07d0d5fd042628 Mon Sep 17 00:00:00 2001 From: Jari Vanhala Date: Thu, 24 Dec 2009 21:52:19 -0800 Subject: Input: ff-memless - start playing FF effects immediately Instead of waiting for the next timer tick to start playing an effect do it immediately. This mostly helps systems using low HZ setting. Signed-off-by: Jari Vanhala Acked-by: Anssi Hannula Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/ff-memless.c b/drivers/input/ff-memless.c index b483b29..decc51f 100644 --- a/drivers/input/ff-memless.c +++ b/drivers/input/ff-memless.c @@ -411,8 +411,6 @@ static int ml_ff_playback(struct input_dev *dev, int effect_id, int value) msecs_to_jiffies(state->effect->replay.length); state->adj_at = state->play_at; - ml_schedule_timer(ml); - } else { debug("initiated stop"); @@ -420,10 +418,10 @@ static int ml_ff_playback(struct input_dev *dev, int effect_id, int value) __set_bit(FF_EFFECT_ABORTING, &state->flags); else __clear_bit(FF_EFFECT_STARTED, &state->flags); - - ml_play_effects(ml); } + ml_play_effects(ml); + return 0; } -- cgit v0.10.2 From 1b11c88d3e8f55dc9d193d19de11e3f7abc1b7d7 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 24 Dec 2009 21:44:19 -0800 Subject: Input: ff-memless - another fix for signed to unsigned overflow The commit 9e68177ef93b2f34eee5a1e1707bceef4b9ba69c changed 'gain' from signed to unsigned to fix an issue with rumble effect calculation, however it introduced problems when calculating constant effects. Having 'gain' being unsigned int was an unfortunate choice since it dominates all implicit type conversions causing everything to be treated as unsigned int. Let's change it back to signed int and simply add proper casts to rumble effect calculations. Reported-by: Gary Stein Acked-by: Anssi Hannula Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/ff-memless.c b/drivers/input/ff-memless.c index decc51f..9667a5f 100644 --- a/drivers/input/ff-memless.c +++ b/drivers/input/ff-memless.c @@ -225,7 +225,7 @@ static int get_compatible_type(struct ff_device *ff, int effect_type) */ static void ml_combine_effects(struct ff_effect *effect, struct ml_effect_state *state, - unsigned int gain) + int gain) { struct ff_effect *new = state->effect; unsigned int strong, weak, i; @@ -252,8 +252,8 @@ static void ml_combine_effects(struct ff_effect *effect, break; case FF_RUMBLE: - strong = new->u.rumble.strong_magnitude * gain / 0xffff; - weak = new->u.rumble.weak_magnitude * gain / 0xffff; + strong = (u32)new->u.rumble.strong_magnitude * gain / 0xffff; + weak = (u32)new->u.rumble.weak_magnitude * gain / 0xffff; effect->u.rumble.strong_magnitude = min(strong + effect->u.rumble.strong_magnitude, 0xffffU); -- cgit v0.10.2 From 94ec26c855bc675259e4f1658673f458040affd7 Mon Sep 17 00:00:00 2001 From: Jari Vanhala Date: Thu, 24 Dec 2009 21:52:20 -0800 Subject: Input: ff-memless - add notion of direction to for rumble effects This adds simple direction calculation when combining effects. It's useful to decide motor direction for rumble (vibrator). Signed-off-by: Jari Vanhala Acked-by: Anssi Hannula Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/ff-memless.c b/drivers/input/ff-memless.c index 9667a5f..f967008 100644 --- a/drivers/input/ff-memless.c +++ b/drivers/input/ff-memless.c @@ -221,6 +221,22 @@ static int get_compatible_type(struct ff_device *ff, int effect_type) } /* + * Only left/right direction should be used (under/over 0x8000) for + * forward/reverse motor direction (to keep calculation fast & simple). + */ +static u16 ml_calculate_direction(u16 direction, u16 force, + u16 new_direction, u16 new_force) +{ + if (!force) + return new_direction; + if (!new_force) + return direction; + return (((u32)(direction >> 1) * force + + (new_direction >> 1) * new_force) / + (force + new_force)) << 1; +} + +/* * Combine two effects and apply gain. */ static void ml_combine_effects(struct ff_effect *effect, @@ -254,6 +270,19 @@ static void ml_combine_effects(struct ff_effect *effect, case FF_RUMBLE: strong = (u32)new->u.rumble.strong_magnitude * gain / 0xffff; weak = (u32)new->u.rumble.weak_magnitude * gain / 0xffff; + + if (effect->u.rumble.strong_magnitude + strong) + effect->direction = ml_calculate_direction( + effect->direction, + effect->u.rumble.strong_magnitude, + new->direction, strong); + else if (effect->u.rumble.weak_magnitude + weak) + effect->direction = ml_calculate_direction( + effect->direction, + effect->u.rumble.weak_magnitude, + new->direction, weak); + else + effect->direction = 0; effect->u.rumble.strong_magnitude = min(strong + effect->u.rumble.strong_magnitude, 0xffffU); @@ -268,6 +297,13 @@ static void ml_combine_effects(struct ff_effect *effect, /* here we also scale it 0x7fff => 0xffff */ i = i * gain / 0x7fff; + if (effect->u.rumble.strong_magnitude + i) + effect->direction = ml_calculate_direction( + effect->direction, + effect->u.rumble.strong_magnitude, + new->direction, i); + else + effect->direction = 0; effect->u.rumble.strong_magnitude = min(i + effect->u.rumble.strong_magnitude, 0xffffU); effect->u.rumble.weak_magnitude = -- cgit v0.10.2 From 98b7fb0472f828536a7786df6bd517322c0c17dc Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 24 Dec 2009 22:37:49 -0800 Subject: Input: iforce - fix oops on device disconnect Do not try to free iforce device when we closing input device; disconnect is the only place where it should be deleted. Reported-by: Johannes Ebke Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c index f6c688c..acc3a9e 100644 --- a/drivers/input/joystick/iforce/iforce-main.c +++ b/drivers/input/joystick/iforce/iforce-main.c @@ -210,7 +210,7 @@ static int iforce_open(struct input_dev *dev) return 0; } -static void iforce_release(struct input_dev *dev) +static void iforce_close(struct input_dev *dev) { struct iforce *iforce = input_get_drvdata(dev); int i; @@ -232,26 +232,10 @@ static void iforce_release(struct input_dev *dev) switch (iforce->bus) { #ifdef CONFIG_JOYSTICK_IFORCE_USB - case IFORCE_USB: - usb_kill_urb(iforce->irq); - - /* The device was unplugged before the file - * was released */ - if (iforce->usbdev == NULL) { - iforce_delete_device(iforce); - kfree(iforce); - } - break; -#endif - } -} - -void iforce_delete_device(struct iforce *iforce) -{ - switch (iforce->bus) { -#ifdef CONFIG_JOYSTICK_IFORCE_USB case IFORCE_USB: - iforce_usb_delete(iforce); + usb_kill_urb(iforce->irq); + usb_kill_urb(iforce->out); + usb_kill_urb(iforce->ctrl); break; #endif #ifdef CONFIG_JOYSTICK_IFORCE_232 @@ -303,7 +287,7 @@ int iforce_init_device(struct iforce *iforce) input_dev->name = "Unknown I-Force device"; input_dev->open = iforce_open; - input_dev->close = iforce_release; + input_dev->close = iforce_close; /* * On-device memory allocation. diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c index 9f289d8..c0ad883 100644 --- a/drivers/input/joystick/iforce/iforce-usb.c +++ b/drivers/input/joystick/iforce/iforce-usb.c @@ -186,33 +186,19 @@ fail: return err; } -/* Called by iforce_delete() */ -void iforce_usb_delete(struct iforce* iforce) -{ - usb_kill_urb(iforce->irq); - usb_kill_urb(iforce->out); - usb_kill_urb(iforce->ctrl); - - usb_free_urb(iforce->irq); - usb_free_urb(iforce->out); - usb_free_urb(iforce->ctrl); -} - static void iforce_usb_disconnect(struct usb_interface *intf) { struct iforce *iforce = usb_get_intfdata(intf); - int open = 0; /* FIXME! iforce->dev.handle->open; */ usb_set_intfdata(intf, NULL); - if (iforce) { - iforce->usbdev = NULL; - input_unregister_device(iforce->dev); - if (!open) { - iforce_delete_device(iforce); - kfree(iforce); - } - } + input_unregister_device(iforce->dev); + + usb_free_urb(iforce->irq); + usb_free_urb(iforce->out); + usb_free_urb(iforce->ctrl); + + kfree(iforce); } static struct usb_device_id iforce_usb_ids [] = { diff --git a/drivers/input/joystick/iforce/iforce.h b/drivers/input/joystick/iforce/iforce.h index f2d91f4..9f494b7 100644 --- a/drivers/input/joystick/iforce/iforce.h +++ b/drivers/input/joystick/iforce/iforce.h @@ -150,11 +150,9 @@ void iforce_serial_xmit(struct iforce *iforce); /* iforce-usb.c */ void iforce_usb_xmit(struct iforce *iforce); -void iforce_usb_delete(struct iforce *iforce); /* iforce-main.c */ int iforce_init_device(struct iforce *iforce); -void iforce_delete_device(struct iforce *iforce); /* iforce-packets.c */ int iforce_control_playback(struct iforce*, u16 id, unsigned int); -- cgit v0.10.2 From dd219234d201431d0fc56a74e3a4a97ca3eb4589 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 24 Dec 2009 22:50:23 -0800 Subject: Input: matrix-keypad - handle cases when GPIOs can't be wakeup sources On certain boards not all GPIOs may be used as wakeup sources, in which case some of enable_irq_wake() calls will fail. On resume calling disable_irq_wake() will warn about unbalanced IRQ wake disable. Solve this by checking whether enable_irq_wake() succeeded or not and no not call disable_irq_wake() for these GPIOs/IRQs that have not been enabled. Reported-by: Pavel Machek Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c index 34f4a29..d3c8b61 100644 --- a/drivers/input/keyboard/matrix_keypad.c +++ b/drivers/input/keyboard/matrix_keypad.c @@ -29,11 +29,13 @@ struct matrix_keypad { unsigned short *keycodes; unsigned int row_shift; + DECLARE_BITMAP(disabled_gpios, MATRIX_MAX_ROWS); + uint32_t last_key_state[MATRIX_MAX_COLS]; struct delayed_work work; + spinlock_t lock; bool scan_pending; bool stopped; - spinlock_t lock; }; /* @@ -222,9 +224,16 @@ static int matrix_keypad_suspend(struct device *dev) matrix_keypad_stop(keypad->input_dev); - if (device_may_wakeup(&pdev->dev)) - for (i = 0; i < pdata->num_row_gpios; i++) - enable_irq_wake(gpio_to_irq(pdata->row_gpios[i])); + if (device_may_wakeup(&pdev->dev)) { + for (i = 0; i < pdata->num_row_gpios; i++) { + if (!test_bit(i, keypad->disabled_gpios)) { + unsigned int gpio = pdata->row_gpios[i]; + + if (enable_irq_wake(gpio_to_irq(gpio)) == 0) + __set_bit(i, keypad->disabled_gpios); + } + } + } return 0; } @@ -236,9 +245,15 @@ static int matrix_keypad_resume(struct device *dev) const struct matrix_keypad_platform_data *pdata = keypad->pdata; int i; - if (device_may_wakeup(&pdev->dev)) - for (i = 0; i < pdata->num_row_gpios; i++) - disable_irq_wake(gpio_to_irq(pdata->row_gpios[i])); + if (device_may_wakeup(&pdev->dev)) { + for (i = 0; i < pdata->num_row_gpios; i++) { + if (test_and_clear_bit(i, keypad->disabled_gpios)) { + unsigned int gpio = pdata->row_gpios[i]; + + disable_irq_wake(gpio_to_irq(gpio)); + } + } + } matrix_keypad_start(keypad->input_dev); -- cgit v0.10.2 From 8b90ca08821fee79e181bfcbc3bbd41ef5637136 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 24 Dec 2009 01:17:46 +0100 Subject: ALSA: Fix indentation in pcm_native.c Signed-off-by: Guennadi Liakhovetski Signed-off-by: Takashi Iwai diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 29ab46a1..25b0641 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -1918,13 +1918,13 @@ int snd_pcm_hw_constraints_complete(struct snd_pcm_substream *substream) err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_RATE, hw->rate_min, hw->rate_max); - if (err < 0) - return err; + if (err < 0) + return err; err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, hw->period_bytes_min, hw->period_bytes_max); - if (err < 0) - return err; + if (err < 0) + return err; err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIODS, hw->periods_min, hw->periods_max); -- cgit v0.10.2 From ef18beded8ddbaafdf4914bab209f77e60ae3a18 Mon Sep 17 00:00:00 2001 From: Wu Fengguang Date: Fri, 25 Dec 2009 13:14:27 +0800 Subject: ALSA: hda - HDMI sticky stream tag support When we run the following commands in turn (with CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0), speaker-test -Dhw:0,3 -c2 -twav # HDMI speaker-test -Dhw:0,0 -c2 -twav # Analog The second command will produce sound in the analog lineout _as well as_ HDMI sink. The root cause is, device 0 "reuses" the same stream tag that was used by device 3, and the "intelhdmi - sticky stream id" patch leaves the HDMI codec in a functional state. So the HDMI codec happily accepts the audio samples which reuse its stream tag. The proposed solution is to remember the last device each azx_dev was assigned to, and prefer to 1) reuse the azx_dev (and hence the stream tag) the HDMI codec last used 2) or assign a never-used azx_dev for HDMI With this patch and the above two speaker-test commands, HDMI codec will use stream tag 8 and Analog codec will use 5. The stream tag used by HDMI codec won't be reused by others, as long as we don't run out of the 4 playback azx_dev's. The legacy Analog codec will continue to use stream tag 5 because its device id is 0 (this is a bit tricky). Signed-off-by: Wu Fengguang Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index ff8ad46..ec9c348 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -356,6 +356,7 @@ struct azx_dev { */ unsigned char stream_tag; /* assigned stream */ unsigned char index; /* stream index */ + int device; /* last device number assigned to */ unsigned int opened :1; unsigned int running :1; @@ -1441,10 +1442,13 @@ static int __devinit azx_codec_configure(struct azx *chip) */ /* assign a stream for the PCM */ -static inline struct azx_dev *azx_assign_device(struct azx *chip, int stream) +static inline struct azx_dev * +azx_assign_device(struct azx *chip, struct snd_pcm_substream *substream) { int dev, i, nums; - if (stream == SNDRV_PCM_STREAM_PLAYBACK) { + struct azx_dev *res = NULL; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { dev = chip->playback_index_offset; nums = chip->playback_streams; } else { @@ -1453,10 +1457,15 @@ static inline struct azx_dev *azx_assign_device(struct azx *chip, int stream) } for (i = 0; i < nums; i++, dev++) if (!chip->azx_dev[dev].opened) { - chip->azx_dev[dev].opened = 1; - return &chip->azx_dev[dev]; + res = &chip->azx_dev[dev]; + if (res->device == substream->pcm->device) + break; } - return NULL; + if (res) { + res->opened = 1; + res->device = substream->pcm->device; + } + return res; } /* release the assigned stream */ @@ -1505,7 +1514,7 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) int err; mutex_lock(&chip->open_mutex); - azx_dev = azx_assign_device(chip, substream->stream); + azx_dev = azx_assign_device(chip, substream); if (azx_dev == NULL) { mutex_unlock(&chip->open_mutex); return -EBUSY; -- cgit v0.10.2 From 2faf2e19dd0e060eeb32442858ef495ac3083277 Mon Sep 17 00:00:00 2001 From: Richard Kennedy Date: Fri, 25 Dec 2009 15:46:07 -0500 Subject: ext4: return correct wbc.nr_to_write in ext4_da_writepages When ext4_da_writepages increases the nr_to_write in writeback_control then it must always re-base the return value. Originally there was a (misguided) attempt prevent wbc.nr_to_write from going negative. In fact, it's necessary to allow nr_to_write to be negative so that wb_writeback() can correctly calculate how many pages were actually written. Signed-off-by: Richard Kennedy Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 282621f..3e3b454 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -2967,8 +2967,7 @@ retry: out_writepages: if (!no_nrwrite_index_update) wbc->no_nrwrite_index_update = 0; - if (wbc->nr_to_write > nr_to_writebump) - wbc->nr_to_write -= nr_to_writebump; + wbc->nr_to_write -= nr_to_writebump; wbc->range_start = range_start; trace_ext4_da_writepages_result(inode, wbc, ret, pages_written); return ret; -- cgit v0.10.2 From 729d55ba972348234759f8e40abf8de020f0d505 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 25 Dec 2009 22:49:01 +0100 Subject: ALSA: hda - Disable tigger at pin-sensing on AD codecs Analog Device codecs seem to have problems with the triggering of pin-sensing although their pincaps give the trigger requirements. Some reported that constant CPU load on HP laptops with AD codecs. For avoiding this regression, add a flag to codec struct to notify explicitly that the codec doesn't suppot the trigger at pin-sensing. Tested-by: Maciej Rutecki Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 950ee5cf..f98b47c 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -1327,11 +1327,13 @@ EXPORT_SYMBOL_HDA(snd_hda_query_pin_caps); */ u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid) { - u32 pincap = snd_hda_query_pin_caps(codec, nid); - - if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */ - snd_hda_codec_read(codec, nid, 0, AC_VERB_SET_PIN_SENSE, 0); + u32 pincap; + if (!codec->no_trigger_sense) { + pincap = snd_hda_query_pin_caps(codec, nid); + if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */ + snd_hda_codec_read(codec, nid, 0, AC_VERB_SET_PIN_SENSE, 0); + } return snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_SENSE, 0); } diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 1d541b7..0a770a2 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h @@ -817,6 +817,7 @@ struct hda_codec { unsigned int pin_amp_workaround:1; /* pin out-amp takes index * (e.g. Conexant codecs) */ + unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */ #ifdef CONFIG_SND_HDA_POWER_SAVE unsigned int power_on :1; /* current (global) power-state */ unsigned int power_transition :1; /* power-state in transition */ diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 1a36137..69a941c 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -1186,6 +1186,8 @@ static int patch_ad1986a(struct hda_codec *codec) */ spec->multiout.no_share_stream = 1; + codec->no_trigger_sense = 1; + return 0; } @@ -1371,6 +1373,8 @@ static int patch_ad1983(struct hda_codec *codec) codec->patch_ops = ad198x_patch_ops; + codec->no_trigger_sense = 1; + return 0; } @@ -1813,6 +1817,9 @@ static int patch_ad1981(struct hda_codec *codec) codec->patch_ops.unsol_event = ad1981_hp_unsol_event; break; } + + codec->no_trigger_sense = 1; + return 0; } @@ -3118,6 +3125,8 @@ static int patch_ad1988(struct hda_codec *codec) #endif spec->vmaster_nid = 0x04; + codec->no_trigger_sense = 1; + return 0; } @@ -3330,6 +3339,8 @@ static int patch_ad1884(struct hda_codec *codec) codec->patch_ops = ad198x_patch_ops; + codec->no_trigger_sense = 1; + return 0; } @@ -4287,6 +4298,8 @@ static int patch_ad1884a(struct hda_codec *codec) break; } + codec->no_trigger_sense = 1; + return 0; } @@ -4623,6 +4636,9 @@ static int patch_ad1882(struct hda_codec *codec) spec->mixers[2] = ad1882_6stack_mixers; break; } + + codec->no_trigger_sense = 1; + return 0; } -- cgit v0.10.2 From a252c81a69c4f9a5a8782f33b91bd837e9dcd406 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 25 Dec 2009 22:56:20 +0100 Subject: ALSA: hda - use snd_hda_jack_detect() again in patch_sigmatel.c Use snd_hda_jack_detect() again for jack-sensing. The triggering problem can be worked around with codec->no_trigger_sense flag now. Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index eeda7be..2291a83 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -4453,14 +4453,7 @@ static inline int get_pin_presence(struct hda_codec *codec, hda_nid_t nid) { if (!nid) return 0; - /* NOTE: we can't use snd_hda_jack_detect() here because STAC/IDT - * codecs behave wrongly when SET_PIN_SENSE is triggered, although - * the pincap gives TRIG_REQ bit. - */ - if (snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_SENSE, 0) & - AC_PINSENSE_PRESENCE) - return 1; - return 0; + return snd_hda_jack_detect(codec, nid); } static void stac92xx_line_out_detect(struct hda_codec *codec, @@ -4962,6 +4955,7 @@ static int patch_stac9200(struct hda_codec *codec) if (spec == NULL) return -ENOMEM; + codec->no_trigger_sense = 1; codec->spec = spec; spec->num_pins = ARRAY_SIZE(stac9200_pin_nids); spec->pin_nids = stac9200_pin_nids; @@ -5024,6 +5018,7 @@ static int patch_stac925x(struct hda_codec *codec) if (spec == NULL) return -ENOMEM; + codec->no_trigger_sense = 1; codec->spec = spec; spec->num_pins = ARRAY_SIZE(stac925x_pin_nids); spec->pin_nids = stac925x_pin_nids; @@ -5108,6 +5103,7 @@ static int patch_stac92hd73xx(struct hda_codec *codec) if (spec == NULL) return -ENOMEM; + codec->no_trigger_sense = 1; codec->spec = spec; codec->slave_dig_outs = stac92hd73xx_slave_dig_outs; spec->num_pins = ARRAY_SIZE(stac92hd73xx_pin_nids); @@ -5255,6 +5251,7 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) if (spec == NULL) return -ENOMEM; + codec->no_trigger_sense = 1; codec->spec = spec; codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs; spec->digbeep_nid = 0x21; @@ -5418,6 +5415,7 @@ static int patch_stac92hd71bxx(struct hda_codec *codec) if (spec == NULL) return -ENOMEM; + codec->no_trigger_sense = 1; codec->spec = spec; codec->patch_ops = stac92xx_patch_ops; spec->num_pins = STAC92HD71BXX_NUM_PINS; @@ -5661,6 +5659,7 @@ static int patch_stac922x(struct hda_codec *codec) if (spec == NULL) return -ENOMEM; + codec->no_trigger_sense = 1; codec->spec = spec; spec->num_pins = ARRAY_SIZE(stac922x_pin_nids); spec->pin_nids = stac922x_pin_nids; @@ -5764,6 +5763,7 @@ static int patch_stac927x(struct hda_codec *codec) if (spec == NULL) return -ENOMEM; + codec->no_trigger_sense = 1; codec->spec = spec; codec->slave_dig_outs = stac927x_slave_dig_outs; spec->num_pins = ARRAY_SIZE(stac927x_pin_nids); @@ -5898,6 +5898,7 @@ static int patch_stac9205(struct hda_codec *codec) if (spec == NULL) return -ENOMEM; + codec->no_trigger_sense = 1; codec->spec = spec; spec->num_pins = ARRAY_SIZE(stac9205_pin_nids); spec->pin_nids = stac9205_pin_nids; @@ -6053,6 +6054,7 @@ static int patch_stac9872(struct hda_codec *codec) spec = kzalloc(sizeof(*spec), GFP_KERNEL); if (spec == NULL) return -ENOMEM; + codec->no_trigger_sense = 1; codec->spec = spec; spec->num_pins = ARRAY_SIZE(stac9872_pin_nids); spec->pin_nids = stac9872_pin_nids; -- cgit v0.10.2 From 17a2a9b57a9a7d2fd8f97df951b5e63e0bd56ef5 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Fri, 25 Dec 2009 15:40:38 -0800 Subject: x86, compress: Force i386 instructions for the decompressor Recently, some distros have started shipping versions of gcc which default to -march=i686. This breaks building kernels for pre-i686 machines, even if they have been selected in Kconfig, due to the generation of CMOV instructions. There isn't enough benefit to try to preserve the generation of these instructions even when selected, so simply force -march=i386 for the decompressor when building a 32-bit kernel. Reported-and-tested-by: Chris Rankin Signed-off-by: H. Peter Anvin LKML-Reference: <219280.97558.qm@web52907.mail.re2.yahoo.com> diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile index f8ed065..f25bbd3 100644 --- a/arch/x86/boot/compressed/Makefile +++ b/arch/x86/boot/compressed/Makefile @@ -9,6 +9,7 @@ targets := vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinu KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2 KBUILD_CFLAGS += -fno-strict-aliasing -fPIC KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING +cflags-$(CONFIG_X86_32) := -march=i386 cflags-$(CONFIG_X86_64) := -mcmodel=small KBUILD_CFLAGS += $(cflags-y) KBUILD_CFLAGS += $(call cc-option,-ffreestanding) -- cgit v0.10.2 From 4a6e47a460ce55e283063fc3f7391c8ea46bea27 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Fri, 25 Dec 2009 17:13:07 -0800 Subject: bnx2x: Initialize cnic status block during chip reset When the device is reset during MTU change, ring size change, or self test, etc, the cnic status block needs to be properly initialized if cnic is registered. Signed-off-by: Michael Chan Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 77ba135..306c2b8 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -7593,6 +7593,8 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode) if (bp->cnic_eth_dev.drv_state & CNIC_DRV_STATE_REGD) { bnx2x_set_iscsi_eth_mac_addr(bp, 1); bp->cnic_flags |= BNX2X_CNIC_FLAG_MAC_SET; + bnx2x_init_sb(bp, bp->cnic_sb, bp->cnic_sb_mapping, + CNIC_SB_ID(bp)); } mutex_unlock(&bp->cnic_mutex); #endif -- cgit v0.10.2 From 28f6aeea3f12d37bd258b2c0d5ba891bff4ec479 Mon Sep 17 00:00:00 2001 From: Jamal Hadi Salim Date: Fri, 25 Dec 2009 17:30:22 -0800 Subject: net: restore ip source validation when using policy routing and the skb mark: there are cases where a back path validation requires us to use a different routing table for src ip validation than the one used for mapping ingress dst ip. One such a case is transparent proxying where we pretend to be the destination system and therefore the local table is used for incoming packets but possibly a main table would be used on outbound. Make the default behavior to allow the above and if users need to turn on the symmetry via sysctl src_valid_mark Signed-off-by: Jamal Hadi Salim Signed-off-by: David S. Miller diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h index 699e85c..b230492 100644 --- a/include/linux/inetdevice.h +++ b/include/linux/inetdevice.h @@ -81,6 +81,7 @@ static inline void ipv4_devconf_setall(struct in_device *in_dev) #define IN_DEV_FORWARD(in_dev) IN_DEV_CONF_GET((in_dev), FORWARDING) #define IN_DEV_MFORWARD(in_dev) IN_DEV_ANDCONF((in_dev), MC_FORWARDING) #define IN_DEV_RPFILTER(in_dev) IN_DEV_MAXCONF((in_dev), RP_FILTER) +#define IN_DEV_SRC_VMARK(in_dev) IN_DEV_ORCONF((in_dev), SRC_VMARK) #define IN_DEV_SOURCE_ROUTE(in_dev) IN_DEV_ANDCONF((in_dev), \ ACCEPT_SOURCE_ROUTE) #define IN_DEV_ACCEPT_LOCAL(in_dev) IN_DEV_ORCONF((in_dev), ACCEPT_LOCAL) diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 877ba03..bd27fbc 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -482,6 +482,7 @@ enum NET_IPV4_CONF_ARP_ACCEPT=21, NET_IPV4_CONF_ARP_NOTIFY=22, NET_IPV4_CONF_ACCEPT_LOCAL=23, + NET_IPV4_CONF_SRC_VMARK=24, __NET_IPV4_CONF_MAX }; diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 5cdbc10..040c4f0 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -1397,6 +1397,7 @@ static struct devinet_sysctl_table { DEVINET_SYSCTL_RW_ENTRY(ACCEPT_SOURCE_ROUTE, "accept_source_route"), DEVINET_SYSCTL_RW_ENTRY(ACCEPT_LOCAL, "accept_local"), + DEVINET_SYSCTL_RW_ENTRY(SRC_VMARK, "src_valid_mark"), DEVINET_SYSCTL_RW_ENTRY(PROXY_ARP, "proxy_arp"), DEVINET_SYSCTL_RW_ENTRY(MEDIUM_ID, "medium_id"), DEVINET_SYSCTL_RW_ENTRY(BOOTP_RELAY, "bootp_relay"), diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 3323168..82dbf71 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -252,6 +252,8 @@ int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif, no_addr = in_dev->ifa_list == NULL; rpf = IN_DEV_RPFILTER(in_dev); accept_local = IN_DEV_ACCEPT_LOCAL(in_dev); + if (mark && !IN_DEV_SRC_VMARK(in_dev)) + fl.mark = 0; } rcu_read_unlock(); -- cgit v0.10.2 From b3837ceca005890f1a328eb1a4204a9dc92b1b9f Mon Sep 17 00:00:00 2001 From: Denis Kirjanov Date: Fri, 25 Dec 2009 18:48:33 -0800 Subject: vxge: use DMA_BIT_MASK instead of plain values. Use DMA_BIT_MASK instead of plain values. Signed-off-by: Denis Kirjanov Signed-off-by: David S. Miller diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index f1c4b2a..0fdfd58 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c @@ -4087,21 +4087,21 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre) goto _exit0; } - if (!pci_set_dma_mask(pdev, 0xffffffffffffffffULL)) { + if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { vxge_debug_ll_config(VXGE_TRACE, "%s : using 64bit DMA", __func__); high_dma = 1; if (pci_set_consistent_dma_mask(pdev, - 0xffffffffffffffffULL)) { + DMA_BIT_MASK(64))) { vxge_debug_init(VXGE_ERR, "%s : unable to obtain 64bit DMA for " "consistent allocations", __func__); ret = -ENOMEM; goto _exit1; } - } else if (!pci_set_dma_mask(pdev, 0xffffffffUL)) { + } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) { vxge_debug_ll_config(VXGE_TRACE, "%s : using 32bit DMA", __func__); } else { -- cgit v0.10.2 From 903b0eb39e3284cbf4d5a3773858e9586d16cbda Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Sat, 26 Dec 2009 03:27:45 +0100 Subject: ALSA: sound/arm: Fix build failure caused by missing struct aaci definition This patch fixes a build failure introduced by the patch ALSA: AACI: factor common hw_params logic into aaci_pcm_hw_params [1] by adding/moving the aaci struct to the right position. The patch mentioned above merged common source parts into one function, but unfortunately left out the aaci struct and consequently caused a build failure e.g. for arm versatile_config [2] References: [1] http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=d3aee7996c30f928bbbbfd0994148e35d2e83084 [2] http://kisskb.ellerman.id.au/kisskb/buildresult/1893605/ Patch against Linus' tree. Signed-off-by: Peter Huewe Signed-off-by: Takashi Iwai diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c index c569986..656e474 100644 --- a/sound/arm/aaci.c +++ b/sound/arm/aaci.c @@ -441,6 +441,7 @@ static int aaci_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { int err; + struct aaci *aaci = substream->private_data; aaci_pcm_hw_free(substream); if (aacirun->pcm_open) { @@ -560,7 +561,6 @@ static int aaci_pcm_open(struct snd_pcm_substream *substream) static int aaci_pcm_playback_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct aaci *aaci = substream->private_data; struct aaci_runtime *aacirun = substream->runtime->private_data; unsigned int channels = params_channels(params); int ret; @@ -659,7 +659,6 @@ static struct snd_pcm_ops aaci_playback_ops = { static int aaci_pcm_capture_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct aaci *aaci = substream->private_data; struct aaci_runtime *aacirun = substream->runtime->private_data; int ret; -- cgit v0.10.2 From fdfa68298816192d47fc7443d1e2f00fa1420985 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Sun, 27 Dec 2009 00:09:45 +0900 Subject: ALSA: Fix a typo in Procfile.txt Fix a typo in Documentation/sound/alsa/Procfile.txt Signed-off-by Masanari Iida Signed-off-by: Takashi Iwai diff --git a/Documentation/sound/alsa/Procfile.txt b/Documentation/sound/alsa/Procfile.txt index 719a819..07301de 100644 --- a/Documentation/sound/alsa/Procfile.txt +++ b/Documentation/sound/alsa/Procfile.txt @@ -95,7 +95,7 @@ card*/pcm*/xrun_debug It takes an integer value, can be changed by writing to this file, such as - # cat 5 > /proc/asound/card0/pcm0p/xrun_debug + # echo 5 > /proc/asound/card0/pcm0p/xrun_debug The value consists of the following bit flags: bit 0 = Enable XRUN/jiffies debug messages -- cgit v0.10.2 From ead510cebcdf41c92fce2a909f342255b028a33d Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sat, 26 Dec 2009 22:52:13 -0200 Subject: thinkpad-acpi: don't take the first ALSA slot by default We don't want to be the first soundcard. We don't want to shift other soundcards out of the way either, even if they load much later. Ask ALSA to (by default) load us in one of the last three slots. This can be overriden at will using the "index" parameter. Reported-by: Whoopie Signed-off-by: Henrique de Moraes Holschuh Signed-off-by: Len Brown diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 448c8ae..3311b00 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -6388,7 +6388,7 @@ static struct ibm_struct brightness_driver_data = { #define TPACPI_ALSA_SHRTNAME "ThinkPad Console Audio Control" #define TPACPI_ALSA_MIXERNAME TPACPI_ALSA_SHRTNAME -static int alsa_index = SNDRV_DEFAULT_IDX1; +static int alsa_index = ~((1 << (SNDRV_CARDS - 3)) - 1); /* last three slots */ static char *alsa_id = "ThinkPadEC"; static int alsa_enable = SNDRV_DEFAULT_ENABLE1; -- cgit v0.10.2 From 74c75c1848b618f6717c1be887ad539ffac2e96d Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sat, 26 Dec 2009 22:52:14 -0200 Subject: thinkpad-acpi: don't fail to load the entire module due to ALSA problems If we cannot create the ALSA mixer, it is a good reason to fail to load the volume subdriver, and not to fail to load the entire module. While at it, add more debugging messages, as the error paths are being used a lot more than I'd expect, and it is failing to set up the ALSA mixer on a number of ThinkPads. Reported-by: Peter Jordan Signed-off-by: Henrique de Moraes Holschuh Signed-off-by: Len Brown diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 3311b00..9b7da9c 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -6705,10 +6705,11 @@ static int __init volume_create_alsa_mixer(void) rc = snd_card_create(alsa_index, alsa_id, THIS_MODULE, sizeof(struct tpacpi_alsa_data), &card); - if (rc < 0) - return rc; - if (!card) - return -ENOMEM; + if (rc < 0 || !card) { + printk(TPACPI_ERR + "Failed to create ALSA card structures: %d\n", rc); + return 1; + } BUG_ON(!card->private_data); data = card->private_data; @@ -6741,8 +6742,9 @@ static int __init volume_create_alsa_mixer(void) rc = snd_ctl_add(card, ctl_vol); if (rc < 0) { printk(TPACPI_ERR - "Failed to create ALSA volume control\n"); - goto err_out; + "Failed to create ALSA volume control: %d\n", + rc); + goto err_exit; } data->ctl_vol_id = &ctl_vol->id; } @@ -6750,22 +6752,25 @@ static int __init volume_create_alsa_mixer(void) ctl_mute = snd_ctl_new1(&volume_alsa_control_mute, NULL); rc = snd_ctl_add(card, ctl_mute); if (rc < 0) { - printk(TPACPI_ERR "Failed to create ALSA mute control\n"); - goto err_out; + printk(TPACPI_ERR "Failed to create ALSA mute control: %d\n", + rc); + goto err_exit; } data->ctl_mute_id = &ctl_mute->id; snd_card_set_dev(card, &tpacpi_pdev->dev); rc = snd_card_register(card); - -err_out: if (rc < 0) { - snd_card_free(card); - card = NULL; + printk(TPACPI_ERR "Failed to register ALSA card: %d\n", rc); + goto err_exit; } alsa_card = card; - return rc; + return 0; + +err_exit: + snd_card_free(card); + return 1; } #define TPACPI_VOL_Q_MUTEONLY 0x0001 /* Mute-only control available */ -- cgit v0.10.2 From ff850c339a1a6a7724537160c73cdc09a483fc5d Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sat, 26 Dec 2009 22:52:15 -0200 Subject: thinkpad-acpi: make volume subdriver optional Allow the user to choose through Kconfig if the Console Audio Control interface (aka "volume subdriver") should be available or not. This not only saves some memory, but also allows the thinkpad-acpi driver to be built-in even if ALSA is modular when the console audio control interface is not wanted. This change fixes a build problem that is causing some annoyances, in a way that doesn't disable the entire driver on kernels without ALSA support. Signed-off-by: Henrique de Moraes Holschuh Cc: Ingo Molnar Cc: Amerigo Wang Cc: Helight Xu Cc: Takashi Iwai Signed-off-by: Len Brown diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index ec4faff..2462dc3 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -233,6 +233,29 @@ config THINKPAD_ACPI If you have an IBM or Lenovo ThinkPad laptop, say Y or M here. +config THINKPAD_ACPI_ALSA_SUPPORT + bool "Console audio control ALSA interface" + depends on THINKPAD_ACPI + depends on SND + depends on SND = y || THINKPAD_ACPI = SND + default y + ---help--- + Enables monitoring of the built-in console audio output control + (headphone and speakers), which is operated by the mute and (in + some ThinkPad models) volume hotkeys. + + If this option is enabled, ThinkPad-ACPI will export an ALSA card + with a single read-only mixer control, which should be used for + on-screen-display feedback purposes by the Desktop Environment. + + Optionally, the driver will also allow software control (the + ALSA mixer will be made read-write). Please refer to the driver + documentation for details. + + All IBM models have both volume and mute control. Newer Lenovo + models only have mute control (the volume hotkeys are just normal + keys and volume control is done through the main HDA mixer). + config THINKPAD_ACPI_DEBUGFACILITIES bool "Maintainer debug facilities" depends on THINKPAD_ACPI diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 9b7da9c..e67e4fe 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -6384,6 +6384,8 @@ static struct ibm_struct brightness_driver_data = { * and we leave them unchanged. */ +#ifdef CONFIG_THINKPAD_ACPI_ALSA_SUPPORT + #define TPACPI_ALSA_DRVNAME "ThinkPad EC" #define TPACPI_ALSA_SHRTNAME "ThinkPad Console Audio Control" #define TPACPI_ALSA_MIXERNAME TPACPI_ALSA_SHRTNAME @@ -7021,6 +7023,28 @@ static struct ibm_struct volume_driver_data = { .shutdown = volume_shutdown, }; +#else /* !CONFIG_THINKPAD_ACPI_ALSA_SUPPORT */ + +#define alsa_card NULL + +static void inline volume_alsa_notify_change(void) +{ +} + +static int __init volume_init(struct ibm_init_struct *iibm) +{ + printk(TPACPI_INFO + "volume: disabled as there is no ALSA support in this kernel\n"); + + return 1; +} + +static struct ibm_struct volume_driver_data = { + .name = "volume", +}; + +#endif /* CONFIG_THINKPAD_ACPI_ALSA_SUPPORT */ + /************************************************************************* * Fan subdriver */ @@ -8743,6 +8767,7 @@ MODULE_PARM_DESC(hotkey_report_mode, "used for backwards compatibility with userspace, " "see documentation"); +#ifdef CONFIG_THINKPAD_ACPI_ALSA_SUPPORT module_param_named(volume_mode, volume_mode, uint, 0444); MODULE_PARM_DESC(volume_mode, "Selects volume control strategy: " @@ -8765,6 +8790,7 @@ module_param_named(id, alsa_id, charp, 0444); MODULE_PARM_DESC(id, "ALSA id for the ACPI EC Mixer"); module_param_named(enable, alsa_enable, bool, 0444); MODULE_PARM_DESC(enable, "Enable the ALSA interface for the ACPI EC Mixer"); +#endif /* CONFIG_THINKPAD_ACPI_ALSA_SUPPORT */ #define TPACPI_PARAM(feature) \ module_param_call(feature, set_ibm_param, NULL, NULL, 0); \ -- cgit v0.10.2 From 169220f88f0f26f4450ac0bc8ff0f807b453ec58 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sat, 26 Dec 2009 22:52:16 -0200 Subject: thinkpad-acpi: update volume subdriver documentation Signed-off-by: Henrique de Moraes Holschuh Signed-off-by: Len Brown diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt index 169091f..75afa12 100644 --- a/Documentation/laptops/thinkpad-acpi.txt +++ b/Documentation/laptops/thinkpad-acpi.txt @@ -1092,8 +1092,8 @@ WARNING: its level up and down at every change. -Volume control --------------- +Volume control (Console Audio control) +-------------------------------------- procfs: /proc/acpi/ibm/volume ALSA: "ThinkPad Console Audio Control", default ID: "ThinkPadEC" @@ -1110,9 +1110,53 @@ the desktop environment to just provide on-screen-display feedback. Software volume control should be done only in the main AC97/HDA mixer. -This feature allows volume control on ThinkPad models with a digital -volume knob (when available, not all models have it), as well as -mute/unmute control. The available commands are: + +About the ThinkPad Console Audio control: + +ThinkPads have a built-in amplifier and muting circuit that drives the +console headphone and speakers. This circuit is after the main AC97 +or HDA mixer in the audio path, and under exclusive control of the +firmware. + +ThinkPads have three special hotkeys to interact with the console +audio control: volume up, volume down and mute. + +It is worth noting that the normal way the mute function works (on +ThinkPads that do not have a "mute LED") is: + +1. Press mute to mute. It will *always* mute, you can press it as + many times as you want, and the sound will remain mute. + +2. Press either volume key to unmute the ThinkPad (it will _not_ + change the volume, it will just unmute). + +This is a very superior design when compared to the cheap software-only +mute-toggle solution found on normal consumer laptops: you can be +absolutely sure the ThinkPad will not make noise if you press the mute +button, no matter the previous state. + +The IBM ThinkPads, and the earlier Lenovo ThinkPads have variable-gain +amplifiers driving the speakers and headphone output, and the firmware +also handles volume control for the headphone and speakers on these +ThinkPads without any help from the operating system (this volume +control stage exists after the main AC97 or HDA mixer in the audio +path). + +The newer Lenovo models only have firmware mute control, and depend on +the main HDA mixer to do volume control (which is done by the operating +system). In this case, the volume keys are filtered out for unmute +key press (there are some firmware bugs in this area) and delivered as +normal key presses to the operating system (thinkpad-acpi is not +involved). + + +The ThinkPad-ACPI volume control: + +The preferred way to interact with the Console Audio control is the +ALSA interface. + +The legacy procfs interface allows one to read the current state, +and if volume control is enabled, accepts the following commands: echo up >/proc/acpi/ibm/volume echo down >/proc/acpi/ibm/volume @@ -1121,12 +1165,10 @@ mute/unmute control. The available commands are: echo 'level ' >/proc/acpi/ibm/volume The number range is 0 to 14 although not all of them may be -distinct. The unmute the volume after the mute command, use either the +distinct. To unmute the volume after the mute command, use either the up or down command (the level command will not unmute the volume), or the unmute command. -The current volume level and mute state is shown in the file. - You can use the volume_capabilities parameter to tell the driver whether your thinkpad has volume control or mute-only control: volume_capabilities=1 for mixers with mute and volume control, -- cgit v0.10.2 From 6e5b08ee941af38cfc6456158e7e04c1bc49306f Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sat, 26 Dec 2009 22:52:17 -0200 Subject: thinkpad-acpi: improve Kconfig help text Document that rfkill and ALSA functionality exists, but requires the subsystems to be available, and not modular if thinkpad-acpi is not modular. Signed-off-by: Henrique de Moraes Holschuh Signed-off-by: Len Brown diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 2462dc3..db32c25 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -231,6 +231,11 @@ config THINKPAD_ACPI This driver was formerly known as ibm-acpi. + Extra functionality will be available if the rfkill (CONFIG_RFKILL) + and/or ALSA (CONFIG_SND) subsystems are available in the kernel. + Note that if you want ThinkPad-ACPI to be built-in instead of + modular, ALSA and rfkill will also have to be built-in. + If you have an IBM or Lenovo ThinkPad laptop, say Y or M here. config THINKPAD_ACPI_ALSA_SUPPORT -- cgit v0.10.2 From 7583605b6d29f1f7f6fc505b883328089f3485ad Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Thu, 24 Dec 2009 05:31:03 +0000 Subject: ucc_geth: Fix empty TX queue processing Following oops was seen with the ucc_geth driver: Unable to handle kernel paging request for data at address 0x00000058 Faulting instruction address: 0xc024f2fc Oops: Kernel access of bad area, sig: 11 [#1] [...] NIP [c024f2fc] skb_recycle_check+0x14/0x100 LR [e30aa0a4] ucc_geth_poll+0xd8/0x4e0 [ucc_geth_driver] Call Trace: [df857d50] [c000b03c] __ipipe_grab_irq+0x3c/0xa4 (unreliable) [df857d60] [e30aa0a4] ucc_geth_poll+0xd8/0x4e0 [ucc_geth_driver] [df857dd0] [c0258cf8] net_rx_action+0xf8/0x1b8 [df857e10] [c0032a38] __do_softirq+0xb8/0x13c [df857e60] [c00065cc] do_softirq+0xa0/0xac [...] This is because ucc_geth_tx() tries to process an empty queue when queues are logically stopped. Stopping the queues doesn't disable polling, and since nowadays ucc_geth_tx() is actually called from the polling routine, the oops above might pop up. Fix this by removing 'netif_queue_stopped() == 0' check. Reported-by: Lennart Sorensen Signed-off-by: Anton Vorontsov Tested-by: Lennart Sorensen Cc: Stable [2.6.32] Signed-off-by: David S. Miller diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index afaf088..0f8c99e 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -3273,7 +3273,7 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ) /* Handle the transmitted buffer and release */ /* the BD to be used with the current frame */ - if ((bd == ugeth->txBd[txQ]) && (netif_queue_stopped(dev) == 0)) + if (bd == ugeth->txBd[txQ]) /* queue empty? */ break; dev->stats.tx_packets++; -- cgit v0.10.2 From 08b5e1c91ce95793c59a59529a362a1bcc81faae Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Thu, 24 Dec 2009 05:31:05 +0000 Subject: ucc_geth: Fix netdev watchdog triggering on link changes Since commit 864fdf884e82bacbe8ca5e93bd43393a61d2e2b4 ("ucc_geth: Fix hangs after switching from full to half duplex") ucc_geth driver disables the controller during MAC configuration changes. Though, disabling the controller might take quite awhile, and so the netdev watchdog might get upset: NETDEV WATCHDOG: eth2 (ucc_geth): transmit queue 0 timed out ------------[ cut here ]------------ Badness at c02729a8 [verbose debug info unavailable] NIP: c02729a8 LR: c02729a8 CTR: c01b6088 REGS: c0451c40 TRAP: 0700 Not tainted (2.6.32-trunk-8360e) [...] NIP [c02729a8] dev_watchdog+0x280/0x290 LR [c02729a8] dev_watchdog+0x280/0x290 Call Trace: [c0451cf0] [c02729a8] dev_watchdog+0x280/0x290 (unreliable) [c0451d50] [c00377c4] run_timer_softirq+0x164/0x224 [c0451da0] [c0032a38] __do_softirq+0xb8/0x13c [c0451df0] [c00065cc] do_softirq+0xa0/0xac [c0451e00] [c003280c] irq_exit+0x7c/0x9c [c0451e10] [c00640c4] __ipipe_sync_stage+0x248/0x24c [...] This patch fixes the issue by detaching the netdev during the time we change the configuration. Reported-by: Lennart Sorensen Signed-off-by: Anton Vorontsov Tested-by: Lennart Sorensen Cc: Stable [2.6.32] Signed-off-by: David S. Miller diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 0f8c99e..7fff4c5 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -1563,7 +1563,10 @@ static int ugeth_disable(struct ucc_geth_private *ugeth, enum comm_dir mode) static void ugeth_quiesce(struct ucc_geth_private *ugeth) { - /* Wait for and prevent any further xmits. */ + /* Prevent any further xmits, plus detach the device. */ + netif_device_detach(ugeth->ndev); + + /* Wait for any current xmits to finish. */ netif_tx_disable(ugeth->ndev); /* Disable the interrupt to avoid NAPI rescheduling. */ @@ -1577,7 +1580,7 @@ static void ugeth_activate(struct ucc_geth_private *ugeth) { napi_enable(&ugeth->napi); enable_irq(ugeth->ug_info->uf_info.irq); - netif_tx_wake_all_queues(ugeth->ndev); + netif_device_attach(ugeth->ndev); } /* Called every time the controller might need to be made -- cgit v0.10.2 From 08fafd8461c0ca8d1b389b7dc11d17e7b2331282 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Thu, 24 Dec 2009 05:31:20 +0000 Subject: ucc_geth: Don't needlessly change MAC settings in adjust_link() If PHY doesn't have an IRQ, phylib would poll for link changes, and would call adjust_link() every second. In that case we disable and enable the controller every second. Let's better check if there is actually anything changed, and, if so, change the MAC settings. Signed-off-by: Anton Vorontsov Signed-off-by: David S. Miller diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 7fff4c5..41ad2f3 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -1651,25 +1651,28 @@ static void adjust_link(struct net_device *dev) ugeth->oldspeed = phydev->speed; } - /* - * To change the MAC configuration we need to disable the - * controller. To do so, we have to either grab ugeth->lock, - * which is a bad idea since 'graceful stop' commands might - * take quite a while, or we can quiesce driver's activity. - */ - ugeth_quiesce(ugeth); - ugeth_disable(ugeth, COMM_DIR_RX_AND_TX); - - out_be32(&ug_regs->maccfg2, tempval); - out_be32(&uf_regs->upsmr, upsmr); - - ugeth_enable(ugeth, COMM_DIR_RX_AND_TX); - ugeth_activate(ugeth); - if (!ugeth->oldlink) { new_state = 1; ugeth->oldlink = 1; } + + if (new_state) { + /* + * To change the MAC configuration we need to disable + * the controller. To do so, we have to either grab + * ugeth->lock, which is a bad idea since 'graceful + * stop' commands might take quite a while, or we can + * quiesce driver's activity. + */ + ugeth_quiesce(ugeth); + ugeth_disable(ugeth, COMM_DIR_RX_AND_TX); + + out_be32(&ug_regs->maccfg2, tempval); + out_be32(&uf_regs->upsmr, upsmr); + + ugeth_enable(ugeth, COMM_DIR_RX_AND_TX); + ugeth_activate(ugeth); + } } else if (ugeth->oldlink) { new_state = 1; ugeth->oldlink = 0; -- cgit v0.10.2 From 80924e5f7dbe00d964b7249160c7ca25fa3cd889 Mon Sep 17 00:00:00 2001 From: Vitaliy Gusev Date: Fri, 25 Dec 2009 07:17:43 +0000 Subject: tun: use tun_sk instead container_of Using macro tun_sk is more clear and shorter. However tun.c has tun_sk, but doesn't use it. Signed-off-by: Vitaliy Gusev Signed-off-by: David S. Miller diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 01e99f2..2834a01 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -849,13 +849,13 @@ static void tun_sock_write_space(struct sock *sk) if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) wake_up_interruptible_sync(sk->sk_sleep); - tun = container_of(sk, struct tun_sock, sk)->tun; + tun = tun_sk(sk)->tun; kill_fasync(&tun->fasync, SIGIO, POLL_OUT); } static void tun_sock_destruct(struct sock *sk) { - free_netdev(container_of(sk, struct tun_sock, sk)->tun->dev); + free_netdev(tun_sk(sk)->tun->dev); } static struct proto tun_proto = { @@ -990,7 +990,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) sk->sk_write_space = tun_sock_write_space; sk->sk_sndbuf = INT_MAX; - container_of(sk, struct tun_sock, sk)->tun = tun; + tun_sk(sk)->tun = tun; security_tun_dev_post_create(sk); -- cgit v0.10.2 From f74dac0859bd9678b289ad9dc215026fd7ce033e Mon Sep 17 00:00:00 2001 From: Sandeep Gopalpet Date: Thu, 24 Dec 2009 03:13:06 +0000 Subject: gianfar: Fix gianfar select_queue bogosity The gfar_select_queue() function was used to set queue mapping only for forwarding/bridging applications and the condition for locally generated packets was completely ignored. The solution is to remove the gfar_select_queue() function and use skb_record_rx_queue to set queue mapping for forwarding/bridging applications. This will ensure that in case of forwarding/bridging applications txq = rxq will be selected and skb_tx_hash will be used to pick up a txq for locally generated packets. Signed-off-by: Sandeep Gopalpet Signed-off-by: David S. Miller diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index e0620d0..8bd3c9f 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -143,7 +143,6 @@ void gfar_start(struct net_device *dev); static void gfar_clear_exact_match(struct net_device *dev); static void gfar_set_mac_for_addr(struct net_device *dev, int num, u8 *addr); static int gfar_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); -u16 gfar_select_queue(struct net_device *dev, struct sk_buff *skb); MODULE_AUTHOR("Freescale Semiconductor, Inc"); MODULE_DESCRIPTION("Gianfar Ethernet Driver"); @@ -455,7 +454,6 @@ static const struct net_device_ops gfar_netdev_ops = { .ndo_set_multicast_list = gfar_set_multi, .ndo_tx_timeout = gfar_timeout, .ndo_do_ioctl = gfar_ioctl, - .ndo_select_queue = gfar_select_queue, .ndo_get_stats = gfar_get_stats, .ndo_vlan_rx_register = gfar_vlan_rx_register, .ndo_set_mac_address = eth_mac_addr, @@ -506,10 +504,6 @@ static inline int gfar_uses_fcb(struct gfar_private *priv) return priv->vlgrp || priv->rx_csum_enable; } -u16 gfar_select_queue(struct net_device *dev, struct sk_buff *skb) -{ - return skb_get_queue_mapping(skb); -} static void free_tx_pointers(struct gfar_private *priv) { int i = 0; @@ -2470,10 +2464,11 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, fcb = (struct rxfcb *)skb->data; /* Remove the FCB from the skb */ - skb_set_queue_mapping(skb, fcb->rq); /* Remove the padded bytes, if there are any */ - if (amount_pull) + if (amount_pull) { + skb_record_rx_queue(skb, fcb->rq); skb_pull(skb, amount_pull); + } if (priv->rx_csum_enable) gfar_rx_checksum(skb, fcb); @@ -2554,7 +2549,7 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit) /* Remove the FCS from the packet length */ skb_put(skb, pkt_len); rx_queue->stats.rx_bytes += pkt_len; - + skb_record_rx_queue(skb, rx_queue->qindex); gfar_process_frame(dev, skb, amount_pull); } else { -- cgit v0.10.2 From 1f04493123763f5b8bc6d5de9aed0222345c052c Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Thu, 24 Dec 2009 08:11:24 +0000 Subject: Fix MAC address access in 3c507, ibmlana, pcnet32 and libertas Commit f001fde5eadd915f4858d22ed70d7040f48767cf changed net_device.dev_addr from a 32-byte array to a pointer. I found 4 ethernet drivers which rely on sizeof(dev_addr), which are now only copying 4 bytes of the address information on 32bit systems. Fix them to use ETH_ALEN. Signed-off-by: Daniel Drake Reviewed-by: Jiri Pirko Signed-off-by: David S. Miller diff --git a/drivers/net/3c507.c b/drivers/net/3c507.c index fbc2311..77cf090 100644 --- a/drivers/net/3c507.c +++ b/drivers/net/3c507.c @@ -56,6 +56,7 @@ static const char version[] = #include #include #include +#include #include #include #include @@ -734,8 +735,7 @@ static void init_82586_mem(struct net_device *dev) memcpy_toio(lp->base, init_words + 5, sizeof(init_words) - 10); /* Fill in the station address. */ - memcpy_toio(lp->base+SA_OFFSET, dev->dev_addr, - sizeof(dev->dev_addr)); + memcpy_toio(lp->base+SA_OFFSET, dev->dev_addr, ETH_ALEN); /* The Tx-block list is written as needed. We just set up the values. */ lp->tx_cmd_link = IDLELOOP + 4; diff --git a/drivers/net/ibmlana.c b/drivers/net/ibmlana.c index 090a6d3..052c740 100644 --- a/drivers/net/ibmlana.c +++ b/drivers/net/ibmlana.c @@ -87,6 +87,7 @@ History: #include #include #include +#include #include #include @@ -988,7 +989,7 @@ static int __devinit ibmlana_init_one(struct device *kdev) /* copy out MAC address */ - for (z = 0; z < sizeof(dev->dev_addr); z++) + for (z = 0; z < ETH_ALEN; z++) dev->dev_addr[z] = inb(dev->base_addr + MACADDRPROM + z); /* print config */ diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c index dcc67a3..e154677 100644 --- a/drivers/net/pcnet32.c +++ b/drivers/net/pcnet32.c @@ -45,6 +45,7 @@ static const char *const version = #include #include #include +#include #include #include #include @@ -1765,7 +1766,7 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev) /* if the ethernet address is not valid, force to 00:00:00:00:00:00 */ if (!is_valid_ether_addr(dev->perm_addr)) - memset(dev->dev_addr, 0, sizeof(dev->dev_addr)); + memset(dev->dev_addr, 0, ETH_ALEN); if (pcnet32_debug & NETIF_MSG_PROBE) { printk(" %pM", dev->dev_addr); diff --git a/drivers/net/wireless/libertas/mesh.c b/drivers/net/wireless/libertas/mesh.c index 2f91c9b..92b7a35 100644 --- a/drivers/net/wireless/libertas/mesh.c +++ b/drivers/net/wireless/libertas/mesh.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -351,8 +352,7 @@ int lbs_add_mesh(struct lbs_private *priv) mesh_dev->netdev_ops = &mesh_netdev_ops; mesh_dev->ethtool_ops = &lbs_ethtool_ops; - memcpy(mesh_dev->dev_addr, priv->dev->dev_addr, - sizeof(priv->dev->dev_addr)); + memcpy(mesh_dev->dev_addr, priv->dev->dev_addr, ETH_ALEN); SET_NETDEV_DEV(priv->mesh_dev, priv->dev->dev.parent); -- cgit v0.10.2 From c99a3d2e04c63a795e13c26d6f2982731e1f1ae0 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 23 Dec 2009 03:27:10 +0000 Subject: bond_3ad.c avoid possible null deref A few lines earlier we assume that best->slave could be either null or non-null so we should check it here as well. Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index 0fb7a49..822f586 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c @@ -1580,7 +1580,7 @@ static void ad_agg_selection_logic(struct aggregator *agg) // check if any partner replys if (best->is_individual) { pr_warning("%s: Warning: No 802.3ad response from the link partner for any adapters in the bond\n", - best->slave->dev->master->name); + best->slave ? best->slave->dev->master->name : "NULL"); } best->is_active = 1; -- cgit v0.10.2 From 96c5340147584481ef0c0afbb5423f7563c1d24a Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Fri, 25 Dec 2009 23:30:02 +0000 Subject: NET: XFRM: Fix spelling of neighbour. Signed-off-by: Ralf Baechle net/xfrm/xfrm_policy.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) Signed-off-by: David S. Miller diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index cb81ca3..4725a54 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -1445,7 +1445,7 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy, if (!dev) goto free_dst; - /* Copy neighbout for reachability confirmation */ + /* Copy neighbour for reachability confirmation */ dst0->neighbour = neigh_clone(dst->neighbour); xfrm_init_path((struct xfrm_dst *)dst0, dst, nfheader_len); -- cgit v0.10.2 From 411fe85c7653f51403c2a6fd9026b0db2ab19478 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Sun, 27 Dec 2009 10:25:58 +0100 Subject: ALSA: hda - Don't cache beep controls The beep control verbs don't need to be cached for resume. Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c index 5fe34a8..ca3c57a 100644 --- a/sound/pci/hda/hda_beep.c +++ b/sound/pci/hda/hda_beep.c @@ -42,7 +42,7 @@ static void snd_hda_generate_beep(struct work_struct *work) return; /* generate tone */ - snd_hda_codec_write_cache(codec, beep->nid, 0, + snd_hda_codec_write(codec, beep->nid, 0, AC_VERB_SET_BEEP_CONTROL, beep->tone); } @@ -119,7 +119,7 @@ static void snd_hda_do_detach(struct hda_beep *beep) beep->dev = NULL; cancel_work_sync(&beep->beep_work); /* turn off beep for sure */ - snd_hda_codec_write_cache(beep->codec, beep->nid, 0, + snd_hda_codec_write(beep->codec, beep->nid, 0, AC_VERB_SET_BEEP_CONTROL, 0); } @@ -192,7 +192,7 @@ int snd_hda_enable_beep_device(struct hda_codec *codec, int enable) beep->enabled = enable; if (!enable) { /* turn off beep */ - snd_hda_codec_write_cache(beep->codec, beep->nid, 0, + snd_hda_codec_write(beep->codec, beep->nid, 0, AC_VERB_SET_BEEP_CONTROL, 0); } if (beep->mode == HDA_BEEP_MODE_SWREG) { -- cgit v0.10.2 From 54f7190b23080c7ac32078ed6a346bdc591ebef1 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Sun, 27 Dec 2009 13:27:39 +0100 Subject: ALSA: hda - Fix Oops at reloading beep devices The recent change for supporting dynamic beep device allocation caused a problem resulting in Oops at reloading the driver. Also, it ignores the error from input device registration. This patch fixes the wrong check in snd_hda_detach_beep_device(), and returns an error when the input device registration fails properly. Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c index ca3c57a..e4581a42 100644 --- a/sound/pci/hda/hda_beep.c +++ b/sound/pci/hda/hda_beep.c @@ -239,8 +239,12 @@ int snd_hda_attach_beep_device(struct hda_codec *codec, int nid) mutex_init(&beep->mutex); if (beep->mode == HDA_BEEP_MODE_ON) { - beep->enabled = 1; - snd_hda_do_register(&beep->register_work); + int err = snd_hda_do_attach(beep); + if (err < 0) { + kfree(beep); + codec->beep = NULL; + return err; + } } return 0; @@ -253,7 +257,7 @@ void snd_hda_detach_beep_device(struct hda_codec *codec) if (beep) { cancel_work_sync(&beep->register_work); cancel_delayed_work(&beep->unregister_work); - if (beep->enabled) + if (beep->dev) snd_hda_do_detach(beep); codec->beep = NULL; kfree(beep); -- cgit v0.10.2 From fb341f572d26e0786167cd96b90cc4febed830cf Mon Sep 17 00:00:00 2001 From: Marcelo Tosatti Date: Sat, 5 Dec 2009 12:34:11 -0200 Subject: KVM: MMU: remove prefault from invlpg handler The invlpg prefault optimization breaks Windows 2008 R2 occasionally. The visible effect is that the invlpg handler instantiates a pte which is, microseconds later, written with a different gfn by another vcpu. The OS could have other mechanisms to prevent a present translation from being used, which the hypervisor is unaware of. While the documentation states that the cpu is at liberty to prefetch tlb entries, it looks like this is not heeded, so remove tlb prefetch from invlpg. Cc: stable@kernel.org Signed-off-by: Marcelo Tosatti Signed-off-by: Avi Kivity diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h index a601713..58a0f1e 100644 --- a/arch/x86/kvm/paging_tmpl.h +++ b/arch/x86/kvm/paging_tmpl.h @@ -455,8 +455,6 @@ out_unlock: static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva) { struct kvm_shadow_walk_iterator iterator; - pt_element_t gpte; - gpa_t pte_gpa = -1; int level; u64 *sptep; int need_flush = 0; @@ -470,10 +468,6 @@ static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva) if (level == PT_PAGE_TABLE_LEVEL || ((level == PT_DIRECTORY_LEVEL && is_large_pte(*sptep))) || ((level == PT_PDPE_LEVEL && is_large_pte(*sptep)))) { - struct kvm_mmu_page *sp = page_header(__pa(sptep)); - - pte_gpa = (sp->gfn << PAGE_SHIFT); - pte_gpa += (sptep - sp->spt) * sizeof(pt_element_t); if (is_shadow_present_pte(*sptep)) { rmap_remove(vcpu->kvm, sptep); @@ -492,18 +486,6 @@ static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva) if (need_flush) kvm_flush_remote_tlbs(vcpu->kvm); spin_unlock(&vcpu->kvm->mmu_lock); - - if (pte_gpa == -1) - return; - if (kvm_read_guest_atomic(vcpu->kvm, pte_gpa, &gpte, - sizeof(pt_element_t))) - return; - if (is_present_gpte(gpte) && (gpte & PT_ACCESSED_MASK)) { - if (mmu_topup_memory_caches(vcpu)) - return; - kvm_mmu_pte_write(vcpu, pte_gpa, (const u8 *)&gpte, - sizeof(pt_element_t), 0); - } } static gpa_t FNAME(gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t vaddr) -- cgit v0.10.2 From fae3a3536a6fecedebd49fa847f810e599bfb132 Mon Sep 17 00:00:00 2001 From: Sheng Yang Date: Tue, 15 Dec 2009 10:28:07 +0800 Subject: KVM: Fix possible circular locking in kvm_vm_ioctl_assign_device() One possible order is: KVM_CREATE_IRQCHIP ioctl(took kvm->lock) -> kvm_iobus_register_dev() -> down_write(kvm->slots_lock). The other one is in kvm_vm_ioctl_assign_device(), which take kvm->slots_lock first, then kvm->lock. Update the comment of lock order as well. Observe it due to kernel locking debug warnings. Cc: stable@kernel.org Signed-off-by: Sheng Yang Signed-off-by: Avi Kivity diff --git a/virt/kvm/assigned-dev.c b/virt/kvm/assigned-dev.c index fd9c097..f73de63 100644 --- a/virt/kvm/assigned-dev.c +++ b/virt/kvm/assigned-dev.c @@ -508,8 +508,8 @@ static int kvm_vm_ioctl_assign_device(struct kvm *kvm, struct kvm_assigned_dev_kernel *match; struct pci_dev *dev; - down_read(&kvm->slots_lock); mutex_lock(&kvm->lock); + down_read(&kvm->slots_lock); match = kvm_find_assigned_dev(&kvm->arch.assigned_dev_head, assigned_dev->assigned_dev_id); @@ -573,8 +573,8 @@ static int kvm_vm_ioctl_assign_device(struct kvm *kvm, } out: - mutex_unlock(&kvm->lock); up_read(&kvm->slots_lock); + mutex_unlock(&kvm->lock); return r; out_list_del: list_del(&match->list); @@ -585,8 +585,8 @@ out_put: pci_dev_put(dev); out_free: kfree(match); - mutex_unlock(&kvm->lock); up_read(&kvm->slots_lock); + mutex_unlock(&kvm->lock); return r; } diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index b5af881..7db071b 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -64,7 +64,7 @@ MODULE_LICENSE("GPL"); /* * Ordering of locks: * - * kvm->slots_lock --> kvm->lock --> kvm->irq_lock + * kvm->lock --> kvm->slots_lock --> kvm->irq_lock */ DEFINE_SPINLOCK(kvm_lock); -- cgit v0.10.2 From 6e24a6eff4571002cd48b99a2b92dc829ce39cb9 Mon Sep 17 00:00:00 2001 From: Marcelo Tosatti Date: Mon, 14 Dec 2009 17:37:35 -0200 Subject: KVM: LAPIC: make sure IRR bitmap is scanned after vm load The vcpus are initialized with irr_pending set to false, but loading the LAPIC registers with pending IRR fails to reset the irr_pending variable. Cc: stable@kernel.org Signed-off-by: Marcelo Tosatti Signed-off-by: Avi Kivity diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index cd60c0b..3063a0c 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -1150,6 +1150,7 @@ void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu) hrtimer_cancel(&apic->lapic_timer.timer); update_divide_count(apic); start_apic_timer(apic); + apic->irr_pending = true; } void __kvm_migrate_apic_timer(struct kvm_vcpu *vcpu) -- cgit v0.10.2 From dab4b911a5327859bb8f969249c6978c26cd4853 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Sun, 6 Dec 2009 18:24:15 +0100 Subject: KVM: x86: Extend KVM_SET_VCPU_EVENTS with selective updates User space may not want to overwrite asynchronously changing VCPU event states on write-back. So allow to skip nmi.pending and sipi_vector by setting corresponding bits in the flags field of kvm_vcpu_events. [avi: advertise the bits in KVM_GET_VCPU_EVENTS] Signed-off-by: Jan Kiszka Signed-off-by: Avi Kivity diff --git a/Documentation/kvm/api.txt b/Documentation/kvm/api.txt index e1a1141..2811e45 100644 --- a/Documentation/kvm/api.txt +++ b/Documentation/kvm/api.txt @@ -685,7 +685,7 @@ struct kvm_vcpu_events { __u8 pad; } nmi; __u32 sipi_vector; - __u32 flags; /* must be zero */ + __u32 flags; }; 4.30 KVM_SET_VCPU_EVENTS @@ -701,6 +701,14 @@ vcpu. See KVM_GET_VCPU_EVENTS for the data structure. +Fields that may be modified asynchronously by running VCPUs can be excluded +from the update. These fields are nmi.pending and sipi_vector. Keep the +corresponding bits in the flags field cleared to suppress overwriting the +current in-kernel state. The bits are: + +KVM_VCPUEVENT_VALID_NMI_PENDING - transfer nmi.pending to the kernel +KVM_VCPUEVENT_VALID_SIPI_VECTOR - transfer sipi_vector + 5. The kvm_run structure diff --git a/arch/x86/include/asm/kvm.h b/arch/x86/include/asm/kvm.h index 950df43..f46b79f 100644 --- a/arch/x86/include/asm/kvm.h +++ b/arch/x86/include/asm/kvm.h @@ -254,6 +254,10 @@ struct kvm_reinject_control { __u8 reserved[31]; }; +/* When set in flags, include corresponding fields on KVM_SET_VCPU_EVENTS */ +#define KVM_VCPUEVENT_VALID_NMI_PENDING 0x00000001 +#define KVM_VCPUEVENT_VALID_SIPI_VECTOR 0x00000002 + /* for KVM_GET/SET_VCPU_EVENTS */ struct kvm_vcpu_events { struct { diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 9d06896..6651dbf 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -1913,7 +1913,8 @@ static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu, events->sipi_vector = vcpu->arch.sipi_vector; - events->flags = 0; + events->flags = (KVM_VCPUEVENT_VALID_NMI_PENDING + | KVM_VCPUEVENT_VALID_SIPI_VECTOR); vcpu_put(vcpu); } @@ -1921,7 +1922,8 @@ static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu, static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu, struct kvm_vcpu_events *events) { - if (events->flags) + if (events->flags & ~(KVM_VCPUEVENT_VALID_NMI_PENDING + | KVM_VCPUEVENT_VALID_SIPI_VECTOR)) return -EINVAL; vcpu_load(vcpu); @@ -1938,10 +1940,12 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu, kvm_pic_clear_isr_ack(vcpu->kvm); vcpu->arch.nmi_injected = events->nmi.injected; - vcpu->arch.nmi_pending = events->nmi.pending; + if (events->flags & KVM_VCPUEVENT_VALID_NMI_PENDING) + vcpu->arch.nmi_pending = events->nmi.pending; kvm_x86_ops->set_nmi_mask(vcpu, events->nmi.masked); - vcpu->arch.sipi_vector = events->sipi_vector; + if (events->flags & KVM_VCPUEVENT_VALID_SIPI_VECTOR) + vcpu->arch.sipi_vector = events->sipi_vector; vcpu_put(vcpu); -- cgit v0.10.2 From a662b8135a1f9fee7d3f9129498cb03f3d6ce772 Mon Sep 17 00:00:00 2001 From: "Luck, Tony" Date: Thu, 17 Dec 2009 17:05:03 -0800 Subject: KVM: ia64: fix build breakage due to host spinlock change Len Brown pointed out that allmodconfig is broken for ia64 because of: arch/ia64/kvm/vmm.c: In function 'vmm_spin_unlock': arch/ia64/kvm/vmm.c:70: error: 'spinlock_t' has no member named 'raw_lock' KVM has it's own spinlock routines. It should not depend on the base kernel spinlock_t type (which changed when ia64 switched to ticket locks). Define its own vmm_spinlock_t type. Signed-off-by: Tony Luck Signed-off-by: Avi Kivity diff --git a/arch/ia64/kvm/vcpu.h b/arch/ia64/kvm/vcpu.h index 360724d..988911b 100644 --- a/arch/ia64/kvm/vcpu.h +++ b/arch/ia64/kvm/vcpu.h @@ -388,6 +388,9 @@ static inline u64 __gpfn_is_io(u64 gpfn) #define _vmm_raw_spin_lock(x) do {}while(0) #define _vmm_raw_spin_unlock(x) do {}while(0) #else +typedef struct { + volatile unsigned int lock; +} vmm_spinlock_t; #define _vmm_raw_spin_lock(x) \ do { \ __u32 *ia64_spinlock_ptr = (__u32 *) (x); \ @@ -405,12 +408,12 @@ static inline u64 __gpfn_is_io(u64 gpfn) #define _vmm_raw_spin_unlock(x) \ do { barrier(); \ - ((spinlock_t *)x)->raw_lock.lock = 0; } \ + ((vmm_spinlock_t *)x)->lock = 0; } \ while (0) #endif -void vmm_spin_lock(spinlock_t *lock); -void vmm_spin_unlock(spinlock_t *lock); +void vmm_spin_lock(vmm_spinlock_t *lock); +void vmm_spin_unlock(vmm_spinlock_t *lock); enum { I_TLB = 1, D_TLB = 2 diff --git a/arch/ia64/kvm/vmm.c b/arch/ia64/kvm/vmm.c index f4b4c89..7a62f75 100644 --- a/arch/ia64/kvm/vmm.c +++ b/arch/ia64/kvm/vmm.c @@ -60,12 +60,12 @@ static void __exit kvm_vmm_exit(void) return ; } -void vmm_spin_lock(spinlock_t *lock) +void vmm_spin_lock(vmm_spinlock_t *lock) { _vmm_raw_spin_lock(lock); } -void vmm_spin_unlock(spinlock_t *lock) +void vmm_spin_unlock(vmm_spinlock_t *lock) { _vmm_raw_spin_unlock(lock); } diff --git a/arch/ia64/kvm/vtlb.c b/arch/ia64/kvm/vtlb.c index 20b3852..4332f7e 100644 --- a/arch/ia64/kvm/vtlb.c +++ b/arch/ia64/kvm/vtlb.c @@ -182,7 +182,7 @@ void mark_pages_dirty(struct kvm_vcpu *v, u64 pte, u64 ps) { u64 i, dirty_pages = 1; u64 base_gfn = (pte&_PAGE_PPN_MASK) >> PAGE_SHIFT; - spinlock_t *lock = __kvm_va(v->arch.dirty_log_lock_pa); + vmm_spinlock_t *lock = __kvm_va(v->arch.dirty_log_lock_pa); void *dirty_bitmap = (void *)KVM_MEM_DIRTY_LOG_BASE; dirty_pages <<= ps <= PAGE_SHIFT ? 0 : ps - PAGE_SHIFT; -- cgit v0.10.2 From 5279aeb4b96cbdac22a0c2f8137dd0bbc35f02b8 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Sat, 19 Dec 2009 18:07:39 +0100 Subject: KVM: powerpc: Fix mtsrin in book3s_64 mmu We were shifting the Ks/Kp/N bits one bit too far on mtsrin. It took me some time to figure that out, so I also put in some debugging and a comment explaining the conversion. This fixes current OpenBIOS boot on PPC64 KVM. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity diff --git a/arch/powerpc/kvm/book3s_64_mmu.c b/arch/powerpc/kvm/book3s_64_mmu.c index 5598f88..e4beeb3 100644 --- a/arch/powerpc/kvm/book3s_64_mmu.c +++ b/arch/powerpc/kvm/book3s_64_mmu.c @@ -390,6 +390,26 @@ static void kvmppc_mmu_book3s_64_mtsrin(struct kvm_vcpu *vcpu, u32 srnum, { u64 rb = 0, rs = 0; + /* + * According to Book3 2.01 mtsrin is implemented as: + * + * The SLB entry specified by (RB)32:35 is loaded from register + * RS, as follows. + * + * SLBE Bit Source SLB Field + * + * 0:31 0x0000_0000 ESID-0:31 + * 32:35 (RB)32:35 ESID-32:35 + * 36 0b1 V + * 37:61 0x00_0000|| 0b0 VSID-0:24 + * 62:88 (RS)37:63 VSID-25:51 + * 89:91 (RS)33:35 Ks Kp N + * 92 (RS)36 L ((RS)36 must be 0b0) + * 93 0b0 C + */ + + dprintk("KVM MMU: mtsrin(0x%x, 0x%lx)\n", srnum, value); + /* ESID = srnum */ rb |= (srnum & 0xf) << 28; /* Set the valid bit */ @@ -400,7 +420,7 @@ static void kvmppc_mmu_book3s_64_mtsrin(struct kvm_vcpu *vcpu, u32 srnum, /* VSID = VSID */ rs |= (value & 0xfffffff) << 12; /* flags = flags */ - rs |= ((value >> 27) & 0xf) << 9; + rs |= ((value >> 28) & 0x7) << 9; kvmppc_mmu_book3s_64_slbmte(vcpu, rs, rb); } -- cgit v0.10.2 From b4329db0d7fd5a233866e799ad3bae8639e90c71 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 18 Dec 2009 09:41:43 +0100 Subject: KVM: get rid of kvm_create_vm() unused label warning on s390 arch/s390/kvm/../../../virt/kvm/kvm_main.c: In function 'kvm_create_vm': arch/s390/kvm/../../../virt/kvm/kvm_main.c:409: warning: label 'out_err' defined but not used Signed-off-by: Heiko Carstens Signed-off-by: Avi Kivity diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 7db071b..a944be3 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -406,8 +406,11 @@ static struct kvm *kvm_create_vm(void) out: return kvm; +#if defined(KVM_COALESCED_MMIO_PAGE_OFFSET) || \ + (defined(CONFIG_MMU_NOTIFIER) && defined(KVM_ARCH_WANT_MMU_NOTIFIER)) out_err: hardware_disable_all(); +#endif out_err_nodisable: kfree(kvm); return ERR_PTR(r); -- cgit v0.10.2 From 0b413e44d64aeac36a096505a40fc2ff470872fa Mon Sep 17 00:00:00 2001 From: Tim Blechmann Date: Sun, 27 Dec 2009 14:43:06 +0100 Subject: perf: Rename perf_event_hw_event in design document perf_event_hw_event has been renamed to perf_event_attr. The design document was still using the old name, though. Signed-off-by: Tim Blechmann Cc: Peter Zijlstra Cc: Mike Galbraith Cc: Paul Mackerras Cc: Arnaldo Carvalho de Melo Cc: Frederic Weisbecker LKML-Reference: <4B37646A.90108@klingt.org> Signed-off-by: Ingo Molnar diff --git a/tools/perf/design.txt b/tools/perf/design.txt index f000c30..8d0de51 100644 --- a/tools/perf/design.txt +++ b/tools/perf/design.txt @@ -21,7 +21,7 @@ There's one file descriptor per virtual counter used. The special file descriptor is opened via the perf_event_open() system call: - int sys_perf_event_open(struct perf_event_hw_event *hw_event_uptr, + int sys_perf_event_open(struct perf_event_attr *hw_event_uptr, pid_t pid, int cpu, int group_fd, unsigned long flags); @@ -32,9 +32,9 @@ can be used to set the blocking mode, etc. Multiple counters can be kept open at a time, and the counters can be poll()ed. -When creating a new counter fd, 'perf_event_hw_event' is: +When creating a new counter fd, 'perf_event_attr' is: -struct perf_event_hw_event { +struct perf_event_attr { /* * The MSB of the config word signifies if the rest contains cpu * specific (raw) counter configuration data, if unset, the next @@ -399,7 +399,7 @@ Notification of new events is possible through poll()/select()/epoll() and fcntl() managing signals. Normally a notification is generated for every page filled, however one can -additionally set perf_event_hw_event.wakeup_events to generate one every +additionally set perf_event_attr.wakeup_events to generate one every so many counter overflow events. Future work will include a splice() interface to the ring-buffer. -- cgit v0.10.2 From d015a092989d673df44a5ad6866dc5d5006b7a2a Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Mon, 28 Dec 2009 10:26:59 +0200 Subject: x86: Use KERN_DEFAULT log-level in __show_regs() Andrew Morton reported a strange looking kmemcheck warning: WARNING: kmemcheck: Caught 32-bit read from uninitialized memory (ffff88004fba6c20) 0000000000000000310000000000000000000000000000002413000000c9ffff u u u u u u u u u u u u u u u u i i i i i i i i u u u u u u u u [] kmemleak_scan+0x25a/0x540 [] kmemleak_scan_thread+0x5b/0xe0 [] kthread+0x9e/0xb0 [] kernel_thread_helper+0x4/0x10 [] 0xffffffffffffffff The above printout is missing register dump completely. The problem here is that the output comes from syslog which doesn't show KERN_INFO log-level messages. We didn't see this before because both of us were testing on 32-bit kernels which use the _default_ log-level. Fix that up by explicitly using KERN_DEFAULT log-level for __show_regs() printks. Signed-off-by: Pekka Enberg Cc: Vegard Nossum Cc: Andrew Morton Cc: Arjan van de Ven Cc: Linus Torvalds LKML-Reference: <1261988819.4641.2.camel@penberg-laptop> Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 98c2cde..c6ee241 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -103,8 +103,8 @@ void show_regs_common(void) if (!product) product = ""; - printk("\n"); - printk(KERN_INFO "Pid: %d, comm: %.20s %s %s %.*s %s/%s\n", + printk(KERN_CONT "\n"); + printk(KERN_DEFAULT "Pid: %d, comm: %.20s %s %s %.*s %s/%s\n", current->pid, current->comm, print_tainted(), init_utsname()->release, (int)strcspn(init_utsname()->version, " "), diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index 9c517b5..37ad1e0 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c @@ -139,16 +139,16 @@ void __show_regs(struct pt_regs *regs, int all) show_regs_common(); - printk("EIP: %04x:[<%08lx>] EFLAGS: %08lx CPU: %d\n", + printk(KERN_DEFAULT "EIP: %04x:[<%08lx>] EFLAGS: %08lx CPU: %d\n", (u16)regs->cs, regs->ip, regs->flags, smp_processor_id()); print_symbol("EIP is at %s\n", regs->ip); - printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n", + printk(KERN_DEFAULT "EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n", regs->ax, regs->bx, regs->cx, regs->dx); - printk("ESI: %08lx EDI: %08lx EBP: %08lx ESP: %08lx\n", + printk(KERN_DEFAULT "ESI: %08lx EDI: %08lx EBP: %08lx ESP: %08lx\n", regs->si, regs->di, regs->bp, sp); - printk(" DS: %04x ES: %04x FS: %04x GS: %04x SS: %04x\n", + printk(KERN_DEFAULT " DS: %04x ES: %04x FS: %04x GS: %04x SS: %04x\n", (u16)regs->ds, (u16)regs->es, (u16)regs->fs, gs, ss); if (!all) @@ -158,19 +158,19 @@ void __show_regs(struct pt_regs *regs, int all) cr2 = read_cr2(); cr3 = read_cr3(); cr4 = read_cr4_safe(); - printk("CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n", + printk(KERN_DEFAULT "CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n", cr0, cr2, cr3, cr4); get_debugreg(d0, 0); get_debugreg(d1, 1); get_debugreg(d2, 2); get_debugreg(d3, 3); - printk("DR0: %08lx DR1: %08lx DR2: %08lx DR3: %08lx\n", + printk(KERN_DEFAULT "DR0: %08lx DR1: %08lx DR2: %08lx DR3: %08lx\n", d0, d1, d2, d3); get_debugreg(d6, 6); get_debugreg(d7, 7); - printk("DR6: %08lx DR7: %08lx\n", + printk(KERN_DEFAULT "DR6: %08lx DR7: %08lx\n", d6, d7); } diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 52fbd0c..f9e0331 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -161,19 +161,19 @@ void __show_regs(struct pt_regs *regs, int all) unsigned int ds, cs, es; show_regs_common(); - printk(KERN_INFO "RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->ip); + printk(KERN_DEFAULT "RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->ip); printk_address(regs->ip, 1); - printk(KERN_INFO "RSP: %04lx:%016lx EFLAGS: %08lx\n", regs->ss, + printk(KERN_DEFAULT "RSP: %04lx:%016lx EFLAGS: %08lx\n", regs->ss, regs->sp, regs->flags); - printk(KERN_INFO "RAX: %016lx RBX: %016lx RCX: %016lx\n", + printk(KERN_DEFAULT "RAX: %016lx RBX: %016lx RCX: %016lx\n", regs->ax, regs->bx, regs->cx); - printk(KERN_INFO "RDX: %016lx RSI: %016lx RDI: %016lx\n", + printk(KERN_DEFAULT "RDX: %016lx RSI: %016lx RDI: %016lx\n", regs->dx, regs->si, regs->di); - printk(KERN_INFO "RBP: %016lx R08: %016lx R09: %016lx\n", + printk(KERN_DEFAULT "RBP: %016lx R08: %016lx R09: %016lx\n", regs->bp, regs->r8, regs->r9); - printk(KERN_INFO "R10: %016lx R11: %016lx R12: %016lx\n", + printk(KERN_DEFAULT "R10: %016lx R11: %016lx R12: %016lx\n", regs->r10, regs->r11, regs->r12); - printk(KERN_INFO "R13: %016lx R14: %016lx R15: %016lx\n", + printk(KERN_DEFAULT "R13: %016lx R14: %016lx R15: %016lx\n", regs->r13, regs->r14, regs->r15); asm("movl %%ds,%0" : "=r" (ds)); @@ -194,21 +194,21 @@ void __show_regs(struct pt_regs *regs, int all) cr3 = read_cr3(); cr4 = read_cr4(); - printk(KERN_INFO "FS: %016lx(%04x) GS:%016lx(%04x) knlGS:%016lx\n", + printk(KERN_DEFAULT "FS: %016lx(%04x) GS:%016lx(%04x) knlGS:%016lx\n", fs, fsindex, gs, gsindex, shadowgs); - printk(KERN_INFO "CS: %04x DS: %04x ES: %04x CR0: %016lx\n", cs, ds, + printk(KERN_DEFAULT "CS: %04x DS: %04x ES: %04x CR0: %016lx\n", cs, ds, es, cr0); - printk(KERN_INFO "CR2: %016lx CR3: %016lx CR4: %016lx\n", cr2, cr3, + printk(KERN_DEFAULT "CR2: %016lx CR3: %016lx CR4: %016lx\n", cr2, cr3, cr4); get_debugreg(d0, 0); get_debugreg(d1, 1); get_debugreg(d2, 2); - printk(KERN_INFO "DR0: %016lx DR1: %016lx DR2: %016lx\n", d0, d1, d2); + printk(KERN_DEFAULT "DR0: %016lx DR1: %016lx DR2: %016lx\n", d0, d1, d2); get_debugreg(d3, 3); get_debugreg(d6, 6); get_debugreg(d7, 7); - printk(KERN_INFO "DR3: %016lx DR6: %016lx DR7: %016lx\n", d3, d6, d7); + printk(KERN_DEFAULT "DR3: %016lx DR6: %016lx DR7: %016lx\n", d3, d6, d7); } void show_regs(struct pt_regs *regs) -- cgit v0.10.2 From c2ef6661ce62e26a8c0978e521fab646128a144b Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 21 Dec 2009 13:02:24 +0100 Subject: kprobes: Fix distinct type warning Every time I see this: kernel/kprobes.c: In function 'register_kretprobe': kernel/kprobes.c:1038: warning: comparison of distinct pointer types lacks a cast I'm wondering if something changed in common code and we need to do something for s390. Apparently that's not the case. Let's get rid of this annoying warning. Signed-off-by: Heiko Carstens Acked-by: Ananth N Mavinakayanahalli Cc: Masami Hiramatsu LKML-Reference: <20091221120224.GA4471@osiris.boeblingen.de.ibm.com> Signed-off-by: Ingo Molnar diff --git a/kernel/kprobes.c b/kernel/kprobes.c index e5342a3..b7df302 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c @@ -1035,7 +1035,7 @@ int __kprobes register_kretprobe(struct kretprobe *rp) /* Pre-allocate memory for max kretprobe instances */ if (rp->maxactive <= 0) { #ifdef CONFIG_PREEMPT - rp->maxactive = max(10, 2 * num_possible_cpus()); + rp->maxactive = max_t(unsigned int, 10, 2*num_possible_cpus()); #else rp->maxactive = num_possible_cpus(); #endif -- cgit v0.10.2 From c0ca9da442df82b67095f230f24762042f9f3b7d Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Mon, 28 Dec 2009 11:02:15 +0200 Subject: x86, kmemcheck: Use KERN_WARNING for error reporting As suggested by Vegard Nossum, use KERN_WARNING for error reporting to make sure kmemcheck reports end up in syslog. Suggested-by: Vegard Nossum Signed-off-by: Pekka Enberg Cc: Andrew Morton LKML-Reference: <1261990935.4641.7.camel@penberg-laptop> Signed-off-by: Ingo Molnar diff --git a/arch/x86/mm/kmemcheck/error.c b/arch/x86/mm/kmemcheck/error.c index 4901d0d..af3b6c8 100644 --- a/arch/x86/mm/kmemcheck/error.c +++ b/arch/x86/mm/kmemcheck/error.c @@ -106,26 +106,25 @@ void kmemcheck_error_recall(void) switch (e->type) { case KMEMCHECK_ERROR_INVALID_ACCESS: - printk(KERN_ERR "WARNING: kmemcheck: Caught %d-bit read " - "from %s memory (%p)\n", + printk(KERN_WARNING "WARNING: kmemcheck: Caught %d-bit read from %s memory (%p)\n", 8 * e->size, e->state < ARRAY_SIZE(desc) ? desc[e->state] : "(invalid shadow state)", (void *) e->address); - printk(KERN_INFO); + printk(KERN_WARNING); for (i = 0; i < SHADOW_COPY_SIZE; ++i) - printk("%02x", e->memory_copy[i]); - printk("\n"); + printk(KERN_CONT "%02x", e->memory_copy[i]); + printk(KERN_CONT "\n"); - printk(KERN_INFO); + printk(KERN_WARNING); for (i = 0; i < SHADOW_COPY_SIZE; ++i) { if (e->shadow_copy[i] < ARRAY_SIZE(short_desc)) - printk(" %c", short_desc[e->shadow_copy[i]]); + printk(KERN_CONT " %c", short_desc[e->shadow_copy[i]]); else - printk(" ?"); + printk(KERN_CONT " ?"); } - printk("\n"); - printk(KERN_INFO "%*c\n", 2 + 2 + printk(KERN_CONT "\n"); + printk(KERN_WARNING "%*c\n", 2 + 2 * (int) (e->address & (SHADOW_COPY_SIZE - 1)), '^'); break; case KMEMCHECK_ERROR_BUG: -- cgit v0.10.2 From 4efb5290ae187514bd31af8c2d7755e175245e19 Mon Sep 17 00:00:00 2001 From: Wenji Huang Date: Mon, 21 Dec 2009 17:52:55 +0800 Subject: perf kmem: Fix statistics typo Replace bytes_req with bytes_alloc. Signed-off-by: Wenji Huang Reviewed-by: Li Zefan Cc: acme@redhat.com LKML-Reference: <1261389175-2227-1-git-send-email-wenji.huang@oracle.com> Signed-off-by: Ingo Molnar diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index fc21ad7..7ceb741 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -137,7 +137,7 @@ static void insert_alloc_stat(unsigned long call_site, unsigned long ptr, if (data && data->ptr == ptr) { data->hit++; data->bytes_req += bytes_req; - data->bytes_alloc += bytes_req; + data->bytes_alloc += bytes_alloc; } else { data = malloc(sizeof(*data)); if (!data) @@ -177,7 +177,7 @@ static void insert_caller_stat(unsigned long call_site, if (data && data->call_site == call_site) { data->hit++; data->bytes_req += bytes_req; - data->bytes_alloc += bytes_req; + data->bytes_alloc += bytes_alloc; } else { data = malloc(sizeof(*data)); if (!data) -- cgit v0.10.2 From 40892367bc893f3abf6f5ca8ac2ed1c98ba26a77 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 21 Dec 2009 12:01:17 -0800 Subject: tracing: Kconfig spelling fixes and cleanups Fix filename reference (ftrace-implementation.txt -> ftrace-design.txt). Fix spelling, punctuation, grammar. Fix help text indentation and line lengths to reduce need for horizontal scrolling or larger window sizes. Signed-off-by: Randy Dunlap Cc: Steven Rostedt Cc: Frederic Weisbecker LKML-Reference: <20091221120117.3fb49cdc.randy.dunlap@oracle.com> Signed-off-by: Ingo Molnar diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index d006554..6c22d8a 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig @@ -12,17 +12,17 @@ config NOP_TRACER config HAVE_FTRACE_NMI_ENTER bool help - See Documentation/trace/ftrace-implementation.txt + See Documentation/trace/ftrace-design.txt config HAVE_FUNCTION_TRACER bool help - See Documentation/trace/ftrace-implementation.txt + See Documentation/trace/ftrace-design.txt config HAVE_FUNCTION_GRAPH_TRACER bool help - See Documentation/trace/ftrace-implementation.txt + See Documentation/trace/ftrace-design.txt config HAVE_FUNCTION_GRAPH_FP_TEST bool @@ -34,17 +34,17 @@ config HAVE_FUNCTION_GRAPH_FP_TEST config HAVE_FUNCTION_TRACE_MCOUNT_TEST bool help - See Documentation/trace/ftrace-implementation.txt + See Documentation/trace/ftrace-design.txt config HAVE_DYNAMIC_FTRACE bool help - See Documentation/trace/ftrace-implementation.txt + See Documentation/trace/ftrace-design.txt config HAVE_FTRACE_MCOUNT_RECORD bool help - See Documentation/trace/ftrace-implementation.txt + See Documentation/trace/ftrace-design.txt config HAVE_HW_BRANCH_TRACER bool @@ -52,7 +52,7 @@ config HAVE_HW_BRANCH_TRACER config HAVE_SYSCALL_TRACEPOINTS bool help - See Documentation/trace/ftrace-implementation.txt + See Documentation/trace/ftrace-design.txt config TRACER_MAX_TRACE bool @@ -83,7 +83,7 @@ config RING_BUFFER_ALLOW_SWAP # This allows those options to appear when no other tracer is selected. But the # options do not appear when something else selects it. We need the two options # GENERIC_TRACER and TRACING to avoid circular dependencies to accomplish the -# hidding of the automatic options. +# hiding of the automatic options. config TRACING bool @@ -119,7 +119,7 @@ menuconfig FTRACE bool "Tracers" default y if DEBUG_KERNEL help - Enable the kernel tracing infrastructure. + Enable the kernel tracing infrastructure. if FTRACE @@ -133,7 +133,7 @@ config FUNCTION_TRACER help Enable the kernel to trace every kernel function. This is done by using a compiler feature to insert a small, 5-byte No-Operation - instruction to the beginning of every kernel function, which NOP + instruction at the beginning of every kernel function, which NOP sequence is then dynamically patched into a tracer call when tracing is enabled by the administrator. If it's runtime disabled (the bootup default), then the overhead of the instructions is very @@ -150,7 +150,7 @@ config FUNCTION_GRAPH_TRACER and its entry. Its first purpose is to trace the duration of functions and draw a call graph for each thread with some information like - the return value. This is done by setting the current return + the return value. This is done by setting the current return address on the current task structure into a stack of calls. @@ -173,7 +173,7 @@ config IRQSOFF_TRACER echo 0 > /sys/kernel/debug/tracing/tracing_max_latency - (Note that kernel size and overhead increases with this option + (Note that kernel size and overhead increase with this option enabled. This option and the preempt-off timing option can be used together or separately.) @@ -186,7 +186,7 @@ config PREEMPT_TRACER select TRACER_MAX_TRACE select RING_BUFFER_ALLOW_SWAP help - This option measures the time spent in preemption off critical + This option measures the time spent in preemption-off critical sections, with microsecond accuracy. The default measurement method is a maximum search, which is @@ -195,7 +195,7 @@ config PREEMPT_TRACER echo 0 > /sys/kernel/debug/tracing/tracing_max_latency - (Note that kernel size and overhead increases with this option + (Note that kernel size and overhead increase with this option enabled. This option and the irqs-off timing option can be used together or separately.) @@ -222,7 +222,7 @@ config ENABLE_DEFAULT_TRACERS depends on !GENERIC_TRACER select TRACING help - This tracer hooks to various trace points in the kernel + This tracer hooks to various trace points in the kernel, allowing the user to pick and choose which trace point they want to trace. It also includes the sched_switch tracer plugin. @@ -265,19 +265,19 @@ choice The likely/unlikely profiler only looks at the conditions that are annotated with a likely or unlikely macro. - The "all branch" profiler will profile every if statement in the + The "all branch" profiler will profile every if-statement in the kernel. This profiler will also enable the likely/unlikely - profiler as well. + profiler. - Either of the above profilers add a bit of overhead to the system. - If unsure choose "No branch profiling". + Either of the above profilers adds a bit of overhead to the system. + If unsure, choose "No branch profiling". config BRANCH_PROFILE_NONE bool "No branch profiling" help - No branch profiling. Branch profiling adds a bit of overhead. - Only enable it if you want to analyse the branching behavior. - Otherwise keep it disabled. + No branch profiling. Branch profiling adds a bit of overhead. + Only enable it if you want to analyse the branching behavior. + Otherwise keep it disabled. config PROFILE_ANNOTATED_BRANCHES bool "Trace likely/unlikely profiler" @@ -288,7 +288,7 @@ config PROFILE_ANNOTATED_BRANCHES /sys/kernel/debug/tracing/profile_annotated_branch - Note: this will add a significant overhead, only turn this + Note: this will add a significant overhead; only turn this on if you need to profile the system's use of these macros. config PROFILE_ALL_BRANCHES @@ -305,7 +305,7 @@ config PROFILE_ALL_BRANCHES This configuration, when enabled, will impose a great overhead on the system. This should only be enabled when the system - is to be analyzed + is to be analyzed in much detail. endchoice config TRACING_BRANCHES @@ -335,7 +335,7 @@ config POWER_TRACER depends on X86 select GENERIC_TRACER help - This tracer helps developers to analyze and optimize the kernels + This tracer helps developers to analyze and optimize the kernel's power management decisions, specifically the C-state and P-state behavior. @@ -391,14 +391,14 @@ config HW_BRANCH_TRACER select GENERIC_TRACER help This tracer records all branches on the system in a circular - buffer giving access to the last N branches for each cpu. + buffer, giving access to the last N branches for each cpu. config KMEMTRACE bool "Trace SLAB allocations" select GENERIC_TRACER help kmemtrace provides tracing for slab allocator functions, such as - kmalloc, kfree, kmem_cache_alloc, kmem_cache_free etc.. Collected + kmalloc, kfree, kmem_cache_alloc, kmem_cache_free, etc. Collected data is then fed to the userspace application in order to analyse allocation hotspots, internal fragmentation and so on, making it possible to see how well an allocator performs, as well as debug @@ -417,15 +417,15 @@ config WORKQUEUE_TRACER bool "Trace workqueues" select GENERIC_TRACER help - The workqueue tracer provides some statistical informations + The workqueue tracer provides some statistical information about each cpu workqueue thread such as the number of the works inserted and executed since their creation. It can help - to evaluate the amount of work each of them have to perform. + to evaluate the amount of work each of them has to perform. For example it can help a developer to decide whether he should - choose a per cpu workqueue instead of a singlethreaded one. + choose a per-cpu workqueue instead of a singlethreaded one. config BLK_DEV_IO_TRACE - bool "Support for tracing block io actions" + bool "Support for tracing block IO actions" depends on SYSFS depends on BLOCK select RELAY @@ -456,15 +456,15 @@ config KPROBE_EVENT select TRACING default y help - This allows the user to add tracing events (similar to tracepoints) on the fly - via the ftrace interface. See Documentation/trace/kprobetrace.txt - for more details. + This allows the user to add tracing events (similar to tracepoints) + on the fly via the ftrace interface. See + Documentation/trace/kprobetrace.txt for more details. Those events can be inserted wherever kprobes can probe, and record various register and memory values. - This option is also required by perf-probe subcommand of perf tools. If - you want to use perf tools, this option is strongly recommended. + This option is also required by perf-probe subcommand of perf tools. + If you want to use perf tools, this option is strongly recommended. config DYNAMIC_FTRACE bool "enable/disable ftrace tracepoints dynamically" @@ -472,32 +472,32 @@ config DYNAMIC_FTRACE depends on HAVE_DYNAMIC_FTRACE default y help - This option will modify all the calls to ftrace dynamically - (will patch them out of the binary image and replaces them - with a No-Op instruction) as they are called. A table is - created to dynamically enable them again. + This option will modify all the calls to ftrace dynamically + (will patch them out of the binary image and replace them + with a No-Op instruction) as they are called. A table is + created to dynamically enable them again. - This way a CONFIG_FUNCTION_TRACER kernel is slightly larger, but otherwise - has native performance as long as no tracing is active. + This way a CONFIG_FUNCTION_TRACER kernel is slightly larger, but + otherwise has native performance as long as no tracing is active. - The changes to the code are done by a kernel thread that - wakes up once a second and checks to see if any ftrace calls - were made. If so, it runs stop_machine (stops all CPUS) - and modifies the code to jump over the call to ftrace. + The changes to the code are done by a kernel thread that + wakes up once a second and checks to see if any ftrace calls + were made. If so, it runs stop_machine (stops all CPUS) + and modifies the code to jump over the call to ftrace. config FUNCTION_PROFILER bool "Kernel function profiler" depends on FUNCTION_TRACER default n help - This option enables the kernel function profiler. A file is created - in debugfs called function_profile_enabled which defaults to zero. - When a 1 is echoed into this file profiling begins, and when a - zero is entered, profiling stops. A file in the trace_stats - directory called functions, that show the list of functions that - have been hit and their counters. + This option enables the kernel function profiler. A file is created + in debugfs called function_profile_enabled which defaults to zero. + When a 1 is echoed into this file profiling begins, and when a + zero is entered, profiling stops. A "functions" file is created in + the trace_stats directory; this file shows the list of functions that + have been hit and their counters. - If in doubt, say N + If in doubt, say N. config FTRACE_MCOUNT_RECORD def_bool y @@ -556,8 +556,8 @@ config RING_BUFFER_BENCHMARK tristate "Ring buffer benchmark stress tester" depends on RING_BUFFER help - This option creates a test to stress the ring buffer and bench mark it. - It creates its own ring buffer such that it will not interfer with + This option creates a test to stress the ring buffer and benchmark it. + It creates its own ring buffer such that it will not interfere with any other users of the ring buffer (such as ftrace). It then creates a producer and consumer that will run for 10 seconds and sleep for 10 seconds. Each interval it will print out the number of events @@ -566,7 +566,7 @@ config RING_BUFFER_BENCHMARK It does not disable interrupts or raise its priority, so it may be affected by processes that are running. - If unsure, say N + If unsure, say N. endif # FTRACE -- cgit v0.10.2 From dfb12eeb0f04b37e5eb3858864d074af4ecd2ac7 Mon Sep 17 00:00:00 2001 From: Daniel T Chen Date: Sun, 27 Dec 2009 15:48:40 -0500 Subject: ALSA: atiixp: Specify codec for Foxconn RC4107MA-RS2 BugLink: https://bugs.launchpad.net/ubuntu/+bug/498863 This mainboard needs ac97_codec=0. Cc: stable@kernel.org Tested-by: Apoorv Parle Signed-off-by: Daniel T Chen Signed-off-by: Takashi Iwai diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c index d6752df..42b4fbb 100644 --- a/sound/pci/atiixp.c +++ b/sound/pci/atiixp.c @@ -297,6 +297,7 @@ static struct pci_device_id snd_atiixp_ids[] = { MODULE_DEVICE_TABLE(pci, snd_atiixp_ids); static struct snd_pci_quirk atiixp_quirks[] __devinitdata = { + SND_PCI_QUIRK(0x105b, 0x0c81, "Foxconn RC4107MA-RS2", 0), SND_PCI_QUIRK(0x15bd, 0x3100, "DFI RS482", 0), { } /* terminator */ }; -- cgit v0.10.2 From 9980c6209ebc2a02eb3ca51a4fae1e17f645c868 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Sun, 27 Dec 2009 22:26:47 +0100 Subject: ALSA: test off by one in setsamplerate() With `while (i++ < MAX_WRITE_RETRY)' i reaches MAX_WRITE_RETRY + 1 after the loop Signed-off-by: Roel Kluin Signed-off-by: Takashi Iwai diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c index b5ca02e..e66ef2b 100644 --- a/sound/pci/riptide/riptide.c +++ b/sound/pci/riptide/riptide.c @@ -1058,7 +1058,7 @@ setsamplerate(struct cmdif *cif, unsigned char *intdec, unsigned int rate) rptr.retwords[2] != M && rptr.retwords[3] != N && i++ < MAX_WRITE_RETRY); - if (i == MAX_WRITE_RETRY) { + if (i > MAX_WRITE_RETRY) { snd_printdd("sent samplerate %d: %d failed\n", *intdec, rate); return -EIO; -- cgit v0.10.2 From 78b8d5d2ee280c463908fd75f3bdf246bcb6ac8d Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 28 Dec 2009 12:24:22 +0100 Subject: ALSA: usb-audio - Avoid Oops after disconnect As the release of substreams may be done asynchronously from the disconnection, close callback needs to check the shutdown flag before actually accessing the usb interface. Reference: Novell bnc#505027 http://bugzilla.novell.com/show_bug.cgi?id=565027 Signed-off-by: Takashi Iwai diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index 4963def..9edef46 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c @@ -1936,7 +1936,7 @@ static int snd_usb_pcm_close(struct snd_pcm_substream *substream, int direction) struct snd_usb_stream *as = snd_pcm_substream_chip(substream); struct snd_usb_substream *subs = &as->substream[direction]; - if (subs->interface >= 0) { + if (!as->chip->shutdown && subs->interface >= 0) { usb_set_interface(subs->dev, subs->interface, 0); subs->interface = -1; } -- cgit v0.10.2 From 2f7a2d89a8b5915d89ad9ebeb0065db7d5831cea Mon Sep 17 00:00:00 2001 From: Shaohua Li Date: Mon, 28 Dec 2009 13:18:44 +0100 Subject: cfq-iosched: don't regard requests with long distance as close seek_mean could be very big sometimes, using it as close criteria is meaningless as this doen't improve any performance. So if it's big, let's fallback to default value. Reviewed-by: Corrado Zoccolo Signed-off-by: Shaohua Li Signed-off-by: Jens Axboe diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 8df4fe5..918c7fd 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -1667,13 +1667,17 @@ static inline sector_t cfq_dist_from_last(struct cfq_data *cfqd, #define CFQQ_SEEKY(cfqq) ((cfqq)->seek_mean > CFQQ_SEEK_THR) static inline int cfq_rq_close(struct cfq_data *cfqd, struct cfq_queue *cfqq, - struct request *rq) + struct request *rq, bool for_preempt) { sector_t sdist = cfqq->seek_mean; if (!sample_valid(cfqq->seek_samples)) sdist = CFQQ_SEEK_THR; + /* if seek_mean is big, using it as close criteria is meaningless */ + if (sdist > CFQQ_SEEK_THR && !for_preempt) + sdist = CFQQ_SEEK_THR; + return cfq_dist_from_last(cfqd, rq) <= sdist; } @@ -1701,7 +1705,7 @@ static struct cfq_queue *cfqq_close(struct cfq_data *cfqd, * will contain the closest sector. */ __cfqq = rb_entry(parent, struct cfq_queue, p_node); - if (cfq_rq_close(cfqd, cur_cfqq, __cfqq->next_rq)) + if (cfq_rq_close(cfqd, cur_cfqq, __cfqq->next_rq, false)) return __cfqq; if (blk_rq_pos(__cfqq->next_rq) < sector) @@ -1712,7 +1716,7 @@ static struct cfq_queue *cfqq_close(struct cfq_data *cfqd, return NULL; __cfqq = rb_entry(node, struct cfq_queue, p_node); - if (cfq_rq_close(cfqd, cur_cfqq, __cfqq->next_rq)) + if (cfq_rq_close(cfqd, cur_cfqq, __cfqq->next_rq, false)) return __cfqq; return NULL; @@ -3112,7 +3116,7 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq, * if this request is as-good as one we would expect from the * current cfqq, let it preempt */ - if (cfq_rq_close(cfqd, cfqq, rq)) + if (cfq_rq_close(cfqd, cfqq, rq, true)) return true; return false; -- cgit v0.10.2 From 00afa758067ac1c947149ef766adcdfe30c44d7d Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Sun, 27 Dec 2009 14:33:14 +0200 Subject: SLAB: Fix lockdep annotation breakage Commit ce79ddc8e2376a9a93c7d42daf89bfcbb9187e62 ("SLAB: Fix lockdep annotations for CPU hotplug") broke init_node_lock_keys() off-slab logic which causes lockdep false positives. Fix that up by reverting the logic back to original while keeping CPU hotplug fixes intact. Reported-and-tested-by: Heiko Carstens Reported-and-tested-by: Andi Kleen Signed-off-by: Pekka Enberg diff --git a/mm/slab.c b/mm/slab.c index 7d41f15..7451bda 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -654,7 +654,7 @@ static void init_node_lock_keys(int q) l3 = s->cs_cachep->nodelists[q]; if (!l3 || OFF_SLAB(s->cs_cachep)) - return; + continue; lockdep_set_class(&l3->list_lock, &on_slab_l3_key); alc = l3->alien; /* @@ -665,7 +665,7 @@ static void init_node_lock_keys(int q) * for alloc_alien_cache, */ if (!alc || (unsigned long)alc == BAD_ALIEN_MAGIC) - return; + continue; for_each_node(r) { if (alc[r]) lockdep_set_class(&alc[r]->lock, -- cgit v0.10.2 From 5b0691508aa99d309101a49b4b084dc16b3d7019 Mon Sep 17 00:00:00 2001 From: Andrey Borzenkov Date: Tue, 22 Dec 2009 21:38:44 +0300 Subject: orinoco: fix GFP_KERNEL in orinoco_set_key with interrupts disabled orinoco_set_key is called from two places both with interrupts disabled (under orinoco_lock). Use GFP_ATOMIC instead of GFP_KERNEL. Fixes following warning: [ 77.254109] WARNING: at /home/bor/src/linux-git/kernel/lockdep.c:2465 lockdep_trace_alloc+0x9a/0xa0() [ 77.254109] Hardware name: PORTEGE 4000 [ 77.254109] Modules linked in: af_packet irnet ppp_generic slhc ircomm_tty ircomm binfmt_misc dm_mirror dm_region_hash dm_log dm_round_robin dm_multipath dm_mod loop nvram toshiba cryptomgr aead pcompress crypto_blkcipher michael_mic crypto_hash crypto_algapi orinoco_cs orinoco cfg80211 smsc_ircc2 pcmcia irda toshiba_acpi yenta_socket video i2c_ali1535 backlight rsrc_nonstatic ali_agp pcmcia_core psmouse output crc_ccitt i2c_core alim1535_wdt rfkill sg evdev ohci_hcd agpgart usbcore pata_ali libata reiserfs [last unloaded: scsi_wait_scan] [ 77.254109] Pid: 2296, comm: wpa_supplicant Not tainted 2.6.32-1avb #1 [ 77.254109] Call Trace: [ 77.254109] [] warn_slowpath_common+0x6d/0xa0 [ 77.254109] [] ? lockdep_trace_alloc+0x9a/0xa0 [ 77.254109] [] ? lockdep_trace_alloc+0x9a/0xa0 [ 77.254109] [] warn_slowpath_null+0x15/0x20 [ 77.254109] [] lockdep_trace_alloc+0x9a/0xa0 [ 77.254109] [] __kmalloc+0x36/0x130 [ 77.254109] [] ? orinoco_set_key+0x48/0x1c0 [orinoco] [ 77.254109] [] orinoco_set_key+0x48/0x1c0 [orinoco] [ 77.254109] [] orinoco_ioctl_set_encodeext+0x1dc/0x2d0 [orinoco] [ 77.254109] [] ioctl_standard_call+0x207/0x3b0 [ 77.254109] [] ? orinoco_ioctl_set_encodeext+0x0/0x2d0 [orinoco] [ 77.254109] [] ? rtnl_lock+0xf/0x20 [ 77.254109] [] ? rtnl_lock+0xf/0x20 [ 77.254109] [] ? __dev_get_by_name+0x85/0xb0 [ 77.254109] [] wext_handle_ioctl+0x176/0x200 [ 77.254109] [] ? orinoco_ioctl_set_encodeext+0x0/0x2d0 [orinoco] [ 77.254109] [] dev_ioctl+0x6af/0x730 [ 77.254109] [] ? move_addr_to_kernel+0x55/0x60 [ 77.254109] [] ? sys_sendto+0xe9/0x130 [ 77.254109] [] sock_ioctl+0x7e/0x250 [ 77.254109] [] ? sock_ioctl+0x0/0x250 [ 77.254109] [] vfs_ioctl+0x1c/0x70 [ 77.254109] [] do_vfs_ioctl+0x6a/0x590 [ 77.254109] [] ? might_fault+0x90/0xa0 [ 77.254109] [] ? might_fault+0x4a/0xa0 [ 77.254109] [] ? sys_socketcall+0x17e/0x280 [ 77.254109] [] sys_ioctl+0x39/0x60 [ 77.254109] [] sysenter_do_call+0x12/0x32 [ 77.254109] ---[ end trace 95ef563548d21efd ]--- Signed-off-by: Andrey Borzenkov Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/orinoco/wext.c b/drivers/net/wireless/orinoco/wext.c index 7698fdd..31ca241 100644 --- a/drivers/net/wireless/orinoco/wext.c +++ b/drivers/net/wireless/orinoco/wext.c @@ -23,7 +23,7 @@ #define MAX_RID_LEN 1024 /* Helper routine to record keys - * Do not call from interrupt context */ + * It is called under orinoco_lock so it may not sleep */ static int orinoco_set_key(struct orinoco_private *priv, int index, enum orinoco_alg alg, const u8 *key, int key_len, const u8 *seq, int seq_len) @@ -32,14 +32,14 @@ static int orinoco_set_key(struct orinoco_private *priv, int index, kzfree(priv->keys[index].seq); if (key_len) { - priv->keys[index].key = kzalloc(key_len, GFP_KERNEL); + priv->keys[index].key = kzalloc(key_len, GFP_ATOMIC); if (!priv->keys[index].key) goto nomem; } else priv->keys[index].key = NULL; if (seq_len) { - priv->keys[index].seq = kzalloc(seq_len, GFP_KERNEL); + priv->keys[index].seq = kzalloc(seq_len, GFP_ATOMIC); if (!priv->keys[index].seq) goto free_key; } else -- cgit v0.10.2 From 659c8e5243caf14564155ad8421404f044dd8031 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Fri, 18 Dec 2009 11:36:49 +0100 Subject: libertas: Remove carrier signaling from the scan code There is no reason to signal a carrier off when doing a 802.11 scan. Cc: Holger Schurig Signed-off-by: Samuel Ortiz Acked-by: Dan Williams Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c index c6a6c04..b0b1c78 100644 --- a/drivers/net/wireless/libertas/scan.c +++ b/drivers/net/wireless/libertas/scan.c @@ -567,11 +567,8 @@ int lbs_scan_networks(struct lbs_private *priv, int full_scan) chan_count = lbs_scan_create_channel_list(priv, chan_list); netif_stop_queue(priv->dev); - netif_carrier_off(priv->dev); - if (priv->mesh_dev) { + if (priv->mesh_dev) netif_stop_queue(priv->mesh_dev); - netif_carrier_off(priv->mesh_dev); - } /* Prepare to continue an interrupted scan */ lbs_deb_scan("chan_count %d, scan_channel %d\n", @@ -635,16 +632,13 @@ out2: priv->scan_channel = 0; out: - if (priv->connect_status == LBS_CONNECTED) { - netif_carrier_on(priv->dev); - if (!priv->tx_pending_len) - netif_wake_queue(priv->dev); - } - if (priv->mesh_dev && (priv->mesh_connect_status == LBS_CONNECTED)) { - netif_carrier_on(priv->mesh_dev); - if (!priv->tx_pending_len) - netif_wake_queue(priv->mesh_dev); - } + if (priv->connect_status == LBS_CONNECTED && !priv->tx_pending_len) + netif_wake_queue(priv->dev); + + if (priv->mesh_dev && (priv->mesh_connect_status == LBS_CONNECTED) && + !priv->tx_pending_len) + netif_wake_queue(priv->mesh_dev); + kfree(chan_list); lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret); -- cgit v0.10.2 From 2e10d330f8d5f039fa1e00baf59435ab0f11c722 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 20 Dec 2009 19:07:09 +0100 Subject: mac80211: fix ibss join with fixed-bssid When fixed bssid is requested when joining an ibss network, incoming beacons that match the configured bssid cause mac80211 to create new sta entries, even before the ibss interface is in joined state. When that happens, it fails to bring up the interface entirely, because it checks for existing sta entries before joining. This patch fixes this bug by refusing to create sta info entries before the interface is fully operational. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 10d1385..1f2db64 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c @@ -382,6 +382,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, u8 *bssid,u8 *addr, u32 supp_rates) { + struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; struct ieee80211_local *local = sdata->local; struct sta_info *sta; int band = local->hw.conf.channel->band; @@ -397,6 +398,9 @@ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, return NULL; } + if (ifibss->state == IEEE80211_IBSS_MLME_SEARCH) + return NULL; + if (compare_ether_addr(bssid, sdata->u.ibss.bssid)) return NULL; -- cgit v0.10.2 From 242ab7ad689accafd5e87ffd22b85cf1bf7fbbef Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Mon, 21 Dec 2009 22:26:48 -0500 Subject: ath5k: fix SWI calibration interrupt storm The calibration period is now invoked by triggering a software interrupt from within the ISR by ath5k_hw_calibration_poll() instead of via a timer. However, the calibration interval isn't initialized before interrupts are enabled, so we can have a situation where an interrupt occurs before the interval is assigned, so the interval is actually negative. As a result, the ISR will arm a software interrupt to schedule the tasklet, and then rearm it when the SWI is processed, and so on, leading to a softlockup at modprobe time. Move the initialization order around so the calibration interval is set before interrupts are active. Another possible fix is to schedule the tasklet directly from the poll routine, but I think there are additional plans for the SWI. Signed-off-by: Bob Copeland Cc: stable@kernel.org Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index a4c086f..2a446a9 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -2381,6 +2381,9 @@ ath5k_init(struct ath5k_softc *sc) */ ath5k_stop_locked(sc); + /* Set PHY calibration interval */ + ah->ah_cal_intval = ath5k_calinterval; + /* * The basic interface to setting the hardware in a good * state is ``reset''. On return the hardware is known to @@ -2408,10 +2411,6 @@ ath5k_init(struct ath5k_softc *sc) /* Set ack to be sent at low bit-rates */ ath5k_hw_set_ack_bitrate_high(ah, false); - - /* Set PHY calibration inteval */ - ah->ah_cal_intval = ath5k_calinterval; - ret = 0; done: mmiowb(); -- cgit v0.10.2 From 5e31258945f60dff65952575625cac214a75893e Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Wed, 23 Dec 2009 00:03:21 +0100 Subject: rt2x00: Add USB ID for Linksys WUSB 600N rev 2. This is a rt2870 based device. Signed-off-by: Gertjan van Wingerde Acked-by: Ivo van Doorn Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index af85d18..ab95346 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -922,6 +922,7 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x1737, 0x0070), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x1737, 0x0071), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x1737, 0x0077), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x1737, 0x0079), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Logitec */ { USB_DEVICE(0x0789, 0x0162), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x0789, 0x0163), USB_DEVICE_DATA(&rt2800usb_ops) }, -- cgit v0.10.2 From 671adc93b6472eaa0142a88d096c945f7b07893a Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 23 Dec 2009 13:12:04 +0100 Subject: wireless: remove remaining qual code This removes the remaining users of the rx status 'qual' field and the field itself. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 2a446a9..e63b7c4 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -1903,17 +1903,6 @@ accept: rxs->noise = sc->ah->ah_noise_floor; rxs->signal = rxs->noise + rs.rs_rssi; - /* An rssi of 35 indicates you should be able use - * 54 Mbps reliably. A more elaborate scheme can be used - * here but it requires a map of SNR/throughput for each - * possible mode used */ - rxs->qual = rs.rs_rssi * 100 / 35; - - /* rssi can be more than 35 though, anything above that - * should be considered at 100% */ - if (rxs->qual > 100) - rxs->qual = 100; - rxs->antenna = rs.rs_antenna; rxs->rate_idx = ath5k_hw_to_driver_rix(sc, rs.rs_rate); rxs->flag |= ath5k_rx_decrypted(sc, ds, skb, &rs); diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index e413bd3..234891d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -681,19 +681,13 @@ static void iwl3945_rx_reply_rx(struct iwl_priv *priv, snr = rx_stats_sig_avg / rx_stats_noise_diff; rx_status.noise = rx_status.signal - iwl3945_calc_db_from_ratio(snr); - rx_status.qual = iwl3945_calc_sig_qual(rx_status.signal, - rx_status.noise); - - /* If noise info not available, calculate signal quality indicator (%) - * using just the dBm signal level. */ } else { rx_status.noise = priv->last_rx_noise; - rx_status.qual = iwl3945_calc_sig_qual(rx_status.signal, 0); } - IWL_DEBUG_STATS(priv, "Rssi %d noise %d qual %d sig_avg %d noise_diff %d\n", - rx_status.signal, rx_status.noise, rx_status.qual, + IWL_DEBUG_STATS(priv, "Rssi %d noise %d sig_avg %d noise_diff %d\n", + rx_status.signal, rx_status.noise, rx_stats_sig_avg, rx_stats_noise_diff); header = (struct ieee80211_hdr *)IWL_RX_DATA(pkt); diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h index ecc23ec..531fa12 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945.h @@ -222,7 +222,6 @@ struct iwl3945_ibss_seq { * *****************************************************************************/ extern int iwl3945_calc_db_from_ratio(int sig_ratio); -extern int iwl3945_calc_sig_qual(int rssi_dbm, int noise_dbm); extern void iwl3945_rx_replenish(void *data); extern void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq); extern unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv, diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index f5c87e7..6f36b6e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -650,47 +650,6 @@ void iwl_reply_statistics(struct iwl_priv *priv, } EXPORT_SYMBOL(iwl_reply_statistics); -#define PERFECT_RSSI (-20) /* dBm */ -#define WORST_RSSI (-95) /* dBm */ -#define RSSI_RANGE (PERFECT_RSSI - WORST_RSSI) - -/* Calculate an indication of rx signal quality (a percentage, not dBm!). - * See http://www.ces.clemson.edu/linux/signal_quality.shtml for info - * about formulas used below. */ -static int iwl_calc_sig_qual(int rssi_dbm, int noise_dbm) -{ - int sig_qual; - int degradation = PERFECT_RSSI - rssi_dbm; - - /* If we get a noise measurement, use signal-to-noise ratio (SNR) - * as indicator; formula is (signal dbm - noise dbm). - * SNR at or above 40 is a great signal (100%). - * Below that, scale to fit SNR of 0 - 40 dB within 0 - 100% indicator. - * Weakest usable signal is usually 10 - 15 dB SNR. */ - if (noise_dbm) { - if (rssi_dbm - noise_dbm >= 40) - return 100; - else if (rssi_dbm < noise_dbm) - return 0; - sig_qual = ((rssi_dbm - noise_dbm) * 5) / 2; - - /* Else use just the signal level. - * This formula is a least squares fit of data points collected and - * compared with a reference system that had a percentage (%) display - * for signal quality. */ - } else - sig_qual = (100 * (RSSI_RANGE * RSSI_RANGE) - degradation * - (15 * RSSI_RANGE + 62 * degradation)) / - (RSSI_RANGE * RSSI_RANGE); - - if (sig_qual > 100) - sig_qual = 100; - else if (sig_qual < 1) - sig_qual = 0; - - return sig_qual; -} - /* Calc max signal level (dBm) among 3 possible receivers */ static inline int iwl_calc_rssi(struct iwl_priv *priv, struct iwl_rx_phy_res *rx_resp) @@ -1101,11 +1060,8 @@ void iwl_rx_reply_rx(struct iwl_priv *priv, if (iwl_is_associated(priv) && !test_bit(STATUS_SCANNING, &priv->status)) { rx_status.noise = priv->last_rx_noise; - rx_status.qual = iwl_calc_sig_qual(rx_status.signal, - rx_status.noise); } else { rx_status.noise = IWL_NOISE_MEAS_NOT_AVAILABLE; - rx_status.qual = iwl_calc_sig_qual(rx_status.signal, 0); } /* Reset beacon noise level if not associated. */ @@ -1118,8 +1074,8 @@ void iwl_rx_reply_rx(struct iwl_priv *priv, iwl_dbg_report_frame(priv, phy_res, len, header, 1); #endif iwl_dbg_log_rx_data_frame(priv, len, header); - IWL_DEBUG_STATS_LIMIT(priv, "Rssi %d, noise %d, qual %d, TSF %llu\n", - rx_status.signal, rx_status.noise, rx_status.qual, + IWL_DEBUG_STATS_LIMIT(priv, "Rssi %d, noise %d, TSF %llu\n", + rx_status.signal, rx_status.noise, (unsigned long long)rx_status.mactime); /* diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index e5d8fa3..f8e4e4b 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -1299,47 +1299,6 @@ int iwl3945_calc_db_from_ratio(int sig_ratio) return (int)ratio2dB[sig_ratio]; } -#define PERFECT_RSSI (-20) /* dBm */ -#define WORST_RSSI (-95) /* dBm */ -#define RSSI_RANGE (PERFECT_RSSI - WORST_RSSI) - -/* Calculate an indication of rx signal quality (a percentage, not dBm!). - * See http://www.ces.clemson.edu/linux/signal_quality.shtml for info - * about formulas used below. */ -int iwl3945_calc_sig_qual(int rssi_dbm, int noise_dbm) -{ - int sig_qual; - int degradation = PERFECT_RSSI - rssi_dbm; - - /* If we get a noise measurement, use signal-to-noise ratio (SNR) - * as indicator; formula is (signal dbm - noise dbm). - * SNR at or above 40 is a great signal (100%). - * Below that, scale to fit SNR of 0 - 40 dB within 0 - 100% indicator. - * Weakest usable signal is usually 10 - 15 dB SNR. */ - if (noise_dbm) { - if (rssi_dbm - noise_dbm >= 40) - return 100; - else if (rssi_dbm < noise_dbm) - return 0; - sig_qual = ((rssi_dbm - noise_dbm) * 5) / 2; - - /* Else use just the signal level. - * This formula is a least squares fit of data points collected and - * compared with a reference system that had a percentage (%) display - * for signal quality. */ - } else - sig_qual = (100 * (RSSI_RANGE * RSSI_RANGE) - degradation * - (15 * RSSI_RANGE + 62 * degradation)) / - (RSSI_RANGE * RSSI_RANGE); - - if (sig_qual > 100) - sig_qual = 100; - else if (sig_qual < 1) - sig_qual = 0; - - return sig_qual; -} - /** * iwl3945_rx_handle - Main entry function for receiving responses from uCode * diff --git a/drivers/net/wireless/libertas_tf/main.c b/drivers/net/wireless/libertas_tf/main.c index 019431d..26a1abd 100644 --- a/drivers/net/wireless/libertas_tf/main.c +++ b/drivers/net/wireless/libertas_tf/main.c @@ -495,7 +495,6 @@ int lbtf_rx(struct lbtf_private *priv, struct sk_buff *skb) stats.band = IEEE80211_BAND_2GHZ; stats.signal = prxpd->snr; stats.noise = prxpd->nf; - stats.qual = prxpd->snr - prxpd->nf; /* Marvell rate index has a hole at value 4 */ if (prxpd->rx_rate > 4) --prxpd->rx_rate; diff --git a/drivers/net/wireless/rtl818x/rtl8180_dev.c b/drivers/net/wireless/rtl818x/rtl8180_dev.c index a1a3dd1..8a40a14 100644 --- a/drivers/net/wireless/rtl818x/rtl8180_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8180_dev.c @@ -132,7 +132,6 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev) rx_status.antenna = (flags2 >> 15) & 1; /* TODO: improve signal/rssi reporting */ - rx_status.qual = flags2 & 0xFF; rx_status.signal = (flags2 >> 8) & 0x7F; /* XXX: is this correct? */ rx_status.rate_idx = (flags >> 20) & 0xF; diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c index dfa1b9bc..7ca95c4 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.c +++ b/drivers/net/wireless/zd1211rw/zd_chip.c @@ -1325,151 +1325,11 @@ int zd_chip_set_basic_rates(struct zd_chip *chip, u16 cr_rates) return r; } -static int ofdm_qual_db(u8 status_quality, u8 zd_rate, unsigned int size) -{ - static const u16 constants[] = { - 715, 655, 585, 540, 470, 410, 360, 315, - 270, 235, 205, 175, 150, 125, 105, 85, - 65, 50, 40, 25, 15 - }; - - int i; - u32 x; - - /* It seems that their quality parameter is somehow per signal - * and is now transferred per bit. - */ - switch (zd_rate) { - case ZD_OFDM_RATE_6M: - case ZD_OFDM_RATE_12M: - case ZD_OFDM_RATE_24M: - size *= 2; - break; - case ZD_OFDM_RATE_9M: - case ZD_OFDM_RATE_18M: - case ZD_OFDM_RATE_36M: - case ZD_OFDM_RATE_54M: - size *= 4; - size /= 3; - break; - case ZD_OFDM_RATE_48M: - size *= 3; - size /= 2; - break; - default: - return -EINVAL; - } - - x = (10000 * status_quality)/size; - for (i = 0; i < ARRAY_SIZE(constants); i++) { - if (x > constants[i]) - break; - } - - switch (zd_rate) { - case ZD_OFDM_RATE_6M: - case ZD_OFDM_RATE_9M: - i += 3; - break; - case ZD_OFDM_RATE_12M: - case ZD_OFDM_RATE_18M: - i += 5; - break; - case ZD_OFDM_RATE_24M: - case ZD_OFDM_RATE_36M: - i += 9; - break; - case ZD_OFDM_RATE_48M: - case ZD_OFDM_RATE_54M: - i += 15; - break; - default: - return -EINVAL; - } - - return i; -} - -static int ofdm_qual_percent(u8 status_quality, u8 zd_rate, unsigned int size) -{ - int r; - - r = ofdm_qual_db(status_quality, zd_rate, size); - ZD_ASSERT(r >= 0); - if (r < 0) - r = 0; - - r = (r * 100)/29; - return r <= 100 ? r : 100; -} - -static unsigned int log10times100(unsigned int x) -{ - static const u8 log10[] = { - 0, - 0, 30, 47, 60, 69, 77, 84, 90, 95, 100, - 104, 107, 111, 114, 117, 120, 123, 125, 127, 130, - 132, 134, 136, 138, 139, 141, 143, 144, 146, 147, - 149, 150, 151, 153, 154, 155, 156, 157, 159, 160, - 161, 162, 163, 164, 165, 166, 167, 168, 169, 169, - 170, 171, 172, 173, 174, 174, 175, 176, 177, 177, - 178, 179, 179, 180, 181, 181, 182, 183, 183, 184, - 185, 185, 186, 186, 187, 188, 188, 189, 189, 190, - 190, 191, 191, 192, 192, 193, 193, 194, 194, 195, - 195, 196, 196, 197, 197, 198, 198, 199, 199, 200, - 200, 200, 201, 201, 202, 202, 202, 203, 203, 204, - 204, 204, 205, 205, 206, 206, 206, 207, 207, 207, - 208, 208, 208, 209, 209, 210, 210, 210, 211, 211, - 211, 212, 212, 212, 213, 213, 213, 213, 214, 214, - 214, 215, 215, 215, 216, 216, 216, 217, 217, 217, - 217, 218, 218, 218, 219, 219, 219, 219, 220, 220, - 220, 220, 221, 221, 221, 222, 222, 222, 222, 223, - 223, 223, 223, 224, 224, 224, 224, - }; - - return x < ARRAY_SIZE(log10) ? log10[x] : 225; -} - -enum { - MAX_CCK_EVM_DB = 45, -}; - -static int cck_evm_db(u8 status_quality) -{ - return (20 * log10times100(status_quality)) / 100; -} - -static int cck_snr_db(u8 status_quality) -{ - int r = MAX_CCK_EVM_DB - cck_evm_db(status_quality); - ZD_ASSERT(r >= 0); - return r; -} - -static int cck_qual_percent(u8 status_quality) -{ - int r; - - r = cck_snr_db(status_quality); - r = (100*r)/17; - return r <= 100 ? r : 100; -} - static inline u8 zd_rate_from_ofdm_plcp_header(const void *rx_frame) { return ZD_OFDM | zd_ofdm_plcp_header_rate(rx_frame); } -u8 zd_rx_qual_percent(const void *rx_frame, unsigned int size, - const struct rx_status *status) -{ - return (status->frame_status&ZD_RX_OFDM) ? - ofdm_qual_percent(status->signal_quality_ofdm, - zd_rate_from_ofdm_plcp_header(rx_frame), - size) : - cck_qual_percent(status->signal_quality_cck); -} - /** * zd_rx_rate - report zd-rate * @rx_frame - received frame diff --git a/drivers/net/wireless/zd1211rw/zd_chip.h b/drivers/net/wireless/zd1211rw/zd_chip.h index 9fd8f35..f8bbf7d 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.h +++ b/drivers/net/wireless/zd1211rw/zd_chip.h @@ -929,9 +929,6 @@ static inline int zd_get_beacon_interval(struct zd_chip *chip, u32 *interval) struct rx_status; -u8 zd_rx_qual_percent(const void *rx_frame, unsigned int size, - const struct rx_status *status); - u8 zd_rx_rate(const void *rx_frame, const struct rx_status *status); struct zd_mc_hash { diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 8a243732..cc648ef 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c @@ -828,9 +828,6 @@ int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length) stats.freq = zd_channels[_zd_chip_get_channel(&mac->chip) - 1].center_freq; stats.band = IEEE80211_BAND_2GHZ; stats.signal = status->signal_strength; - stats.qual = zd_rx_qual_percent(buffer, - length - sizeof(struct rx_status), - status); rate = zd_rx_rate(buffer, status); diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 538d6b7..0bf3697 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -547,7 +547,6 @@ enum mac80211_rx_flags { * unspecified depending on the hardware capabilities flags * @IEEE80211_HW_SIGNAL_* * @noise: noise when receiving this frame, in dBm. - * @qual: overall signal quality indication, in percent (0-100). * @antenna: antenna used * @rate_idx: index of data rate into band's supported rates or MCS index if * HT rates are use (RX_FLAG_HT) @@ -559,7 +558,6 @@ struct ieee80211_rx_status { int freq; int signal; int noise; - int __deprecated qual; int antenna; int rate_idx; int flag; -- cgit v0.10.2 From 3bdb2d48c5f58c781a4099c99044384a23620884 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 23 Dec 2009 13:12:05 +0100 Subject: cfg80211: fix race between deauth and assoc response Joseph Nahmias reported, in http://bugs.debian.org/562016, that he was getting the following warning (with some log around the issue): ath0: direct probe to AP 00:11:95:77:e0:b0 (try 1) ath0: direct probe responded ath0: authenticate with AP 00:11:95:77:e0:b0 (try 1) ath0: authenticated ath0: associate with AP 00:11:95:77:e0:b0 (try 1) ath0: deauthenticating from 00:11:95:77:e0:b0 by local choice (reason=3) ath0: direct probe to AP 00:11:95:77:e0:b0 (try 1) ath0: RX AssocResp from 00:11:95:77:e0:b0 (capab=0x421 status=0 aid=2) ath0: associated ------------[ cut here ]------------ WARNING: at net/wireless/mlme.c:97 cfg80211_send_rx_assoc+0x14d/0x152 [cfg80211]() Hardware name: 7658CTO ... Pid: 761, comm: phy0 Not tainted 2.6.32-trunk-686 #1 Call Trace: [] ? warn_slowpath_common+0x5e/0x8a [] ? warn_slowpath_null+0xa/0xc [] ? cfg80211_send_rx_assoc+0x14d/0x152 ... ath0: link becomes ready ath0: deauthenticating from 00:11:95:77:e0:b0 by local choice (reason=3) ath0: no IPv6 routers present ath0: link is not ready ath0: direct probe to AP 00:11:95:77:e0:b0 (try 1) ath0: direct probe responded ath0: authenticate with AP 00:11:95:77:e0:b0 (try 1) ath0: authenticated ath0: associate with AP 00:11:95:77:e0:b0 (try 1) ath0: RX ReassocResp from 00:11:95:77:e0:b0 (capab=0x421 status=0 aid=2) ath0: associated It is not clear to me how the first "direct probe" here happens, but this seems to be a race condition, if the user requests to deauth after requesting assoc, but before the assoc response is received. In that case, it may happen that mac80211 tries to report the assoc success to cfg80211, but gets blocked on the wdev lock that is held because the user is requesting the deauth. The result is that we run into a warning. This is mostly harmless, but maybe cause an unexpected event to be sent to userspace; we'd send an assoc success event although userspace was no longer expecting that. To fix this, remove the warning and check whether the race happened and in that case abort processing. Reported-by: Joseph Nahmias Cc: stable@kernel.org Cc: 562016-quiet@bugs.debian.org Signed-off-by: Johannes Berg Signed-off-by: John W. Linville diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index 1001db4..82e6002 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c @@ -93,7 +93,18 @@ void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len) } } - WARN_ON(!bss); + /* + * We might be coming here because the driver reported + * a successful association at the same time as the + * user requested a deauth. In that case, we will have + * removed the BSS from the auth_bsses list due to the + * deauth request when the assoc response makes it. If + * the two code paths acquire the lock the other way + * around, that's just the standard situation of a + * deauth being requested while connected. + */ + if (!bss) + goto out; } else if (wdev->conn) { cfg80211_sme_failed_assoc(wdev); /* -- cgit v0.10.2 From 83bd11a06da8bd119cc517de84b3214df3a7a6d4 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Wed, 23 Dec 2009 14:04:43 +0100 Subject: ath9k: Storage class should be before const qualifier The C99 specification states in section 6.11.5: The placement of a storage-class specifier other than at the beginning of the declaration specifiers in a declaration is an obsolescent feature. Signed-off-by: Tobias Klauser Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index 5321f73..f7af5ea 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c @@ -96,7 +96,7 @@ static void ath_pci_bt_coex_prep(struct ath_common *common) pci_write_config_byte(pdev, ATH_PCIE_CAP_LINK_CTRL, aspm); } -const static struct ath_bus_ops ath_pci_bus_ops = { +static const struct ath_bus_ops ath_pci_bus_ops = { .read_cachesize = ath_pci_read_cachesize, .cleanup = ath_pci_cleanup, .eeprom_read = ath_pci_eeprom_read, -- cgit v0.10.2 From 79496738eb896d1658d9f3cca98e474c5f31eea3 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Wed, 23 Dec 2009 14:18:11 +0100 Subject: iwlwifi: Storage class should be before const qualifier The C99 specification states in section 6.11.5: The placement of a storage-class specifier other than at the beginning of the declaration specifiers in a declaration is an obsolescent feature. Signed-off-by: Tobias Klauser Acked-by: Zhu Yi Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index fe511cb..b93e491 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -150,7 +150,7 @@ static s32 expected_tpt_mimo3_40MHz[4][IWL_RATE_COUNT] = { }; /* mbps, mcs */ -const static struct iwl_rate_mcs_info iwl_rate_mcs[IWL_RATE_COUNT] = { +static const struct iwl_rate_mcs_info iwl_rate_mcs[IWL_RATE_COUNT] = { { "1", "BPSK DSSS"}, { "2", "QPSK DSSS"}, {"5.5", "BPSK CCK"}, -- cgit v0.10.2 From befabac2d8e4925b97c5eebc78ecc4b2079fd9dd Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 23 Dec 2009 15:23:19 +0200 Subject: wl1271_cmd.c: cleanup char => u8 This is just a clean up and doesn't make a functional difference. It keeps the lint checkers happy. Signed-off-by: Dan Carpenter Reviewed-by: Kalle Valo Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.c b/drivers/net/wireless/wl12xx/wl1271_cmd.c index 886a9bc..c3385b3 100644 --- a/drivers/net/wireless/wl12xx/wl1271_cmd.c +++ b/drivers/net/wireless/wl12xx/wl1271_cmd.c @@ -777,7 +777,7 @@ out: return ret; } -static int wl1271_build_basic_rates(char *rates, u8 band) +static int wl1271_build_basic_rates(u8 *rates, u8 band) { u8 index = 0; @@ -804,7 +804,7 @@ static int wl1271_build_basic_rates(char *rates, u8 band) return index; } -static int wl1271_build_extended_rates(char *rates, u8 band) +static int wl1271_build_extended_rates(u8 *rates, u8 band) { u8 index = 0; -- cgit v0.10.2 From 65486c8b30498dd274eea2c542696f22b63fe5b8 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 23 Dec 2009 15:33:35 +0100 Subject: cfg80211: fix error path in cfg80211_wext_siwscan If there's an invalid channel or SSID, the code leaks the scan request. Always free the scan request, unless it was successfully given to the driver. Reported-by: Dan Carpenter Signed-off-by: Johannes Berg Acked-by: Dan Carpenter Signed-off-by: John W. Linville diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 12dfa62..0c2cbbe 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -601,7 +601,7 @@ int cfg80211_wext_siwscan(struct net_device *dev, struct cfg80211_registered_device *rdev; struct wiphy *wiphy; struct iw_scan_req *wreq = NULL; - struct cfg80211_scan_request *creq; + struct cfg80211_scan_request *creq = NULL; int i, err, n_channels = 0; enum ieee80211_band band; @@ -694,8 +694,10 @@ int cfg80211_wext_siwscan(struct net_device *dev, /* translate "Scan for SSID" request */ if (wreq) { if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { - if (wreq->essid_len > IEEE80211_MAX_SSID_LEN) - return -EINVAL; + if (wreq->essid_len > IEEE80211_MAX_SSID_LEN) { + err = -EINVAL; + goto out; + } memcpy(creq->ssids[0].ssid, wreq->essid, wreq->essid_len); creq->ssids[0].ssid_len = wreq->essid_len; } @@ -707,12 +709,15 @@ int cfg80211_wext_siwscan(struct net_device *dev, err = rdev->ops->scan(wiphy, dev, creq); if (err) { rdev->scan_req = NULL; - kfree(creq); + /* creq will be freed below */ } else { nl80211_send_scan_start(rdev, dev); + /* creq now owned by driver */ + creq = NULL; dev_hold(dev); } out: + kfree(creq); cfg80211_unlock_rdev(rdev); return err; } -- cgit v0.10.2 From 3867cf6a8c699846e928e8f5a9f31013708df192 Mon Sep 17 00:00:00 2001 From: Sujith Date: Wed, 23 Dec 2009 20:03:27 -0500 Subject: ath9k: fix suspend by waking device prior to stop Ensure the device is awake prior to trying to tell hardware to stop it. Impact of not doing this is we can likely leave the device in an undefined state likely causing issues with suspend and resume. This patch ensures harware is where it should be prior to suspend. Cc: stable@kernel.org Signed-off-by: Sujith Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 9e68c1a..2ec7451 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -2514,6 +2514,9 @@ static void ath9k_stop(struct ieee80211_hw *hw) return; /* another wiphy still in use */ } + /* Ensure HW is awake when we try to shut it down. */ + ath9k_ps_wakeup(sc); + if (ah->btcoex_hw.enabled) { ath9k_hw_btcoex_disable(ah); if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) @@ -2534,6 +2537,9 @@ static void ath9k_stop(struct ieee80211_hw *hw) /* disable HAL and put h/w to sleep */ ath9k_hw_disable(ah); ath9k_hw_configpcipowersave(ah, 1, 1); + ath9k_ps_restore(sc); + + /* Finally, put the chip in FULL SLEEP mode */ ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP); sc->sc_flags |= SC_OP_INVALID; -- cgit v0.10.2 From 5f70a88f631c3480107853cae12925185eb4c598 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Wed, 23 Dec 2009 20:03:28 -0500 Subject: ath9k: wake hardware for interface IBSS/AP/Mesh removal When we remove a IBSS/AP/Mesh interface we stop DMA but to do this we should ensure hardware is on. Awaken the device prior to these calls. This should ensure DMA is stopped upon suspend and plain device removal. Cc: stable@kernel.org Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 2ec7451..623ade8 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -2653,8 +2653,10 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) || (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) || (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) { + ath9k_ps_wakeup(sc); ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); ath_beacon_return(sc, avp); + ath9k_ps_restore(sc); } sc->sc_flags &= ~SC_OP_BEACONS; -- cgit v0.10.2 From 8b685ba9de803f210936400612a32a2003f47cd3 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Wed, 23 Dec 2009 20:03:29 -0500 Subject: ath9k: wake hardware during AMPDU TX actions AMDPDU actions poke hardware for TX operation, as such we want to turn hardware on for these actions. AMDPU RX operations do not require hardware on as nothing is done in hardware for those actions. Without this we cannot guarantee hardware has been programmed correctly for each AMPDU TX action. Cc: stable@kernel.org Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 623ade8..996eb90 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -3105,15 +3105,21 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, case IEEE80211_AMPDU_RX_STOP: break; case IEEE80211_AMPDU_TX_START: + ath9k_ps_wakeup(sc); ath_tx_aggr_start(sc, sta, tid, ssn); ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); + ath9k_ps_restore(sc); break; case IEEE80211_AMPDU_TX_STOP: + ath9k_ps_wakeup(sc); ath_tx_aggr_stop(sc, sta, tid); ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); + ath9k_ps_restore(sc); break; case IEEE80211_AMPDU_TX_OPERATIONAL: + ath9k_ps_wakeup(sc); ath_tx_aggr_resume(sc, sta, tid); + ath9k_ps_restore(sc); break; default: ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, -- cgit v0.10.2 From 5b479a076de091590423a9e6dfc2584126b28761 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 24 Dec 2009 14:04:32 +0100 Subject: ath9k: fix missed error codes in the tx status check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit My previous change added in: commit 815833e7ecf0b9a017315cae6aef4d7cd9517681 ath9k: fix tx status reporting was not checking all possible tx error conditions. This could possibly lead to throughput issues due to slow rate control adaption or missed retransmissions of failed A-MPDU frames. This patch adds a mask for all possible error conditions and uses it in the xmit ok check. Cc: stable@kernel.org Reported-by: Björn Smedman Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h index 0c87771..e185479 100644 --- a/drivers/net/wireless/ath/ath9k/mac.h +++ b/drivers/net/wireless/ath/ath9k/mac.h @@ -77,6 +77,9 @@ #define ATH9K_TXERR_XTXOP 0x08 #define ATH9K_TXERR_TIMER_EXPIRED 0x10 #define ATH9K_TX_ACKED 0x20 +#define ATH9K_TXERR_MASK \ + (ATH9K_TXERR_XRETRY | ATH9K_TXERR_FILT | ATH9K_TXERR_FIFO | \ + ATH9K_TXERR_XTXOP | ATH9K_TXERR_TIMER_EXPIRED) #define ATH9K_TX_BA 0x01 #define ATH9K_TX_PWRMGMT 0x02 diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 1e813bb..fa12b90 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -2072,7 +2072,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) &txq->axq_q, lastbf->list.prev); txq->axq_depth--; - txok = !(ds->ds_txstat.ts_status & ATH9K_TXERR_FILT); + txok = !(ds->ds_txstat.ts_status & ATH9K_TXERR_MASK); txq->axq_tx_inprogress = false; spin_unlock_bh(&txq->axq_lock); -- cgit v0.10.2 From b98c06b6debfe84c90200143bb1102f312f50a33 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Thu, 24 Dec 2009 15:26:09 -0500 Subject: mac80211: fix race with suspend and dynamic_ps_disable_work When mac80211 suspends it calls a driver's suspend callback as a last step and after that the driver assumes no calls will be made to it until we resume and its start callback is kicked. If such calls are made, however, suspend can end up throwing hardware in an unexpected state and making the device unusable upon resume. Fix this by preventing mac80211 to schedule dynamic_ps_disable_work by checking for when mac80211 starts to suspend and starts quiescing. Frames should be allowed to go through though as that is part of the quiescing steps and we do not flush the mac80211 workqueue since it was already done towards the beginning of suspend cycle. The other mac80211 issue will be hanled in the next patch. For further details see refer to the thread: http://marc.info/?t=126144866100001&r=1&w=2 Cc: stable@kernel.org Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 8834cc9..27ceaef 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1419,6 +1419,10 @@ static bool need_dynamic_ps(struct ieee80211_local *local) if (!local->ps_sdata) return false; + /* No point if we're going to suspend */ + if (local->quiescing) + return false; + return true; } -- cgit v0.10.2 From 24feda0084722189468a65e20019cdd8ef99702b Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Thu, 24 Dec 2009 15:38:22 -0500 Subject: mac80211: fix propagation of failed hardware reconfigurations mac80211 does not propagate failed hardware reconfiguration requests. For suspend and resume this is important due to all the possible issues that can come out of the suspend <-> resume cycle. Not propagating the error means cfg80211 will assume the resume for the device went through fine and mac80211 will continue on trying to poke at the hardware, enable timers, queue work, and so on for a device which is completley unfunctional. The least we can do is to propagate device start issues and warn when this occurs upon resume. A side effect of this patch is we also now propagate the start errors upon harware reconfigurations (non-suspend), but this should also be desirable anyway, there is not point in continuing to reconfigure a device if mac80211 was unable to start the device. For further details refer to the thread: http://marc.info/?t=126151038700001&r=1&w=2 Cc: stable@kernel.org Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 78a6e92..dc76267 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -1039,7 +1039,19 @@ int ieee80211_reconfig(struct ieee80211_local *local) /* restart hardware */ if (local->open_count) { + /* + * Upon resume hardware can sometimes be goofy due to + * various platform / driver / bus issues, so restarting + * the device may at times not work immediately. Propagate + * the error. + */ res = drv_start(local); + if (res) { + WARN(local->suspended, "Harware became unavailable " + "upon resume. This is could be a software issue" + "prior to suspend or a harware issue\n"); + return res; + } ieee80211_led_radio(local, true); } -- cgit v0.10.2 From e8a4a6df7397eb3b43ad3139d3fe9b41df70d6b0 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Sat, 26 Dec 2009 20:31:59 +0100 Subject: wl1251: timeout one too soon in wl1251_boot_run_firmware() `loop' reaches INIT_LOOP + 1 after the loop. so if ACX_INTR_INIT_COMPLETE occurs in the last iteration the write occurs but also the error out as if a timeout occurred. This is probably very unlikely to ever occur. Signed-off-by: Roel Kluin Acked-by: Kalle Valo Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/wl12xx/wl1251_boot.c b/drivers/net/wireless/wl12xx/wl1251_boot.c index 2e733e7..28a8086 100644 --- a/drivers/net/wireless/wl12xx/wl1251_boot.c +++ b/drivers/net/wireless/wl12xx/wl1251_boot.c @@ -256,7 +256,7 @@ int wl1251_boot_run_firmware(struct wl1251 *wl) } } - if (loop >= INIT_LOOP) { + if (loop > INIT_LOOP) { wl1251_error("timeout waiting for the hardware to " "complete initialization"); return -EIO; -- cgit v0.10.2 From 6c853da3f30c93eae847ecbcd9fdf10ba0da04c2 Mon Sep 17 00:00:00 2001 From: Zhu Yi Date: Mon, 28 Dec 2009 14:23:11 +0800 Subject: iwmc3200wifi: fix array out-of-boundary access Allocate priv->rx_packets[IWM_RX_ID_HASH + 1] because the max array index is IWM_RX_ID_HASH according to IWM_RX_ID_GET_HASH(). Cc: stable@kernel.org Signed-off-by: Zhu Yi Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/iwmc3200wifi/iwm.h b/drivers/net/wireless/iwmc3200wifi/iwm.h index 79ffa3b..8428111 100644 --- a/drivers/net/wireless/iwmc3200wifi/iwm.h +++ b/drivers/net/wireless/iwmc3200wifi/iwm.h @@ -268,7 +268,7 @@ struct iwm_priv { struct sk_buff_head rx_list; struct list_head rx_tickets; - struct list_head rx_packets[IWM_RX_ID_HASH]; + struct list_head rx_packets[IWM_RX_ID_HASH + 1]; struct workqueue_struct *rx_wq; struct work_struct rx_worker; -- cgit v0.10.2 From 8152a74bc087ffd03e024eaaf5a853ecf62d376d Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 29 Dec 2009 11:09:30 +0900 Subject: sh: Only provide a PCLK definition for legacy CPG CPUs. As CPUs are migrated over to more fully-featured clock frameworks of their own and off of the legacy CPG code, they no longer have any real need for defining the PCLK value. The PCLK define in itself is already fairly misleading, as many boards get their input clocks from different sources, making this value fairly arbitrary anyways. Outside of the legacy CPG clock framework, the only place where this value is used is for deriving CLOCK_TICK_RATE, which we set back to the legacy PIT value that it was before the PCLK definitions were added in the first place. Signed-off-by: Paul Mundt diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 0031a69..2121fbb 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -540,14 +540,16 @@ config SH_TIMER_MTU2 config SH_PCLK_FREQ int "Peripheral clock frequency (in Hz)" - default "27000000" if CPU_SUBTYPE_SH7343 + depends on SH_CLK_CPG_LEGACY default "31250000" if CPU_SUBTYPE_SH7619 - default "32000000" if CPU_SUBTYPE_SH7722 - default "33333333" if CPU_SUBTYPE_SH7770 || CPU_SUBTYPE_SH7723 || \ - CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7705 || \ - CPU_SUBTYPE_SH7203 || CPU_SUBTYPE_SH7206 || \ - CPU_SUBTYPE_SH7263 || CPU_SUBTYPE_MXG || \ - CPU_SUBTYPE_SH7786 || CPU_SUBTYPE_SH7724 + default "33333333" if CPU_SUBTYPE_SH7770 || \ + CPU_SUBTYPE_SH7760 || \ + CPU_SUBTYPE_SH7705 || \ + CPU_SUBTYPE_SH7203 || \ + CPU_SUBTYPE_SH7206 || \ + CPU_SUBTYPE_SH7263 || \ + CPU_SUBTYPE_MXG || \ + CPU_SUBTYPE_SH7786 default "60000000" if CPU_SUBTYPE_SH7751 || CPU_SUBTYPE_SH7751R default "66000000" if CPU_SUBTYPE_SH4_202 default "50000000" diff --git a/arch/sh/include/asm/timex.h b/arch/sh/include/asm/timex.h index b556d49..18bf06d 100644 --- a/arch/sh/include/asm/timex.h +++ b/arch/sh/include/asm/timex.h @@ -6,7 +6,17 @@ #ifndef __ASM_SH_TIMEX_H #define __ASM_SH_TIMEX_H +/* + * Only parts using the legacy CPG code for their clock framework + * implementation need to define their own Pclk value. If provided, this + * can be used for accurately setting CLOCK_TICK_RATE, otherwise we + * simply fall back on the i8253 PIT value. + */ +#ifdef CONFIG_SH_PCLK_FREQ #define CLOCK_TICK_RATE (CONFIG_SH_PCLK_FREQ / 4) /* Underlying HZ */ +#else +#define CLOCK_TICK_RATE 1193180 +#endif #include -- cgit v0.10.2 From 39d30770992895d55789de64bad2349510af68d0 Mon Sep 17 00:00:00 2001 From: Mike Travis Date: Mon, 28 Dec 2009 13:28:25 -0800 Subject: x86: SGI UV: Fix writes to led registers on remote uv hubs The wrong address was being used to write the SCIR led regs on remote hubs. Also, there was an inconsistency between how BIOS and the kernel indexed these regs. Standardize on using the lower 6 bits of the APIC ID as the index. This patch fixes the problem of writing to an errant address to a cpu # >= 64. Signed-off-by: Mike Travis Reviewed-by: Jack Steiner Cc: Robin Holt Cc: Linus Torvalds Cc: stable@kernel.org LKML-Reference: <4B3922F9.3060905@sgi.com> [ v2: fix a number of annoying checkpatch artifacts and whitespace noise ] Signed-off-by: Ingo Molnar diff --git a/arch/x86/include/asm/uv/uv_hub.h b/arch/x86/include/asm/uv/uv_hub.h index 811bfab..bc54fa9 100644 --- a/arch/x86/include/asm/uv/uv_hub.h +++ b/arch/x86/include/asm/uv/uv_hub.h @@ -31,20 +31,20 @@ * contiguous (although various IO spaces may punch holes in * it).. * - * N - Number of bits in the node portion of a socket physical - * address. + * N - Number of bits in the node portion of a socket physical + * address. * - * NASID - network ID of a router, Mbrick or Cbrick. Nasid values of - * routers always have low bit of 1, C/MBricks have low bit - * equal to 0. Most addressing macros that target UV hub chips - * right shift the NASID by 1 to exclude the always-zero bit. - * NASIDs contain up to 15 bits. + * NASID - network ID of a router, Mbrick or Cbrick. Nasid values of + * routers always have low bit of 1, C/MBricks have low bit + * equal to 0. Most addressing macros that target UV hub chips + * right shift the NASID by 1 to exclude the always-zero bit. + * NASIDs contain up to 15 bits. * * GNODE - NASID right shifted by 1 bit. Most mmrs contain gnodes instead * of nasids. * - * PNODE - the low N bits of the GNODE. The PNODE is the most useful variant - * of the nasid for socket usage. + * PNODE - the low N bits of the GNODE. The PNODE is the most useful variant + * of the nasid for socket usage. * * * NumaLink Global Physical Address Format: @@ -71,12 +71,12 @@ * * * APICID format - * NOTE!!!!!! This is the current format of the APICID. However, code - * should assume that this will change in the future. Use functions - * in this file for all APICID bit manipulations and conversion. + * NOTE!!!!!! This is the current format of the APICID. However, code + * should assume that this will change in the future. Use functions + * in this file for all APICID bit manipulations and conversion. * - * 1111110000000000 - * 5432109876543210 + * 1111110000000000 + * 5432109876543210 * pppppppppplc0cch * sssssssssss * @@ -89,9 +89,9 @@ * Note: Processor only supports 12 bits in the APICID register. The ACPI * tables hold all 16 bits. Software needs to be aware of this. * - * Unless otherwise specified, all references to APICID refer to - * the FULL value contained in ACPI tables, not the subset in the - * processor APICID register. + * Unless otherwise specified, all references to APICID refer to + * the FULL value contained in ACPI tables, not the subset in the + * processor APICID register. */ @@ -151,16 +151,16 @@ struct uv_hub_info_s { }; DECLARE_PER_CPU(struct uv_hub_info_s, __uv_hub_info); -#define uv_hub_info (&__get_cpu_var(__uv_hub_info)) +#define uv_hub_info (&__get_cpu_var(__uv_hub_info)) #define uv_cpu_hub_info(cpu) (&per_cpu(__uv_hub_info, cpu)) /* * Local & Global MMR space macros. - * Note: macros are intended to be used ONLY by inline functions - * in this file - not by other kernel code. - * n - NASID (full 15-bit global nasid) - * g - GNODE (full 15-bit global nasid, right shifted 1) - * p - PNODE (local part of nsids, right shifted 1) + * Note: macros are intended to be used ONLY by inline functions + * in this file - not by other kernel code. + * n - NASID (full 15-bit global nasid) + * g - GNODE (full 15-bit global nasid, right shifted 1) + * p - PNODE (local part of nsids, right shifted 1) */ #define UV_NASID_TO_PNODE(n) (((n) >> 1) & uv_hub_info->pnode_mask) #define UV_PNODE_TO_GNODE(p) ((p) |uv_hub_info->gnode_extra) @@ -215,8 +215,8 @@ DECLARE_PER_CPU(struct uv_hub_info_s, __uv_hub_info); /* * Macros for converting between kernel virtual addresses, socket local physical * addresses, and UV global physical addresses. - * Note: use the standard __pa() & __va() macros for converting - * between socket virtual and socket physical addresses. + * Note: use the standard __pa() & __va() macros for converting + * between socket virtual and socket physical addresses. */ /* socket phys RAM --> UV global physical address */ @@ -287,21 +287,18 @@ static inline int uv_apicid_to_pnode(int apicid) * Access global MMRs using the low memory MMR32 space. This region supports * faster MMR access but not all MMRs are accessible in this space. */ -static inline unsigned long *uv_global_mmr32_address(int pnode, - unsigned long offset) +static inline unsigned long *uv_global_mmr32_address(int pnode, unsigned long offset) { return __va(UV_GLOBAL_MMR32_BASE | UV_GLOBAL_MMR32_PNODE_BITS(pnode) | offset); } -static inline void uv_write_global_mmr32(int pnode, unsigned long offset, - unsigned long val) +static inline void uv_write_global_mmr32(int pnode, unsigned long offset, unsigned long val) { writeq(val, uv_global_mmr32_address(pnode, offset)); } -static inline unsigned long uv_read_global_mmr32(int pnode, - unsigned long offset) +static inline unsigned long uv_read_global_mmr32(int pnode, unsigned long offset) { return readq(uv_global_mmr32_address(pnode, offset)); } @@ -310,21 +307,18 @@ static inline unsigned long uv_read_global_mmr32(int pnode, * Access Global MMR space using the MMR space located at the top of physical * memory. */ -static inline unsigned long *uv_global_mmr64_address(int pnode, - unsigned long offset) +static inline unsigned long *uv_global_mmr64_address(int pnode, unsigned long offset) { return __va(UV_GLOBAL_MMR64_BASE | UV_GLOBAL_MMR64_PNODE_BITS(pnode) | offset); } -static inline void uv_write_global_mmr64(int pnode, unsigned long offset, - unsigned long val) +static inline void uv_write_global_mmr64(int pnode, unsigned long offset, unsigned long val) { writeq(val, uv_global_mmr64_address(pnode, offset)); } -static inline unsigned long uv_read_global_mmr64(int pnode, - unsigned long offset) +static inline unsigned long uv_read_global_mmr64(int pnode, unsigned long offset) { return readq(uv_global_mmr64_address(pnode, offset)); } @@ -338,6 +332,16 @@ static inline unsigned long uv_global_gru_mmr_address(int pnode, unsigned long o return UV_GLOBAL_GRU_MMR_BASE | offset | (pnode << uv_hub_info->m_val); } +static inline void uv_write_global_mmr8(int pnode, unsigned long offset, unsigned char val) +{ + writeb(val, uv_global_mmr64_address(pnode, offset)); +} + +static inline unsigned char uv_read_global_mmr8(int pnode, unsigned long offset) +{ + return readb(uv_global_mmr64_address(pnode, offset)); +} + /* * Access hub local MMRs. Faster than using global space but only local MMRs * are accessible. @@ -457,11 +461,17 @@ static inline void uv_set_scir_bits(unsigned char value) } } +static inline unsigned long uv_scir_offset(int apicid) +{ + return SCIR_LOCAL_MMR_BASE | (apicid & 0x3f); +} + static inline void uv_set_cpu_scir_bits(int cpu, unsigned char value) { if (uv_cpu_hub_info(cpu)->scir.state != value) { + uv_write_global_mmr8(uv_cpu_to_pnode(cpu), + uv_cpu_hub_info(cpu)->scir.offset, value); uv_cpu_hub_info(cpu)->scir.state = value; - uv_write_local_mmr8(uv_cpu_hub_info(cpu)->scir.offset, value); } } diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index d56b0ef..5f92494 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c @@ -629,8 +629,10 @@ void __init uv_system_init(void) uv_rtc_init(); for_each_present_cpu(cpu) { + int apicid = per_cpu(x86_cpu_to_apicid, cpu); + nid = cpu_to_node(cpu); - pnode = uv_apicid_to_pnode(per_cpu(x86_cpu_to_apicid, cpu)); + pnode = uv_apicid_to_pnode(apicid); blade = boot_pnode_to_blade(pnode); lcpu = uv_blade_info[blade].nr_possible_cpus; uv_blade_info[blade].nr_possible_cpus++; @@ -651,15 +653,13 @@ void __init uv_system_init(void) uv_cpu_hub_info(cpu)->gnode_extra = gnode_extra; uv_cpu_hub_info(cpu)->global_mmr_base = mmr_base; uv_cpu_hub_info(cpu)->coherency_domain_number = sn_coherency_id; - uv_cpu_hub_info(cpu)->scir.offset = SCIR_LOCAL_MMR_BASE + lcpu; + uv_cpu_hub_info(cpu)->scir.offset = uv_scir_offset(apicid); uv_node_to_blade[nid] = blade; uv_cpu_to_blade[cpu] = blade; max_pnode = max(pnode, max_pnode); - printk(KERN_DEBUG "UV: cpu %d, apicid 0x%x, pnode %d, nid %d, " - "lcpu %d, blade %d\n", - cpu, per_cpu(x86_cpu_to_apicid, cpu), pnode, nid, - lcpu, blade); + printk(KERN_DEBUG "UV: cpu %d, apicid 0x%x, pnode %d, nid %d, lcpu %d, blade %d\n", + cpu, apicid, pnode, nid, lcpu, blade); } /* Add blade/pnode info for nodes without cpus */ -- cgit v0.10.2 From da2c3f0ead336c04b4d1ad36ff42d8d264f44f65 Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Sat, 26 Dec 2009 16:25:18 +0800 Subject: [ARM] pxafb: fix building issue of incorrect reference Commit "d2a34c1 drivers/video: Move dereference after NULL test" introduced a build error of "fbi->dev->platform_data->smart_update" being unknown type to the compiler, fix this by removing the unnecessary test of 'fbi'. Cc: Julia Lawall Signed-off-by: Eric Miao diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index 415858b..825b665 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c @@ -1221,9 +1221,9 @@ static void setup_smart_timing(struct pxafb_info *fbi, static int pxafb_smart_thread(void *arg) { struct pxafb_info *fbi = arg; - struct pxafb_mach_info *inf; + struct pxafb_mach_info *inf = fbi->dev->platform_data; - if (!fbi || !fbi->dev->platform_data->smart_update) { + if (!inf->smart_update) { pr_err("%s: not properly initialized, thread terminated\n", __func__); return -EINVAL; -- cgit v0.10.2 From 1692231cfda6577d411945ea1dacce548e63a0a4 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 23 Nov 2009 12:24:32 -0500 Subject: [ARM] pxa: use resource_size() in pwm.c Use resource_size for {request/release}_mem_region and ioremap. Signed-off-by: H Hartley Sweeten Signed-off-by: Eric Miao diff --git a/arch/arm/plat-pxa/pwm.c b/arch/arm/plat-pxa/pwm.c index a9eabdc..51dc5c8 100644 --- a/arch/arm/plat-pxa/pwm.c +++ b/arch/arm/plat-pxa/pwm.c @@ -204,14 +204,14 @@ static int __devinit pwm_probe(struct platform_device *pdev) goto err_free_clk; } - r = request_mem_region(r->start, r->end - r->start + 1, pdev->name); + r = request_mem_region(r->start, resource_size(r), pdev->name); if (r == NULL) { dev_err(&pdev->dev, "failed to request memory resource\n"); ret = -EBUSY; goto err_free_clk; } - pwm->mmio_base = ioremap(r->start, r->end - r->start + 1); + pwm->mmio_base = ioremap(r->start, resource_size(r)); if (pwm->mmio_base == NULL) { dev_err(&pdev->dev, "failed to ioremap() registers\n"); ret = -ENODEV; @@ -241,7 +241,7 @@ static int __devinit pwm_probe(struct platform_device *pdev) return 0; err_free_mem: - release_mem_region(r->start, r->end - r->start + 1); + release_mem_region(r->start, resource_size(r)); err_free_clk: clk_put(pwm->clk); err_free: @@ -271,7 +271,7 @@ static int __devexit pwm_remove(struct platform_device *pdev) iounmap(pwm->mmio_base); r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - release_mem_region(r->start, r->end - r->start + 1); + release_mem_region(r->start, resource_size(r)); clk_put(pwm->clk); kfree(pwm); -- cgit v0.10.2 From 6d26ce68e034fb3dc93e8d56452c85f57b322101 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 27 Dec 2009 16:04:35 +0100 Subject: [ARM] pxa/littleton: add UART3 GPIO config Signed-off-by: Marek Vasut Signed-off-by: Eric Miao diff --git a/arch/arm/mach-pxa/littleton.c b/arch/arm/mach-pxa/littleton.c index f28c171..fa527b2 100644 --- a/arch/arm/mach-pxa/littleton.c +++ b/arch/arm/mach-pxa/littleton.c @@ -110,6 +110,12 @@ static mfp_cfg_t littleton_mfp_cfg[] __initdata = { GPIO7_MMC1_CLK, GPIO8_MMC1_CMD, GPIO15_GPIO, /* card detect */ + + /* UART3 */ + GPIO107_UART3_CTS, + GPIO108_UART3_RTS, + GPIO109_UART3_TXD, + GPIO110_UART3_RXD, }; static struct resource smc91x_resources[] = { -- cgit v0.10.2 From 9a8a0c46de1fac06e9b78d13edd7612a97d0061d Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 27 Dec 2009 18:14:25 +0100 Subject: [ARM] pxa/littleton: select CPU_PXA300 and CPU_PXA310 This has to be selected, otherwise some peripherals don't get initialized. Signed-off-by: Marek Vasut Signed-off-by: Eric Miao diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index 8a0837e..dee9218 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -37,6 +37,8 @@ config MACH_ZYLONITE320 config MACH_LITTLETON bool "PXA3xx Form Factor Platform (aka Littleton)" select PXA3xx + select CPU_PXA300 + select CPU_PXA310 select PXA_SSP config MACH_TAVOREVB -- cgit v0.10.2 From 100627b4bacd0bd669aab5a68f8a0bfd0d28d002 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Sat, 26 Dec 2009 21:24:11 +0100 Subject: [ARM] pxa/zeus: make internal zeus_get_pcb_info static Signed-off-by: Marc Zyngier Signed-off-by: Eric Miao diff --git a/arch/arm/mach-pxa/zeus.c b/arch/arm/mach-pxa/zeus.c index 5b986a8..865df5d 100644 --- a/arch/arm/mach-pxa/zeus.c +++ b/arch/arm/mach-pxa/zeus.c @@ -626,8 +626,8 @@ static void zeus_power_off(void) pxa27x_cpu_suspend(PWRMODE_DEEPSLEEP); } -int zeus_get_pcb_info(struct i2c_client *client, unsigned gpio, - unsigned ngpio, void *context) +static int zeus_get_pcb_info(struct i2c_client *client, unsigned gpio, + unsigned ngpio, void *context) { int i; u8 pcb_info = 0; -- cgit v0.10.2 From 5f86cebaa56268f1afa2321e6d424530b1a49a12 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Sat, 26 Dec 2009 21:24:12 +0100 Subject: [ARM] pxa/zeus: relax memory timings on Zeus ethernet ports DM9000s on Zeus sometime fail under heavy load. Relaxing the timings a bit seems to be of a great help. Signed-off-by: Marc Zyngier Signed-off-by: Eric Miao diff --git a/arch/arm/mach-pxa/zeus.c b/arch/arm/mach-pxa/zeus.c index 865df5d..2f480a2 100644 --- a/arch/arm/mach-pxa/zeus.c +++ b/arch/arm/mach-pxa/zeus.c @@ -726,9 +726,18 @@ static mfp_cfg_t zeus_pin_config[] __initdata = { GPIO99_GPIO, /* CF RDY */ }; +/* + * DM9k MSCx settings: SRAM, 16 bits + * 17 cycles delay first access + * 5 cycles delay next access + * 13 cycles recovery time + * faster device + */ +#define DM9K_MSC_VALUE 0xe4c9 + static void __init zeus_init(void) { - u16 dm9000_msc = 0xe279; + u16 dm9000_msc = DM9K_MSC_VALUE; system_rev = __raw_readw(ZEUS_CPLD_VERSION); pr_info("Zeus CPLD V%dI%d\n", (system_rev & 0xf0) >> 4, (system_rev & 0x0f)); -- cgit v0.10.2 From a1916eb0ea142c5ac67289e65a022d5253a8ec92 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Sat, 26 Dec 2009 21:24:13 +0100 Subject: [ARM] pxa/zeus: provide power-source information when APM is enabled Signed-off-by: Marc Zyngier Signed-off-by: Eric Miao diff --git a/arch/arm/mach-pxa/zeus.c b/arch/arm/mach-pxa/zeus.c index 2f480a2..75f2a37 100644 --- a/arch/arm/mach-pxa/zeus.c +++ b/arch/arm/mach-pxa/zeus.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -626,6 +627,25 @@ static void zeus_power_off(void) pxa27x_cpu_suspend(PWRMODE_DEEPSLEEP); } +#ifdef CONFIG_APM_EMULATION +static void zeus_get_power_status(struct apm_power_info *info) +{ + /* Power supply is always present */ + info->ac_line_status = APM_AC_ONLINE; + info->battery_status = APM_BATTERY_STATUS_NOT_PRESENT; + info->battery_flag = APM_BATTERY_FLAG_NOT_PRESENT; +} + +static inline void zeus_setup_apm(void) +{ + apm_get_power_status = zeus_get_power_status; +} +#else +static inline void zeus_setup_apm(void) +{ +} +#endif + static int zeus_get_pcb_info(struct i2c_client *client, unsigned gpio, unsigned ngpio, void *context) { @@ -747,6 +767,7 @@ static void __init zeus_init(void) MSC1 = (MSC1 & 0xffff0000) | dm9000_msc; pm_power_off = zeus_power_off; + zeus_setup_apm(); pxa2xx_mfp_config(ARRAY_AND_SIZE(zeus_pin_config)); -- cgit v0.10.2 From c57b9343437a801f0a93b272df8eabf1df102034 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Thu, 17 Dec 2009 14:56:57 +0100 Subject: [ARM] pxa/ttc_dkb: remove duplicate macro definition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ARRAY_AND_SIZE is already defined arch/arm/mach-mmp/common.h which is already included. Signed-off-by: Uwe Kleine-König Cc: Russell King Cc: Bin Yang Acked-by: Haojian Zhuang Signed-off-by: Eric Miao diff --git a/arch/arm/mach-mmp/ttc_dkb.c b/arch/arm/mach-mmp/ttc_dkb.c index 8f49b2b..b22dec4 100644 --- a/arch/arm/mach-mmp/ttc_dkb.c +++ b/arch/arm/mach-mmp/ttc_dkb.c @@ -24,8 +24,6 @@ #include "common.h" -#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x) - static unsigned long ttc_dkb_pin_config[] __initdata = { /* UART2 */ GPIO47_UART2_RXD, -- cgit v0.10.2 From f91e4906e26c053ab2ea6067c6354e49b71d8fa9 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Tue, 22 Dec 2009 07:29:40 -0500 Subject: [ARM] pxa/zylonite: simplify reduntant gpio settings on mmc slot PXA mmc host driver supports card detect, read only and power gpio pin setting already. Zylonite platform driver needn't implement this any more. Signed-off-by: Haojian Zhuang Signed-off-by: Eric Miao diff --git a/arch/arm/mach-pxa/include/mach/zylonite.h b/arch/arm/mach-pxa/include/mach/zylonite.h index bf6785a..9edf645 100644 --- a/arch/arm/mach-pxa/include/mach/zylonite.h +++ b/arch/arm/mach-pxa/include/mach/zylonite.h @@ -8,13 +8,6 @@ /* the following variables are processor specific and initialized * by the corresponding zylonite_pxa3xx_init() */ -struct platform_mmc_slot { - int gpio_cd; - int gpio_wp; -}; - -extern struct platform_mmc_slot zylonite_mmc_slot[]; - extern int gpio_eth_irq; extern int gpio_debug_led1; extern int gpio_debug_led2; diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c index b66e9e2..2b4043c 100644 --- a/arch/arm/mach-pxa/zylonite.c +++ b/arch/arm/mach-pxa/zylonite.c @@ -36,9 +36,6 @@ #include "devices.h" #include "generic.h" -#define MAX_SLOTS 3 -struct platform_mmc_slot zylonite_mmc_slot[MAX_SLOTS]; - int gpio_eth_irq; int gpio_debug_led1; int gpio_debug_led2; @@ -220,84 +217,28 @@ static inline void zylonite_init_lcd(void) {} #endif #if defined(CONFIG_MMC) -static int zylonite_mci_ro(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - - return gpio_get_value(zylonite_mmc_slot[pdev->id].gpio_wp); -} - -static int zylonite_mci_init(struct device *dev, - irq_handler_t zylonite_detect_int, - void *data) -{ - struct platform_device *pdev = to_platform_device(dev); - int err, cd_irq, gpio_cd, gpio_wp; - - cd_irq = gpio_to_irq(zylonite_mmc_slot[pdev->id].gpio_cd); - gpio_cd = zylonite_mmc_slot[pdev->id].gpio_cd; - gpio_wp = zylonite_mmc_slot[pdev->id].gpio_wp; - - /* - * setup GPIO for Zylonite MMC controller - */ - err = gpio_request(gpio_cd, "mmc card detect"); - if (err) - goto err_request_cd; - gpio_direction_input(gpio_cd); - - err = gpio_request(gpio_wp, "mmc write protect"); - if (err) - goto err_request_wp; - gpio_direction_input(gpio_wp); - - err = request_irq(cd_irq, zylonite_detect_int, - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, - "MMC card detect", data); - if (err) { - printk(KERN_ERR "%s: MMC/SD/SDIO: " - "can't request card detect IRQ\n", __func__); - goto err_request_irq; - } - - return 0; - -err_request_irq: - gpio_free(gpio_wp); -err_request_wp: - gpio_free(gpio_cd); -err_request_cd: - return err; -} - -static void zylonite_mci_exit(struct device *dev, void *data) -{ - struct platform_device *pdev = to_platform_device(dev); - int cd_irq, gpio_cd, gpio_wp; - - cd_irq = gpio_to_irq(zylonite_mmc_slot[pdev->id].gpio_cd); - gpio_cd = zylonite_mmc_slot[pdev->id].gpio_cd; - gpio_wp = zylonite_mmc_slot[pdev->id].gpio_wp; - - free_irq(cd_irq, data); - gpio_free(gpio_cd); - gpio_free(gpio_wp); -} - static struct pxamci_platform_data zylonite_mci_platform_data = { .detect_delay = 20, .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, - .init = zylonite_mci_init, - .exit = zylonite_mci_exit, - .get_ro = zylonite_mci_ro, - .gpio_card_detect = -1, - .gpio_card_ro = -1, + .gpio_card_detect = EXT_GPIO(0), + .gpio_card_ro = EXT_GPIO(2), .gpio_power = -1, }; static struct pxamci_platform_data zylonite_mci2_platform_data = { .detect_delay = 20, .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, + .gpio_card_detect = EXT_GPIO(1), + .gpio_card_ro = EXT_GPIO(3), + .gpio_power = -1, +}; + +static struct pxamci_platform_data zylonite_mci3_platform_data = { + .detect_delay = 20, + .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, + .gpio_card_detect = EXT_GPIO(30), + .gpio_card_ro = EXT_GPIO(31), + .gpio_power = -1, }; static void __init zylonite_init_mmc(void) @@ -305,7 +246,7 @@ static void __init zylonite_init_mmc(void) pxa_set_mci_info(&zylonite_mci_platform_data); pxa3xx_set_mci2_info(&zylonite_mci2_platform_data); if (cpu_is_pxa310()) - pxa3xx_set_mci3_info(&zylonite_mci_platform_data); + pxa3xx_set_mci3_info(&zylonite_mci3_platform_data); } #else static inline void zylonite_init_mmc(void) {} diff --git a/arch/arm/mach-pxa/zylonite_pxa300.c b/arch/arm/mach-pxa/zylonite_pxa300.c index 8409544..3aa73b3 100644 --- a/arch/arm/mach-pxa/zylonite_pxa300.c +++ b/arch/arm/mach-pxa/zylonite_pxa300.c @@ -129,8 +129,8 @@ static mfp_cfg_t common_mfp_cfg[] __initdata = { GPIO22_I2C_SDA, /* GPIO */ - GPIO18_GPIO, /* GPIO Expander #0 INT_N */ - GPIO19_GPIO, /* GPIO Expander #1 INT_N */ + GPIO18_GPIO | MFP_PULL_HIGH, /* GPIO Expander #0 INT_N */ + GPIO19_GPIO | MFP_PULL_HIGH, /* GPIO Expander #1 INT_N */ }; static mfp_cfg_t pxa300_mfp_cfg[] __initdata = { @@ -258,10 +258,6 @@ void __init zylonite_pxa300_init(void) /* detect LCD panel */ zylonite_detect_lcd_panel(); - /* MMC card detect & write protect for controller 0 */ - zylonite_mmc_slot[0].gpio_cd = EXT_GPIO(0); - zylonite_mmc_slot[0].gpio_wp = EXT_GPIO(2); - /* WM9713 IRQ */ wm9713_irq = mfp_to_gpio(MFP_PIN_GPIO26); @@ -276,10 +272,6 @@ void __init zylonite_pxa300_init(void) if (cpu_is_pxa310()) { pxa3xx_mfp_config(ARRAY_AND_SIZE(pxa310_mfp_cfg)); gpio_eth_irq = mfp_to_gpio(MFP_PIN_GPIO102); - - /* MMC card detect & write protect for controller 2 */ - zylonite_mmc_slot[2].gpio_cd = EXT_GPIO(30); - zylonite_mmc_slot[2].gpio_wp = EXT_GPIO(31); } /* GPIOs for Debug LEDs */ diff --git a/arch/arm/mach-pxa/zylonite_pxa320.c b/arch/arm/mach-pxa/zylonite_pxa320.c index 60d08f2..9942bac 100644 --- a/arch/arm/mach-pxa/zylonite_pxa320.c +++ b/arch/arm/mach-pxa/zylonite_pxa320.c @@ -209,10 +209,6 @@ void __init zylonite_pxa320_init(void) gpio_debug_led1 = mfp_to_gpio(MFP_PIN_GPIO1_2); gpio_debug_led2 = mfp_to_gpio(MFP_PIN_GPIO4_2); - /* MMC card detect & write protect for controller 0 */ - zylonite_mmc_slot[0].gpio_cd = mfp_to_gpio(MFP_PIN_GPIO1); - zylonite_mmc_slot[0].gpio_wp = mfp_to_gpio(MFP_PIN_GPIO5); - /* WM9713 IRQ */ wm9713_irq = mfp_to_gpio(MFP_PIN_GPIO15); } -- cgit v0.10.2 From 91a86a964f0773fdf466fe02577c8494ca8e2083 Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Fri, 25 Dec 2009 09:21:34 +0800 Subject: [ARM] pxa/poodle: fix incorrect 'gpio_card_detect' of MMC Signed-off-by: Eric Miao diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c index e5eeb3a..c2b938a 100644 --- a/arch/arm/mach-pxa/poodle.c +++ b/arch/arm/mach-pxa/poodle.c @@ -293,7 +293,7 @@ static struct pxamci_platform_data poodle_mci_platform_data = { .init = poodle_mci_init, .setpower = poodle_mci_setpower, .exit = poodle_mci_exit, - .gpio_card_detect = POODLE_IRQ_GPIO_nSD_DETECT, + .gpio_card_detect = POODLE_GPIO_nSD_DETECT, .gpio_card_ro = POODLE_GPIO_nSD_WP, .gpio_power = -1, }; -- cgit v0.10.2 From 81744ee44ab2845c16ffd7d6f762f7b4a49a4750 Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Tue, 29 Dec 2009 08:35:35 +0100 Subject: block: Fix incorrect alignment offset reporting and update documentation queue_sector_alignment_offset returned the wrong value which caused partitions to report an incorrect alignment_offset. Since offset alignment calculation is needed several places it has been split into a separate helper function. The topology stacking function has been updated accordingly. Furthermore, comments have been added to clarify how the stacking function works. Signed-off-by: Martin K. Petersen Tested-by: Mike Snitzer Signed-off-by: Jens Axboe diff --git a/block/blk-settings.c b/block/blk-settings.c index e14fcbc..d52d4ad 100644 --- a/block/blk-settings.c +++ b/block/blk-settings.c @@ -505,20 +505,30 @@ static unsigned int lcm(unsigned int a, unsigned int b) /** * blk_stack_limits - adjust queue_limits for stacked devices - * @t: the stacking driver limits (top) - * @b: the underlying queue limits (bottom) + * @t: the stacking driver limits (top device) + * @b: the underlying queue limits (bottom, component device) * @offset: offset to beginning of data within component device * * Description: - * Merges two queue_limit structs. Returns 0 if alignment didn't - * change. Returns -1 if adding the bottom device caused - * misalignment. + * This function is used by stacking drivers like MD and DM to ensure + * that all component devices have compatible block sizes and + * alignments. The stacking driver must provide a queue_limits + * struct (top) and then iteratively call the stacking function for + * all component (bottom) devices. The stacking function will + * attempt to combine the values and ensure proper alignment. + * + * Returns 0 if the top and bottom queue_limits are compatible. The + * top device's block sizes and alignment offsets may be adjusted to + * ensure alignment with the bottom device. If no compatible sizes + * and alignments exist, -1 is returned and the resulting top + * queue_limits will have the misaligned flag set to indicate that + * the alignment_offset is undefined. */ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, sector_t offset) { sector_t alignment; - unsigned int top, bottom, granularity; + unsigned int top, bottom; t->max_sectors = min_not_zero(t->max_sectors, b->max_sectors); t->max_hw_sectors = min_not_zero(t->max_hw_sectors, b->max_hw_sectors); @@ -536,15 +546,18 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, t->max_segment_size = min_not_zero(t->max_segment_size, b->max_segment_size); - granularity = max(b->physical_block_size, b->io_min); - alignment = b->alignment_offset - (offset & (granularity - 1)); + alignment = queue_limit_alignment_offset(b, offset); + /* Bottom device has different alignment. Check that it is + * compatible with the current top alignment. + */ if (t->alignment_offset != alignment) { top = max(t->physical_block_size, t->io_min) + t->alignment_offset; - bottom = granularity + alignment; + bottom = max(b->physical_block_size, b->io_min) + alignment; + /* Verify that top and bottom intervals line up */ if (max(top, bottom) & (min(top, bottom) - 1)) t->misaligned = 1; } @@ -561,32 +574,39 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, t->no_cluster |= b->no_cluster; t->discard_zeroes_data &= b->discard_zeroes_data; + /* Physical block size a multiple of the logical block size? */ if (t->physical_block_size & (t->logical_block_size - 1)) { t->physical_block_size = t->logical_block_size; t->misaligned = 1; } + /* Minimum I/O a multiple of the physical block size? */ if (t->io_min & (t->physical_block_size - 1)) { t->io_min = t->physical_block_size; t->misaligned = 1; } + /* Optimal I/O a multiple of the physical block size? */ if (t->io_opt & (t->physical_block_size - 1)) { t->io_opt = 0; t->misaligned = 1; } + /* Find lowest common alignment_offset */ t->alignment_offset = lcm(t->alignment_offset, alignment) & (max(t->physical_block_size, t->io_min) - 1); + /* Verify that new alignment_offset is on a logical block boundary */ if (t->alignment_offset & (t->logical_block_size - 1)) t->misaligned = 1; /* Discard alignment and granularity */ if (b->discard_granularity) { + unsigned int granularity = b->discard_granularity; + offset &= granularity - 1; - alignment = b->discard_alignment - - (offset & (b->discard_granularity - 1)); + alignment = (granularity + b->discard_alignment - offset) + & (granularity - 1); if (t->discard_granularity != 0 && t->discard_alignment != alignment) { @@ -598,6 +618,8 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, t->discard_misaligned = 1; } + t->max_discard_sectors = min_not_zero(t->max_discard_sectors, + b->max_discard_sectors); t->discard_granularity = max(t->discard_granularity, b->discard_granularity); t->discard_alignment = lcm(t->discard_alignment, alignment) & diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 784a919..59b832b 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -1116,11 +1116,18 @@ static inline int queue_alignment_offset(struct request_queue *q) return q->limits.alignment_offset; } +static inline int queue_limit_alignment_offset(struct queue_limits *lim, sector_t offset) +{ + unsigned int granularity = max(lim->physical_block_size, lim->io_min); + + offset &= granularity - 1; + return (granularity + lim->alignment_offset - offset) & (granularity - 1); +} + static inline int queue_sector_alignment_offset(struct request_queue *q, sector_t sector) { - return ((sector << 9) - q->limits.alignment_offset) - & (q->limits.io_min - 1); + return queue_limit_alignment_offset(&q->limits, sector << 9); } static inline int bdev_alignment_offset(struct block_device *bdev) -- cgit v0.10.2 From e79e95db5cffb2e01170d510686489c40937faa1 Mon Sep 17 00:00:00 2001 From: OGAWA Hirofumi Date: Tue, 29 Dec 2009 08:53:54 +0100 Subject: block: Honor the gfp_mask for alloc_page() in blkdev_issue_discard() Signed-off-by: OGAWA Hirofumi Signed-off-by: Jens Axboe diff --git a/block/blk-barrier.c b/block/blk-barrier.c index 8873b9b..8618d89 100644 --- a/block/blk-barrier.c +++ b/block/blk-barrier.c @@ -402,7 +402,7 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector, * our current implementations need. If we'll ever need * more the interface will need revisiting. */ - page = alloc_page(GFP_KERNEL | __GFP_ZERO); + page = alloc_page(gfp_mask | __GFP_ZERO); if (!page) goto out_free_bio; if (bio_add_pc_page(q, bio, page, sector_size, 0) < sector_size) -- cgit v0.10.2 From db5d247ae811f49185a71e703b65acad845e4b18 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Thu, 24 Dec 2009 12:05:58 +0100 Subject: firewire: fix use of multiple AV/C devices, allow multiple FCP listeners Control of more than one AV/C device at once --- e.g. camcorders, tape decks, audio devices, TV tuners --- failed or worked only unreliably, depending on driver implementation. This affected kernelspace and userspace drivers alike and was caused by firewire-core's inability to accept multiple registrations of FCP listeners. The fix allows multiple address handlers to be registered for the FCP command and response registers. When a request for these registers is received, all handlers are invoked, and the Firewire response is generated by the core and not by any handler. The cdev API does not change, i.e., userspace is still expected to send a response for FCP requests; this response is silently ignored. Signed-off-by: Clemens Ladisch Signed-off-by: Stefan Richter (changelog, rebased, whitespace) diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c index 231e6ee..2cb22d16 100644 --- a/drivers/firewire/core-cdev.c +++ b/drivers/firewire/core-cdev.c @@ -601,8 +601,9 @@ static void release_request(struct client *client, struct inbound_transaction_resource *r = container_of(resource, struct inbound_transaction_resource, resource); - fw_send_response(client->device->card, r->request, - RCODE_CONFLICT_ERROR); + if (r->request) + fw_send_response(client->device->card, r->request, + RCODE_CONFLICT_ERROR); kfree(r); } @@ -645,7 +646,8 @@ static void handle_request(struct fw_card *card, struct fw_request *request, failed: kfree(r); kfree(e); - fw_send_response(card, request, RCODE_CONFLICT_ERROR); + if (request) + fw_send_response(card, request, RCODE_CONFLICT_ERROR); } static void release_address_handler(struct client *client, @@ -715,15 +717,17 @@ static int ioctl_send_response(struct client *client, void *buffer) r = container_of(resource, struct inbound_transaction_resource, resource); - if (request->length < r->length) - r->length = request->length; - - if (copy_from_user(r->data, u64_to_uptr(request->data), r->length)) { - ret = -EFAULT; - goto out; + if (r->request) { + if (request->length < r->length) + r->length = request->length; + if (copy_from_user(r->data, u64_to_uptr(request->data), + r->length)) { + ret = -EFAULT; + goto out; + } + fw_send_response(client->device->card, r->request, + request->rcode); } - - fw_send_response(client->device->card, r->request, request->rcode); out: kfree(r); diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c index 842739d..495849e 100644 --- a/drivers/firewire/core-transaction.c +++ b/drivers/firewire/core-transaction.c @@ -432,14 +432,20 @@ static struct fw_address_handler *lookup_overlapping_address_handler( return NULL; } +static bool is_enclosing_handler(struct fw_address_handler *handler, + unsigned long long offset, size_t length) +{ + return handler->offset <= offset && + offset + length <= handler->offset + handler->length; +} + static struct fw_address_handler *lookup_enclosing_address_handler( struct list_head *list, unsigned long long offset, size_t length) { struct fw_address_handler *handler; list_for_each_entry(handler, list, link) { - if (handler->offset <= offset && - offset + length <= handler->offset + handler->length) + if (is_enclosing_handler(handler, offset, length)) return handler; } @@ -465,6 +471,12 @@ const struct fw_address_region fw_unit_space_region = { .start = 0xfffff0000900ULL, .end = 0x1000000000000ULL, }; #endif /* 0 */ +static bool is_in_fcp_region(u64 offset, size_t length) +{ + return offset >= (CSR_REGISTER_BASE | CSR_FCP_COMMAND) && + offset + length <= (CSR_REGISTER_BASE | CSR_FCP_END); +} + /** * fw_core_add_address_handler - register for incoming requests * @handler: callback @@ -477,8 +489,11 @@ const struct fw_address_region fw_unit_space_region = * give the details of the particular request. * * Return value: 0 on success, non-zero otherwise. + * * The start offset of the handler's address region is determined by * fw_core_add_address_handler() and is returned in handler->offset. + * + * Address allocations are exclusive, except for the FCP registers. */ int fw_core_add_address_handler(struct fw_address_handler *handler, const struct fw_address_region *region) @@ -498,10 +513,12 @@ int fw_core_add_address_handler(struct fw_address_handler *handler, handler->offset = region->start; while (handler->offset + handler->length <= region->end) { - other = - lookup_overlapping_address_handler(&address_handler_list, - handler->offset, - handler->length); + if (is_in_fcp_region(handler->offset, handler->length)) + other = NULL; + else + other = lookup_overlapping_address_handler + (&address_handler_list, + handler->offset, handler->length); if (other != NULL) { handler->offset += other->length; } else { @@ -668,6 +685,9 @@ static struct fw_request *allocate_request(struct fw_packet *p) void fw_send_response(struct fw_card *card, struct fw_request *request, int rcode) { + if (WARN_ONCE(!request, "invalid for FCP address handlers")) + return; + /* unified transaction or broadcast transaction: don't respond */ if (request->ack != ACK_PENDING || HEADER_DESTINATION_IS_BROADCAST(request->request_header[0])) { @@ -686,26 +706,15 @@ void fw_send_response(struct fw_card *card, } EXPORT_SYMBOL(fw_send_response); -void fw_core_handle_request(struct fw_card *card, struct fw_packet *p) +static void handle_exclusive_region_request(struct fw_card *card, + struct fw_packet *p, + struct fw_request *request, + unsigned long long offset) { struct fw_address_handler *handler; - struct fw_request *request; - unsigned long long offset; unsigned long flags; int tcode, destination, source; - if (p->ack != ACK_PENDING && p->ack != ACK_COMPLETE) - return; - - request = allocate_request(p); - if (request == NULL) { - /* FIXME: send statically allocated busy packet. */ - return; - } - - offset = - ((unsigned long long) - HEADER_GET_OFFSET_HIGH(p->header[1]) << 32) | p->header[2]; tcode = HEADER_GET_TCODE(p->header[0]); destination = HEADER_GET_DESTINATION(p->header[0]); source = HEADER_GET_SOURCE(p->header[1]); @@ -732,6 +741,73 @@ void fw_core_handle_request(struct fw_card *card, struct fw_packet *p) request->data, request->length, handler->callback_data); } + +static void handle_fcp_region_request(struct fw_card *card, + struct fw_packet *p, + struct fw_request *request, + unsigned long long offset) +{ + struct fw_address_handler *handler; + unsigned long flags; + int tcode, destination, source; + + if ((offset != (CSR_REGISTER_BASE | CSR_FCP_COMMAND) && + offset != (CSR_REGISTER_BASE | CSR_FCP_RESPONSE)) || + request->length > 0x200) { + fw_send_response(card, request, RCODE_ADDRESS_ERROR); + + return; + } + + tcode = HEADER_GET_TCODE(p->header[0]); + destination = HEADER_GET_DESTINATION(p->header[0]); + source = HEADER_GET_SOURCE(p->header[1]); + + if (tcode != TCODE_WRITE_QUADLET_REQUEST && + tcode != TCODE_WRITE_BLOCK_REQUEST) { + fw_send_response(card, request, RCODE_TYPE_ERROR); + + return; + } + + spin_lock_irqsave(&address_handler_lock, flags); + list_for_each_entry(handler, &address_handler_list, link) { + if (is_enclosing_handler(handler, offset, request->length)) + handler->address_callback(card, NULL, tcode, + destination, source, + p->generation, p->speed, + offset, request->data, + request->length, + handler->callback_data); + } + spin_unlock_irqrestore(&address_handler_lock, flags); + + fw_send_response(card, request, RCODE_COMPLETE); +} + +void fw_core_handle_request(struct fw_card *card, struct fw_packet *p) +{ + struct fw_request *request; + unsigned long long offset; + + if (p->ack != ACK_PENDING && p->ack != ACK_COMPLETE) + return; + + request = allocate_request(p); + if (request == NULL) { + /* FIXME: send statically allocated busy packet. */ + return; + } + + offset = ((u64)HEADER_GET_OFFSET_HIGH(p->header[1]) << 32) | + p->header[2]; + + if (!is_in_fcp_region(offset, request->length)) + handle_exclusive_region_request(card, p, request, offset); + else + handle_fcp_region_request(card, p, request, offset); + +} EXPORT_SYMBOL(fw_core_handle_request); void fw_core_handle_response(struct fw_card *card, struct fw_packet *p) diff --git a/drivers/media/dvb/firewire/firedtv-fw.c b/drivers/media/dvb/firewire/firedtv-fw.c index fe44789..6223bf0 100644 --- a/drivers/media/dvb/firewire/firedtv-fw.c +++ b/drivers/media/dvb/firewire/firedtv-fw.c @@ -202,14 +202,8 @@ static void handle_fcp(struct fw_card *card, struct fw_request *request, unsigned long flags; int su; - if ((tcode != TCODE_WRITE_QUADLET_REQUEST && - tcode != TCODE_WRITE_BLOCK_REQUEST) || - offset != CSR_REGISTER_BASE + CSR_FCP_RESPONSE || - length == 0 || - (((u8 *)payload)[0] & 0xf0) != 0) { - fw_send_response(card, request, RCODE_TYPE_ERROR); + if (length < 2 || (((u8 *)payload)[0] & 0xf0) != 0) return; - } su = ((u8 *)payload)[1] & 0x7; @@ -230,10 +224,8 @@ static void handle_fcp(struct fw_card *card, struct fw_request *request, } spin_unlock_irqrestore(&node_list_lock, flags); - if (fdtv) { + if (fdtv) avc_recv(fdtv, payload, length); - fw_send_response(card, request, RCODE_COMPLETE); - } } static struct fw_address_handler fcp_handler = { diff --git a/include/linux/firewire-cdev.h b/include/linux/firewire-cdev.h index c6b3ca3..1f716d9 100644 --- a/include/linux/firewire-cdev.h +++ b/include/linux/firewire-cdev.h @@ -340,6 +340,9 @@ struct fw_cdev_send_response { * The @closure field is passed back to userspace in the response event. * The @handle field is an out parameter, returning a handle to the allocated * range to be used for later deallocation of the range. + * + * The address range is allocated on all local nodes. The address allocation + * is exclusive except for the FCP command and response registers. */ struct fw_cdev_allocate { __u64 offset; diff --git a/include/linux/firewire.h b/include/linux/firewire.h index 9416a46..a0e6715 100644 --- a/include/linux/firewire.h +++ b/include/linux/firewire.h @@ -248,8 +248,8 @@ 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. + * Important note: Except for the FCP registers, 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, -- cgit v0.10.2 From cf0e575dcc4cab9fd955e9bec49df7e8ee30a7cf Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sat, 26 Dec 2009 01:34:29 +0100 Subject: firewire: cdev: fix another memory leak in an error path If copy_from_user in an FW_CDEV_IOC_SEND_RESPONSE ioctl failed, the fw_request pointed to by the inbound_transaction_resource is no longer referenced and needs to be freed. Signed-off-by: Stefan Richter diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c index 2cb22d16..e6d63849 100644 --- a/drivers/firewire/core-cdev.c +++ b/drivers/firewire/core-cdev.c @@ -723,6 +723,7 @@ static int ioctl_send_response(struct client *client, void *buffer) if (copy_from_user(r->data, u64_to_uptr(request->data), r->length)) { ret = -EFAULT; + kfree(r->request); goto out; } fw_send_response(client->device->card, r->request, -- cgit v0.10.2 From 090699c0530ae5380a9b8511d76f656cc437bb6e Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sat, 26 Dec 2009 01:35:14 +0100 Subject: firewire: ohci: always use packet-per-buffer mode for isochronous reception This is a minimal change meant for the short term: Never set the ohci->use_dualbuffer flag to true. There are two reasons to do so: - Packet-per-buffer mode and dual-buffer mode do not behave the same under certain circumstances, notably if several packets are covered by a single fw_cdev_iso_packet descriptor. http://marc.info/?l=linux1394-devel&m=124965653718313 Therefore the driver stack should not silently choose one or the other mode but should leave the choice to the high-level driver (regardless if kernel driver or userspace driver). Or simply always only offer packet-per-buffer mode, since a considerable number of controllers, even current ones, does not offer dual-buffer support. - Even under circumstances where packet-per-buffer mode and dual-buffer mode behave exactly the same --- notably when used through libraw1394, libdc1394, as well as the current two kernel drivers which use isochronous reception (firewire-net and firedtv) --- we are still faced with the problem that several OHCI 1.1 controllers have bugs in dual-buffer mode. Although it looks like we have identified most of those buggy controllers by now, we cannot be quite sure about that. So, use packet-per-buffer by default from now on. This change should be followed up by a more complete solution: Either extend the in-kernel API and the userspace ABI by a choice between the two IR modes or remove all dual-buffer related code from firewire-ohci. Signed-off-by: Stefan Richter diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 96768e1..a61571c 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c @@ -2226,7 +2226,6 @@ static int ohci_queue_iso_receive_dualbuffer(struct fw_iso_context *base, if (rest == 0) return -EINVAL; - /* FIXME: make packet-per-buffer/dual-buffer a context option */ while (rest > 0) { d = context_get_descriptors(&ctx->context, z + header_z, &d_bus); @@ -2470,7 +2469,10 @@ static int __devinit pci_probe(struct pci_dev *dev, } version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff; +#if 0 + /* FIXME: make it a context option or remove dual-buffer mode */ ohci->use_dualbuffer = version >= OHCI_VERSION_1_1; +#endif /* dual-buffer mode is broken if more than one IR context is active */ if (dev->vendor == PCI_VENDOR_ID_AGERE && -- cgit v0.10.2 From 958a29cb1c9161d61dcd4ced51f260578e19823c Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sat, 26 Dec 2009 01:36:12 +0100 Subject: firewire, ieee1394: update MAINTAINERS entries Ben and Kristian have not been involved in maintenance of the IEEE 1394 drivers for quite some time; submitters are not required to Cc them on patches. The linux1394.org domain has been dead for a while and is no longer under control of a Linux developer. The current web site of the Linux 1394 project is http://ieee1394.wiki.kernel.org/. The classic drivers/ieee1394/ stack is now obsolete from the development point of view, though still a useful alternative in productive use. But nobody should attempt to submit style cleanup patches for it or to develop new drivers on top of this stack, hence mark its MAINTAINERS entry as Obsolete. drivers/ieee1394/raw1394*, like the rest of the old stack, does not receive bigger code changes anymore, hence shrink the MAINTAINERS database a bit by dropping raw1394's special entry. If something important and urgent is going to come up for raw1394, I will make sure that Dan will be notified of it besides via linux1394-devel. Signed-off-by: Stefan Richter Signed-off-by: Dan Dennedy Cc: Ben Collins Cc: Kristian Hoegsberg diff --git a/MAINTAINERS b/MAINTAINERS index 66f5f7d..c22d597 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2169,10 +2169,9 @@ F: drivers/hwmon/f75375s.c F: include/linux/f75375s.h FIREWIRE SUBSYSTEM -M: Kristian Hoegsberg M: Stefan Richter L: linux1394-devel@lists.sourceforge.net -W: http://www.linux1394.org/ +W: http://ieee1394.wiki.kernel.org/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6.git S: Maintained F: drivers/firewire/ @@ -2705,22 +2704,14 @@ S: Supported F: drivers/idle/i7300_idle.c IEEE 1394 SUBSYSTEM -M: Ben Collins M: Stefan Richter L: linux1394-devel@lists.sourceforge.net -W: http://www.linux1394.org/ +W: http://ieee1394.wiki.kernel.org/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6.git -S: Maintained +S: Obsolete F: Documentation/debugging-via-ohci1394.txt F: drivers/ieee1394/ -IEEE 1394 RAW I/O DRIVER -M: Dan Dennedy -M: Stefan Richter -L: linux1394-devel@lists.sourceforge.net -S: Maintained -F: drivers/ieee1394/raw1394* - IEEE 802.15.4 SUBSYSTEM M: Dmitry Eremin-Solenikov M: Sergey Lapin -- cgit v0.10.2 From 5d7db0499e5bb13381a7fbfdd0d913b966545e75 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sat, 26 Dec 2009 01:36:53 +0100 Subject: firewire, ieee1394: update Kconfig help Update the Kconfig help texts of both stacks to encourage a general move from the older to the newer drivers. However, do not label ieee1394 as "Obsolete" yet, as the newer drivers have not been deployed as default stack in the majority of Linux distributions yet, and those who start doing so now may still want to install the old drivers as fallback for unforeseen issues. Since Linux 2.6.32, FireWire audio devices can be driven by the newer firewire driver stack too, hence remove an outdated comment about audio devices. Also remove comments about library versions since the 2nd generation of libraw1394 and libdc1394 is now in common use; details on library versions can be read at the wiki link from the help texts. Signed-off-by: Stefan Richter diff --git a/drivers/Kconfig b/drivers/Kconfig index 8a07363..368ae6d 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -28,7 +28,7 @@ source "drivers/md/Kconfig" source "drivers/message/fusion/Kconfig" -source "drivers/ieee1394/Kconfig" +source "drivers/firewire/Kconfig" source "drivers/message/i2o/Kconfig" diff --git a/drivers/firewire/Kconfig b/drivers/firewire/Kconfig index 13efcd3..a9371b3 100644 --- a/drivers/firewire/Kconfig +++ b/drivers/firewire/Kconfig @@ -1,5 +1,10 @@ +menu "IEEE 1394 (FireWire) support" + depends on PCI || BROKEN + # firewire-core does not depend on PCI but is + # not useful without PCI controller driver + comment "You can enable one or both FireWire driver stacks." -comment "See the help texts for more information." +comment "The newer stack is recommended." config FIREWIRE tristate "FireWire driver stack" @@ -15,16 +20,6 @@ config FIREWIRE To compile this driver as a module, say M here: the module will be called firewire-core. - This module functionally replaces ieee1394, raw1394, and video1394. - To access it from application programs, you generally need at least - libraw1394 v2. IIDC/DCAM applications need libdc1394 v2. - No libraries are required to access storage devices through the - firewire-sbp2 driver. - - NOTE: - FireWire audio devices currently require the old drivers (ieee1394, - ohci1394, raw1394). - config FIREWIRE_OHCI tristate "OHCI-1394 controllers" depends on PCI && FIREWIRE @@ -34,22 +29,7 @@ config FIREWIRE_OHCI is the only chipset in use, so say Y here. To compile this driver as a module, say M here: The module will be - called firewire-ohci. It replaces ohci1394 of the classic IEEE 1394 - stack. - - NOTE: - If you want to install firewire-ohci and ohci1394 together, you - should configure them only as modules and blacklist the driver(s) - which you don't want to have auto-loaded. Add either - - blacklist firewire-ohci - or - blacklist ohci1394 - blacklist video1394 - blacklist dv1394 - - to /etc/modprobe.conf or /etc/modprobe.d/* and update modprobe.conf - depending on your distribution. + called firewire-ohci. config FIREWIRE_OHCI_DEBUG bool @@ -66,8 +46,7 @@ config FIREWIRE_SBP2 like scanners. To compile this driver as a module, say M here: The module will be - called firewire-sbp2. It replaces sbp2 of the classic IEEE 1394 - stack. + called firewire-sbp2. You should also enable support for disks, CD-ROMs, etc. in the SCSI configuration section. @@ -83,5 +62,8 @@ config FIREWIRE_NET NOTE, this driver is not stable yet! To compile this driver as a module, say M here: The module will be - called firewire-net. It replaces eth1394 of the classic IEEE 1394 - stack. + called firewire-net. + +source "drivers/ieee1394/Kconfig" + +endmenu diff --git a/drivers/ieee1394/Kconfig b/drivers/ieee1394/Kconfig index f102fcc..e02096c 100644 --- a/drivers/ieee1394/Kconfig +++ b/drivers/ieee1394/Kconfig @@ -1,8 +1,3 @@ -menu "IEEE 1394 (FireWire) support" - depends on PCI || BROKEN - -source "drivers/firewire/Kconfig" - config IEEE1394 tristate "Legacy alternative FireWire driver stack" depends on PCI || BROKEN @@ -16,8 +11,13 @@ config IEEE1394 is the core support only, you will also need to select a driver for your IEEE 1394 adapter. - To compile this driver as a module, say M here: the - module will be called ieee1394. + To compile this driver as a module, say M here: the module will be + called ieee1394. + + NOTE: + ieee1394 is superseded by the newer firewire-core driver. See + http://ieee1394.wiki.kernel.org/index.php/Juju_Migration for + further information on how to switch to the new FireWire drivers. config IEEE1394_OHCI1394 tristate "OHCI-1394 controllers" @@ -29,19 +29,23 @@ config IEEE1394_OHCI1394 use one of these chipsets. It should work with any OHCI-1394 compliant card, however. - To compile this driver as a module, say M here: the - module will be called ohci1394. + To compile this driver as a module, say M here: the module will be + called ohci1394. NOTE: + ohci1394 is superseded by the newer firewire-ohci driver. See + http://ieee1394.wiki.kernel.org/index.php/Juju_Migration for + further information on how to switch to the new FireWire drivers. + If you want to install firewire-ohci and ohci1394 together, you should configure them only as modules and blacklist the driver(s) which you don't want to have auto-loaded. Add either - blacklist firewire-ohci - or blacklist ohci1394 blacklist video1394 blacklist dv1394 + or + blacklist firewire-ohci to /etc/modprobe.conf or /etc/modprobe.d/* and update modprobe.conf depending on your distribution. @@ -58,8 +62,8 @@ config IEEE1394_PCILYNX Instruments PCILynx chip. Note: this driver is written for revision 2 of this chip and may not work with revision 0. - To compile this driver as a module, say M here: the - module will be called pcilynx. + To compile this driver as a module, say M here: the module will be + called pcilynx. Only some old and now very rare PCI and CardBus cards and PowerMacs G3 B&W contain the PCILynx controller. Therefore @@ -79,6 +83,14 @@ config IEEE1394_SBP2 You should also enable support for disks, CD-ROMs, etc. in the SCSI configuration section. + To compile this driver as a module, say M here: the module will be + called sbp2. + + NOTE: + sbp2 is superseded by the newer firewire-sbp2 driver. See + http://ieee1394.wiki.kernel.org/index.php/Juju_Migration for + further information on how to switch to the new FireWire drivers. + config IEEE1394_SBP2_PHYS_DMA bool "Enable replacement for physical DMA in SBP2" depends on IEEE1394_SBP2 && VIRT_TO_BUS && EXPERIMENTAL @@ -111,6 +123,11 @@ config IEEE1394_ETH1394 The module is called eth1394 although it does not emulate Ethernet. + NOTE: + eth1394 is superseded by the newer firewire-net driver. See + http://ieee1394.wiki.kernel.org/index.php/Juju_Migration for + further information on how to switch to the new FireWire drivers. + config IEEE1394_RAWIO tristate "raw1394 userspace interface" depends on IEEE1394 @@ -123,6 +140,11 @@ config IEEE1394_RAWIO To compile this driver as a module, say M here: the module will be called raw1394. + NOTE: + raw1394 is superseded by the newer firewire-core driver. See + http://ieee1394.wiki.kernel.org/index.php/Juju_Migration for + further information on how to switch to the new FireWire drivers. + config IEEE1394_VIDEO1394 tristate "video1394 userspace interface" depends on IEEE1394 && IEEE1394_OHCI1394 @@ -136,13 +158,18 @@ config IEEE1394_VIDEO1394 To compile this driver as a module, say M here: the module will be called video1394. + NOTE: + video1394 is superseded by the newer firewire-core driver. See + http://ieee1394.wiki.kernel.org/index.php/Juju_Migration for + further information on how to switch to the new FireWire drivers. + config IEEE1394_DV1394 tristate "dv1394 userspace interface (deprecated)" depends on IEEE1394 && IEEE1394_OHCI1394 help The dv1394 driver is unsupported and may be removed from Linux in a - future release. Its functionality is now provided by raw1394 together - with libraries such as libiec61883. + future release. Its functionality is now provided by either + raw1394 or firewire-core together with libraries such as libiec61883. config IEEE1394_VERBOSEDEBUG bool "Excessive debugging output" @@ -153,5 +180,3 @@ config IEEE1394_VERBOSEDEBUG will quickly result in large amounts of data sent to the system log. Say Y if you really need the debugging output. Everyone else says N. - -endmenu -- cgit v0.10.2 From 55afc80b2ab100618c17af77915f75307b6bd5d1 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Tue, 29 Dec 2009 14:07:42 -0500 Subject: Revert "b43: Enforce DMA descriptor memory constraints" This reverts commit 9bd568a50c446433038dec2a5186c5c57c3dbd23. That commit is shown to cause allocation failures during initialization on some machines. http://bugzilla.kernel.org/show_bug.cgi?id=14844 Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index 027be27..88d1fd0 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c @@ -383,160 +383,44 @@ static inline } } -/* Check if a DMA region fits the device constraints. - * Returns true, if the region is OK for usage with this device. */ -static inline bool b43_dma_address_ok(struct b43_dmaring *ring, - dma_addr_t addr, size_t size) -{ - switch (ring->type) { - case B43_DMA_30BIT: - if ((u64)addr + size > (1ULL << 30)) - return 0; - break; - case B43_DMA_32BIT: - if ((u64)addr + size > (1ULL << 32)) - return 0; - break; - case B43_DMA_64BIT: - /* Currently we can't have addresses beyond - * 64bit in the kernel. */ - break; - } - return 1; -} - -#define is_4k_aligned(addr) (((u64)(addr) & 0x0FFFull) == 0) -#define is_8k_aligned(addr) (((u64)(addr) & 0x1FFFull) == 0) - -static void b43_unmap_and_free_ringmem(struct b43_dmaring *ring, void *base, - dma_addr_t dmaaddr, size_t size) -{ - ssb_dma_unmap_single(ring->dev->dev, dmaaddr, size, DMA_TO_DEVICE); - free_pages((unsigned long)base, get_order(size)); -} - -static void * __b43_get_and_map_ringmem(struct b43_dmaring *ring, - dma_addr_t *dmaaddr, size_t size, - gfp_t gfp_flags) -{ - void *base; - - base = (void *)__get_free_pages(gfp_flags, get_order(size)); - if (!base) - return NULL; - memset(base, 0, size); - *dmaaddr = ssb_dma_map_single(ring->dev->dev, base, size, - DMA_TO_DEVICE); - if (ssb_dma_mapping_error(ring->dev->dev, *dmaaddr)) { - free_pages((unsigned long)base, get_order(size)); - return NULL; - } - - return base; -} - -static void * b43_get_and_map_ringmem(struct b43_dmaring *ring, - dma_addr_t *dmaaddr, size_t size) -{ - void *base; - - base = __b43_get_and_map_ringmem(ring, dmaaddr, size, - GFP_KERNEL); - if (!base) { - b43err(ring->dev->wl, "Failed to allocate or map pages " - "for DMA ringmemory\n"); - return NULL; - } - if (!b43_dma_address_ok(ring, *dmaaddr, size)) { - /* The memory does not fit our device constraints. - * Retry with GFP_DMA set to get lower memory. */ - b43_unmap_and_free_ringmem(ring, base, *dmaaddr, size); - base = __b43_get_and_map_ringmem(ring, dmaaddr, size, - GFP_KERNEL | GFP_DMA); - if (!base) { - b43err(ring->dev->wl, "Failed to allocate or map pages " - "in the GFP_DMA region for DMA ringmemory\n"); - return NULL; - } - if (!b43_dma_address_ok(ring, *dmaaddr, size)) { - b43_unmap_and_free_ringmem(ring, base, *dmaaddr, size); - b43err(ring->dev->wl, "Failed to allocate DMA " - "ringmemory that fits device constraints\n"); - return NULL; - } - } - /* We expect the memory to be 4k aligned, at least. */ - if (B43_WARN_ON(!is_4k_aligned(*dmaaddr))) { - b43_unmap_and_free_ringmem(ring, base, *dmaaddr, size); - return NULL; - } - - return base; -} - static int alloc_ringmemory(struct b43_dmaring *ring) { - unsigned int required; - void *base; - dma_addr_t dmaaddr; - - /* There are several requirements to the descriptor ring memory: - * - The memory region needs to fit the address constraints for the - * device (same as for frame buffers). - * - For 30/32bit DMA devices, the descriptor ring must be 4k aligned. - * - For 64bit DMA devices, the descriptor ring must be 8k aligned. + gfp_t flags = GFP_KERNEL; + + /* The specs call for 4K buffers for 30- and 32-bit DMA with 4K + * alignment and 8K buffers for 64-bit DMA with 8K alignment. Testing + * has shown that 4K is sufficient for the latter as long as the buffer + * does not cross an 8K boundary. + * + * For unknown reasons - possibly a hardware error - the BCM4311 rev + * 02, which uses 64-bit DMA, needs the ring buffer in very low memory, + * which accounts for the GFP_DMA flag below. + * + * The flags here must match the flags in free_ringmemory below! */ - if (ring->type == B43_DMA_64BIT) - required = ring->nr_slots * sizeof(struct b43_dmadesc64); - else - required = ring->nr_slots * sizeof(struct b43_dmadesc32); - if (B43_WARN_ON(required > 0x1000)) + flags |= GFP_DMA; + ring->descbase = ssb_dma_alloc_consistent(ring->dev->dev, + B43_DMA_RINGMEMSIZE, + &(ring->dmabase), flags); + if (!ring->descbase) { + b43err(ring->dev->wl, "DMA ringmemory allocation failed\n"); return -ENOMEM; - - ring->alloc_descsize = 0x1000; - base = b43_get_and_map_ringmem(ring, &dmaaddr, ring->alloc_descsize); - if (!base) - return -ENOMEM; - ring->alloc_descbase = base; - ring->alloc_dmabase = dmaaddr; - - if ((ring->type != B43_DMA_64BIT) || is_8k_aligned(dmaaddr)) { - /* We're on <=32bit DMA, or we already got 8k aligned memory. - * That's all we need, so we're fine. */ - ring->descbase = base; - ring->dmabase = dmaaddr; - return 0; - } - b43_unmap_and_free_ringmem(ring, base, dmaaddr, ring->alloc_descsize); - - /* Ok, we failed at the 8k alignment requirement. - * Try to force-align the memory region now. */ - ring->alloc_descsize = 0x2000; - base = b43_get_and_map_ringmem(ring, &dmaaddr, ring->alloc_descsize); - if (!base) - return -ENOMEM; - ring->alloc_descbase = base; - ring->alloc_dmabase = dmaaddr; - - if (is_8k_aligned(dmaaddr)) { - /* We're already 8k aligned. That Ok, too. */ - ring->descbase = base; - ring->dmabase = dmaaddr; - return 0; } - /* Force-align it to 8k */ - ring->descbase = (void *)((u8 *)base + 0x1000); - ring->dmabase = dmaaddr + 0x1000; - B43_WARN_ON(!is_8k_aligned(ring->dmabase)); + memset(ring->descbase, 0, B43_DMA_RINGMEMSIZE); return 0; } static void free_ringmemory(struct b43_dmaring *ring) { - b43_unmap_and_free_ringmem(ring, ring->alloc_descbase, - ring->alloc_dmabase, ring->alloc_descsize); + gfp_t flags = GFP_KERNEL; + + if (ring->type == B43_DMA_64BIT) + flags |= GFP_DMA; + + ssb_dma_free_consistent(ring->dev->dev, B43_DMA_RINGMEMSIZE, + ring->descbase, ring->dmabase, flags); } /* Reset the RX DMA channel */ @@ -646,14 +530,29 @@ static bool b43_dma_mapping_error(struct b43_dmaring *ring, if (unlikely(ssb_dma_mapping_error(ring->dev->dev, addr))) return 1; - if (!b43_dma_address_ok(ring, addr, buffersize)) { - /* We can't support this address. Unmap it again. */ - unmap_descbuffer(ring, addr, buffersize, dma_to_device); - return 1; + switch (ring->type) { + case B43_DMA_30BIT: + if ((u64)addr + buffersize > (1ULL << 30)) + goto address_error; + break; + case B43_DMA_32BIT: + if ((u64)addr + buffersize > (1ULL << 32)) + goto address_error; + break; + case B43_DMA_64BIT: + /* Currently we can't have addresses beyond + * 64bit in the kernel. */ + break; } /* The address is OK. */ return 0; + +address_error: + /* We can't support this address. Unmap it again. */ + unmap_descbuffer(ring, addr, buffersize, dma_to_device); + + return 1; } static bool b43_rx_buffer_is_poisoned(struct b43_dmaring *ring, struct sk_buff *skb) @@ -715,9 +614,6 @@ static int setup_rx_descbuffer(struct b43_dmaring *ring, meta->dmaaddr = dmaaddr; ring->ops->fill_descriptor(ring, desc, dmaaddr, ring->rx_buffersize, 0, 0, 0); - ssb_dma_sync_single_for_device(ring->dev->dev, - ring->alloc_dmabase, - ring->alloc_descsize, DMA_TO_DEVICE); return 0; } @@ -1354,9 +1250,6 @@ static int dma_tx_fragment(struct b43_dmaring *ring, } /* Now transfer the whole frame. */ wmb(); - ssb_dma_sync_single_for_device(ring->dev->dev, - ring->alloc_dmabase, - ring->alloc_descsize, DMA_TO_DEVICE); ops->poke_tx(ring, next_slot(ring, slot)); return 0; diff --git a/drivers/net/wireless/b43/dma.h b/drivers/net/wireless/b43/dma.h index e607b39..f7ab37c 100644 --- a/drivers/net/wireless/b43/dma.h +++ b/drivers/net/wireless/b43/dma.h @@ -157,6 +157,7 @@ struct b43_dmadesc_generic { } __attribute__ ((__packed__)); /* Misc DMA constants */ +#define B43_DMA_RINGMEMSIZE PAGE_SIZE #define B43_DMA0_RX_FRAMEOFFSET 30 /* DMA engine tuning knobs */ @@ -246,12 +247,6 @@ struct b43_dmaring { /* The QOS priority assigned to this ring. Only used for TX rings. * This is the mac80211 "queue" value. */ u8 queue_prio; - /* Pointers and size of the originally allocated and mapped memory - * region for the descriptor ring. */ - void *alloc_descbase; - dma_addr_t alloc_dmabase; - unsigned int alloc_descsize; - /* Pointer to our wireless device. */ struct b43_wldev *dev; #ifdef CONFIG_B43_DEBUG /* Maximum number of used slots. */ -- cgit v0.10.2 From 98ea3f50bcc97689cc0e1fa3b6733f03aeb8fef4 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Tue, 29 Dec 2009 21:51:15 +0100 Subject: reiserfs: Fix remaining in-reclaim-fs <-> reclaim-fs-on locking inversion Commit 500f5a0bf5f0624dae34307010e240ec090e4cde (reiserfs: Fix possible recursive lock) fixed a vmalloc under reiserfs lock that triggered a lockdep warning because of a IN-FS-RECLAIM <-> RECLAIM-FS-ON locking dependency inversion. But this patch has ommitted another vmalloc call in the same path that allocates the journal. Relax the lock for this one too. Reported-by: Alexander Beregalov Signed-off-by: Frederic Weisbecker Cc: Chris Mason Cc: Ingo Molnar diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c index 2f8a7e7..a059879 100644 --- a/fs/reiserfs/journal.c +++ b/fs/reiserfs/journal.c @@ -2758,11 +2758,18 @@ int journal_init(struct super_block *sb, const char *j_dev_name, struct reiserfs_journal *journal; struct reiserfs_journal_list *jl; char b[BDEVNAME_SIZE]; + int ret; + /* + * Unlock here to avoid various RECLAIM-FS-ON <-> IN-RECLAIM-FS + * dependency inversion warnings. + */ + reiserfs_write_unlock(sb); journal = SB_JOURNAL(sb) = vmalloc(sizeof(struct reiserfs_journal)); if (!journal) { reiserfs_warning(sb, "journal-1256", "unable to get memory for journal structure"); + reiserfs_write_lock(sb); return 1; } memset(journal, 0, sizeof(struct reiserfs_journal)); @@ -2771,10 +2778,12 @@ int journal_init(struct super_block *sb, const char *j_dev_name, INIT_LIST_HEAD(&journal->j_working_list); INIT_LIST_HEAD(&journal->j_journal_list); journal->j_persistent_trans = 0; - if (reiserfs_allocate_list_bitmaps(sb, - journal->j_list_bitmap, - reiserfs_bmap_count(sb))) + ret = reiserfs_allocate_list_bitmaps(sb, journal->j_list_bitmap, + reiserfs_bmap_count(sb)); + reiserfs_write_lock(sb); + if (ret) goto free_and_return; + allocate_bitmap_nodes(sb); /* reserved for journal area support */ -- cgit v0.10.2 From cbd1998377504df005302ac90d49db72a48552a6 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Wed, 30 Dec 2009 12:08:49 +1100 Subject: md: Fix unfortunate interaction with evms evms configures md arrays by: open device send ioctl close device for each different ioctl needed. Since 2.6.29, the device can disappear after the 'close' unless a significant configuration has happened to the device. The change made by "SET_ARRAY_INFO" can too minor to stop the device from disappearing, but important enough that losing the change is bad. So: make sure SET_ARRAY_INFO sets mddev->ctime, and keep the device active as long as ctime is non-zero (it gets zeroed with lots of other things when the array is stopped). This is suitable for -stable kernels since 2.6.29. Signed-off-by: NeilBrown Cc: stable@kernel.org diff --git a/drivers/md/md.c b/drivers/md/md.c index f4f5f82..7862231 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -386,7 +386,9 @@ static void mddev_put(mddev_t *mddev) if (!atomic_dec_and_lock(&mddev->active, &all_mddevs_lock)) return; if (!mddev->raid_disks && list_empty(&mddev->disks) && - !mddev->hold_active) { + mddev->ctime == 0 && !mddev->hold_active) { + /* Array is not configured at all, and not held active, + * so destroy it */ list_del(&mddev->all_mddevs); if (mddev->gendisk) { /* we did a probe so need to clean up. @@ -5262,6 +5264,10 @@ static int set_array_info(mddev_t * mddev, mdu_array_info_t *info) mddev->minor_version = info->minor_version; mddev->patch_version = info->patch_version; mddev->persistent = !info->not_persistent; + /* ensure mddev_put doesn't delete this now that there + * is some minimal configuration. + */ + mddev->ctime = get_seconds(); return 0; } mddev->major_version = MD_MAJOR_VERSION; -- cgit v0.10.2 From 0f9552b5dc4fe10da37fa3f4a4ca185d90fa41c9 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Wed, 30 Dec 2009 12:08:50 +1100 Subject: md: fix small irregularity with start_ro module parameter The start_ro modules parameter can be used to force arrays to be started in 'auto-readonly' in which they are read-only until the first write. This ensures that no resync/recovery happens until something else writes to the device. This is important for resume-from-disk off an md array. However if an array is started 'readonly' (by writing 'readonly' to the 'array_state' sysfs attribute) we want it to be really 'readonly', not 'auto-readonly'. So strengthen the condition to only set auto-readonly if the array is not already read-only. Signed-off-by: NeilBrown diff --git a/drivers/md/md.c b/drivers/md/md.c index 7862231..d2aff72 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -4357,7 +4357,7 @@ static int do_md_run(mddev_t * mddev) mddev->barriers_work = 1; mddev->ok_start_degraded = start_dirty_degraded; - if (start_readonly) + if (start_readonly && mddev->ro == 0) mddev->ro = 2; /* read-only, but switch on first write */ err = mddev->pers->run(mddev); -- cgit v0.10.2 From a2d79c324ac0c26ae9995a312a7731067a7f01fc Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 21 Dec 2009 18:18:36 -0700 Subject: md: make recovery started by do_md_run() visible via sync_action By default md_do_sync() will perform recovery if no other actions are specified. However, action_show() relies on MD_RECOVERY_RECOVER to be set otherwise it returns 'idle'. So, add a missing set MD_RECOVERY_RECOVER when starting recovery. Signed-off-by: Dan Williams Signed-off-by: NeilBrown diff --git a/drivers/md/md.c b/drivers/md/md.c index d2aff72..fd55f2a 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -4436,6 +4436,7 @@ static int do_md_run(mddev_t * mddev) if (spares && mddev->pers->sync_request) { mddev->recovery = 0; set_bit(MD_RECOVERY_RUNNING, &mddev->recovery); + set_bit(MD_RECOVERY_RECOVER, &mddev->recovery); mddev->sync_thread = md_register_thread(md_do_sync, mddev, "resync"); -- cgit v0.10.2 From 7fb9dadc91948ddd16d1d32e414b5e71ec63b97b Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Wed, 30 Dec 2009 15:19:08 +1100 Subject: md: remove unnecessary code from do_md_run Since commit dfc7064500061677720fa26352963c772d3ebe6b, ->hot_remove_disks has not removed non-failed devices from an array until recovery is no longer possible. So the code in do_md_run to get around the fact that md_check_recovery (which calls ->hot_remove_disks) would remove partially-in-sync devices is no longer needed. So remove it. Signed-off-by: NeilBrown diff --git a/drivers/md/md.c b/drivers/md/md.c index fd55f2a..c4bdf06 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -4421,34 +4421,6 @@ static int do_md_run(mddev_t * mddev) set_capacity(disk, mddev->array_sectors); - /* If there is a partially-recovered drive we need to - * start recovery here. If we leave it to md_check_recovery, - * it will remove the drives and not do the right thing - */ - if (mddev->degraded && !mddev->sync_thread) { - int spares = 0; - list_for_each_entry(rdev, &mddev->disks, same_set) - if (rdev->raid_disk >= 0 && - !test_bit(In_sync, &rdev->flags) && - !test_bit(Faulty, &rdev->flags)) - /* complete an interrupted recovery */ - spares++; - if (spares && mddev->pers->sync_request) { - mddev->recovery = 0; - set_bit(MD_RECOVERY_RUNNING, &mddev->recovery); - set_bit(MD_RECOVERY_RECOVER, &mddev->recovery); - mddev->sync_thread = md_register_thread(md_do_sync, - mddev, - "resync"); - if (!mddev->sync_thread) { - printk(KERN_ERR "%s: could not start resync" - " thread...\n", - mdname(mddev)); - /* leave the spares where they are, it shouldn't hurt */ - mddev->recovery = 0; - } - } - } md_wakeup_thread(mddev->thread); md_wakeup_thread(mddev->sync_thread); /* possibly kick off a reshape */ -- cgit v0.10.2 From 404e4b43fdd6daa7b4a9f81bc7e4358281d763fa Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Wed, 30 Dec 2009 15:25:23 +1100 Subject: md: allow a resync that is waiting for other resync to complete, to be aborted. If two arrays share a device, then they will not both resync at the same time. One will wait for the other to complete. While waiting, the MD_RECOVERY_INTR flag is not checked so a device failure, which would make the resync pointless, does not cause the resync to abort, so the failed device cannot be removed (as it cannot be remove while a resync is happening). So add a test for MD_RECOVERY_INTR. Reported-by: Brett Russ Signed-off-by: NeilBrown diff --git a/drivers/md/md.c b/drivers/md/md.c index c4bdf06..dd3dfe4 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -6473,10 +6473,11 @@ void md_do_sync(mddev_t *mddev) mddev->curr_resync = 2; try_again: - if (kthread_should_stop()) { + if (kthread_should_stop()) set_bit(MD_RECOVERY_INTR, &mddev->recovery); + + if (test_bit(MD_RECOVERY_INTR, &mddev->recovery)) goto skip; - } for_each_mddev(mddev2, tmp) { if (mddev2 == mddev) continue; -- cgit v0.10.2 From 515f41c33a9d44a964264c9511ad2c869af1fac3 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Tue, 29 Dec 2009 23:39:06 -0500 Subject: ext4: Ensure zeroout blocks have no dirty metadata This fixes a bug (found by Curt Wohlgemuth) in which new blocks returned from an extent created with ext4_ext_zeroout() can have dirty metadata still associated with them. Signed-off-by: Aneesh Kumar K.V Signed-off-by: Curt Wohlgemuth Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 8fd6c56..91ae460 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -3023,6 +3023,14 @@ out: return err; } +static void unmap_underlying_metadata_blocks(struct block_device *bdev, + sector_t block, int count) +{ + int i; + for (i = 0; i < count; i++) + unmap_underlying_metadata(bdev, block + i); +} + static int ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode, ext4_lblk_t iblock, unsigned int max_blocks, @@ -3098,6 +3106,18 @@ out: } else allocated = ret; set_buffer_new(bh_result); + /* + * if we allocated more blocks than requested + * we need to make sure we unmap the extra block + * allocated. The actual needed block will get + * unmapped later when we find the buffer_head marked + * new. + */ + if (allocated > max_blocks) { + unmap_underlying_metadata_blocks(inode->i_sb->s_bdev, + newblock + max_blocks, + allocated - max_blocks); + } map_out: set_buffer_mapped(bh_result); out1: -- cgit v0.10.2 From 27d0567ab635bc2af11be48f91c8d5a7a2dca2e4 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 17 Dec 2009 08:50:25 +0100 Subject: ACPI: fix ACPI=n allmodconfig build Today's -tip failed to build because commit 9e368fa011d4e0aa050db348d69514900520e40b ("ipmi: add PNP discovery (ACPI namespace via PNPACPI)") from today's upstream kernel causes the following build failure on x86, for CONFIG_ACPI=n && CONFIG_IPMI_SI=y: drivers/char/ipmi/ipmi_si_intf.c:3208: error: 'ipmi_pnp_driver' undeclared (first use in this function) drivers/char/ipmi/ipmi_si_intf.c:3208: error: (Each undeclared identifier is reported only once drivers/char/ipmi/ipmi_si_intf.c:3208: error: for each function it appears in.) drivers/char/ipmi/ipmi_si_intf.c:3334: error: 'ipmi_pnp_driver' undeclared (first use in this function) The reason is that the ipmi_pnp_driver depends on ACPI facilities and is only made available under ACPI - while the registration and unregistration is made dependent on CONFIG_PNP: #ifdef CONFIG_PNP pnp_register_driver(&ipmi_pnp_driver); #endif The solution is to only register this driver under ACPI. (Also, the CONFIG_PNP dependency is not needed because pnp_register_driver() is stubbed out in the !CONFIG_PNP case.) Signed-off-by: Ingo Molnar Acked-by: Myron Stowe Signed-off-by: Len Brown diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 679cd08..176f175 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -3204,7 +3204,7 @@ static __devinit int init_ipmi_si(void) #ifdef CONFIG_ACPI spmi_find_bmc(); #endif -#ifdef CONFIG_PNP +#ifdef CONFIG_ACPI pnp_register_driver(&ipmi_pnp_driver); #endif @@ -3330,7 +3330,7 @@ static __exit void cleanup_ipmi_si(void) #ifdef CONFIG_PCI pci_unregister_driver(&ipmi_pci_driver); #endif -#ifdef CONFIG_PNP +#ifdef CONFIG_ACPI pnp_unregister_driver(&ipmi_pnp_driver); #endif -- cgit v0.10.2 From 28c32e99bdf5ab838e7179c1aaca5a35a07f2a2b Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Mon, 13 Jul 2009 10:33:24 +0800 Subject: ACPI video: no warning message if "acpi_backlight=vendor" is used AML code always sends notifications to ACPI video device, even if we disable the ACPI backlight control by using boot option "acpi_backlight=vendor". In this case we should not print any warning message. http://bugzilla.kernel.org/show_bug.cgi?id=13671#c14 Sigend-off-by: Zhang Rui Signed-off-by: Len Brown diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 05dff63..3b063a6 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -1979,6 +1979,10 @@ acpi_video_switch_brightness(struct acpi_video_device *device, int event) unsigned long long level_current, level_next; int result = -EINVAL; + /* no warning message if acpi_backlight=vendor is used */ + if (!acpi_video_backlight_support()) + return 0; + if (!device->brightness) goto out; -- cgit v0.10.2 From 88f7a890d74137ab0d126a5d65679cd620f1a289 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Wed, 30 Dec 2009 14:22:22 +0800 Subject: ksym_tracer: Fix to make the tracer work ksym tracer doesn't work: # echo tasklist_lock:rw- > ksym_trace_filter -bash: echo: write error: No such device It's because we pass to perf_event_create_kernel_counter() a cpu number which is not present. Signed-off-by: Li Zefan Cc: Steven Rostedt Cc: K.Prasad Cc: Frederic Weisbecker LKML-Reference: <4B3AF19E.1010201@cn.fujitsu.com> Signed-off-by: Ingo Molnar diff --git a/kernel/hw_breakpoint.c b/kernel/hw_breakpoint.c index 366eedf..48fb0bb 100644 --- a/kernel/hw_breakpoint.c +++ b/kernel/hw_breakpoint.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include @@ -388,7 +389,8 @@ register_wide_hw_breakpoint(struct perf_event_attr *attr, if (!cpu_events) return ERR_PTR(-ENOMEM); - for_each_possible_cpu(cpu) { + get_online_cpus(); + for_each_online_cpu(cpu) { pevent = per_cpu_ptr(cpu_events, cpu); bp = perf_event_create_kernel_counter(attr, cpu, -1, triggered); @@ -399,18 +401,20 @@ register_wide_hw_breakpoint(struct perf_event_attr *attr, goto fail; } } + put_online_cpus(); return cpu_events; fail: - for_each_possible_cpu(cpu) { + for_each_online_cpu(cpu) { pevent = per_cpu_ptr(cpu_events, cpu); if (IS_ERR(*pevent)) break; unregister_hw_breakpoint(*pevent); } + put_online_cpus(); + free_percpu(cpu_events); - /* return the error if any */ return ERR_PTR(err); } EXPORT_SYMBOL_GPL(register_wide_hw_breakpoint); diff --git a/kernel/trace/trace_ksym.c b/kernel/trace/trace_ksym.c index faf37fa..340b6ff 100644 --- a/kernel/trace/trace_ksym.c +++ b/kernel/trace/trace_ksym.c @@ -197,7 +197,6 @@ int process_new_ksym_entry(char *ksymname, int op, unsigned long addr) entry->attr.bp_addr = addr; entry->attr.bp_len = HW_BREAKPOINT_LEN_4; - ret = -EAGAIN; entry->ksym_hbp = register_wide_hw_breakpoint(&entry->attr, ksym_hbp_handler); -- cgit v0.10.2 From 3d13ec2efdb5843ad91e57b60d50b44d922cf063 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Wed, 30 Dec 2009 14:23:19 +0800 Subject: ksym_tracer: Fix to allow writing newline to ksym_trace_filter It used to work, but now doesn't: # echo > ksym_filter bash: echo: write error: Invalid argument It's caused by d954fbf0ff6b5fdfb32350e85a2f15d3db976506 ("tracing: Fix wrong usage of strstrip in trace_ksyms"). Signed-off-by: Li Zefan Cc: Steven Rostedt Cc: K.Prasad Cc: Frederic Weisbecker LKML-Reference: <4B3AF1D7.5040400@cn.fujitsu.com> Signed-off-by: Ingo Molnar diff --git a/kernel/trace/trace_ksym.c b/kernel/trace/trace_ksym.c index 340b6ff..160a8d8 100644 --- a/kernel/trace/trace_ksym.c +++ b/kernel/trace/trace_ksym.c @@ -299,8 +299,8 @@ static ssize_t ksym_trace_filter_write(struct file *file, * 2: echo 0 > ksym_trace_filter * 3: echo "*:---" > ksym_trace_filter */ - if (!buf[0] || !strcmp(buf, "0") || - !strcmp(buf, "*:---")) { + if (!input_string[0] || !strcmp(input_string, "0") || + !strcmp(input_string, "*:---")) { __ksym_trace_reset(); ret = 0; goto out; -- cgit v0.10.2 From e6d9491bf8ba6728cc86aeabbc688d20ec0563b5 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Wed, 30 Dec 2009 14:23:40 +0800 Subject: ksym_tracer: Fix race when incrementing count We are under rcu read section but not holding the write lock, so count++ is not atomic. Use atomic64_t instead. Signed-off-by: Li Zefan Cc: Steven Rostedt Cc: K.Prasad Cc: Frederic Weisbecker LKML-Reference: <4B3AF1EC.9010608@cn.fujitsu.com> Signed-off-by: Ingo Molnar diff --git a/kernel/trace/trace_ksym.c b/kernel/trace/trace_ksym.c index 160a8d8..67d79f7 100644 --- a/kernel/trace/trace_ksym.c +++ b/kernel/trace/trace_ksym.c @@ -32,6 +32,8 @@ #include #include +#include + /* * For now, let us restrict the no. of symbols traced simultaneously to number * of available hardware breakpoint registers. @@ -44,7 +46,7 @@ struct trace_ksym { struct perf_event **ksym_hbp; struct perf_event_attr attr; #ifdef CONFIG_PROFILE_KSYM_TRACER - unsigned long counter; + atomic64_t counter; #endif struct hlist_node ksym_hlist; }; @@ -69,9 +71,8 @@ void ksym_collect_stats(unsigned long hbp_hit_addr) rcu_read_lock(); hlist_for_each_entry_rcu(entry, node, &ksym_filter_head, ksym_hlist) { - if ((entry->attr.bp_addr == hbp_hit_addr) && - (entry->counter <= MAX_UL_INT)) { - entry->counter++; + if (entry->attr.bp_addr == hbp_hit_addr) { + atomic64_inc(&entry->counter); break; } } @@ -501,7 +502,8 @@ static int ksym_tracer_stat_show(struct seq_file *m, void *v) seq_printf(m, " %-36s", fn_name); else seq_printf(m, " %-36s", ""); - seq_printf(m, " %15lu\n", entry->counter); + seq_printf(m, " %15llu\n", + (unsigned long long)atomic64_read(&entry->counter)); return 0; } -- cgit v0.10.2 From 53ab668064edaeef99c0ee22799483d45f4c81f6 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Wed, 30 Dec 2009 14:24:03 +0800 Subject: ksym_tracer: Remove trace_stat trace_stat is problematic. Don't use it, use seqfile instead. This fixes a race that reading the stat file is not protected by any lock, which can lead to use after free. Signed-off-by: Li Zefan Cc: Steven Rostedt Cc: K.Prasad Cc: Frederic Weisbecker LKML-Reference: <4B3AF203.40200@cn.fujitsu.com> Signed-off-by: Ingo Molnar diff --git a/kernel/trace/trace_ksym.c b/kernel/trace/trace_ksym.c index 67d79f7..94103cd 100644 --- a/kernel/trace/trace_ksym.c +++ b/kernel/trace/trace_ksym.c @@ -26,7 +26,6 @@ #include #include "trace_output.h" -#include "trace_stat.h" #include "trace.h" #include @@ -444,103 +443,77 @@ struct tracer ksym_tracer __read_mostly = .print_line = ksym_trace_output }; -__init static int init_ksym_trace(void) -{ - struct dentry *d_tracer; - struct dentry *entry; - - d_tracer = tracing_init_dentry(); - ksym_filter_entry_count = 0; - - entry = debugfs_create_file("ksym_trace_filter", 0644, d_tracer, - NULL, &ksym_tracing_fops); - if (!entry) - pr_warning("Could not create debugfs " - "'ksym_trace_filter' file\n"); - - return register_tracer(&ksym_tracer); -} -device_initcall(init_ksym_trace); - - #ifdef CONFIG_PROFILE_KSYM_TRACER -static int ksym_tracer_stat_headers(struct seq_file *m) +static int ksym_profile_show(struct seq_file *m, void *v) { + struct hlist_node *node; + struct trace_ksym *entry; + int access_type = 0; + char fn_name[KSYM_NAME_LEN]; + seq_puts(m, " Access Type "); seq_puts(m, " Symbol Counter\n"); seq_puts(m, " ----------- "); seq_puts(m, " ------ -------\n"); - return 0; -} -static int ksym_tracer_stat_show(struct seq_file *m, void *v) -{ - struct hlist_node *stat = v; - struct trace_ksym *entry; - int access_type = 0; - char fn_name[KSYM_NAME_LEN]; + rcu_read_lock(); + hlist_for_each_entry_rcu(entry, node, &ksym_filter_head, ksym_hlist) { - entry = hlist_entry(stat, struct trace_ksym, ksym_hlist); + access_type = entry->attr.bp_type; - access_type = entry->attr.bp_type; + switch (access_type) { + case HW_BREAKPOINT_R: + seq_puts(m, " R "); + break; + case HW_BREAKPOINT_W: + seq_puts(m, " W "); + break; + case HW_BREAKPOINT_R | HW_BREAKPOINT_W: + seq_puts(m, " RW "); + break; + default: + seq_puts(m, " NA "); + } - switch (access_type) { - case HW_BREAKPOINT_R: - seq_puts(m, " R "); - break; - case HW_BREAKPOINT_W: - seq_puts(m, " W "); - break; - case HW_BREAKPOINT_R | HW_BREAKPOINT_W: - seq_puts(m, " RW "); - break; - default: - seq_puts(m, " NA "); + if (lookup_symbol_name(entry->attr.bp_addr, fn_name) >= 0) + seq_printf(m, " %-36s", fn_name); + else + seq_printf(m, " %-36s", ""); + seq_printf(m, " %15llu\n", + (unsigned long long)atomic64_read(&entry->counter)); } - - if (lookup_symbol_name(entry->attr.bp_addr, fn_name) >= 0) - seq_printf(m, " %-36s", fn_name); - else - seq_printf(m, " %-36s", ""); - seq_printf(m, " %15llu\n", - (unsigned long long)atomic64_read(&entry->counter)); + rcu_read_unlock(); return 0; } -static void *ksym_tracer_stat_start(struct tracer_stat *trace) +static int ksym_profile_open(struct inode *node, struct file *file) { - return ksym_filter_head.first; -} - -static void * -ksym_tracer_stat_next(void *v, int idx) -{ - struct hlist_node *stat = v; - - return stat->next; + return single_open(file, ksym_profile_show, NULL); } -static struct tracer_stat ksym_tracer_stats = { - .name = "ksym_tracer", - .stat_start = ksym_tracer_stat_start, - .stat_next = ksym_tracer_stat_next, - .stat_headers = ksym_tracer_stat_headers, - .stat_show = ksym_tracer_stat_show +static const struct file_operations ksym_profile_fops = { + .open = ksym_profile_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, }; +#endif /* CONFIG_PROFILE_KSYM_TRACER */ -__init static int ksym_tracer_stat_init(void) +__init static int init_ksym_trace(void) { - int ret; + struct dentry *d_tracer; - ret = register_stat_tracer(&ksym_tracer_stats); - if (ret) { - printk(KERN_WARNING "Warning: could not register " - "ksym tracer stats\n"); - return 1; - } + d_tracer = tracing_init_dentry(); - return 0; + trace_create_file("ksym_trace_filter", 0644, d_tracer, + NULL, &ksym_tracing_fops); + +#ifdef CONFIG_PROFILE_KSYM_TRACER + trace_create_file("ksym_profile", 0444, d_tracer, + NULL, &ksym_profile_fops); +#endif + + return register_tracer(&ksym_tracer); } -fs_initcall(ksym_tracer_stat_init); -#endif /* CONFIG_PROFILE_KSYM_TRACER */ +device_initcall(init_ksym_trace); -- cgit v0.10.2 From e01ce79b7f6ebc5b57128ee058811aa8f9059319 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Wed, 29 Jul 2009 08:53:29 +0800 Subject: ACPI video: correct error-handling code backlight_device_register may return an ERR_PTR value rather than a valid pointer. Problem found by Julia Lawall, properly fixed by Zhang Rui. Signed-off-by: Zhang Rui Acked-by: Julia Lawall Signed-off-by: Len Brown diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 05dff63..3f685db 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -999,8 +999,10 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) sprintf(name, "acpi_video%d", count++); device->backlight = backlight_device_register(name, NULL, device, &acpi_backlight_ops); - device->backlight->props.max_brightness = device->brightness->count-3; kfree(name); + if (IS_ERR(device->backlight)) + return; + device->backlight->props.max_brightness = device->brightness->count-3; result = sysfs_create_link(&device->backlight->dev.kobj, &device->dev->dev.kobj, "device"); -- cgit v0.10.2 From c6bde2d9cb75a41cd2b331953784843b4caa89df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Bolldorf?= Date: Tue, 29 Dec 2009 23:06:52 -0800 Subject: Input: psmouse - fix compile warning in hgpk module The variable 'dev' is unused in function 'hgpk_register'. Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/mouse/hgpk.c b/drivers/input/mouse/hgpk.c index b146237..90be30e 100644 --- a/drivers/input/mouse/hgpk.c +++ b/drivers/input/mouse/hgpk.c @@ -427,7 +427,6 @@ static void hgpk_recalib_work(struct work_struct *work) static int hgpk_register(struct psmouse *psmouse) { - struct input_dev *dev = psmouse->dev; int err; /* register handlers */ -- cgit v0.10.2 From e97006ae1c87f9630b6f5c4d4384921059d881a8 Mon Sep 17 00:00:00 2001 From: Rakib Mullick Date: Tue, 29 Dec 2009 23:19:31 -0800 Subject: Input: wistron - fix test for CONFIG_PM This should fix the following compile warning: drivers/input/misc/wistron_btns.c:1331:5: warning: "CONFIG_PM" is not defined Signed-off-by: Rakib Mullick Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c index 38da6ab..c0afb71 100644 --- a/drivers/input/misc/wistron_btns.c +++ b/drivers/input/misc/wistron_btns.c @@ -1328,7 +1328,7 @@ static struct platform_driver wistron_driver = { .driver = { .name = "wistron-bios", .owner = THIS_MODULE, -#if CONFIG_PM +#ifdef CONFIG_PM .pm = &wistron_pm_ops, #endif }, -- cgit v0.10.2 From 614af4eeb9e89806c001dab50c59e11f40753601 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 29 Dec 2009 23:19:31 -0800 Subject: Input: lifebook - add CONFIG_DMI dependency Lifebook protocol can only be activated if we find known DMI signature. It is useles without DMI. Reported-by: Rakib Mullick Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig index 3feeb3a..c714ca2 100644 --- a/drivers/input/mouse/Kconfig +++ b/drivers/input/mouse/Kconfig @@ -70,7 +70,7 @@ config MOUSE_PS2_SYNAPTICS config MOUSE_PS2_LIFEBOOK bool "Fujitsu Lifebook PS/2 mouse protocol extension" if EMBEDDED default y - depends on MOUSE_PS2 && X86 + depends on MOUSE_PS2 && X86 && DMI help Say Y here if you have a Fujitsu B-series Lifebook PS/2 TouchScreen connected to your system. diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c index 2e6bdfe..6d7aa10 100644 --- a/drivers/input/mouse/lifebook.c +++ b/drivers/input/mouse/lifebook.c @@ -44,7 +44,6 @@ static int lifebook_set_6byte_proto(const struct dmi_system_id *d) } static const struct dmi_system_id __initconst lifebook_dmi_table[] = { -#if defined(CONFIG_DMI) && defined(CONFIG_X86) { /* FLORA-ie 55mi */ .matches = { @@ -118,7 +117,6 @@ static const struct dmi_system_id __initconst lifebook_dmi_table[] = { }, }, { } -#endif }; void __init lifebook_module_init(void) -- cgit v0.10.2 From 3f58061d0160424d244e3a72258a1366ab4a8547 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 29 Dec 2009 23:15:51 -0800 Subject: Input: twl4030_keypad - switch to using threaded IRQ Signed-off-by: Felipe Balbi Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/keyboard/twl4030_keypad.c b/drivers/input/keyboard/twl4030_keypad.c index eeaa7ac..21d6184 100644 --- a/drivers/input/keyboard/twl4030_keypad.c +++ b/drivers/input/keyboard/twl4030_keypad.c @@ -253,14 +253,6 @@ static irqreturn_t do_kp_irq(int irq, void *_kp) u8 reg; int ret; -#ifdef CONFIG_LOCKDEP - /* WORKAROUND for lockdep forcing IRQF_DISABLED on us, which - * we don't want and can't tolerate. Although it might be - * friendlier not to borrow this thread context... - */ - local_irq_enable(); -#endif - /* Read & Clear TWL4030 pending interrupt */ ret = twl4030_kpread(kp, ®, KEYP_ISR1, 1); @@ -403,7 +395,8 @@ static int __devinit twl4030_kp_probe(struct platform_device *pdev) * * NOTE: we assume this host is wired to TWL4040 INT1, not INT2 ... */ - error = request_irq(kp->irq, do_kp_irq, 0, pdev->name, kp); + error = request_threaded_irq(kp->irq, NULL, do_kp_irq, + 0, pdev->name, kp); if (error) { dev_info(kp->dbg_dev, "request_irq failed for irq no=%d\n", kp->irq); -- cgit v0.10.2 From 70f944139084c4f297ac90b3af4cb67a8a68b2cf Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 29 Dec 2009 23:16:28 -0800 Subject: Input: twl4030-pwrbutton - switch to using threaded IRQ Signed-off-by: Felipe Balbi Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/misc/twl4030-pwrbutton.c b/drivers/input/misc/twl4030-pwrbutton.c index bdde5c8..e9069b8 100644 --- a/drivers/input/misc/twl4030-pwrbutton.c +++ b/drivers/input/misc/twl4030-pwrbutton.c @@ -39,18 +39,8 @@ static irqreturn_t powerbutton_irq(int irq, void *_pwr) int err; u8 value; -#ifdef CONFIG_LOCKDEP - /* WORKAROUND for lockdep forcing IRQF_DISABLED on us, which - * we don't want and can't tolerate since this is a threaded - * IRQ and can sleep due to the i2c reads it has to issue. - * Although it might be friendlier not to borrow this thread - * context... - */ - local_irq_enable(); -#endif - err = twl_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &value, - STS_HW_CONDITIONS); + STS_HW_CONDITIONS); if (!err) { input_report_key(pwr, KEY_POWER, value & PWR_PWRON_IRQ); input_sync(pwr); @@ -80,7 +70,7 @@ static int __devinit twl4030_pwrbutton_probe(struct platform_device *pdev) pwr->phys = "twl4030_pwrbutton/input0"; pwr->dev.parent = &pdev->dev; - err = request_irq(irq, powerbutton_irq, + err = request_threaded_irq(irq, NULL, powerbutton_irq, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "twl4030_pwrbutton", pwr); if (err < 0) { -- cgit v0.10.2 From 9bd3f98821a83041e77ee25158b80b535d02d7b4 Mon Sep 17 00:00:00 2001 From: Gui Jianfeng Date: Wed, 30 Dec 2009 08:41:07 +0100 Subject: block: blk_rq_err_sectors cleanup blk_rq_err_sectors() seems useless, get rid of it. Signed-off-by: Gui Jianfeng Signed-off-by: Jens Axboe diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 59b832b..9b98173 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -845,7 +845,6 @@ static inline struct request_queue *bdev_get_queue(struct block_device *bdev) * blk_rq_err_bytes() : bytes left till the next error boundary * blk_rq_sectors() : sectors left in the entire request * blk_rq_cur_sectors() : sectors left in the current segment - * blk_rq_err_sectors() : sectors left till the next error boundary */ static inline sector_t blk_rq_pos(const struct request *rq) { @@ -874,11 +873,6 @@ static inline unsigned int blk_rq_cur_sectors(const struct request *rq) return blk_rq_cur_bytes(rq) >> 9; } -static inline unsigned int blk_rq_err_sectors(const struct request *rq) -{ - return blk_rq_err_bytes(rq) >> 9; -} - /* * Request issue related functions. */ -- cgit v0.10.2 From abb631bfe271a9102fb5b05419272b7aec37a974 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Sat, 26 Dec 2009 21:51:38 -0500 Subject: dell-wmi: sys_init_module: 'dell_wmi'->init suspiciously returned 21, it should follow 0/-E convention wmi_install_notify_handler() returns an acpi_error, but dell_wmi_init() needs return a -errno style error. Tested-by: Paul Rolland Signed-off-by: Len Brown diff --git a/drivers/platform/x86/dell-wmi.c b/drivers/platform/x86/dell-wmi.c index 916ccb2..4c7e702 100644 --- a/drivers/platform/x86/dell-wmi.c +++ b/drivers/platform/x86/dell-wmi.c @@ -323,6 +323,7 @@ static int __init dell_wmi_input_setup(void) static int __init dell_wmi_init(void) { int err; + acpi_status status; if (wmi_has_guid(DELL_EVENT_GUID)) { printk(KERN_WARNING "dell-wmi: No known WMI GUID found\n"); @@ -336,14 +337,14 @@ static int __init dell_wmi_init(void) if (err) return err; - err = wmi_install_notify_handler(DELL_EVENT_GUID, + status = wmi_install_notify_handler(DELL_EVENT_GUID, dell_wmi_notify, NULL); - if (err) { + if (ACPI_FAILURE(status)) { input_unregister_device(dell_wmi_input_dev); printk(KERN_ERR "dell-wmi: Unable to register notify handler - %d\n", - err); - return err; + status); + return -ENODEV; } return 0; -- cgit v0.10.2 From f27725756be8a2c2dc65eaf70d0b52807aa2f113 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Sat, 26 Dec 2009 22:04:03 -0500 Subject: ACPI: hp-wmi, msi-wmi: clarify that wmi_install_notify_handler() returns an acpi_status Emphasize that that wmi_install_notify_handler() returns an acpi_status rather than -errno by by testing ACPI_SUCCESS(), ACPI_FAILURE(). No functional change in this patch, but this confusion caused a bug in dell-wmi. Signed-off-by: Len Brown diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c index 8781d8fa..18bf741 100644 --- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c @@ -581,7 +581,7 @@ static int __init hp_wmi_init(void) if (wmi_has_guid(HPWMI_EVENT_GUID)) { err = wmi_install_notify_handler(HPWMI_EVENT_GUID, hp_wmi_notify, NULL); - if (!err) + if (ACPI_SUCCESS(err)) hp_wmi_input_setup(); } diff --git a/drivers/platform/x86/msi-wmi.c b/drivers/platform/x86/msi-wmi.c index 7f77f90..f746c67 100644 --- a/drivers/platform/x86/msi-wmi.c +++ b/drivers/platform/x86/msi-wmi.c @@ -236,7 +236,7 @@ static int __init msi_wmi_init(void) } err = wmi_install_notify_handler(MSIWMI_EVENT_GUID, msi_wmi_notify, NULL); - if (err) + if (ACPI_FAILURE(err)) return -EINVAL; err = msi_wmi_input_setup(); -- cgit v0.10.2 From fda11e61ff8a4e3a8ebbd434e46560b67cc0ca9d Mon Sep 17 00:00:00 2001 From: Len Brown Date: Sat, 26 Dec 2009 23:02:24 -0500 Subject: dell-wmi, hp-wmi, msi-wmi: check wmi_get_event_data() return value When acpi_evaluate_object() is passed ACPI_ALLOCATE_BUFFER, the caller must kfree the returned buffer if AE_OK is returned. The callers of wmi_get_event_data() pass ACPI_ALLOCATE_BUFFER, and thus must check its return value before accessing or kfree() on the buffer. Signed-off-by: Len Brown diff --git a/drivers/platform/x86/dell-wmi.c b/drivers/platform/x86/dell-wmi.c index 4c7e702..500af8c 100644 --- a/drivers/platform/x86/dell-wmi.c +++ b/drivers/platform/x86/dell-wmi.c @@ -202,8 +202,13 @@ static void dell_wmi_notify(u32 value, void *context) struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL }; static struct key_entry *key; union acpi_object *obj; + acpi_status status; - wmi_get_event_data(value, &response); + status = wmi_get_event_data(value, &response); + if (status != AE_OK) { + printk(KERN_INFO "dell-wmi: bad event status 0x%x\n", status); + return; + } obj = (union acpi_object *)response.pointer; diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c index 18bf741..5b648f0 100644 --- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c @@ -338,8 +338,13 @@ static void hp_wmi_notify(u32 value, void *context) static struct key_entry *key; union acpi_object *obj; int eventcode; + acpi_status status; - wmi_get_event_data(value, &response); + status = wmi_get_event_data(value, &response); + if (status != AE_OK) { + printk(KERN_INFO "hp-wmi: bad event status 0x%x\n", status); + return; + } obj = (union acpi_object *)response.pointer; diff --git a/drivers/platform/x86/msi-wmi.c b/drivers/platform/x86/msi-wmi.c index f746c67..f5f70d4 100644 --- a/drivers/platform/x86/msi-wmi.c +++ b/drivers/platform/x86/msi-wmi.c @@ -149,8 +149,13 @@ static void msi_wmi_notify(u32 value, void *context) static struct key_entry *key; union acpi_object *obj; ktime_t cur; + acpi_status status; - wmi_get_event_data(value, &response); + status = wmi_get_event_data(value, &response); + if (status != AE_OK) { + printk(KERN_INFO DRV_PFX "bad event status 0x%x\n", status); + return; + } obj = (union acpi_object *)response.pointer; -- cgit v0.10.2 From c03b26a5a5597a59b2e247d005d5901430109a8a Mon Sep 17 00:00:00 2001 From: Paul Rolland Date: Wed, 30 Dec 2009 01:07:40 -0500 Subject: wmi: check find_guid() return value to prevent oops Signed-off-by: Paul Rolland Signed-off-by: Len Brown diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c index 9f93d6c..cc9ad74 100644 --- a/drivers/platform/x86/wmi.c +++ b/drivers/platform/x86/wmi.c @@ -492,8 +492,7 @@ wmi_notify_handler handler, void *data) if (!guid || !handler) return AE_BAD_PARAMETER; - find_guid(guid, &block); - if (!block) + if (!find_guid(guid, &block)) return AE_NOT_EXIST; if (block->handler) @@ -521,8 +520,7 @@ acpi_status wmi_remove_notify_handler(const char *guid) if (!guid) return AE_BAD_PARAMETER; - find_guid(guid, &block); - if (!block) + if (!find_guid(guid, &block)) return AE_NOT_EXIST; if (!block->handler) -- cgit v0.10.2 From 7a9568f536754623738110a314ff33286cdbb17d Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 25 Dec 2009 11:49:35 -0800 Subject: dell-wmi - fix condition to abort driver loading From: Dmitry Torokhov The commit 1fdd407f4e3f2ecb453954cbebb6c22491c61853 incorrectly made driver abort loading when known GUID is present when it should have done exactly the opposite. Signed-off-by: Dmitry Torokhov Signed-off-by: Len Brown diff --git a/drivers/platform/x86/dell-wmi.c b/drivers/platform/x86/dell-wmi.c index 500af8c..1b1dddb 100644 --- a/drivers/platform/x86/dell-wmi.c +++ b/drivers/platform/x86/dell-wmi.c @@ -330,7 +330,7 @@ static int __init dell_wmi_init(void) int err; acpi_status status; - if (wmi_has_guid(DELL_EVENT_GUID)) { + if (!wmi_has_guid(DELL_EVENT_GUID)) { printk(KERN_WARNING "dell-wmi: No known WMI GUID found\n"); return -ENODEV; } -- cgit v0.10.2 From d1f9e4970742bb1e22d07b01bd44f9c357d25c42 Mon Sep 17 00:00:00 2001 From: Carlos Corbacho Date: Sat, 26 Dec 2009 19:14:59 +0000 Subject: ACPI: WMI: Survive BIOS with duplicate GUIDs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It would appear that in BIOS's with nVidia hooks, the GUID 05901221-D566-11D1-B2F0-00A0C9062910 is duplicated. For now, the simplest solution is to just ignore any duplicate GUIDs. These particular hooks are not currently supported/ used in the kernel, so whoever does that can figure out what the 'right' solution should be (if there's a better one). http://bugzilla.kernel.org/show_bug.cgi?id=14846 Signed-off-by: Carlos Corbacho Reported-by: Larry Finger Reported-by: Oldřich Jedlička Signed-off-by: Len Brown diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c index cc9ad74..b104302 100644 --- a/drivers/platform/x86/wmi.c +++ b/drivers/platform/x86/wmi.c @@ -714,6 +714,22 @@ static int wmi_class_init(void) return ret; } +static bool guid_already_parsed(const char *guid_string) +{ + struct guid_block *gblock; + struct wmi_block *wblock; + struct list_head *p; + + list_for_each(p, &wmi_blocks.list) { + wblock = list_entry(p, struct wmi_block, list); + gblock = &wblock->gblock; + + if (strncmp(gblock->guid, guid_string, 16) == 0) + return true; + } + return false; +} + /* * Parse the _WDG method for the GUID data blocks */ @@ -723,6 +739,7 @@ static __init acpi_status parse_wdg(acpi_handle handle) union acpi_object *obj; struct guid_block *gblock; struct wmi_block *wblock; + char guid_string[37]; acpi_status status; u32 i, total; @@ -745,6 +762,19 @@ static __init acpi_status parse_wdg(acpi_handle handle) memcpy(gblock, obj->buffer.pointer, obj->buffer.length); for (i = 0; i < total; i++) { + /* + Some WMI devices, like those for nVidia hooks, have a + duplicate GUID. It's not clear what we should do in this + case yet, so for now, we'll just ignore the duplicate. + Anyone who wants to add support for that device can come + up with a better workaround for the mess then. + */ + if (guid_already_parsed(gblock[i].guid) == true) { + wmi_gtoa(gblock[i].guid, guid_string); + printk(KERN_INFO PREFIX "Skipping duplicate GUID %s\n", + guid_string); + continue; + } wblock = kzalloc(sizeof(struct wmi_block), GFP_KERNEL); if (!wblock) return AE_NO_MEMORY; -- cgit v0.10.2 From f405d2c02395a74d3883bd03ded36457aa3697ad Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Mon, 28 Dec 2009 18:11:56 +0900 Subject: x86/agp: Fix agp_amd64_init() initialization with CONFIG_GART_IOMMU enabled with CONFIG_GART_IOMMU enabled drivers/char/agp/amd64-agp.c has: #ifndef CONFIG_GART_IOMMU module_init(agp_amd64_init); module_exit(agp_amd64_cleanup); #endif agp_amd64_init() was called via gart_iommu_init with CONFIG_GART_IOMMU=y agp_amd64_init() was called via module_init with CONFIG_GART_IOMMU=n The commit 75f1cdf1dda92cae037ec848ae63690d91913eac changes the x86 dma initialization routine: gart_iommu_init() is called only when GART IOMMU is detected. So when GART IOMMU isn't detected, agp_amd64_init isn't called. Marin Mitov reported this issue: http://marc.info/?l=linux-kernel&m=126192729110083&w=2 With this patch, agp_amd64_init() is always called via module_init (the above ifndef is removed). If agp_amd64_init() is called via gart_iommu_init() earlier, agp_amd64_init() finishes without doing anything (when it is called via module_init). Reported-by: Marin Mitov Tested-by: Marin Mitov Signed-off-by: FUJITA Tomonori Cc: davej@redhat.com LKML-Reference: <20091228181118C.fujita.tomonori@lab.ntt.co.jp> Signed-off-by: Ingo Molnar diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c index 2fb2e6c..5aa7a58 100644 --- a/drivers/char/agp/amd64-agp.c +++ b/drivers/char/agp/amd64-agp.c @@ -725,9 +725,14 @@ static struct pci_driver agp_amd64_pci_driver = { int __init agp_amd64_init(void) { int err = 0; + static int done = 0; if (agp_off) return -EINVAL; + + if (done++) + return agp_bridges_found ? 0 : -ENODEV; + err = pci_register_driver(&agp_amd64_pci_driver); if (err < 0) return err; @@ -771,12 +776,8 @@ static void __exit agp_amd64_cleanup(void) pci_unregister_driver(&agp_amd64_pci_driver); } -/* On AMD64 the PCI driver needs to initialize this driver early - for the IOMMU, so it has to be called via a backdoor. */ -#ifndef CONFIG_GART_IOMMU module_init(agp_amd64_init); module_exit(agp_amd64_cleanup); -#endif MODULE_AUTHOR("Dave Jones , Andi Kleen"); module_param(agp_try_unsupported, bool, 0); -- cgit v0.10.2 From 79b408210885b9f7f0b067b07a09d68f4da3a700 Mon Sep 17 00:00:00 2001 From: Lai Jiangshan Date: Tue, 15 Dec 2009 15:39:19 +0800 Subject: tracing/kprobe: Show sign of fields in trace_kprobe format files The format files of trace_kprobe do not show the sign of the fields. The other format files show the field signed type of the fields and this patch makes the trace_kprobe formats consistent with the others. Signed-off-by: Lai Jiangshan LKML-Reference: <4B273D27.5040009@cn.fujitsu.com> Acked-by: Masami Hiramatsu Signed-off-by: Steven Rostedt diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 7ecab06..83f1e6e 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -1182,10 +1182,11 @@ static int __probe_event_show_format(struct trace_seq *s, #undef SHOW_FIELD #define SHOW_FIELD(type, item, name) \ do { \ - ret = trace_seq_printf(s, "\tfield: " #type " %s;\t" \ - "offset:%u;\tsize:%u;\n", name, \ + ret = trace_seq_printf(s, "\tfield:" #type " %s;\t" \ + "offset:%u;\tsize:%u;\tsigned:%d;\n", name,\ (unsigned int)offsetof(typeof(field), item),\ - (unsigned int)sizeof(type)); \ + (unsigned int)sizeof(type), \ + is_signed_type(type)); \ if (!ret) \ return 0; \ } while (0) -- cgit v0.10.2 From e96dc9674cb597de4fee757ed005c8465072d13f Mon Sep 17 00:00:00 2001 From: Lai Jiangshan Date: Tue, 15 Dec 2009 15:39:26 +0800 Subject: tracing/syscalls: Fix typo in SYSCALL_DEFINE0 The struct syscall_metadata variable name in SYSCALL_DEFINE0 should be __syscall_meta__##sname instead of __syscall_meta_##sname to match the name that is in SYSCALL_DEFINE1/2/3/4/5/6. This error causes event_enter_##sname->data to point to the wrong location, which causes syscalls which are defined by SYSCALL_DEFINE0() not to be traced. Signed-off-by: Lai Jiangshan LKML-Reference: <4B273D2E.1010807@cn.fujitsu.com> Acked-by: Frederic Weisbecker Signed-off-by: Steven Rostedt diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 65793e9..207466a 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -195,7 +195,7 @@ struct perf_event_attr; static const struct syscall_metadata __used \ __attribute__((__aligned__(4))) \ __attribute__((section("__syscalls_metadata"))) \ - __syscall_meta_##sname = { \ + __syscall_meta__##sname = { \ .name = "sys_"#sname, \ .nb_args = 0, \ .enter_event = &event_enter__##sname, \ -- cgit v0.10.2 From fb7ae981cb9fe8665b9da97e8734745e030c151d Mon Sep 17 00:00:00 2001 From: Lai Jiangshan Date: Tue, 15 Dec 2009 15:39:38 +0800 Subject: tracing: Fix sign fields in ftrace_define_fields_##call() Add is_signed_type() call to trace_define_field() in ftrace macros. The code previously just passed in 0 (false), disregarding whether or not the field was actually a signed type. Signed-off-by: Lai Jiangshan LKML-Reference: <4B273D3A.6020007@cn.fujitsu.com> Signed-off-by: Steven Rostedt diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h index 73523151..c6fe03e 100644 --- a/include/trace/ftrace.h +++ b/include/trace/ftrace.h @@ -414,7 +414,8 @@ ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \ BUILD_BUG_ON(len > MAX_FILTER_STR_VAL); \ ret = trace_define_field(event_call, #type "[" #len "]", #item, \ offsetof(typeof(field), item), \ - sizeof(field.item), 0, FILTER_OTHER); \ + sizeof(field.item), \ + is_signed_type(type), FILTER_OTHER); \ if (ret) \ return ret; @@ -422,8 +423,8 @@ ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \ #define __dynamic_array(type, item, len) \ ret = trace_define_field(event_call, "__data_loc " #type "[]", #item, \ offsetof(typeof(field), __data_loc_##item), \ - sizeof(field.__data_loc_##item), 0, \ - FILTER_OTHER); + sizeof(field.__data_loc_##item), \ + is_signed_type(type), FILTER_OTHER); #undef __string #define __string(item, src) __dynamic_array(char, item, -1) diff --git a/kernel/trace/trace_export.c b/kernel/trace/trace_export.c index 458e5bf..d4fa5dc 100644 --- a/kernel/trace/trace_export.c +++ b/kernel/trace/trace_export.c @@ -158,7 +158,8 @@ ftrace_format_##name(struct ftrace_event_call *unused, \ BUILD_BUG_ON(len > MAX_FILTER_STR_VAL); \ ret = trace_define_field(event_call, #type "[" #len "]", #item, \ offsetof(typeof(field), item), \ - sizeof(field.item), 0, FILTER_OTHER); \ + sizeof(field.item), \ + is_signed_type(type), FILTER_OTHER); \ if (ret) \ return ret; @@ -168,8 +169,8 @@ ftrace_format_##name(struct ftrace_event_call *unused, \ ret = trace_define_field(event_call, #type "[" #len "]", #item, \ offsetof(typeof(field), \ container.item), \ - sizeof(field.container.item), 0, \ - FILTER_OTHER); \ + sizeof(field.container.item), \ + is_signed_type(type), FILTER_OTHER); \ if (ret) \ return ret; -- cgit v0.10.2 From 44214ab474671e1ab5a860954db413bce52f7e04 Mon Sep 17 00:00:00 2001 From: Rakesh Ranjan Date: Tue, 15 Dec 2009 12:19:19 +0530 Subject: [SCSI] cxgb3i: Fix a login over vlan issue Fix a target login issue, when parent interface is vlan and we are using cxgb3i sepecific private ip address in '/etc/iscsi/ifaces/' iface file. Signed-off-by: Rakesh Ranjan Acked-by: Karen Xie Signed-off-by: James Bottomley diff --git a/drivers/scsi/cxgb3i/cxgb3i_offload.c b/drivers/scsi/cxgb3i/cxgb3i_offload.c index 26ffdcd..15a00e8 100644 --- a/drivers/scsi/cxgb3i/cxgb3i_offload.c +++ b/drivers/scsi/cxgb3i/cxgb3i_offload.c @@ -1440,6 +1440,10 @@ void cxgb3i_c3cn_release(struct s3_conn *c3cn) static int is_cxgb3_dev(struct net_device *dev) { struct cxgb3i_sdev_data *cdata; + struct net_device *ndev = dev; + + if (dev->priv_flags & IFF_802_1Q_VLAN) + ndev = vlan_dev_real_dev(dev); write_lock(&cdata_rwlock); list_for_each_entry(cdata, &cdata_list, list) { @@ -1447,7 +1451,7 @@ static int is_cxgb3_dev(struct net_device *dev) int i; for (i = 0; i < ports->nports; i++) - if (dev == ports->lldevs[i]) { + if (ndev == ports->lldevs[i]) { write_unlock(&cdata_rwlock); return 1; } @@ -1566,6 +1570,26 @@ out_err: return -EINVAL; } +/** + * cxgb3i_find_dev - find the interface associated with the given address + * @ipaddr: ip address + */ +static struct net_device * +cxgb3i_find_dev(struct net_device *dev, __be32 ipaddr) +{ + struct flowi fl; + int err; + struct rtable *rt; + + memset(&fl, 0, sizeof(fl)); + fl.nl_u.ip4_u.daddr = ipaddr; + + err = ip_route_output_key(dev ? dev_net(dev) : &init_net, &rt, &fl); + if (!err) + return (&rt->u.dst)->dev; + + return NULL; +} /** * cxgb3i_c3cn_connect - initiates an iscsi tcp connection to a given address @@ -1581,6 +1605,7 @@ int cxgb3i_c3cn_connect(struct net_device *dev, struct s3_conn *c3cn, struct cxgb3i_sdev_data *cdata; struct t3cdev *cdev; __be32 sipv4; + struct net_device *dstdev; int err; c3cn_conn_debug("c3cn 0x%p, dev 0x%p.\n", c3cn, dev); @@ -1591,6 +1616,13 @@ int cxgb3i_c3cn_connect(struct net_device *dev, struct s3_conn *c3cn, c3cn->daddr.sin_port = usin->sin_port; c3cn->daddr.sin_addr.s_addr = usin->sin_addr.s_addr; + dstdev = cxgb3i_find_dev(dev, usin->sin_addr.s_addr); + if (!dstdev || !is_cxgb3_dev(dstdev)) + return -ENETUNREACH; + + if (dstdev->priv_flags & IFF_802_1Q_VLAN) + dev = dstdev; + rt = find_route(dev, c3cn->saddr.sin_addr.s_addr, c3cn->daddr.sin_addr.s_addr, c3cn->saddr.sin_port, -- cgit v0.10.2 From 3064ff39b8121acbd731f64d046218ebf3c2f9c0 Mon Sep 17 00:00:00 2001 From: Michael Hernandez Date: Tue, 15 Dec 2009 21:29:44 -0800 Subject: [SCSI] qla2xxx: Get the link data rate explicitly during device resync. When the hba port gets logged out of the fabric, or other such transitional state when the physical link is still present, the driver doesn't receive a loop up asyn event (where the link data rate currently gets set). Hence send a explicit mailbox command to get the link rate in such conditions. Signed-off-by: Giridhar Malavali Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 0b6801f..f61fb8d 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -324,6 +324,7 @@ qla2x00_read_ram_word(scsi_qla_host_t *, uint32_t, uint32_t *); extern int qla2x00_write_ram_word(scsi_qla_host_t *, uint32_t, uint32_t); +extern int qla2x00_get_data_rate(scsi_qla_host_t *); /* * Global Function Prototypes in qla_isr.c source file. */ diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 73a7935..0f7ea6c 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -2266,6 +2266,8 @@ qla2x00_configure_loop(scsi_qla_host_t *vha) clear_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); clear_bit(RSCN_UPDATE, &vha->dpc_flags); + qla2x00_get_data_rate(vha); + /* Determine what we need to do */ if (ha->current_topology == ISP_CFG_FL && (test_bit(LOCAL_LOOP_UPDATE, &flags))) { diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 05d595d..e91f3d8 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -3643,3 +3643,36 @@ qla2x00_write_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t data) return rval; } + +int +qla2x00_get_data_rate(scsi_qla_host_t *vha) +{ + int rval; + mbx_cmd_t mc; + mbx_cmd_t *mcp = &mc; + struct qla_hw_data *ha = vha->hw; + + if (!IS_FWI2_CAPABLE(ha)) + return QLA_FUNCTION_FAILED; + + DEBUG11(printk(KERN_INFO "%s(%ld): entered.\n", __func__, vha->host_no)); + + mcp->mb[0] = MBC_DATA_RATE; + mcp->mb[1] = 0; + mcp->out_mb = MBX_1|MBX_0; + mcp->in_mb = MBX_2|MBX_1|MBX_0; + mcp->tov = MBX_TOV_SECONDS; + mcp->flags = 0; + rval = qla2x00_mailbox_command(vha, mcp); + if (rval != QLA_SUCCESS) { + DEBUG2_3_11(printk(KERN_INFO "%s(%ld): failed=%x mb[0]=%x.\n", + __func__, vha->host_no, rval, mcp->mb[0])); + } else { + DEBUG11(printk(KERN_INFO + "%s(%ld): done.\n", __func__, vha->host_no)); + if (mcp->mb[1] != 0x7) + ha->link_data_rate = mcp->mb[1]; + } + + return rval; +} -- cgit v0.10.2 From 5c66f5d193f68c2a7da0f2ad3535ed30ab14307b Mon Sep 17 00:00:00 2001 From: Anirban Chakraborty Date: Tue, 15 Dec 2009 21:29:45 -0800 Subject: [SCSI] qla2xxx: Fix for a multiqueue bug in CPU affinity mode Hold the hardware lock while do the response completion in work queue threads as it involves sharing a common request queue among multiple threads. Signed-off-by: Anirban Chakraborty Signed-off-by: Giridhar Malavali Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index 2a4c7f4..b901aa2 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c @@ -639,8 +639,10 @@ static void qla_do_work(struct work_struct *work) struct rsp_que *rsp = container_of(work, struct rsp_que, q_work); struct scsi_qla_host *vha; + spin_lock_irq(&rsp->hw->hardware_lock); vha = qla25xx_get_host(rsp); qla24xx_process_response_queue(vha, rsp); + spin_unlock_irq(&rsp->hw->hardware_lock); } /* create response queue */ -- cgit v0.10.2 From 858808019313f217d63ec4ad26686e6fb7b08c19 Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Tue, 15 Dec 2009 21:29:46 -0800 Subject: [SCSI] qla2xxx: Extend base EEH support in qla2xxx. Signed-off-by: Giridhar Malavali Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 21e2bc4..3a9f5b2 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -232,6 +232,9 @@ qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj, if (off) return 0; + if (unlikely(pci_channel_offline(ha->pdev))) + return 0; + if (sscanf(buf, "%d:%x:%x", &val, &start, &size) < 1) return -EINVAL; if (start > ha->optrom_size) @@ -379,6 +382,9 @@ qla2x00_sysfs_read_vpd(struct kobject *kobj, struct device, kobj))); struct qla_hw_data *ha = vha->hw; + if (unlikely(pci_channel_offline(ha->pdev))) + return 0; + if (!capable(CAP_SYS_ADMIN)) return 0; @@ -398,6 +404,9 @@ qla2x00_sysfs_write_vpd(struct kobject *kobj, struct qla_hw_data *ha = vha->hw; uint8_t *tmp_data; + if (unlikely(pci_channel_offline(ha->pdev))) + return 0; + if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->vpd_size || !ha->isp_ops->write_nvram) return 0; @@ -1238,10 +1247,11 @@ qla2x00_fw_state_show(struct device *dev, struct device_attribute *attr, char *buf) { scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); - int rval; + int rval = QLA_FUNCTION_FAILED; uint16_t state[5]; - rval = qla2x00_get_firmware_state(vha, state); + if (!vha->hw->flags.eeh_busy) + rval = qla2x00_get_firmware_state(vha, state); if (rval != QLA_SUCCESS) memset(state, -1, sizeof(state)); @@ -1452,10 +1462,13 @@ qla2x00_dev_loss_tmo_callbk(struct fc_rport *rport) if (!fcport) return; - if (unlikely(pci_channel_offline(fcport->vha->hw->pdev))) + if (test_bit(ABORT_ISP_ACTIVE, &fcport->vha->dpc_flags)) + return; + + if (unlikely(pci_channel_offline(fcport->vha->hw->pdev))) { qla2x00_abort_all_cmds(fcport->vha, DID_NO_CONNECT << 16); - else - qla2x00_abort_fcport_cmds(fcport); + return; + } /* * Transport has effectively 'deleted' the rport, clear @@ -1475,6 +1488,9 @@ qla2x00_terminate_rport_io(struct fc_rport *rport) if (!fcport) return; + if (test_bit(ABORT_ISP_ACTIVE, &fcport->vha->dpc_flags)) + return; + if (unlikely(pci_channel_offline(fcport->vha->hw->pdev))) { qla2x00_abort_all_cmds(fcport->vha, DID_NO_CONNECT << 16); return; @@ -1515,6 +1531,12 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost) pfc_host_stat = &ha->fc_host_stat; memset(pfc_host_stat, -1, sizeof(struct fc_host_statistics)); + if (test_bit(UNLOADING, &vha->dpc_flags)) + goto done; + + if (unlikely(pci_channel_offline(ha->pdev))) + goto done; + stats = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &stats_dma); if (stats == NULL) { DEBUG2_3_11(printk("%s(%ld): Failed to allocate memory.\n", diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h index f660dd7..d6d9c86 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.h +++ b/drivers/scsi/qla2xxx/qla_dbg.h @@ -26,7 +26,7 @@ /* #define QL_DEBUG_LEVEL_14 */ /* Output RSCN trace msgs */ /* #define QL_DEBUG_LEVEL_15 */ /* Output NPIV trace msgs */ /* #define QL_DEBUG_LEVEL_16 */ /* Output ISP84XX trace msgs */ -/* #define QL_DEBUG_LEVEL_17 */ /* Output MULTI-Q trace messages */ +/* #define QL_DEBUG_LEVEL_17 */ /* Output EEH trace messages */ /* * Macros use for debugging the driver. @@ -132,6 +132,13 @@ #else #define DEBUG16(x) do {} while (0) #endif + +#if defined(QL_DEBUG_LEVEL_17) +#define DEBUG17(x) do {x;} while (0) +#else +#define DEBUG17(x) do {} while (0) +#endif + /* * Firmware Dump structure definition */ diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 384afda..608e675 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -2256,11 +2256,13 @@ struct qla_hw_data { uint32_t disable_serdes :1; uint32_t gpsc_supported :1; uint32_t npiv_supported :1; + uint32_t pci_channel_io_perm_failure :1; uint32_t fce_enabled :1; uint32_t fac_supported :1; uint32_t chip_reset_done :1; uint32_t port0 :1; uint32_t running_gold_fw :1; + uint32_t eeh_busy :1; uint32_t cpu_affinity_enabled :1; uint32_t disable_msix_handshake :1; } flags; diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 0f7ea6c..b4a0eac 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -269,6 +269,8 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha) vha->flags.online = 0; ha->flags.chip_reset_done = 0; vha->flags.reset_active = 0; + ha->flags.pci_channel_io_perm_failure = 0; + ha->flags.eeh_busy = 0; atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); atomic_set(&vha->loop_state, LOOP_DOWN); vha->device_flags = DFLG_NO_CABLE; @@ -581,6 +583,9 @@ qla2x00_reset_chip(scsi_qla_host_t *vha) uint32_t cnt; uint16_t cmd; + if (unlikely(pci_channel_offline(ha->pdev))) + return; + ha->isp_ops->disable_intrs(ha); spin_lock_irqsave(&ha->hardware_lock, flags); @@ -786,6 +791,12 @@ void qla24xx_reset_chip(scsi_qla_host_t *vha) { struct qla_hw_data *ha = vha->hw; + + if (pci_channel_offline(ha->pdev) && + ha->flags.pci_channel_io_perm_failure) { + return; + } + ha->isp_ops->disable_intrs(ha); /* Perform RISC reset. */ @@ -3562,6 +3573,13 @@ qla2x00_abort_isp(scsi_qla_host_t *vha) /* Requeue all commands in outstanding command list. */ qla2x00_abort_all_cmds(vha, DID_RESET << 16); + if (unlikely(pci_channel_offline(ha->pdev) && + ha->flags.pci_channel_io_perm_failure)) { + clear_bit(ISP_ABORT_RETRY, &vha->dpc_flags); + status = 0; + return status; + } + ha->isp_ops->get_flash_version(vha, req->ring); ha->isp_ops->nvram_config(vha); @@ -4460,6 +4478,8 @@ qla2x00_try_to_stop_firmware(scsi_qla_host_t *vha) int ret, retries; struct qla_hw_data *ha = vha->hw; + if (ha->flags.pci_channel_io_perm_failure) + return; if (!IS_FWI2_CAPABLE(ha)) return; if (!ha->fw_major_version) diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 1692a88..ffd0efd 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -152,7 +152,7 @@ qla2300_intr_handler(int irq, void *dev_id) for (iter = 50; iter--; ) { stat = RD_REG_DWORD(®->u.isp2300.host_status); if (stat & HSR_RISC_PAUSED) { - if (pci_channel_offline(ha->pdev)) + if (unlikely(pci_channel_offline(ha->pdev))) break; hccr = RD_REG_WORD(®->hccr); @@ -1846,12 +1846,15 @@ qla24xx_intr_handler(int irq, void *dev_id) reg = &ha->iobase->isp24; status = 0; + if (unlikely(pci_channel_offline(ha->pdev))) + return IRQ_HANDLED; + spin_lock_irqsave(&ha->hardware_lock, flags); vha = pci_get_drvdata(ha->pdev); for (iter = 50; iter--; ) { stat = RD_REG_DWORD(®->host_status); if (stat & HSRX_RISC_PAUSED) { - if (pci_channel_offline(ha->pdev)) + if (unlikely(pci_channel_offline(ha->pdev))) break; hccr = RD_REG_DWORD(®->hccr); @@ -1992,7 +1995,7 @@ qla24xx_msix_default(int irq, void *dev_id) do { stat = RD_REG_DWORD(®->host_status); if (stat & HSRX_RISC_PAUSED) { - if (pci_channel_offline(ha->pdev)) + if (unlikely(pci_channel_offline(ha->pdev))) break; hccr = RD_REG_DWORD(®->hccr); diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index e91f3d8..056e4d4 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -56,6 +56,12 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) DEBUG11(printk("%s(%ld): entered.\n", __func__, base_vha->host_no)); + if (ha->flags.pci_channel_io_perm_failure) { + DEBUG(printk("%s(%ld): Perm failure on EEH, timeout MBX " + "Exiting.\n", __func__, vha->host_no)); + return QLA_FUNCTION_TIMEOUT; + } + /* * Wait for active mailbox commands to finish by waiting at most tov * seconds. This is to serialize actual issuing of mailbox cmds during @@ -154,10 +160,14 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) /* Check for pending interrupts. */ qla2x00_poll(ha->rsp_q_map[0]); - if (command != MBC_LOAD_RISC_RAM_EXTENDED && - !ha->flags.mbox_int) + if (!ha->flags.mbox_int && + !(IS_QLA2200(ha) && + command == MBC_LOAD_RISC_RAM_EXTENDED)) msleep(10); } /* while */ + DEBUG17(qla_printk(KERN_WARNING, ha, + "Waited %d sec\n", + (uint)((jiffies - (wait_time - (mcp->tov * HZ)))/HZ))); } /* Check whether we timed out */ @@ -227,7 +237,8 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) if (rval == QLA_FUNCTION_TIMEOUT && mcp->mb[0] != MBC_GEN_SYSTEM_ERROR) { - if (!io_lock_on || (mcp->flags & IOCTL_CMD)) { + if (!io_lock_on || (mcp->flags & IOCTL_CMD) || + ha->flags.eeh_busy) { /* not in dpc. schedule it for dpc to take over. */ DEBUG(printk("%s(%ld): timeout schedule " "isp_abort_needed.\n", __func__, @@ -237,7 +248,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) base_vha->host_no)); qla_printk(KERN_WARNING, ha, "Mailbox command timeout occurred. Scheduling ISP " - "abort.\n"); + "abort. eeh_busy: 0x%x\n", ha->flags.eeh_busy); set_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags); qla2xxx_wake_dpc(vha); } else if (!abort_active) { @@ -2530,6 +2541,9 @@ qla2x00_enable_eft_trace(scsi_qla_host_t *vha, dma_addr_t eft_dma, if (!IS_FWI2_CAPABLE(vha->hw)) return QLA_FUNCTION_FAILED; + if (unlikely(pci_channel_offline(vha->hw->pdev))) + return QLA_FUNCTION_FAILED; + DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); mcp->mb[0] = MBC_TRACE_CONTROL; @@ -2565,6 +2579,9 @@ qla2x00_disable_eft_trace(scsi_qla_host_t *vha) if (!IS_FWI2_CAPABLE(vha->hw)) return QLA_FUNCTION_FAILED; + if (unlikely(pci_channel_offline(vha->hw->pdev))) + return QLA_FUNCTION_FAILED; + DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); mcp->mb[0] = MBC_TRACE_CONTROL; @@ -2595,6 +2612,9 @@ qla2x00_enable_fce_trace(scsi_qla_host_t *vha, dma_addr_t fce_dma, if (!IS_QLA25XX(vha->hw) && !IS_QLA81XX(vha->hw)) return QLA_FUNCTION_FAILED; + if (unlikely(pci_channel_offline(vha->hw->pdev))) + return QLA_FUNCTION_FAILED; + DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); mcp->mb[0] = MBC_TRACE_CONTROL; @@ -2639,6 +2659,9 @@ qla2x00_disable_fce_trace(scsi_qla_host_t *vha, uint64_t *wr, uint64_t *rd) if (!IS_FWI2_CAPABLE(vha->hw)) return QLA_FUNCTION_FAILED; + if (unlikely(pci_channel_offline(vha->hw->pdev))) + return QLA_FUNCTION_FAILED; + DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); mcp->mb[0] = MBC_TRACE_CONTROL; diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 2f873d2..1ab3582 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -475,11 +475,11 @@ qla2xxx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) srb_t *sp; int rval; - if (unlikely(pci_channel_offline(ha->pdev))) { - if (ha->pdev->error_state == pci_channel_io_frozen) - cmd->result = DID_REQUEUE << 16; - else + if (ha->flags.eeh_busy) { + if (ha->flags.pci_channel_io_perm_failure) cmd->result = DID_NO_CONNECT << 16; + else + cmd->result = DID_REQUEUE << 16; goto qc24_fail_command; } @@ -552,8 +552,15 @@ qla2x00_eh_wait_on_command(struct scsi_cmnd *cmd) #define ABORT_POLLING_PERIOD 1000 #define ABORT_WAIT_ITER ((10 * 1000) / (ABORT_POLLING_PERIOD)) unsigned long wait_iter = ABORT_WAIT_ITER; + scsi_qla_host_t *vha = shost_priv(cmd->device->host); + struct qla_hw_data *ha = vha->hw; int ret = QLA_SUCCESS; + if (unlikely(pci_channel_offline(ha->pdev)) || ha->flags.eeh_busy) { + DEBUG17(qla_printk(KERN_WARNING, ha, "return:eh_wait\n")); + return ret; + } + while (CMD_SP(cmd) && wait_iter--) { msleep(ABORT_POLLING_PERIOD); } @@ -2174,6 +2181,24 @@ qla2x00_free_device(scsi_qla_host_t *vha) { struct qla_hw_data *ha = vha->hw; + qla2x00_abort_all_cmds(vha, DID_NO_CONNECT << 16); + + /* Disable timer */ + if (vha->timer_active) + qla2x00_stop_timer(vha); + + /* Kill the kernel thread for this host */ + if (ha->dpc_thread) { + struct task_struct *t = ha->dpc_thread; + + /* + * qla2xxx_wake_dpc checks for ->dpc_thread + * so we need to zero it out. + */ + ha->dpc_thread = NULL; + kthread_stop(t); + } + qla25xx_delete_queues(vha); if (ha->flags.fce_enabled) @@ -2185,6 +2210,8 @@ qla2x00_free_device(scsi_qla_host_t *vha) /* Stop currently executing firmware. */ qla2x00_try_to_stop_firmware(vha); + vha->flags.online = 0; + /* turn-off interrupts on the card */ if (ha->interrupts_on) ha->isp_ops->disable_intrs(ha); @@ -2859,6 +2886,13 @@ qla2x00_do_dpc(void *data) if (!base_vha->flags.init_done) continue; + if (ha->flags.eeh_busy) { + DEBUG17(qla_printk(KERN_WARNING, ha, + "qla2x00_do_dpc: dpc_flags: %lx\n", + base_vha->dpc_flags)); + continue; + } + DEBUG3(printk("scsi(%ld): DPC handler\n", base_vha->host_no)); ha->dpc_active = 1; @@ -3049,8 +3083,13 @@ qla2x00_timer(scsi_qla_host_t *vha) int index; srb_t *sp; int t; + uint16_t w; struct qla_hw_data *ha = vha->hw; struct req_que *req; + + /* Hardware read to raise pending EEH errors during mailbox waits. */ + if (!pci_channel_offline(ha->pdev)) + pci_read_config_word(ha->pdev, PCI_VENDOR_ID, &w); /* * Ports - Port down timer. * @@ -3252,16 +3291,23 @@ qla2x00_release_firmware(void) static pci_ers_result_t qla2xxx_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state) { - scsi_qla_host_t *base_vha = pci_get_drvdata(pdev); + scsi_qla_host_t *vha = pci_get_drvdata(pdev); + struct qla_hw_data *ha = vha->hw; + + DEBUG2(qla_printk(KERN_WARNING, ha, "error_detected:state %x\n", + state)); switch (state) { case pci_channel_io_normal: + ha->flags.eeh_busy = 0; return PCI_ERS_RESULT_CAN_RECOVER; case pci_channel_io_frozen: + ha->flags.eeh_busy = 1; pci_disable_device(pdev); return PCI_ERS_RESULT_NEED_RESET; case pci_channel_io_perm_failure: - qla2x00_abort_all_cmds(base_vha, DID_NO_CONNECT << 16); + ha->flags.pci_channel_io_perm_failure = 1; + qla2x00_abort_all_cmds(vha, DID_NO_CONNECT << 16); return PCI_ERS_RESULT_DISCONNECT; } return PCI_ERS_RESULT_NEED_RESET; @@ -3312,6 +3358,8 @@ qla2xxx_pci_slot_reset(struct pci_dev *pdev) struct qla_hw_data *ha = base_vha->hw; int rc; + DEBUG17(qla_printk(KERN_WARNING, ha, "slot_reset\n")); + if (ha->mem_only) rc = pci_enable_device_mem(pdev); else @@ -3320,19 +3368,33 @@ qla2xxx_pci_slot_reset(struct pci_dev *pdev) if (rc) { qla_printk(KERN_WARNING, ha, "Can't re-enable PCI device after reset.\n"); - return ret; } - pci_set_master(pdev); if (ha->isp_ops->pci_config(base_vha)) return ret; +#ifdef QL_DEBUG_LEVEL_17 + { + uint8_t b; + uint32_t i; + + printk("slot_reset_1: "); + for (i = 0; i < 256; i++) { + pci_read_config_byte(ha->pdev, i, &b); + printk("%s%02x", (i%16) ? " " : "\n", b); + } + printk("\n"); + } +#endif set_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags); if (qla2x00_abort_isp(base_vha) == QLA_SUCCESS) ret = PCI_ERS_RESULT_RECOVERED; clear_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags); + DEBUG17(qla_printk(KERN_WARNING, ha, + "slot_reset-return:ret=%x\n", ret)); + return ret; } @@ -3343,12 +3405,17 @@ qla2xxx_pci_resume(struct pci_dev *pdev) struct qla_hw_data *ha = base_vha->hw; int ret; + DEBUG17(qla_printk(KERN_WARNING, ha, "pci_resume\n")); + ret = qla2x00_wait_for_hba_online(base_vha); if (ret != QLA_SUCCESS) { qla_printk(KERN_ERR, ha, "the device failed to resume I/O " "from slot/link_reset"); } + + ha->flags.eeh_busy = 0; + pci_cleanup_aer_uncorrect_error_status(pdev); } -- cgit v0.10.2 From ca79cf664806d833e28c8c05824b2361f59b8bc8 Mon Sep 17 00:00:00 2001 From: Duane Grigsby Date: Tue, 15 Dec 2009 21:29:47 -0800 Subject: [SCSI] qla2xxx: Added to EEH support. Added fundamental reset and pci save state. Signed-off-by: Giridhar Malavali Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 1ab3582..209f50e 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -1817,6 +1817,13 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) /* Set ISP-type information. */ qla2x00_set_isp_flags(ha); + + /* Set EEH reset type to fundamental if required by hba */ + if ( IS_QLA24XX(ha) || IS_QLA25XX(ha) || IS_QLA81XX(ha)) { + pdev->needs_freset = 1; + pci_save_state(pdev); + } + /* Configure PCI I/O space */ ret = qla2x00_iospace_config(ha); if (ret) -- cgit v0.10.2 From 3b9c212a5cbb1e13ced92639ce83f7a48b8b2331 Mon Sep 17 00:00:00 2001 From: Giridhar Malavali Date: Tue, 15 Dec 2009 21:29:48 -0800 Subject: [SCSI] qla2xxx: Update version number to 8.03.01-k9. Signed-off-by: Giridhar Malavali Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index c482220..a65dd95 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h @@ -7,7 +7,7 @@ /* * Driver version */ -#define QLA2XXX_VERSION "8.03.01-k8" +#define QLA2XXX_VERSION "8.03.01-k9" #define QLA_DRIVER_MAJOR_VER 8 #define QLA_DRIVER_MINOR_VER 3 -- cgit v0.10.2 From a70757ba9a3719f99760713c3b72134b21016c6e Mon Sep 17 00:00:00 2001 From: Anil Ravindranath Date: Thu, 17 Dec 2009 14:51:53 -0800 Subject: [SCSI] pmcraid: fix to avoid twice scsi_dma_unmap for a command For a particular driver error condition, driver was doing double scsi_dma_unmaps. Driver was calling scsi_dma_unmap in pmcraid_error_handler and return 0. This pmcraid_error_handler is called by pmcraid_io_done which will do scsi_dma_unmap again when it has return 0 from pmcraid_error_handler. Signed-off-by: James Bottomley diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c index e7d2688..b6f1ef9 100644 --- a/drivers/scsi/pmcraid.c +++ b/drivers/scsi/pmcraid.c @@ -2483,14 +2483,12 @@ static int pmcraid_error_handler(struct pmcraid_cmd *cmd) sense_copied = 1; } - if (RES_IS_GSCSI(res->cfg_entry)) { + if (RES_IS_GSCSI(res->cfg_entry)) pmcraid_cancel_all(cmd, sense_copied); - } else if (sense_copied) { + else if (sense_copied) pmcraid_erp_done(cmd); - return 0; - } else { + else pmcraid_request_sense(cmd); - } return 1; -- cgit v0.10.2 From 0637c6f4135f592f094207c7c21e7c0fc5557834 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Wed, 30 Dec 2009 14:20:45 -0500 Subject: ext4: Patch up how we claim metadata blocks for quota purposes As reported in Kernel Bugzilla #14936, commit d21cd8f triggered a BUG in the function ext4_da_update_reserve_space() found in fs/ext4/inode.c. The root cause of this BUG() was caused by the fact that ext4_calc_metadata_amount() can severely over-estimate how many metadata blocks will be needed, especially when using direct block-mapped files. In addition, it can also badly *under* estimate how much space is needed, since ext4_calc_metadata_amount() assumes that the blocks are contiguous, and this is not always true. If the application is writing blocks to a sparse file, the number of metadata blocks necessary can be severly underestimated by the functions ext4_da_reserve_space(), ext4_da_update_reserve_space() and ext4_da_release_space(). This was the cause of the dq_claim_space reports found on kerneloops.org. Unfortunately, doing this right means that we need to massively over-estimate the amount of free space needed. So in some cases we may need to force the inode to be written to disk asynchronously in to avoid spurious quota failures. http://bugzilla.kernel.org/show_bug.cgi?id=14936 Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 3e3b454..84eeb8f 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -1043,43 +1043,47 @@ static int ext4_calc_metadata_amount(struct inode *inode, int blocks) return ext4_indirect_calc_metadata_amount(inode, blocks); } +/* + * Called with i_data_sem down, which is important since we can call + * ext4_discard_preallocations() from here. + */ static void ext4_da_update_reserve_space(struct inode *inode, int used) { struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); - int total, mdb, mdb_free, mdb_claim = 0; - - spin_lock(&EXT4_I(inode)->i_block_reservation_lock); - /* recalculate the number of metablocks still need to be reserved */ - total = EXT4_I(inode)->i_reserved_data_blocks - used; - mdb = ext4_calc_metadata_amount(inode, total); - - /* figure out how many metablocks to release */ - BUG_ON(mdb > EXT4_I(inode)->i_reserved_meta_blocks); - mdb_free = EXT4_I(inode)->i_reserved_meta_blocks - mdb; - - if (mdb_free) { - /* Account for allocated meta_blocks */ - mdb_claim = EXT4_I(inode)->i_allocated_meta_blocks; - BUG_ON(mdb_free < mdb_claim); - mdb_free -= mdb_claim; - - /* update fs dirty blocks counter */ + struct ext4_inode_info *ei = EXT4_I(inode); + int mdb_free = 0; + + spin_lock(&ei->i_block_reservation_lock); + if (unlikely(used > ei->i_reserved_data_blocks)) { + ext4_msg(inode->i_sb, KERN_NOTICE, "%s: ino %lu, used %d " + "with only %d reserved data blocks\n", + __func__, inode->i_ino, used, + ei->i_reserved_data_blocks); + WARN_ON(1); + used = ei->i_reserved_data_blocks; + } + + /* Update per-inode reservations */ + ei->i_reserved_data_blocks -= used; + used += ei->i_allocated_meta_blocks; + ei->i_reserved_meta_blocks -= ei->i_allocated_meta_blocks; + ei->i_allocated_meta_blocks = 0; + percpu_counter_sub(&sbi->s_dirtyblocks_counter, used); + + if (ei->i_reserved_data_blocks == 0) { + /* + * We can release all of the reserved metadata blocks + * only when we have written all of the delayed + * allocation blocks. + */ + mdb_free = ei->i_allocated_meta_blocks; percpu_counter_sub(&sbi->s_dirtyblocks_counter, mdb_free); - EXT4_I(inode)->i_allocated_meta_blocks = 0; - EXT4_I(inode)->i_reserved_meta_blocks = mdb; + ei->i_allocated_meta_blocks = 0; } - - /* update per-inode reservations */ - BUG_ON(used > EXT4_I(inode)->i_reserved_data_blocks); - EXT4_I(inode)->i_reserved_data_blocks -= used; - percpu_counter_sub(&sbi->s_dirtyblocks_counter, used + mdb_claim); spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); - vfs_dq_claim_block(inode, used + mdb_claim); - - /* - * free those over-booking quota for metadata blocks - */ + /* Update quota subsystem */ + vfs_dq_claim_block(inode, used); if (mdb_free) vfs_dq_release_reservation_block(inode, mdb_free); @@ -1088,7 +1092,8 @@ static void ext4_da_update_reserve_space(struct inode *inode, int used) * there aren't any writers on the inode, we can discard the * inode's preallocations. */ - if (!total && (atomic_read(&inode->i_writecount) == 0)) + if ((ei->i_reserved_data_blocks == 0) && + (atomic_read(&inode->i_writecount) == 0)) ext4_discard_preallocations(inode); } @@ -1801,7 +1806,8 @@ static int ext4_da_reserve_space(struct inode *inode, int nrblocks) { int retries = 0; struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); - unsigned long md_needed, mdblocks, total = 0; + struct ext4_inode_info *ei = EXT4_I(inode); + unsigned long md_needed, md_reserved, total = 0; /* * recalculate the amount of metadata blocks to reserve @@ -1809,35 +1815,44 @@ static int ext4_da_reserve_space(struct inode *inode, int nrblocks) * worse case is one extent per block */ repeat: - spin_lock(&EXT4_I(inode)->i_block_reservation_lock); - total = EXT4_I(inode)->i_reserved_data_blocks + nrblocks; - mdblocks = ext4_calc_metadata_amount(inode, total); - BUG_ON(mdblocks < EXT4_I(inode)->i_reserved_meta_blocks); - - md_needed = mdblocks - EXT4_I(inode)->i_reserved_meta_blocks; + spin_lock(&ei->i_block_reservation_lock); + md_reserved = ei->i_reserved_meta_blocks; + md_needed = ext4_calc_metadata_amount(inode, nrblocks); total = md_needed + nrblocks; - spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); + spin_unlock(&ei->i_block_reservation_lock); /* * Make quota reservation here to prevent quota overflow * later. Real quota accounting is done at pages writeout * time. */ - if (vfs_dq_reserve_block(inode, total)) + if (vfs_dq_reserve_block(inode, total)) { + /* + * We tend to badly over-estimate the amount of + * metadata blocks which are needed, so if we have + * reserved any metadata blocks, try to force out the + * inode and see if we have any better luck. + */ + if (md_reserved && retries++ <= 3) + goto retry; return -EDQUOT; + } if (ext4_claim_free_blocks(sbi, total)) { vfs_dq_release_reservation_block(inode, total); if (ext4_should_retry_alloc(inode->i_sb, &retries)) { + retry: + if (md_reserved) + write_inode_now(inode, (retries == 3)); yield(); goto repeat; } return -ENOSPC; } - spin_lock(&EXT4_I(inode)->i_block_reservation_lock); - EXT4_I(inode)->i_reserved_data_blocks += nrblocks; - EXT4_I(inode)->i_reserved_meta_blocks += md_needed; - spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); + spin_lock(&ei->i_block_reservation_lock); + ei->i_reserved_data_blocks += nrblocks; + ei->i_reserved_meta_blocks += md_needed; + spin_unlock(&ei->i_block_reservation_lock); return 0; /* success */ } @@ -1845,49 +1860,45 @@ repeat: static void ext4_da_release_space(struct inode *inode, int to_free) { struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); - int total, mdb, mdb_free, release; + struct ext4_inode_info *ei = EXT4_I(inode); if (!to_free) return; /* Nothing to release, exit */ spin_lock(&EXT4_I(inode)->i_block_reservation_lock); - if (!EXT4_I(inode)->i_reserved_data_blocks) { + if (unlikely(to_free > ei->i_reserved_data_blocks)) { /* - * if there is no reserved blocks, but we try to free some - * then the counter is messed up somewhere. - * but since this function is called from invalidate - * page, it's harmless to return without any action + * if there aren't enough reserved blocks, then the + * counter is messed up somewhere. Since this + * function is called from invalidate page, it's + * harmless to return without any action. */ - printk(KERN_INFO "ext4 delalloc try to release %d reserved " - "blocks for inode %lu, but there is no reserved " - "data blocks\n", to_free, inode->i_ino); - spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); - return; + ext4_msg(inode->i_sb, KERN_NOTICE, "ext4_da_release_space: " + "ino %lu, to_free %d with only %d reserved " + "data blocks\n", inode->i_ino, to_free, + ei->i_reserved_data_blocks); + WARN_ON(1); + to_free = ei->i_reserved_data_blocks; } + ei->i_reserved_data_blocks -= to_free; - /* recalculate the number of metablocks still need to be reserved */ - total = EXT4_I(inode)->i_reserved_data_blocks - to_free; - mdb = ext4_calc_metadata_amount(inode, total); - - /* figure out how many metablocks to release */ - BUG_ON(mdb > EXT4_I(inode)->i_reserved_meta_blocks); - mdb_free = EXT4_I(inode)->i_reserved_meta_blocks - mdb; - - release = to_free + mdb_free; - - /* update fs dirty blocks counter for truncate case */ - percpu_counter_sub(&sbi->s_dirtyblocks_counter, release); + if (ei->i_reserved_data_blocks == 0) { + /* + * We can release all of the reserved metadata blocks + * only when we have written all of the delayed + * allocation blocks. + */ + to_free += ei->i_allocated_meta_blocks; + ei->i_allocated_meta_blocks = 0; + } - /* update per-inode reservations */ - BUG_ON(to_free > EXT4_I(inode)->i_reserved_data_blocks); - EXT4_I(inode)->i_reserved_data_blocks -= to_free; + /* update fs dirty blocks counter */ + percpu_counter_sub(&sbi->s_dirtyblocks_counter, to_free); - BUG_ON(mdb > EXT4_I(inode)->i_reserved_meta_blocks); - EXT4_I(inode)->i_reserved_meta_blocks = mdb; spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); - vfs_dq_release_reservation_block(inode, release); + vfs_dq_release_reservation_block(inode, to_free); } static void ext4_da_page_release_reservation(struct page *page, -- cgit v0.10.2 From c2b27ef672992a206e5b221b8676972dd840ffa5 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 30 Dec 2009 12:18:24 -0800 Subject: Input: iforce - wait for command completion when closing the device We need to wait for the command to disable FF effects to complete before continuing with closing the device. Tested-by: Johannes Ebke Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c index acc3a9e..b1edd77 100644 --- a/drivers/input/joystick/iforce/iforce-main.c +++ b/drivers/input/joystick/iforce/iforce-main.c @@ -228,6 +228,9 @@ static void iforce_close(struct input_dev *dev) /* Disable force feedback playback */ iforce_send_packet(iforce, FF_CMD_ENABLE, "\001"); + /* Wait for the command to complete */ + wait_event_interruptible(iforce->wait, + !test_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags)); } switch (iforce->bus) { diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c index c0ad883..b41303d 100644 --- a/drivers/input/joystick/iforce/iforce-usb.c +++ b/drivers/input/joystick/iforce/iforce-usb.c @@ -109,6 +109,7 @@ static void iforce_usb_out(struct urb *urb) struct iforce *iforce = urb->context; if (urb->status) { + clear_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags); dbg("urb->status %d, exiting", urb->status); return; } -- cgit v0.10.2 From 75c85a0bc13367aabb36e8208d4e373b022b43b3 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Wed, 30 Dec 2009 13:21:06 -0600 Subject: libsrp: fix compile failure commit 45465487897a1c6d508b14b904dc5777f7ec7e04 ("kfifo: move struct kfifo in place") caused a compile failure in ibmvscsitgt.c because it changed a pointer to kfifo in the libsrp.h structure to a direct inclusion without including . The fix is simple, just add the include, but how did this happen? This change, introduced at -rc2, hardly looks like a bug fix, and it clearly didn't go through linux-next, which would have picked up this compile failure (it only occurs on ppc because of the ibm virtual scsi target). [ Apparently all of -mm wasn't in linux-next.. ] Signed-off-by: James Bottomley Signed-off-by: Linus Torvalds diff --git a/include/scsi/libsrp.h b/include/scsi/libsrp.h index 07e3add..f4105c9 100644 --- a/include/scsi/libsrp.h +++ b/include/scsi/libsrp.h @@ -2,6 +2,7 @@ #define __LIBSRP_H__ #include +#include #include #include #include -- cgit v0.10.2 From 66f0dc481e5b802ab363b979fc1753410c7d82b5 Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Wed, 30 Dec 2009 20:17:34 +0000 Subject: mm: move sys_mmap_pgoff from util.c Move sys_mmap_pgoff() from mm/util.c to mm/mmap.c and mm/nommu.c, where we'd expect to find such code: especially now that it contains the MAP_HUGETLB handling. Revert mm/util.c to how it was in 2.6.32. This patch just ignores MAP_HUGETLB in the nommu case, as in 2.6.32, whereas 2.6.33-rc2 reported -ENOSYS. Perhaps validate_mmap_request() should reject it with -EINVAL? Add that later if necessary. Signed-off-by: Hugh Dickins Signed-off-by: Linus Torvalds diff --git a/mm/mmap.c b/mm/mmap.c index d9c77b2..ee22989 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -1043,6 +1043,46 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, } EXPORT_SYMBOL(do_mmap_pgoff); +SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len, + unsigned long, prot, unsigned long, flags, + unsigned long, fd, unsigned long, pgoff) +{ + struct file *file = NULL; + unsigned long retval = -EBADF; + + if (!(flags & MAP_ANONYMOUS)) { + if (unlikely(flags & MAP_HUGETLB)) + return -EINVAL; + file = fget(fd); + if (!file) + goto out; + } else if (flags & MAP_HUGETLB) { + struct user_struct *user = NULL; + /* + * VM_NORESERVE is used because the reservations will be + * taken when vm_ops->mmap() is called + * A dummy user value is used because we are not locking + * memory so no accounting is necessary + */ + len = ALIGN(len, huge_page_size(&default_hstate)); + file = hugetlb_file_setup(HUGETLB_ANON_FILE, len, VM_NORESERVE, + &user, HUGETLB_ANONHUGE_INODE); + if (IS_ERR(file)) + return PTR_ERR(file); + } + + flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); + + down_write(¤t->mm->mmap_sem); + retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); + up_write(¤t->mm->mmap_sem); + + if (file) + fput(file); +out: + return retval; +} + /* * Some shared mappigns will want the pages marked read-only * to track write events. If so, we'll downgrade vm_page_prot diff --git a/mm/nommu.c b/mm/nommu.c index 8687973..6f9248f 100644 --- a/mm/nommu.c +++ b/mm/nommu.c @@ -1398,6 +1398,31 @@ error_getting_region: } EXPORT_SYMBOL(do_mmap_pgoff); +SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len, + unsigned long, prot, unsigned long, flags, + unsigned long, fd, unsigned long, pgoff) +{ + struct file *file = NULL; + unsigned long retval = -EBADF; + + if (!(flags & MAP_ANONYMOUS)) { + file = fget(fd); + if (!file) + goto out; + } + + flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); + + down_write(¤t->mm->mmap_sem); + retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); + up_write(¤t->mm->mmap_sem); + + if (file) + fput(file); +out: + return retval; +} + /* * split a vma into two pieces at address 'addr', a new vma is allocated either * for the first part or the tail. diff --git a/mm/util.c b/mm/util.c index b377ce4..7c35ad9 100644 --- a/mm/util.c +++ b/mm/util.c @@ -4,10 +4,6 @@ #include #include #include -#include -#include -#include -#include #include #define CREATE_TRACE_POINTS @@ -272,46 +268,6 @@ int __attribute__((weak)) get_user_pages_fast(unsigned long start, } EXPORT_SYMBOL_GPL(get_user_pages_fast); -SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len, - unsigned long, prot, unsigned long, flags, - unsigned long, fd, unsigned long, pgoff) -{ - struct file * file = NULL; - unsigned long retval = -EBADF; - - if (!(flags & MAP_ANONYMOUS)) { - if (unlikely(flags & MAP_HUGETLB)) - return -EINVAL; - file = fget(fd); - if (!file) - goto out; - } else if (flags & MAP_HUGETLB) { - struct user_struct *user = NULL; - /* - * VM_NORESERVE is used because the reservations will be - * taken when vm_ops->mmap() is called - * A dummy user value is used because we are not locking - * memory so no accounting is necessary - */ - len = ALIGN(len, huge_page_size(&default_hstate)); - file = hugetlb_file_setup(HUGETLB_ANON_FILE, len, VM_NORESERVE, - &user, HUGETLB_ANONHUGE_INODE); - if (IS_ERR(file)) - return PTR_ERR(file); - } - - flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); - - down_write(¤t->mm->mmap_sem); - retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); - up_write(¤t->mm->mmap_sem); - - if (file) - fput(file); -out: - return retval; -} - /* Tracepoints definitions. */ EXPORT_TRACEPOINT_SYMBOL(kmalloc); EXPORT_TRACEPOINT_SYMBOL(kmem_cache_alloc); -- cgit v0.10.2 From 9a7262a0563da6b91019156abf487bcdf1a41526 Mon Sep 17 00:00:00 2001 From: Mike Travis Date: Mon, 28 Dec 2009 13:28:25 -0800 Subject: x86_64 SGI UV: Fix writes to led registers on remote uv hubs. The wrong address was being used to write the SCIR led regs on remote hubs. Also, there was an inconsistency between how BIOS and the kernel indexed these regs. Standardize on using the lower 6 bits of the APIC ID as the index. This patch fixes the problem of writing to an errant address to a cpu # >= 64. Signed-off-by: Mike Travis Reviewed-by: Jack Steiner Cc: stable@kernel.org Signed-off-by: Linus Torvalds diff --git a/arch/x86/include/asm/uv/uv_hub.h b/arch/x86/include/asm/uv/uv_hub.h index 811bfab..bcdb708 100644 --- a/arch/x86/include/asm/uv/uv_hub.h +++ b/arch/x86/include/asm/uv/uv_hub.h @@ -338,6 +338,18 @@ static inline unsigned long uv_global_gru_mmr_address(int pnode, unsigned long o return UV_GLOBAL_GRU_MMR_BASE | offset | (pnode << uv_hub_info->m_val); } +static inline void uv_write_global_mmr8(int pnode, unsigned long offset, + unsigned char val) +{ + writeb(val, uv_global_mmr64_address(pnode, offset)); +} + +static inline unsigned char uv_read_global_mmr8(int pnode, + unsigned long offset) +{ + return readb(uv_global_mmr64_address(pnode, offset)); +} + /* * Access hub local MMRs. Faster than using global space but only local MMRs * are accessible. @@ -457,11 +469,17 @@ static inline void uv_set_scir_bits(unsigned char value) } } +static inline unsigned long uv_scir_offset(int apicid) +{ + return SCIR_LOCAL_MMR_BASE | (apicid & 0x3f); +} + static inline void uv_set_cpu_scir_bits(int cpu, unsigned char value) { if (uv_cpu_hub_info(cpu)->scir.state != value) { + uv_write_global_mmr8(uv_cpu_to_pnode(cpu), + uv_cpu_hub_info(cpu)->scir.offset, value); uv_cpu_hub_info(cpu)->scir.state = value; - uv_write_local_mmr8(uv_cpu_hub_info(cpu)->scir.offset, value); } } diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index d56b0ef..5f92494 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c @@ -629,8 +629,10 @@ void __init uv_system_init(void) uv_rtc_init(); for_each_present_cpu(cpu) { + int apicid = per_cpu(x86_cpu_to_apicid, cpu); + nid = cpu_to_node(cpu); - pnode = uv_apicid_to_pnode(per_cpu(x86_cpu_to_apicid, cpu)); + pnode = uv_apicid_to_pnode(apicid); blade = boot_pnode_to_blade(pnode); lcpu = uv_blade_info[blade].nr_possible_cpus; uv_blade_info[blade].nr_possible_cpus++; @@ -651,15 +653,13 @@ void __init uv_system_init(void) uv_cpu_hub_info(cpu)->gnode_extra = gnode_extra; uv_cpu_hub_info(cpu)->global_mmr_base = mmr_base; uv_cpu_hub_info(cpu)->coherency_domain_number = sn_coherency_id; - uv_cpu_hub_info(cpu)->scir.offset = SCIR_LOCAL_MMR_BASE + lcpu; + uv_cpu_hub_info(cpu)->scir.offset = uv_scir_offset(apicid); uv_node_to_blade[nid] = blade; uv_cpu_to_blade[cpu] = blade; max_pnode = max(pnode, max_pnode); - printk(KERN_DEBUG "UV: cpu %d, apicid 0x%x, pnode %d, nid %d, " - "lcpu %d, blade %d\n", - cpu, per_cpu(x86_cpu_to_apicid, cpu), pnode, nid, - lcpu, blade); + printk(KERN_DEBUG "UV: cpu %d, apicid 0x%x, pnode %d, nid %d, lcpu %d, blade %d\n", + cpu, apicid, pnode, nid, lcpu, blade); } /* Add blade/pnode info for nodes without cpus */ -- cgit v0.10.2 From 7ea6600148c265b1fd53e521022b1d7aec81d974 Mon Sep 17 00:00:00 2001 From: "Serge E. Hallyn" Date: Tue, 29 Dec 2009 14:50:19 -0600 Subject: generic_permission: MAY_OPEN is not write access generic_permission was refusing CAP_DAC_READ_SEARCH-enabled processes from opening DAC-protected files read-only, because do_filp_open adds MAY_OPEN to the open mask. Ignore MAY_OPEN. After this patch, CAP_DAC_READ_SEARCH is again sufficient to open(fname, O_RDONLY) on a file to which DAC otherwise refuses us read permission. Reported-by: Mike Kazantsev Signed-off-by: Serge E. Hallyn Tested-by: Mike Kazantsev Signed-off-by: Linus Torvalds diff --git a/fs/namei.c b/fs/namei.c index 68921d9..b55440b 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -232,6 +232,7 @@ int generic_permission(struct inode *inode, int mask, /* * Searching includes executable on directories, else just read. */ + mask &= MAY_READ | MAY_WRITE | MAY_EXEC; if (mask == MAY_READ || (S_ISDIR(inode->i_mode) && !(mask & MAY_WRITE))) if (capable(CAP_DAC_READ_SEARCH)) return 0; -- cgit v0.10.2 From b58454ec25e80fdb84e294758aeb22dd6d5ee6f9 Mon Sep 17 00:00:00 2001 From: Paul Rolland Date: Wed, 30 Dec 2009 01:19:12 -0500 Subject: wmi: check find_guid() return value to prevent oops Signed-off-by: rol@as2917.net Signed-off-by: Len Brown Signed-off-by: Linus Torvalds diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c index 9f93d6c..cc9ad74 100644 --- a/drivers/platform/x86/wmi.c +++ b/drivers/platform/x86/wmi.c @@ -492,8 +492,7 @@ wmi_notify_handler handler, void *data) if (!guid || !handler) return AE_BAD_PARAMETER; - find_guid(guid, &block); - if (!block) + if (!find_guid(guid, &block)) return AE_NOT_EXIST; if (block->handler) @@ -521,8 +520,7 @@ acpi_status wmi_remove_notify_handler(const char *guid) if (!guid) return AE_BAD_PARAMETER; - find_guid(guid, &block); - if (!block) + if (!find_guid(guid, &block)) return AE_NOT_EXIST; if (!block->handler) -- cgit v0.10.2 From 5ccf73bb4dc7cc9e1f761202a34de5714164724f Mon Sep 17 00:00:00 2001 From: Len Brown Date: Wed, 30 Dec 2009 01:21:42 -0500 Subject: dell-wmi: sys_init_module: 'dell_wmi'->init suspiciously returned 21, it should follow 0/-E convention wmi_install_notify_handler() returns an acpi_error, but dell_wmi_init() needs return a -errno style error. Signed-off-by: Len Brown Tested-by: Paul Rolland Signed-off-by: Linus Torvalds diff --git a/drivers/platform/x86/dell-wmi.c b/drivers/platform/x86/dell-wmi.c index 916ccb2..4c7e702 100644 --- a/drivers/platform/x86/dell-wmi.c +++ b/drivers/platform/x86/dell-wmi.c @@ -323,6 +323,7 @@ static int __init dell_wmi_input_setup(void) static int __init dell_wmi_init(void) { int err; + acpi_status status; if (wmi_has_guid(DELL_EVENT_GUID)) { printk(KERN_WARNING "dell-wmi: No known WMI GUID found\n"); @@ -336,14 +337,14 @@ static int __init dell_wmi_init(void) if (err) return err; - err = wmi_install_notify_handler(DELL_EVENT_GUID, + status = wmi_install_notify_handler(DELL_EVENT_GUID, dell_wmi_notify, NULL); - if (err) { + if (ACPI_FAILURE(status)) { input_unregister_device(dell_wmi_input_dev); printk(KERN_ERR "dell-wmi: Unable to register notify handler - %d\n", - err); - return err; + status); + return -ENODEV; } return 0; -- cgit v0.10.2 From ed656d8deccc5669afa33387568e7ec6f14e3e94 Mon Sep 17 00:00:00 2001 From: Rolf Eike Beer Date: Sat, 26 Dec 2009 17:58:11 +0100 Subject: kfifo: Fix typo in comment It's DECLARE_KFIFO, not DECLARED_KFIFO. Signed-off-by: Rolf Eike Beer Signed-off-by: Linus Torvalds diff --git a/include/linux/kfifo.h b/include/linux/kfifo.h index 3d44e9c..7c6b32a1 100644 --- a/include/linux/kfifo.h +++ b/include/linux/kfifo.h @@ -81,7 +81,7 @@ union { \ } /** - * INIT_KFIFO - Initialize a kfifo declared by DECLARED_KFIFO + * INIT_KFIFO - Initialize a kfifo declared by DECLARE_KFIFO * @name: name of the declared kfifo datatype */ #define INIT_KFIFO(name) \ -- cgit v0.10.2 From d7f0eea9e431e1b8b0742a74db1a9490730b2a25 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Wed, 30 Dec 2009 15:36:42 +0800 Subject: ACPI: introduce kernel parameter acpi_sleep=sci_force_enable Introduce kernel parameter acpi_sleep=sci_force_enable some laptop requires SCI_EN being set directly on resume, or else they hung somewhere in the resume code path. We already have a blacklist for these laptops but we still need this option, especially when debugging some suspend/resume problems, in case there are systems that need this workaround and are not yet in the blacklist. Signed-off-by: Zhang Rui Acked-by: Rafael J. Wysocki Signed-off-by: Len Brown diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 5ba4d9d..736d456 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -240,7 +240,7 @@ and is between 256 and 4096 characters. It is defined in the file acpi_sleep= [HW,ACPI] Sleep options Format: { s3_bios, s3_mode, s3_beep, s4_nohwsig, - old_ordering, s4_nonvs } + old_ordering, s4_nonvs, sci_force_enable } See Documentation/power/video.txt for information on s3_bios and s3_mode. s3_beep is for debugging; it makes the PC's speaker beep @@ -253,6 +253,9 @@ and is between 256 and 4096 characters. It is defined in the file of _PTS is used by default). s4_nonvs prevents the kernel from saving/restoring the ACPI NVS memory during hibernation. + sci_force_enable causes the kernel to set SCI_EN directly + on resume from S1/S3 (which is against the ACPI spec, + but some broken systems don't work without it). acpi_use_timer_override [HW,ACPI] Use timer override. For some broken Nvidia NF5 boards diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c index 82e5086..f996103 100644 --- a/arch/x86/kernel/acpi/sleep.c +++ b/arch/x86/kernel/acpi/sleep.c @@ -162,6 +162,8 @@ static int __init acpi_sleep_setup(char *str) #endif if (strncmp(str, "old_ordering", 12) == 0) acpi_old_suspend_ordering(); + if (strncmp(str, "sci_force_enable", 16) == 0) + acpi_set_sci_en_on_resume(); str = strchr(str, ','); if (str != NULL) str += strspn(str, ", \t"); diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 5f2c379..79d33d9 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -81,6 +81,23 @@ static int acpi_sleep_prepare(u32 acpi_state) #ifdef CONFIG_ACPI_SLEEP static u32 acpi_target_sleep_state = ACPI_STATE_S0; /* + * According to the ACPI specification the BIOS should make sure that ACPI is + * enabled and SCI_EN bit is set on wake-up from S1 - S3 sleep states. Still, + * some BIOSes don't do that and therefore we use acpi_enable() to enable ACPI + * on such systems during resume. Unfortunately that doesn't help in + * particularly pathological cases in which SCI_EN has to be set directly on + * resume, although the specification states very clearly that this flag is + * owned by the hardware. The set_sci_en_on_resume variable will be set in such + * cases. + */ +static bool set_sci_en_on_resume; + +void __init acpi_set_sci_en_on_resume(void) +{ + set_sci_en_on_resume = true; +} + +/* * ACPI 1.0 wants us to execute _PTS before suspending devices, so we allow the * user to request that behavior by using the 'acpi_old_suspend_ordering' * kernel command line option that causes the following variable to be set. @@ -170,18 +187,6 @@ static void acpi_pm_end(void) #endif /* CONFIG_ACPI_SLEEP */ #ifdef CONFIG_SUSPEND -/* - * According to the ACPI specification the BIOS should make sure that ACPI is - * enabled and SCI_EN bit is set on wake-up from S1 - S3 sleep states. Still, - * some BIOSes don't do that and therefore we use acpi_enable() to enable ACPI - * on such systems during resume. Unfortunately that doesn't help in - * particularly pathological cases in which SCI_EN has to be set directly on - * resume, although the specification states very clearly that this flag is - * owned by the hardware. The set_sci_en_on_resume variable will be set in such - * cases. - */ -static bool set_sci_en_on_resume; - extern void do_suspend_lowlevel(void); static u32 acpi_suspend_states[] = { diff --git a/include/linux/acpi.h b/include/linux/acpi.h index ce945d4..3692425 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -251,6 +251,7 @@ int acpi_check_mem_region(resource_size_t start, resource_size_t n, void __init acpi_no_s4_hw_signature(void); void __init acpi_old_suspend_ordering(void); void __init acpi_s4_no_nvs(void); +void __init acpi_set_sci_en_on_resume(void); #endif /* CONFIG_PM_SLEEP */ struct acpi_osc_context { -- cgit v0.10.2 From 86470e98cc52532006f47a6cb96d3ebe1ba7ad97 Mon Sep 17 00:00:00 2001 From: Tao Ma Date: Thu, 3 Dec 2009 21:55:05 +0800 Subject: ocfs2: Handle O_DIRECT when writing to a refcounted cluster. In case of writing to a refcounted cluster with O_DIRECT, we need to fall back to buffer write. And when it is finished, we need to flush the page and the journal as we did for other O_DIRECT writes. This patch fix oss bug 1191. http://oss.oracle.com/bugzilla/show_bug.cgi?id=1191 Signed-off-by: Tao Ma Tested-by: Tristan Ye Signed-off-by: Joel Becker diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 3d30a1c..06ccf6a 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -1772,7 +1772,8 @@ static int ocfs2_prepare_inode_for_write(struct dentry *dentry, loff_t *ppos, size_t count, int appending, - int *direct_io) + int *direct_io, + int *has_refcount) { int ret = 0, meta_level = 0; struct inode *inode = dentry->d_inode; @@ -1833,6 +1834,8 @@ static int ocfs2_prepare_inode_for_write(struct dentry *dentry, saved_pos, count, &meta_level); + if (has_refcount) + *has_refcount = 1; } if (ret < 0) { @@ -1856,6 +1859,10 @@ static int ocfs2_prepare_inode_for_write(struct dentry *dentry, break; } + if (has_refcount && *has_refcount == 1) { + *direct_io = 0; + break; + } /* * Allowing concurrent direct writes means * i_size changes wouldn't be synchronized, so @@ -1899,7 +1906,7 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, loff_t pos) { int ret, direct_io, appending, rw_level, have_alloc_sem = 0; - int can_do_direct; + int can_do_direct, has_refcount = 0; ssize_t written = 0; size_t ocount; /* original count */ size_t count; /* after file limit checks */ @@ -1942,7 +1949,7 @@ relock: can_do_direct = direct_io; ret = ocfs2_prepare_inode_for_write(file->f_path.dentry, ppos, iocb->ki_left, appending, - &can_do_direct); + &can_do_direct, &has_refcount); if (ret < 0) { mlog_errno(ret); goto out; @@ -2006,14 +2013,16 @@ out_dio: /* buffered aio wouldn't have proper lock coverage today */ BUG_ON(ret == -EIOCBQUEUED && !(file->f_flags & O_DIRECT)); - if ((file->f_flags & O_DSYNC && !direct_io) || IS_SYNC(inode)) { + if ((file->f_flags & O_DSYNC && !direct_io) || IS_SYNC(inode) || + (file->f_flags & O_DIRECT && has_refcount)) { ret = filemap_fdatawrite_range(file->f_mapping, pos, pos + count - 1); if (ret < 0) written = ret; if (!ret && (old_size != i_size_read(inode) || - old_clusters != OCFS2_I(inode)->ip_clusters)) { + old_clusters != OCFS2_I(inode)->ip_clusters || + has_refcount)) { ret = jbd2_journal_force_commit(osb->journal->j_journal); if (ret < 0) written = ret; @@ -2062,7 +2071,7 @@ static int ocfs2_splice_to_file(struct pipe_inode_info *pipe, int ret; ret = ocfs2_prepare_inode_for_write(out->f_path.dentry, &sd->pos, - sd->total_len, 0, NULL); + sd->total_len, 0, NULL, NULL); if (ret < 0) { mlog_errno(ret); return ret; -- cgit v0.10.2 From 541cd3ee00a4fe975b22fac6a3bc846bacef37f7 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Wed, 30 Dec 2009 08:23:28 +0000 Subject: phylib: Fix deadlock on resume Sometimes kernel hangs on resume with the following trace: ucc_geth e0102000.ucc: resume INFO: task bash:1764 blocked for more than 120 seconds. "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. bash D 0fecf43c 0 1764 1763 0x00000000 Call Trace: [cf9a7c10] [c0012868] ret_from_except+0x0/0x14 (unreliable) --- Exception: cf9a7ce0 at __switch_to+0x4c/0x6c LR = 0xcf9a7cc0 [cf9a7cd0] [c0008c14] __switch_to+0x4c/0x6c (unreliable) [cf9a7ce0] [c028bcfc] schedule+0x158/0x260 [cf9a7d10] [c028c720] __mutex_lock_slowpath+0x80/0xd8 [cf9a7d40] [c01cf388] phy_stop+0x20/0x70 [cf9a7d50] [c01d514c] ugeth_resume+0x6c/0x13c [...] Here is why. On suspend: - PM core starts suspending devices, ucc_geth_suspend gets called; - ucc_geth calls phy_stop() on suspend. Note that phy_stop() is mostly asynchronous so it doesn't block ucc_geth's suspend routine, it just sets PHY_HALTED state and disables PHY's interrupts; - Suddenly the state machine gets scheduled, it grabs the phydev->lock mutex and tries to process the PHY_HALTED state, so it calls phydev->adjust_link(phydev->attached_dev). In ucc_geth case adjust_link() calls msleep(), which reschedules the code flow back to PM core, which now finishes suspend and so we end up sleeping with phydev->lock mutex held. On resume: - PM core starts resuming devices (notice that nobody rescheduled the state machine yet, so the mutex is still held), the core calls ucc_geth's resume routine; - ucc_geth_resume restarts the PHY with phy_stop()/phy_start() sequence, and the phy_*() calls are trying to grab the phydev->lock mutex. Here comes the deadlock. This patch fixes the issue by stopping the state machine on suspend and starting it again on resume. Signed-off-by: Anton Vorontsov Signed-off-by: David S. Miller diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index bd4e8d7..49252d3 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c @@ -303,8 +303,18 @@ static int mdio_bus_suspend(struct device * dev, pm_message_t state) struct phy_driver *phydrv = to_phy_driver(dev->driver); struct phy_device *phydev = to_phy_device(dev); + /* + * We must stop the state machine manually, otherwise it stops out of + * control, possibly with the phydev->lock held. Upon resume, netdev + * may call phy routines that try to grab the same lock, and that may + * lead to a deadlock. + */ + if (phydev->attached_dev) + phy_stop_machine(phydev); + if (!mdio_bus_phy_may_suspend(phydev)) return 0; + return phydrv->suspend(phydev); } @@ -312,10 +322,20 @@ static int mdio_bus_resume(struct device * dev) { struct phy_driver *phydrv = to_phy_driver(dev->driver); struct phy_device *phydev = to_phy_device(dev); + int ret; if (!mdio_bus_phy_may_suspend(phydev)) - return 0; - return phydrv->resume(phydev); + goto no_resume; + + ret = phydrv->resume(phydev); + if (ret < 0) + return ret; + +no_resume: + if (phydev->attached_dev) + phy_start_machine(phydev, NULL); + + return 0; } struct bus_type mdio_bus_type = { -- cgit v0.10.2 From 2f5cb43406d0b29b96248f5328a14a6f6abf8ae6 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Wed, 30 Dec 2009 08:23:30 +0000 Subject: phylib: Properly reinitialize PHYs after hibernation Since hibernation assumes power loss, we should fully reinitialize PHYs (including platform fixups), as if PHYs were just attached. This patch factors phy_init_hw() out of phy_attach_direct(), then converts mdio_bus to dev_pm_ops and adds an appropriate restore() callback. Signed-off-by: Anton Vorontsov Signed-off-by: David S. Miller diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index 49252d3..e17b702 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c @@ -264,6 +264,8 @@ static int mdio_bus_match(struct device *dev, struct device_driver *drv) (phydev->phy_id & phydrv->phy_id_mask)); } +#ifdef CONFIG_PM + static bool mdio_bus_phy_may_suspend(struct phy_device *phydev) { struct device_driver *drv = phydev->dev.driver; @@ -295,10 +297,7 @@ static bool mdio_bus_phy_may_suspend(struct phy_device *phydev) return true; } -/* Suspend and resume. Copied from platform_suspend and - * platform_resume - */ -static int mdio_bus_suspend(struct device * dev, pm_message_t state) +static int mdio_bus_suspend(struct device *dev) { struct phy_driver *phydrv = to_phy_driver(dev->driver); struct phy_device *phydev = to_phy_device(dev); @@ -318,7 +317,7 @@ static int mdio_bus_suspend(struct device * dev, pm_message_t state) return phydrv->suspend(phydev); } -static int mdio_bus_resume(struct device * dev) +static int mdio_bus_resume(struct device *dev) { struct phy_driver *phydrv = to_phy_driver(dev->driver); struct phy_device *phydev = to_phy_device(dev); @@ -338,11 +337,48 @@ no_resume: return 0; } +static int mdio_bus_restore(struct device *dev) +{ + struct phy_device *phydev = to_phy_device(dev); + struct net_device *netdev = phydev->attached_dev; + int ret; + + if (!netdev) + return 0; + + ret = phy_init_hw(phydev); + if (ret < 0) + return ret; + + /* The PHY needs to renegotiate. */ + phydev->link = 0; + phydev->state = PHY_UP; + + phy_start_machine(phydev, NULL); + + return 0; +} + +static struct dev_pm_ops mdio_bus_pm_ops = { + .suspend = mdio_bus_suspend, + .resume = mdio_bus_resume, + .freeze = mdio_bus_suspend, + .thaw = mdio_bus_resume, + .restore = mdio_bus_restore, +}; + +#define MDIO_BUS_PM_OPS (&mdio_bus_pm_ops) + +#else + +#define MDIO_BUS_PM_OPS NULL + +#endif /* CONFIG_PM */ + struct bus_type mdio_bus_type = { .name = "mdio_bus", .match = mdio_bus_match, - .suspend = mdio_bus_suspend, - .resume = mdio_bus_resume, + .pm = MDIO_BUS_PM_OPS, }; EXPORT_SYMBOL(mdio_bus_type); diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index b10fedd..8212b2b 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -378,6 +378,20 @@ void phy_disconnect(struct phy_device *phydev) } EXPORT_SYMBOL(phy_disconnect); +int phy_init_hw(struct phy_device *phydev) +{ + int ret; + + if (!phydev->drv || !phydev->drv->config_init) + return 0; + + ret = phy_scan_fixups(phydev); + if (ret < 0) + return ret; + + return phydev->drv->config_init(phydev); +} + /** * phy_attach_direct - attach a network device to a given PHY device pointer * @dev: network device to attach @@ -425,21 +439,7 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, /* Do initial configuration here, now that * we have certain key parameters * (dev_flags and interface) */ - if (phydev->drv->config_init) { - int err; - - err = phy_scan_fixups(phydev); - - if (err < 0) - return err; - - err = phydev->drv->config_init(phydev); - - if (err < 0) - return err; - } - - return 0; + return phy_init_hw(phydev); } EXPORT_SYMBOL(phy_attach_direct); diff --git a/include/linux/phy.h b/include/linux/phy.h index b1368b8..7968def 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -447,6 +447,7 @@ struct phy_device* get_phy_device(struct mii_bus *bus, int addr); int phy_device_register(struct phy_device *phy); int phy_clear_interrupt(struct phy_device *phydev); int phy_config_interrupt(struct phy_device *phydev, u32 interrupts); +int phy_init_hw(struct phy_device *phydev); int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, u32 flags, phy_interface_t interface); struct phy_device * phy_attach(struct net_device *dev, -- cgit v0.10.2 From 29fb00e047eae927a3f1a0367c0cfed7ad5228ef Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Wed, 30 Dec 2009 08:23:32 +0000 Subject: ucc_geth: Fix netdev watchdog triggering on suspend Sometimes ucc_geth fails to suspend with the following trace: ucc_geth e0103000.ucc: suspend ucc_geth e0102000.ucc: suspend NETDEV WATCHDOG: eth0 (ucc_geth): transmit queue 0 timed out ------------[ cut here ]------------ Badness at net/sched/sch_generic.c:255 NIP: c021cb5c LR: c021cb5c CTR: c01ab4b4 [...] NIP [c021cb5c] dev_watchdog+0x298/0x2a8 LR [c021cb5c] dev_watchdog+0x298/0x2a8 Call Trace: [c0389da0] [c021cb5c] dev_watchdog+0x298/0x2a8 (unreliable) [c0389e00] [c0031ed8] run_timer_softirq+0x16c/0x1dc [c0389e50] [c002c638] __do_softirq+0xa4/0x11c [...] This patch fixes the issue by properly detaching the device on suspend, and attaching it back on resume. Signed-off-by: Anton Vorontsov Signed-off-by: David S. Miller diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 41ad2f3..96bdc0b 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -3607,6 +3607,7 @@ static int ucc_geth_suspend(struct of_device *ofdev, pm_message_t state) if (!netif_running(ndev)) return 0; + netif_device_detach(ndev); napi_disable(&ugeth->napi); /* @@ -3665,7 +3666,7 @@ static int ucc_geth_resume(struct of_device *ofdev) phy_start(ugeth->phydev); napi_enable(&ugeth->napi); - netif_start_queue(ndev); + netif_device_attach(ndev); return 0; } -- cgit v0.10.2 From b3319b10523d8dac82b134a05de2a403119abebd Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Wed, 30 Dec 2009 08:23:34 +0000 Subject: fsl_pq_mdio: Fix iomem unmapping for non-eTSEC2.0 controllers We use a rather complicated logic to support eTSEC and eTSEC2.0 registers maps in a single driver. Currently, the code tries to unmap 'regs', but for non-eTSEC2.0 controllers 'regs' doesn't point to a mapping start, and this might cause badness on probe failure or module removal: Freescale PowerQUICC MII Bus: probed Trying to vfree() nonexistent vm area (e107f000) ------------[ cut here ]------------ Badness at c00a7754 [verbose debug info unavailable] NIP: c00a7754 LR: c00a7754 CTR: c02231ec [...] NIP [c00a7754] __vunmap+0xec/0xf4 LR [c00a7754] __vunmap+0xec/0xf4 Call Trace: [df827e50] [c00a7754] __vunmap+0xec/0xf4 (unreliable) [df827e70] [c001519c] iounmap+0x44/0x54 [df827e80] [c028b924] fsl_pq_mdio_probe+0x1cc/0x2fc [df827eb0] [c02fb9b4] of_platform_device_probe+0x5c/0x84 [df827ed0] [c0229928] really_probe+0x78/0x1a8 [df827ef0] [c0229b20] __driver_attach+0xa4/0xa8 Fix this by introducing a proper priv structure (finally!), which now holds 'regs' and 'map' fields separately. Signed-off-by: Anton Vorontsov Signed-off-by: David S. Miller diff --git a/drivers/net/fsl_pq_mdio.c b/drivers/net/fsl_pq_mdio.c index 25fabb3..d5160ed 100644 --- a/drivers/net/fsl_pq_mdio.c +++ b/drivers/net/fsl_pq_mdio.c @@ -46,6 +46,11 @@ #include "gianfar.h" #include "fsl_pq_mdio.h" +struct fsl_pq_mdio_priv { + void __iomem *map; + struct fsl_pq_mdio __iomem *regs; +}; + /* * Write value to the PHY at mii_id at register regnum, * on the bus attached to the local interface, which may be different from the @@ -105,7 +110,9 @@ int fsl_pq_local_mdio_read(struct fsl_pq_mdio __iomem *regs, static struct fsl_pq_mdio __iomem *fsl_pq_mdio_get_regs(struct mii_bus *bus) { - return (void __iomem __force *)bus->priv; + struct fsl_pq_mdio_priv *priv = bus->priv; + + return priv->regs; } /* @@ -266,6 +273,7 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev, { struct device_node *np = ofdev->node; struct device_node *tbi; + struct fsl_pq_mdio_priv *priv; struct fsl_pq_mdio __iomem *regs = NULL; void __iomem *map; u32 __iomem *tbipa; @@ -274,14 +282,19 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev, u64 addr = 0, size = 0; int err = 0; + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + new_bus = mdiobus_alloc(); if (NULL == new_bus) - return -ENOMEM; + goto err_free_priv; new_bus->name = "Freescale PowerQUICC MII Bus", new_bus->read = &fsl_pq_mdio_read, new_bus->write = &fsl_pq_mdio_write, new_bus->reset = &fsl_pq_mdio_reset, + new_bus->priv = priv; fsl_pq_mdio_bus_name(new_bus->id, np); /* Set the PHY base address */ @@ -291,6 +304,7 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev, err = -ENOMEM; goto err_free_bus; } + priv->map = map; if (of_device_is_compatible(np, "fsl,gianfar-mdio") || of_device_is_compatible(np, "fsl,gianfar-tbi") || @@ -298,8 +312,7 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev, of_device_is_compatible(np, "ucc_geth_phy")) map -= offsetof(struct fsl_pq_mdio, miimcfg); regs = map; - - new_bus->priv = (void __force *)regs; + priv->regs = regs; new_bus->irq = kcalloc(PHY_MAX_ADDR, sizeof(int), GFP_KERNEL); @@ -392,10 +405,11 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev, err_free_irqs: kfree(new_bus->irq); err_unmap_regs: - iounmap(regs); + iounmap(priv->map); err_free_bus: kfree(new_bus); - +err_free_priv: + kfree(priv); return err; } @@ -404,14 +418,16 @@ static int fsl_pq_mdio_remove(struct of_device *ofdev) { struct device *device = &ofdev->dev; struct mii_bus *bus = dev_get_drvdata(device); + struct fsl_pq_mdio_priv *priv = bus->priv; mdiobus_unregister(bus); dev_set_drvdata(device, NULL); - iounmap(fsl_pq_mdio_get_regs(bus)); + iounmap(priv->map); bus->priv = NULL; mdiobus_free(bus); + kfree(priv); return 0; } -- cgit v0.10.2 From 48b5ba9cc98d676712da29d9931f1c88e5185ff2 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Thu, 31 Dec 2009 05:53:02 +0100 Subject: perf: Pass appropriate frame pointer to dump_trace() Pass the frame pointer from the regs of the interrupted path to dump_trace() while processing the stack trace. Currently, dump_trace() takes the current bp and starts the callchain from dump_trace() itself. This is wasteful because we need to walk through the entire NMI/DEBUG stack before retrieving the interrupted point. We can fix that by just using the frame pointer from the captured regs. It points exactly where we want to start. Signed-off-by: Frederic Weisbecker Cc: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: Paul Mackerras LKML-Reference: <1262235183-5320-1-git-send-regression-fweisbec@gmail.com> Signed-off-by: Ingo Molnar Cc: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: Paul Mackerras diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index c223b7e..d616c06 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -2347,7 +2347,7 @@ perf_callchain_kernel(struct pt_regs *regs, struct perf_callchain_entry *entry) callchain_store(entry, PERF_CONTEXT_KERNEL); callchain_store(entry, regs->ip); - dump_trace(NULL, regs, NULL, 0, &backtrace_ops, entry); + dump_trace(NULL, regs, NULL, regs->bp, &backtrace_ops, entry); } /* -- cgit v0.10.2 From 05cbaa2853cdfc255fdd04e65a82bfe9208c4e52 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 30 Dec 2009 16:00:35 +0100 Subject: perf: Fix NULL deref in inheritance code Liming found a NULL deref when a task has a perf context but no counters when it forks. This can occur in two cases, a race during construction where the fork hits after installing the context but before the first counter gets inserted, or more reproducably, a fork after the last counter is closed (which leaves the context around). Reported-by: Wang Liming Signed-off-by: Peter Zijlstra Cc: Frederic Weisbecker Cc: Paul Mackerras CC: LKML-Reference: <1262185684.7135.222.camel@laptop> Signed-off-by: Ingo Molnar diff --git a/kernel/perf_event.c b/kernel/perf_event.c index 03cc061..58ed1da 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c @@ -5148,7 +5148,7 @@ int perf_event_init_task(struct task_struct *child) GFP_KERNEL); if (!child_ctx) { ret = -ENOMEM; - goto exit; + break; } __perf_event_init_context(child_ctx, child); @@ -5164,7 +5164,7 @@ int perf_event_init_task(struct task_struct *child) } } - if (inherited_all) { + if (child_ctx && inherited_all) { /* * Mark the child context as a clone of the parent * context, or of whatever the parent is a clone of. @@ -5184,7 +5184,6 @@ int perf_event_init_task(struct task_struct *child) get_ctx(child_ctx->parent_ctx); } -exit: mutex_unlock(&parent_ctx->mutex); perf_unpin_context(parent_ctx); -- cgit v0.10.2 From a8fe9ea200ea21421ea750423d1d4d4f7ce037cf Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 31 Dec 2009 15:16:23 +0100 Subject: dma-debug: Fix bug causing build warning Stephen Rothwell reported the following build warning: lib/dma-debug.c: In function 'dma_debug_device_change': lib/dma-debug.c:680: warning: 'return' with no value, in function returning non-void Introduced by commit f797d9881b62c2ddb1d2e7bd80d87141949c84aa ("dma-debug: Do not add notifier when dma debugging is disabled"). Return 0 [notify-done] when disabled. (this is standard bus notifier behavior.) Signed-off-by: Shaun Ruffell Signed-off-by: Joerg Roedel Cc: Linus Torvalds Cc: LKML-Reference: <20091231125624.GA14666@liondog.tnic> Signed-off-by: Ingo Molnar diff --git a/lib/dma-debug.c b/lib/dma-debug.c index 7399744..cf90620 100644 --- a/lib/dma-debug.c +++ b/lib/dma-debug.c @@ -670,14 +670,13 @@ static int device_dma_allocations(struct device *dev) return count; } -static int dma_debug_device_change(struct notifier_block *nb, - unsigned long action, void *data) +static int dma_debug_device_change(struct notifier_block *nb, unsigned long action, void *data) { struct device *dev = data; int count; if (global_disable) - return; + return 0; switch (action) { case BUS_NOTIFY_UNBOUND_DRIVER: -- cgit v0.10.2 From 5b889bf237fca383b5807ad69fde3ad1e2287e42 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 31 Dec 2009 19:06:35 +0100 Subject: PCI: Fix build if quirks are not enabled After commit b9c3b266411d27f1a6466c19d146d08db576bfea ("PCI: support device-specific reset methods") the kernel build is broken if CONFIG_PCI_QUIRKS is unset. Fix this by moving pci_dev_specific_reset() to drivers/pci/quirks.c and providing an empty replacement for !CONFIG_PCI_QUIRKS builds. Signed-off-by: Rafael J. Wysocki Reported-by: Ingo Molnar Signed-off-by: Linus Torvalds diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 864e703..0906599 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -2284,21 +2284,6 @@ static int pci_parent_bus_reset(struct pci_dev *dev, int probe) return 0; } -static int pci_dev_specific_reset(struct pci_dev *dev, int probe) -{ - struct pci_dev_reset_methods *i; - - for (i = pci_dev_reset_methods; i->reset; i++) { - if ((i->vendor == dev->vendor || - i->vendor == (u16)PCI_ANY_ID) && - (i->device == dev->device || - i->device == (u16)PCI_ANY_ID)) - return i->reset(dev, probe); - } - - return -ENOTTY; -} - static int pci_dev_reset(struct pci_dev *dev, int probe) { int rc; diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 709eaa4..fbd0e3a 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -319,6 +319,6 @@ struct pci_dev_reset_methods { int (*reset)(struct pci_dev *dev, int probe); }; -extern struct pci_dev_reset_methods pci_dev_reset_methods[]; +extern int pci_dev_specific_reset(struct pci_dev *dev, int probe); #endif /* DRIVERS_PCI_H */ diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 8726698..5c449fc 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -2684,14 +2684,31 @@ static int reset_intel_82599_sfp_virtfn(struct pci_dev *dev, int probe) #define PCI_DEVICE_ID_INTEL_82599_SFP_VF 0x10ed -struct pci_dev_reset_methods pci_dev_reset_methods[] = { +static const struct pci_dev_reset_methods pci_dev_reset_methods[] = { { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82599_SFP_VF, reset_intel_82599_sfp_virtfn }, { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, reset_intel_generic_dev }, { 0 } }; + +int pci_dev_specific_reset(struct pci_dev *dev, int probe) +{ + struct pci_dev_reset_methods *i; + + for (i = pci_dev_reset_methods; i->reset; i++) { + if ((i->vendor == dev->vendor || + i->vendor == (u16)PCI_ANY_ID) && + (i->device == dev->device || + i->device == (u16)PCI_ANY_ID)) + return i->reset(dev, probe); + } + + return -ENOTTY; +} + #else void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) {} +int pci_dev_specific_reset(struct pci_dev *dev, int probe) { return -ENOTTY; } #endif EXPORT_SYMBOL(pci_fixup_device); -- cgit v0.10.2 From df9d1e8a4379119cbc47c474f168b5103e404e17 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 31 Dec 2009 16:44:43 -0800 Subject: pci: avoid compiler warning in quirks.c Introduced by commit 5b889bf23 ("PCI: Fix build if quirks are not enabled"), which made the pci_dev_reset_methods[] array static and 'const', but didn't then change the code to match, and use a const pointer when moving it to quirks.c. Trivially fixed by just adding the required 'const' to the iterator variable. Reported-by: Stephen Rothwell Cc: Rafael J. Wysocki Signed-off-by: Linus Torvalds diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 5c449fc..c746943 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -2694,7 +2694,7 @@ static const struct pci_dev_reset_methods pci_dev_reset_methods[] = { int pci_dev_specific_reset(struct pci_dev *dev, int probe) { - struct pci_dev_reset_methods *i; + const struct pci_dev_reset_methods *i; for (i = pci_dev_reset_methods; i->reset; i++) { if ((i->vendor == dev->vendor || -- cgit v0.10.2 From cd6e125c58ae1561bedb6ea6f70b00d6c2599d62 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 31 Dec 2009 17:26:05 -0800 Subject: twl4030-irq.c: fix compiler warning due to raw-spinlock conversion Commit 239007b844 ("genirq: Convert irq_desc.lock to raw_spinlock") seems to have missed this driver, leaving it to use the normal spin-lock functions for the irq descriptor lock, which is now a raw lock. Reported-and-compile-tested-by: Stephen Rothwell Signed-off-by: Linus Torvalds diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c index 20d29ba..9df9a5a 100644 --- a/drivers/mfd/twl4030-irq.c +++ b/drivers/mfd/twl4030-irq.c @@ -568,12 +568,12 @@ static void twl4030_sih_do_edge(struct work_struct *work) bytes[byte] &= ~(0x03 << off); - spin_lock_irq(&d->lock); + raw_spin_lock_irq(&d->lock); if (d->status & IRQ_TYPE_EDGE_RISING) bytes[byte] |= BIT(off + 1); if (d->status & IRQ_TYPE_EDGE_FALLING) bytes[byte] |= BIT(off + 0); - spin_unlock_irq(&d->lock); + raw_spin_unlock_irq(&d->lock); edge_change &= ~BIT(i); } -- cgit v0.10.2 From ee5f4d9cdf32fd99172d11665c592a288c2b1ff4 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Fri, 1 Jan 2010 02:36:15 -0500 Subject: ext4: Fix accounting of reserved metadata blocks Commit 0637c6f had a typo which caused the reserved metadata blocks to not be released correctly. Fix this. Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 84eeb8f..bdaa92a 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -1076,9 +1076,9 @@ static void ext4_da_update_reserve_space(struct inode *inode, int used) * only when we have written all of the delayed * allocation blocks. */ - mdb_free = ei->i_allocated_meta_blocks; + mdb_free = ei->i_reserved_meta_blocks; + ei->i_reserved_meta_blocks = 0; percpu_counter_sub(&sbi->s_dirtyblocks_counter, mdb_free); - ei->i_allocated_meta_blocks = 0; } spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); @@ -1889,8 +1889,8 @@ static void ext4_da_release_space(struct inode *inode, int to_free) * only when we have written all of the delayed * allocation blocks. */ - to_free += ei->i_allocated_meta_blocks; - ei->i_allocated_meta_blocks = 0; + to_free += ei->i_reserved_meta_blocks; + ei->i_reserved_meta_blocks = 0; } /* update fs dirty blocks counter */ -- cgit v0.10.2 From 9d0be50230b333005635967f7ecd4897dbfd181b Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Fri, 1 Jan 2010 02:41:30 -0500 Subject: ext4: Calculate metadata requirements more accurately In the past, ext4_calc_metadata_amount(), and its sub-functions ext4_ext_calc_metadata_amount() and ext4_indirect_calc_metadata_amount() badly over-estimated the number of metadata blocks that might be required for delayed allocation blocks. This didn't matter as much when functions which managed the reserved metadata blocks were more aggressive about dropping reserved metadata blocks as delayed allocation blocks were written, but unfortunately they were too aggressive. This was fixed in commit 0637c6f, but as a result the over-estimation by ext4_calc_metadata_amount() would lead to reserving 2-3 times the number of pending delayed allocation blocks as potentially required metadata blocks. So if there are 1 megabytes of blocks which have been not yet been allocation, up to 3 megabytes of space would get reserved out of the user's quota and from the file system free space pool until all of the inode's data blocks have been allocated. This commit addresses this problem by much more accurately estimating the number of metadata blocks that will be required. It will still somewhat over-estimate the number of blocks needed, since it must make a worst case estimate not knowing which physical blocks will be needed, but it is much more accurate than before. Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 56f9271..af7b626 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -699,6 +699,8 @@ struct ext4_inode_info { unsigned int i_reserved_meta_blocks; unsigned int i_allocated_meta_blocks; unsigned short i_delalloc_reserved_flag; + sector_t i_da_metadata_calc_last_lblock; + int i_da_metadata_calc_len; /* on-disk additional length */ __u16 i_extra_isize; diff --git a/fs/ext4/ext4_extents.h b/fs/ext4/ext4_extents.h index 2ca6864..bdb6ce7 100644 --- a/fs/ext4/ext4_extents.h +++ b/fs/ext4/ext4_extents.h @@ -225,7 +225,8 @@ static inline void ext4_ext_mark_initialized(struct ext4_extent *ext) ext->ee_len = cpu_to_le16(ext4_ext_get_actual_len(ext)); } -extern int ext4_ext_calc_metadata_amount(struct inode *inode, int blocks); +extern int ext4_ext_calc_metadata_amount(struct inode *inode, + sector_t lblocks); extern ext4_fsblk_t ext_pblock(struct ext4_extent *ex); extern ext4_fsblk_t idx_pblock(struct ext4_extent_idx *); extern void ext4_ext_store_pblock(struct ext4_extent *, ext4_fsblk_t); diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 91ae460..7d7b74e 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -296,29 +296,44 @@ static inline int ext4_ext_space_root_idx(struct inode *inode, int check) * to allocate @blocks * Worse case is one block per extent */ -int ext4_ext_calc_metadata_amount(struct inode *inode, int blocks) +int ext4_ext_calc_metadata_amount(struct inode *inode, sector_t lblock) { - int lcap, icap, rcap, leafs, idxs, num; - int newextents = blocks; - - rcap = ext4_ext_space_root_idx(inode, 0); - lcap = ext4_ext_space_block(inode, 0); - icap = ext4_ext_space_block_idx(inode, 0); + struct ext4_inode_info *ei = EXT4_I(inode); + int idxs, num = 0; - /* number of new leaf blocks needed */ - num = leafs = (newextents + lcap - 1) / lcap; + idxs = ((inode->i_sb->s_blocksize - sizeof(struct ext4_extent_header)) + / sizeof(struct ext4_extent_idx)); /* - * Worse case, we need separate index block(s) - * to link all new leaf blocks + * If the new delayed allocation block is contiguous with the + * previous da block, it can share index blocks with the + * previous block, so we only need to allocate a new index + * block every idxs leaf blocks. At ldxs**2 blocks, we need + * an additional index block, and at ldxs**3 blocks, yet + * another index blocks. */ - idxs = (leafs + icap - 1) / icap; - do { - num += idxs; - idxs = (idxs + icap - 1) / icap; - } while (idxs > rcap); + if (ei->i_da_metadata_calc_len && + ei->i_da_metadata_calc_last_lblock+1 == lblock) { + if ((ei->i_da_metadata_calc_len % idxs) == 0) + num++; + if ((ei->i_da_metadata_calc_len % (idxs*idxs)) == 0) + num++; + if ((ei->i_da_metadata_calc_len % (idxs*idxs*idxs)) == 0) { + num++; + ei->i_da_metadata_calc_len = 0; + } else + ei->i_da_metadata_calc_len++; + ei->i_da_metadata_calc_last_lblock++; + return num; + } - return num; + /* + * In the worst case we need a new set of index blocks at + * every level of the inode's extent tree. + */ + ei->i_da_metadata_calc_len = 1; + ei->i_da_metadata_calc_last_lblock = lblock; + return ext_depth(inode) + 1; } static int diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index bdaa92a..c818972 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -1009,38 +1009,44 @@ qsize_t *ext4_get_reserved_space(struct inode *inode) return &EXT4_I(inode)->i_reserved_quota; } #endif + /* * Calculate the number of metadata blocks need to reserve - * to allocate @blocks for non extent file based file + * to allocate a new block at @lblocks for non extent file based file */ -static int ext4_indirect_calc_metadata_amount(struct inode *inode, int blocks) +static int ext4_indirect_calc_metadata_amount(struct inode *inode, + sector_t lblock) { - int icap = EXT4_ADDR_PER_BLOCK(inode->i_sb); - int ind_blks, dind_blks, tind_blks; - - /* number of new indirect blocks needed */ - ind_blks = (blocks + icap - 1) / icap; + struct ext4_inode_info *ei = EXT4_I(inode); + int dind_mask = EXT4_ADDR_PER_BLOCK(inode->i_sb) - 1; + int blk_bits; - dind_blks = (ind_blks + icap - 1) / icap; + if (lblock < EXT4_NDIR_BLOCKS) + return 0; - tind_blks = 1; + lblock -= EXT4_NDIR_BLOCKS; - return ind_blks + dind_blks + tind_blks; + if (ei->i_da_metadata_calc_len && + (lblock & dind_mask) == ei->i_da_metadata_calc_last_lblock) { + ei->i_da_metadata_calc_len++; + return 0; + } + ei->i_da_metadata_calc_last_lblock = lblock & dind_mask; + ei->i_da_metadata_calc_len = 1; + blk_bits = roundup_pow_of_two(lblock + 1); + return (blk_bits / EXT4_ADDR_PER_BLOCK_BITS(inode->i_sb)) + 1; } /* * Calculate the number of metadata blocks need to reserve - * to allocate given number of blocks + * to allocate a block located at @lblock */ -static int ext4_calc_metadata_amount(struct inode *inode, int blocks) +static int ext4_calc_metadata_amount(struct inode *inode, sector_t lblock) { - if (!blocks) - return 0; - if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) - return ext4_ext_calc_metadata_amount(inode, blocks); + return ext4_ext_calc_metadata_amount(inode, lblock); - return ext4_indirect_calc_metadata_amount(inode, blocks); + return ext4_indirect_calc_metadata_amount(inode, lblock); } /* @@ -1078,6 +1084,7 @@ static void ext4_da_update_reserve_space(struct inode *inode, int used) */ mdb_free = ei->i_reserved_meta_blocks; ei->i_reserved_meta_blocks = 0; + ei->i_da_metadata_calc_len = 0; percpu_counter_sub(&sbi->s_dirtyblocks_counter, mdb_free); } spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); @@ -1802,12 +1809,15 @@ static int ext4_journalled_write_end(struct file *file, return ret ? ret : copied; } -static int ext4_da_reserve_space(struct inode *inode, int nrblocks) +/* + * Reserve a single block located at lblock + */ +static int ext4_da_reserve_space(struct inode *inode, sector_t lblock) { int retries = 0; struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); struct ext4_inode_info *ei = EXT4_I(inode); - unsigned long md_needed, md_reserved, total = 0; + unsigned long md_needed, md_reserved; /* * recalculate the amount of metadata blocks to reserve @@ -1817,8 +1827,7 @@ static int ext4_da_reserve_space(struct inode *inode, int nrblocks) repeat: spin_lock(&ei->i_block_reservation_lock); md_reserved = ei->i_reserved_meta_blocks; - md_needed = ext4_calc_metadata_amount(inode, nrblocks); - total = md_needed + nrblocks; + md_needed = ext4_calc_metadata_amount(inode, lblock); spin_unlock(&ei->i_block_reservation_lock); /* @@ -1826,7 +1835,7 @@ repeat: * later. Real quota accounting is done at pages writeout * time. */ - if (vfs_dq_reserve_block(inode, total)) { + if (vfs_dq_reserve_block(inode, md_needed + 1)) { /* * We tend to badly over-estimate the amount of * metadata blocks which are needed, so if we have @@ -1838,8 +1847,8 @@ repeat: return -EDQUOT; } - if (ext4_claim_free_blocks(sbi, total)) { - vfs_dq_release_reservation_block(inode, total); + if (ext4_claim_free_blocks(sbi, md_needed + 1)) { + vfs_dq_release_reservation_block(inode, md_needed + 1); if (ext4_should_retry_alloc(inode->i_sb, &retries)) { retry: if (md_reserved) @@ -1850,7 +1859,7 @@ repeat: return -ENOSPC; } spin_lock(&ei->i_block_reservation_lock); - ei->i_reserved_data_blocks += nrblocks; + ei->i_reserved_data_blocks++; ei->i_reserved_meta_blocks += md_needed; spin_unlock(&ei->i_block_reservation_lock); @@ -1891,6 +1900,7 @@ static void ext4_da_release_space(struct inode *inode, int to_free) */ to_free += ei->i_reserved_meta_blocks; ei->i_reserved_meta_blocks = 0; + ei->i_da_metadata_calc_len = 0; } /* update fs dirty blocks counter */ @@ -2504,7 +2514,7 @@ static int ext4_da_get_block_prep(struct inode *inode, sector_t iblock, * XXX: __block_prepare_write() unmaps passed block, * is it OK? */ - ret = ext4_da_reserve_space(inode, 1); + ret = ext4_da_reserve_space(inode, iblock); if (ret) /* not enough space to reserve */ return ret; diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 7cccb35..735c20d 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -702,6 +702,7 @@ static struct inode *ext4_alloc_inode(struct super_block *sb) ei->i_reserved_data_blocks = 0; ei->i_reserved_meta_blocks = 0; ei->i_allocated_meta_blocks = 0; + ei->i_da_metadata_calc_len = 0; ei->i_delalloc_reserved_flag = 0; spin_lock_init(&(ei->i_block_reservation_lock)); #ifdef CONFIG_QUOTA -- cgit v0.10.2 From dc8601a224d546bb321b058fc5ecabdb688a3582 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Wed, 30 Dec 2009 02:27:24 -0500 Subject: [ARM] pxa: do not enable L2 after MMU is enabled Outer cache checked whether L2 is enabled or not. If L2 isn't enabled in XSC3, it would enable L2. This operation is evil that would make system hang. In XSC3 core document, these words are mentioned in below. "Following reset, the L2 Unified Cache Enable bit is cleared. To enable the L2 Cache, software may set the bit to a '1' before or at the same time as enabling the MMU. Enabling the L2 Cache after the MMU has been enabled or disabling the L2 Cache after the L2 Cache has been enabled, may result in unpredictable behavior of the processor." When outer cache is initialized, the MMU is already enabled. We couldn't enable L2 after MMU enabled. Signed-off-by: Haojian Zhuang Signed-off-by: Eric Miao diff --git a/arch/arm/mm/cache-xsc3l2.c b/arch/arm/mm/cache-xsc3l2.c index 5d180cb..c315492 100644 --- a/arch/arm/mm/cache-xsc3l2.c +++ b/arch/arm/mm/cache-xsc3l2.c @@ -221,15 +221,14 @@ static int __init xsc3_l2_init(void) if (!cpu_is_xsc3() || !xsc3_l2_present()) return 0; - if (!(get_cr() & CR_L2)) { + if (get_cr() & CR_L2) { pr_info("XScale3 L2 cache enabled.\n"); - adjust_cr(CR_L2, CR_L2); xsc3_l2_inv_all(); - } - outer_cache.inv_range = xsc3_l2_inv_range; - outer_cache.clean_range = xsc3_l2_clean_range; - outer_cache.flush_range = xsc3_l2_flush_range; + outer_cache.inv_range = xsc3_l2_inv_range; + outer_cache.clean_range = xsc3_l2_clean_range; + outer_cache.flush_range = xsc3_l2_flush_range; + } return 0; } -- cgit v0.10.2 From 548c6af4627f4dcb24512a381193206e09bd6d31 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Wed, 30 Dec 2009 10:02:57 -0500 Subject: [ARM] pxa: enable L2 if present in XSC3 Check whether L2 is present or not in XSC3. If it's present, enable L2 immediately. Disabling L2 after L2 is enabled that would result in unpredicatable behavior of XSC3 processor. Signed-off-by: Haojian Zhuang Signed-off-by: Eric Miao diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S index 96456f5..8e4f6dc 100644 --- a/arch/arm/mm/proc-xsc3.S +++ b/arch/arm/mm/proc-xsc3.S @@ -407,6 +407,13 @@ __xsc3_setup: adr r5, xsc3_crval ldmia r5, {r5, r6} + +#ifdef CONFIG_CACHE_XSC3L2 + mrc p15, 1, r0, c0, c0, 1 @ get L2 present information + ands r0, r0, #0xf8 + orrne r6, r6, #(1 << 26) @ enable L2 if present +#endif + mrc p15, 0, r0, c1, c0, 0 @ get control register bic r0, r0, r5 @ ..V. ..R. .... ..A. orr r0, r0, r6 @ ..VI Z..S .... .C.M (mmu) -- cgit v0.10.2 From c9c041fcb1a4d69ed4791f00b57554eeb341d148 Mon Sep 17 00:00:00 2001 From: Anisse Astier Date: Thu, 31 Dec 2009 16:41:33 +0100 Subject: hp-wmi: remove double free caused by merge conflict Commit 3e9b988e4edf065d39c1343937f717319b1c1065 "wmi: Free the allocated acpi objects through wmi_get_event_data" had the same purpose as commit 44ef00e6482e755f36629773abc2aee83a6f53e3 "hp-wmi: Fix two memleaks" This should solve this regression: http://bugzilla.kernel.org/show_bug.cgi?id=14890 Signed-off-by: Anisse Astier Reported-by: Sedat Dilek Signed-off-by: Len Brown diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c index 5b648f0..ad4c414d 100644 --- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c @@ -393,8 +393,6 @@ static void hp_wmi_notify(u32 value, void *context) } else printk(KERN_INFO "HP WMI: Unknown key pressed - %x\n", eventcode); - - kfree(obj); } static int __init hp_wmi_input_setup(void) -- cgit v0.10.2 From 0719d3434747889b314a1e8add776418c4148bcf Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Wed, 30 Dec 2009 00:39:22 +0100 Subject: reiserfs: Fix reiserfs lock <-> i_xattr_sem dependency inversion i_xattr_sem depends on the reiserfs lock. But after we grab i_xattr_sem, we may relax/relock the reiserfs lock while waiting on a freezed filesystem, creating a dependency inversion between the two locks. In order to avoid the i_xattr_sem -> reiserfs lock dependency, let's create a reiserfs_down_read_safe() that acts like reiserfs_mutex_lock_safe(): relax the reiserfs lock while grabbing another lock to avoid undesired dependencies induced by the heivyweight reiserfs lock. This fixes the following warning: [ 990.005931] ======================================================= [ 990.012373] [ INFO: possible circular locking dependency detected ] [ 990.013233] 2.6.33-rc1 #1 [ 990.013233] ------------------------------------------------------- [ 990.013233] dbench/1891 is trying to acquire lock: [ 990.013233] (&REISERFS_SB(s)->lock){+.+.+.}, at: [] reiserfs_write_lock+0x35/0x50 [ 990.013233] [ 990.013233] but task is already holding lock: [ 990.013233] (&REISERFS_I(inode)->i_xattr_sem){+.+.+.}, at: [] reiserfs_xattr_set_handle+0x8a/0x470 [ 990.013233] [ 990.013233] which lock already depends on the new lock. [ 990.013233] [ 990.013233] [ 990.013233] the existing dependency chain (in reverse order) is: [ 990.013233] [ 990.013233] -> #1 (&REISERFS_I(inode)->i_xattr_sem){+.+.+.}: [ 990.013233] [] __lock_acquire+0xf9c/0x1560 [ 990.013233] [] lock_acquire+0x8f/0xb0 [ 990.013233] [] down_write+0x44/0x80 [ 990.013233] [] reiserfs_xattr_set_handle+0x8a/0x470 [ 990.013233] [] reiserfs_xattr_set+0xb0/0x150 [ 990.013233] [] user_set+0x8a/0x90 [ 990.013233] [] reiserfs_setxattr+0xaa/0xb0 [ 990.013233] [] __vfs_setxattr_noperm+0x36/0xa0 [ 990.013233] [] vfs_setxattr+0xbc/0xc0 [ 990.013233] [] setxattr+0xc0/0x150 [ 990.013233] [] sys_fsetxattr+0x8d/0xa0 [ 990.013233] [] system_call_fastpath+0x16/0x1b [ 990.013233] [ 990.013233] -> #0 (&REISERFS_SB(s)->lock){+.+.+.}: [ 990.013233] [] __lock_acquire+0x12d0/0x1560 [ 990.013233] [] lock_acquire+0x8f/0xb0 [ 990.013233] [] __mutex_lock_common+0x47/0x3b0 [ 990.013233] [] mutex_lock_nested+0x3e/0x50 [ 990.013233] [] reiserfs_write_lock+0x35/0x50 [ 990.013233] [] reiserfs_prepare_write+0x45/0x180 [ 990.013233] [] reiserfs_xattr_set_handle+0x2a6/0x470 [ 990.013233] [] reiserfs_xattr_set+0xb0/0x150 [ 990.013233] [] user_set+0x8a/0x90 [ 990.013233] [] reiserfs_setxattr+0xaa/0xb0 [ 990.013233] [] __vfs_setxattr_noperm+0x36/0xa0 [ 990.013233] [] vfs_setxattr+0xbc/0xc0 [ 990.013233] [] setxattr+0xc0/0x150 [ 990.013233] [] sys_fsetxattr+0x8d/0xa0 [ 990.013233] [] system_call_fastpath+0x16/0x1b [ 990.013233] [ 990.013233] other info that might help us debug this: [ 990.013233] [ 990.013233] 2 locks held by dbench/1891: [ 990.013233] #0: (&sb->s_type->i_mutex_key#12){+.+.+.}, at: [] vfs_setxattr+0x78/0xc0 [ 990.013233] #1: (&REISERFS_I(inode)->i_xattr_sem){+.+.+.}, at: [] reiserfs_xattr_set_handle+0x8a/0x470 [ 990.013233] [ 990.013233] stack backtrace: [ 990.013233] Pid: 1891, comm: dbench Not tainted 2.6.33-rc1 #1 [ 990.013233] Call Trace: [ 990.013233] [] print_circular_bug+0xe9/0xf0 [ 990.013233] [] __lock_acquire+0x12d0/0x1560 [ 990.013233] [] ? reiserfs_xattr_set_handle+0x8a/0x470 [ 990.013233] [] lock_acquire+0x8f/0xb0 [ 990.013233] [] ? reiserfs_write_lock+0x35/0x50 [ 990.013233] [] ? reiserfs_xattr_set_handle+0x8a/0x470 [ 990.013233] [] __mutex_lock_common+0x47/0x3b0 [ 990.013233] [] ? reiserfs_write_lock+0x35/0x50 [ 990.013233] [] ? reiserfs_write_lock+0x35/0x50 [ 990.013233] [] ? mark_held_locks+0x72/0xa0 [ 990.013233] [] ? __mutex_unlock_slowpath+0xbd/0x140 [ 990.013233] [] ? trace_hardirqs_on_caller+0x14d/0x1a0 [ 990.013233] [] mutex_lock_nested+0x3e/0x50 [ 990.013233] [] reiserfs_write_lock+0x35/0x50 [ 990.013233] [] reiserfs_prepare_write+0x45/0x180 [ 990.013233] [] reiserfs_xattr_set_handle+0x2a6/0x470 [ 990.013233] [] reiserfs_xattr_set+0xb0/0x150 [ 990.013233] [] ? __mutex_lock_common+0x284/0x3b0 [ 990.013233] [] user_set+0x8a/0x90 [ 990.013233] [] reiserfs_setxattr+0xaa/0xb0 [ 990.013233] [] __vfs_setxattr_noperm+0x36/0xa0 [ 990.013233] [] vfs_setxattr+0xbc/0xc0 [ 990.013233] [] setxattr+0xc0/0x150 [ 990.013233] [] ? sched_clock_cpu+0xb8/0x100 [ 990.013233] [] ? trace_hardirqs_off+0xd/0x10 [ 990.013233] [] ? cpu_clock+0x43/0x50 [ 990.013233] [] ? fget+0xb0/0x110 [ 990.013233] [] ? fget+0x0/0x110 [ 990.013233] [] ? sysret_check+0x27/0x62 [ 990.013233] [] sys_fsetxattr+0x8d/0xa0 [ 990.013233] [] system_call_fastpath+0x16/0x1b Reported-and-tested-by: Christian Kujau Signed-off-by: Frederic Weisbecker Cc: Alexander Beregalov Cc: Chris Mason Cc: Ingo Molnar diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index 8891cd8..a0e2e7a 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c @@ -484,7 +484,7 @@ reiserfs_xattr_set_handle(struct reiserfs_transaction_handle *th, if (IS_ERR(dentry)) return PTR_ERR(dentry); - down_write(&REISERFS_I(inode)->i_xattr_sem); + reiserfs_down_read_safe(&REISERFS_I(inode)->i_xattr_sem, inode->i_sb); xahash = xattr_hash(buffer, buffer_size); while (buffer_pos < buffer_size || buffer_pos == 0) { diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h index 4351b49..35d3f45 100644 --- a/include/linux/reiserfs_fs.h +++ b/include/linux/reiserfs_fs.h @@ -106,6 +106,14 @@ reiserfs_mutex_lock_nested_safe(struct mutex *m, unsigned int subclass, reiserfs_write_lock(s); } +static inline void +reiserfs_down_read_safe(struct rw_semaphore *sem, struct super_block *s) +{ + reiserfs_write_unlock(s); + down_read(sem); + reiserfs_write_lock(s); +} + /* * When we schedule, we usually want to also release the write lock, * according to the previous bkl based locking scheme of reiserfs. -- cgit v0.10.2 From c4a62ca362258d98f42efb282cfbf9b61caffdbe Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Wed, 30 Dec 2009 03:20:19 +0100 Subject: reiserfs: Warn on lock relax if taken recursively When we relax the reiserfs lock to avoid creating unwanted dependencies against others locks while grabbing these, we want to ensure it has not been taken recursively, otherwise the lock won't be really relaxed. Only its depth will be decreased. The unwanted dependency would then actually happen. To prevent from that, add a reiserfs_lock_check_recursive() call in the places that need it. Signed-off-by: Frederic Weisbecker Cc: Alexander Beregalov Cc: Chris Mason Cc: Ingo Molnar diff --git a/fs/reiserfs/lock.c b/fs/reiserfs/lock.c index ee2cfc0..b87aa2c 100644 --- a/fs/reiserfs/lock.c +++ b/fs/reiserfs/lock.c @@ -86,3 +86,12 @@ void reiserfs_check_lock_depth(struct super_block *sb, char *caller) reiserfs_panic(sb, "%s called without kernel lock held %d", caller); } + +#ifdef CONFIG_REISERFS_CHECK +void reiserfs_lock_check_recursive(struct super_block *sb) +{ + struct reiserfs_sb_info *sb_i = REISERFS_SB(sb); + + WARN_ONCE((sb_i->lock_depth > 0), "Unwanted recursive reiserfs lock!\n"); +} +#endif diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h index 35d3f45..793bf83 100644 --- a/include/linux/reiserfs_fs.h +++ b/include/linux/reiserfs_fs.h @@ -62,6 +62,12 @@ void reiserfs_write_unlock(struct super_block *s); int reiserfs_write_lock_once(struct super_block *s); void reiserfs_write_unlock_once(struct super_block *s, int lock_depth); +#ifdef CONFIG_REISERFS_CHECK +void reiserfs_lock_check_recursive(struct super_block *s); +#else +static inline void reiserfs_lock_check_recursive(struct super_block *s) { } +#endif + /* * Several mutexes depend on the write lock. * However sometimes we want to relax the write lock while we hold @@ -92,6 +98,7 @@ void reiserfs_write_unlock_once(struct super_block *s, int lock_depth); static inline void reiserfs_mutex_lock_safe(struct mutex *m, struct super_block *s) { + reiserfs_lock_check_recursive(s); reiserfs_write_unlock(s); mutex_lock(m); reiserfs_write_lock(s); @@ -101,6 +108,7 @@ static inline void reiserfs_mutex_lock_nested_safe(struct mutex *m, unsigned int subclass, struct super_block *s) { + reiserfs_lock_check_recursive(s); reiserfs_write_unlock(s); mutex_lock_nested(m, subclass); reiserfs_write_lock(s); @@ -109,6 +117,7 @@ reiserfs_mutex_lock_nested_safe(struct mutex *m, unsigned int subclass, static inline void reiserfs_down_read_safe(struct rw_semaphore *sem, struct super_block *s) { + reiserfs_lock_check_recursive(s); reiserfs_write_unlock(s); down_read(sem); reiserfs_write_lock(s); -- cgit v0.10.2 From 27026a05bb805866a3b9068dda8153b72cb942f4 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Wed, 30 Dec 2009 05:06:21 +0100 Subject: reiserfs: Fix reiserfs lock <-> i_mutex dependency inversion on xattr While deleting the xattrs of an inode, we hold the reiserfs lock and grab the inode->i_mutex of the targeted inode and the root private xattr directory. Later on, we may relax the reiserfs lock for various reasons, this creates inverted dependencies. We can remove the reiserfs lock -> i_mutex dependency by relaxing the former before calling open_xa_dir(). This is fine because the lookup and creation of xattr private directories done in open_xa_dir() are covered by the targeted inode mutexes. And deeper operations in the tree are still done under the write lock. This fixes the following lockdep report: ======================================================= [ INFO: possible circular locking dependency detected ] 2.6.32-atom #173 ------------------------------------------------------- cp/3204 is trying to acquire lock: (&REISERFS_SB(s)->lock){+.+.+.}, at: [] reiserfs_write_lock_once+0x29/0x50 but task is already holding lock: (&sb->s_type->i_mutex_key#4/3){+.+.+.}, at: [] open_xa_dir+0xd8/0x1b0 which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #1 (&sb->s_type->i_mutex_key#4/3){+.+.+.}: [] __lock_acquire+0x11ff/0x19e0 [] lock_acquire+0x68/0x90 [] mutex_lock_nested+0x5b/0x340 [] open_xa_dir+0x43/0x1b0 [] reiserfs_for_each_xattr+0x62/0x260 [] reiserfs_delete_xattrs+0x1a/0x60 [] reiserfs_delete_inode+0x9f/0x150 [] generic_delete_inode+0xa2/0x170 [] generic_drop_inode+0x4f/0x70 [] iput+0x47/0x50 [] do_unlinkat+0xd5/0x160 [] sys_unlink+0x10/0x20 [] sysenter_do_call+0x12/0x32 -> #0 (&REISERFS_SB(s)->lock){+.+.+.}: [] __lock_acquire+0x18f6/0x19e0 [] lock_acquire+0x68/0x90 [] mutex_lock_nested+0x5b/0x340 [] reiserfs_write_lock_once+0x29/0x50 [] reiserfs_lookup+0x62/0x140 [] __lookup_hash+0xef/0x110 [] lookup_one_len+0x8d/0xc0 [] open_xa_dir+0xea/0x1b0 [] xattr_lookup+0x15/0x160 [] reiserfs_xattr_get+0x56/0x2a0 [] reiserfs_get_acl+0xa2/0x360 [] reiserfs_cache_default_acl+0x3a/0x160 [] reiserfs_mkdir+0x6c/0x2c0 [] vfs_mkdir+0xd6/0x180 [] sys_mkdirat+0xc0/0xd0 [] sys_mkdir+0x20/0x30 [] sysenter_do_call+0x12/0x32 other info that might help us debug this: 2 locks held by cp/3204: #0: (&sb->s_type->i_mutex_key#4/1){+.+.+.}, at: [] lookup_create+0x26/0xa0 #1: (&sb->s_type->i_mutex_key#4/3){+.+.+.}, at: [] open_xa_dir+0xd8/0x1b0 stack backtrace: Pid: 3204, comm: cp Not tainted 2.6.32-atom #173 Call Trace: [] ? printk+0x18/0x1a [] print_circular_bug+0xca/0xd0 [] __lock_acquire+0x18f6/0x19e0 [] ? check_usage+0x6a/0x460 [] lock_acquire+0x68/0x90 [] ? reiserfs_write_lock_once+0x29/0x50 [] ? reiserfs_write_lock_once+0x29/0x50 [] mutex_lock_nested+0x5b/0x340 [] ? reiserfs_write_lock_once+0x29/0x50 [] reiserfs_write_lock_once+0x29/0x50 [] reiserfs_lookup+0x62/0x140 [] ? debug_check_no_locks_freed+0x8a/0x140 [] ? trace_hardirqs_on_caller+0x124/0x170 [] __lookup_hash+0xef/0x110 [] lookup_one_len+0x8d/0xc0 [] open_xa_dir+0xea/0x1b0 [] xattr_lookup+0x15/0x160 [] reiserfs_xattr_get+0x56/0x2a0 [] reiserfs_get_acl+0xa2/0x360 [] ? new_inode+0x27/0xa0 [] reiserfs_cache_default_acl+0x3a/0x160 [] ? _spin_unlock+0x27/0x40 [] reiserfs_mkdir+0x6c/0x2c0 [] ? __d_lookup+0x108/0x190 [] ? mark_held_locks+0x62/0x80 [] ? mutex_lock_nested+0x2bd/0x340 [] ? generic_permission+0x1a/0xa0 [] ? security_inode_permission+0x1e/0x20 [] vfs_mkdir+0xd6/0x180 [] sys_mkdirat+0xc0/0xd0 [] ? up_read+0x16/0x30 [] ? restore_all_notrace+0x0/0x18 [] sys_mkdir+0x20/0x30 [] sysenter_do_call+0x12/0x32 v2: Don't drop reiserfs_mutex_lock_nested_safe() as we'll still need it later Signed-off-by: Frederic Weisbecker Tested-by: Christian Kujau Cc: Alexander Beregalov Cc: Chris Mason Cc: Ingo Molnar diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index a0e2e7a..c320c77 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c @@ -234,17 +234,22 @@ static int reiserfs_for_each_xattr(struct inode *inode, if (IS_PRIVATE(inode) || get_inode_sd_version(inode) == STAT_DATA_V1) return 0; + reiserfs_write_unlock(inode->i_sb); dir = open_xa_dir(inode, XATTR_REPLACE); if (IS_ERR(dir)) { err = PTR_ERR(dir); + reiserfs_write_lock(inode->i_sb); goto out; } else if (!dir->d_inode) { err = 0; + reiserfs_write_lock(inode->i_sb); goto out_dir; } - reiserfs_mutex_lock_nested_safe(&dir->d_inode->i_mutex, I_MUTEX_XATTR, - inode->i_sb); + mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_XATTR); + + reiserfs_write_lock(inode->i_sb); + buf.xadir = dir; err = reiserfs_readdir_dentry(dir, &buf, fill_with_dentries, &pos); while ((err == 0 || err == -ENOSPC) && buf.count) { -- cgit v0.10.2 From 0523676d3f3aa7edeea63cc3a1bc4dc612380a26 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Wed, 30 Dec 2009 05:56:08 +0100 Subject: reiserfs: Relax reiserfs lock while freeing the journal Keeping the reiserfs lock while freeing the journal on umount path triggers a lock inversion between bdev->bd_mutex and the reiserfs lock. We don't need the reiserfs lock at this stage. The filesystem is not usable anymore, and there are no more pending commits, everything got flushed (even this operation was done in parallel and didn't required the reiserfs lock from the current process). This fixes the following lockdep report: ======================================================= [ INFO: possible circular locking dependency detected ] 2.6.32-atom #172 ------------------------------------------------------- umount/3904 is trying to acquire lock: (&bdev->bd_mutex){+.+.+.}, at: [] __blkdev_put+0x22/0x160 but task is already holding lock: (&REISERFS_SB(s)->lock){+.+.+.}, at: [] reiserfs_write_lock+0x29/0x40 which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #3 (&REISERFS_SB(s)->lock){+.+.+.}: [] __lock_acquire+0x11ff/0x19e0 [] lock_acquire+0x68/0x90 [] mutex_lock_nested+0x5b/0x340 [] reiserfs_write_lock_once+0x29/0x50 [] reiserfs_get_block+0x85/0x1620 [] do_mpage_readpage+0x1f0/0x6d0 [] mpage_readpages+0xc0/0x100 [] reiserfs_readpages+0x19/0x20 [] __do_page_cache_readahead+0x1bc/0x260 [] ra_submit+0x28/0x40 [] filemap_fault+0x40e/0x420 [] __do_fault+0x3d/0x430 [] handle_mm_fault+0x12e/0x790 [] do_page_fault+0x135/0x330 [] error_code+0x6b/0x70 [] load_elf_binary+0x82a/0x1a10 [] search_binary_handler+0x90/0x1d0 [] do_execve+0x1df/0x250 [] sys_execve+0x46/0x70 [] syscall_call+0x7/0xb -> #2 (&mm->mmap_sem){++++++}: [] __lock_acquire+0x11ff/0x19e0 [] lock_acquire+0x68/0x90 [] might_fault+0x8b/0xb0 [] copy_to_user+0x32/0x70 [] filldir64+0xa4/0xf0 [] sysfs_readdir+0x116/0x210 [] vfs_readdir+0x8d/0xb0 [] sys_getdents64+0x69/0xb0 [] sysenter_do_call+0x12/0x32 -> #1 (sysfs_mutex){+.+.+.}: [] __lock_acquire+0x11ff/0x19e0 [] lock_acquire+0x68/0x90 [] mutex_lock_nested+0x5b/0x340 [] sysfs_addrm_start+0x2c/0xb0 [] create_dir+0x40/0x90 [] sysfs_create_dir+0x2b/0x50 [] kobject_add_internal+0xc2/0x1b0 [] kobject_add_varg+0x31/0x50 [] kobject_add+0x2c/0x60 [] device_add+0x94/0x560 [] add_partition+0x18a/0x2a0 [] rescan_partitions+0x33a/0x450 [] __blkdev_get+0x12f/0x2d0 [] blkdev_get+0xa/0x10 [] register_disk+0x108/0x130 [] add_disk+0xd9/0x130 [] sd_probe_async+0x105/0x1d0 [] async_thread+0xcf/0x230 [] kthread+0x74/0x80 [] kernel_thread_helper+0x7/0x3c -> #0 (&bdev->bd_mutex){+.+.+.}: [] __lock_acquire+0x18f6/0x19e0 [] lock_acquire+0x68/0x90 [] mutex_lock_nested+0x5b/0x340 [] __blkdev_put+0x22/0x160 [] blkdev_put+0xa/0x10 [] free_journal_ram+0xd2/0x130 [] do_journal_release+0x98/0x190 [] journal_release+0xa/0x10 [] reiserfs_put_super+0x36/0x130 [] generic_shutdown_super+0x4f/0xe0 [] kill_block_super+0x25/0x40 [] reiserfs_kill_sb+0x7f/0x90 [] deactivate_super+0x7a/0x90 [] mntput_no_expire+0x98/0xd0 [] sys_umount+0x4c/0x310 [] sys_oldumount+0x19/0x20 [] sysenter_do_call+0x12/0x32 other info that might help us debug this: 2 locks held by umount/3904: #0: (&type->s_umount_key#30){+++++.}, at: [] deactivate_super+0x75/0x90 #1: (&REISERFS_SB(s)->lock){+.+.+.}, at: [] reiserfs_write_lock+0x29/0x40 stack backtrace: Pid: 3904, comm: umount Not tainted 2.6.32-atom #172 Call Trace: [] ? printk+0x18/0x1a [] print_circular_bug+0xca/0xd0 [] __lock_acquire+0x18f6/0x19e0 [] ? free_pcppages_bulk+0x1f/0x250 [] lock_acquire+0x68/0x90 [] ? __blkdev_put+0x22/0x160 [] ? __blkdev_put+0x22/0x160 [] mutex_lock_nested+0x5b/0x340 [] ? __blkdev_put+0x22/0x160 [] ? mark_held_locks+0x62/0x80 [] ? kfree+0x92/0xd0 [] __blkdev_put+0x22/0x160 [] ? trace_hardirqs_on+0xb/0x10 [] blkdev_put+0xa/0x10 [] free_journal_ram+0xd2/0x130 [] do_journal_release+0x98/0x190 [] journal_release+0xa/0x10 [] reiserfs_put_super+0x36/0x130 [] ? up_write+0x16/0x30 [] generic_shutdown_super+0x4f/0xe0 [] kill_block_super+0x25/0x40 [] ? vfs_quota_off+0x0/0x20 [] reiserfs_kill_sb+0x7f/0x90 [] deactivate_super+0x7a/0x90 [] mntput_no_expire+0x98/0xd0 [] sys_umount+0x4c/0x310 [] sys_oldumount+0x19/0x20 [] sysenter_do_call+0x12/0x32 Signed-off-by: Frederic Weisbecker Cc: Alexander Beregalov Cc: Chris Mason Cc: Ingo Molnar diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c index a059879..83ac4d3 100644 --- a/fs/reiserfs/journal.c +++ b/fs/reiserfs/journal.c @@ -2009,10 +2009,11 @@ static int do_journal_release(struct reiserfs_transaction_handle *th, destroy_workqueue(commit_wq); commit_wq = NULL; } - reiserfs_write_lock(sb); free_journal_ram(sb); + reiserfs_write_lock(sb); + return 0; } -- cgit v0.10.2 From 3f14fea6bbd3444dd46a2af3a2e219e792616645 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Wed, 30 Dec 2009 07:03:53 +0100 Subject: reiserfs: Relax lock before open xattr dir in reiserfs_xattr_set_handle() We call xattr_lookup() from reiserfs_xattr_get(). We then hold the reiserfs lock when we grab the i_mutex. But later, we may relax the reiserfs lock, creating dependency inversion between both locks. The lookups and creation jobs ar already protected by the inode mutex, so we can safely relax the reiserfs lock, dropping the unwanted reiserfs lock -> i_mutex dependency, as shown in the following lockdep report: ======================================================= [ INFO: possible circular locking dependency detected ] 2.6.32-atom #173 ------------------------------------------------------- cp/3204 is trying to acquire lock: (&REISERFS_SB(s)->lock){+.+.+.}, at: [] reiserfs_write_lock_once+0x29/0x50 but task is already holding lock: (&sb->s_type->i_mutex_key#4/3){+.+.+.}, at: [] open_xa_dir+0xd8/0x1b0 which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #1 (&sb->s_type->i_mutex_key#4/3){+.+.+.}: [] __lock_acquire+0x11ff/0x19e0 [] lock_acquire+0x68/0x90 [] mutex_lock_nested+0x5b/0x340 [] open_xa_dir+0x43/0x1b0 [] reiserfs_for_each_xattr+0x62/0x260 [] reiserfs_delete_xattrs+0x1a/0x60 [] reiserfs_delete_inode+0x9f/0x150 [] generic_delete_inode+0xa2/0x170 [] generic_drop_inode+0x4f/0x70 [] iput+0x47/0x50 [] do_unlinkat+0xd5/0x160 [] sys_unlink+0x10/0x20 [] sysenter_do_call+0x12/0x32 -> #0 (&REISERFS_SB(s)->lock){+.+.+.}: [] __lock_acquire+0x18f6/0x19e0 [] lock_acquire+0x68/0x90 [] mutex_lock_nested+0x5b/0x340 [] reiserfs_write_lock_once+0x29/0x50 [] reiserfs_lookup+0x62/0x140 [] __lookup_hash+0xef/0x110 [] lookup_one_len+0x8d/0xc0 [] open_xa_dir+0xea/0x1b0 [] xattr_lookup+0x15/0x160 [] reiserfs_xattr_get+0x56/0x2a0 [] reiserfs_get_acl+0xa2/0x360 [] reiserfs_cache_default_acl+0x3a/0x160 [] reiserfs_mkdir+0x6c/0x2c0 [] vfs_mkdir+0xd6/0x180 [] sys_mkdirat+0xc0/0xd0 [] sys_mkdir+0x20/0x30 [] sysenter_do_call+0x12/0x32 other info that might help us debug this: 2 locks held by cp/3204: #0: (&sb->s_type->i_mutex_key#4/1){+.+.+.}, at: [] lookup_create+0x26/0xa0 #1: (&sb->s_type->i_mutex_key#4/3){+.+.+.}, at: [] open_xa_dir+0xd8/0x1b0 stack backtrace: Pid: 3204, comm: cp Not tainted 2.6.32-atom #173 Call Trace: [] ? printk+0x18/0x1a [] print_circular_bug+0xca/0xd0 [] __lock_acquire+0x18f6/0x19e0 [] ? check_usage+0x6a/0x460 [] lock_acquire+0x68/0x90 [] ? reiserfs_write_lock_once+0x29/0x50 [] ? reiserfs_write_lock_once+0x29/0x50 [] mutex_lock_nested+0x5b/0x340 [] ? reiserfs_write_lock_once+0x29/0x50 [] reiserfs_write_lock_once+0x29/0x50 [] reiserfs_lookup+0x62/0x140 [] ? debug_check_no_locks_freed+0x8a/0x140 [] ? trace_hardirqs_on_caller+0x124/0x170 [] __lookup_hash+0xef/0x110 [] lookup_one_len+0x8d/0xc0 [] open_xa_dir+0xea/0x1b0 [] xattr_lookup+0x15/0x160 [] reiserfs_xattr_get+0x56/0x2a0 [] reiserfs_get_acl+0xa2/0x360 [] ? new_inode+0x27/0xa0 [] reiserfs_cache_default_acl+0x3a/0x160 [] ? _spin_unlock+0x27/0x40 [] reiserfs_mkdir+0x6c/0x2c0 [] ? __d_lookup+0x108/0x190 [] ? mark_held_locks+0x62/0x80 [] ? mutex_lock_nested+0x2bd/0x340 [] ? generic_permission+0x1a/0xa0 [] ? security_inode_permission+0x1e/0x20 [] vfs_mkdir+0xd6/0x180 [] sys_mkdirat+0xc0/0xd0 [] ? up_read+0x16/0x30 [] ? restore_all_notrace+0x0/0x18 [] sys_mkdir+0x20/0x30 [] sysenter_do_call+0x12/0x32 Signed-off-by: Frederic Weisbecker Tested-by: Christian Kujau Cc: Alexander Beregalov Cc: Chris Mason Cc: Ingo Molnar diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index c320c77..78a3f24 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c @@ -485,11 +485,16 @@ reiserfs_xattr_set_handle(struct reiserfs_transaction_handle *th, if (!buffer) return lookup_and_delete_xattr(inode, name); + reiserfs_write_unlock(inode->i_sb); dentry = xattr_lookup(inode, name, flags); - if (IS_ERR(dentry)) + if (IS_ERR(dentry)) { + reiserfs_write_lock(inode->i_sb); return PTR_ERR(dentry); + } - reiserfs_down_read_safe(&REISERFS_I(inode)->i_xattr_sem, inode->i_sb); + down_read(&REISERFS_I(inode)->i_xattr_sem); + + reiserfs_write_lock(inode->i_sb); xahash = xattr_hash(buffer, buffer_size); while (buffer_pos < buffer_size || buffer_pos == 0) { -- cgit v0.10.2 From c674905ca74ad0ae5b048afb1ef68663a0d7e987 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Wed, 30 Dec 2009 07:12:03 +0100 Subject: reiserfs: Fix unwanted recursive reiserfs lock in reiserfs_unlink() reiserfs_unlink() may or may not be called under the reiserfs lock. But it also takes the reiserfs lock and can then acquire it recursively which leads to do_journal_begin_r() that fails to relax the reiserfs lock before grabbing the journal mutex, creating an unexpected lock inversion. We need to ensure reiserfs_unlink() won't get the reiserfs lock recursively using reiserfs_write_lock_once(). This fixes the following warning that precedes a lock inversion report (reiserfs lock <-> journal mutex). ------------[ cut here ]------------ WARNING: at fs/reiserfs/lock.c:95 reiserfs_lock_check_recursive+0x3a/0x50() Hardware name: MS-7418 Unwanted recursive reiserfs lock! Pid: 3208, comm: dbench Not tainted 2.6.32-atom #177 Call Trace: [] ? reiserfs_lock_check_recursive+0x3a/0x50 [] ? reiserfs_lock_check_recursive+0x3a/0x50 [] warn_slowpath_common+0x67/0xc0 [] ? reiserfs_lock_check_recursive+0x3a/0x50 [] warn_slowpath_fmt+0x26/0x30 [] reiserfs_lock_check_recursive+0x3a/0x50 [] do_journal_begin_r+0x83/0x360 [] ? __lock_acquire+0x1296/0x19e0 [] ? xattr_unlink+0x57/0xb0 [] journal_begin+0x80/0x130 [] reiserfs_unlink+0x7d/0x2d0 [] ? xattr_unlink+0x57/0xb0 [] ? xattr_unlink+0x57/0xb0 [] ? xattr_unlink+0x57/0xb0 [] xattr_unlink+0x64/0xb0 [] delete_one_xattr+0x29/0x100 [] reiserfs_for_each_xattr+0x10b/0x290 [] ? delete_one_xattr+0x0/0x100 [] ? mutex_lock_nested+0x299/0x340 [] reiserfs_delete_xattrs+0x1a/0x60 [] ? reiserfs_write_lock_once+0x29/0x50 [] reiserfs_delete_inode+0x9f/0x150 [] ? _atomic_dec_and_lock+0x4f/0x70 [] ? reiserfs_delete_inode+0x0/0x150 [] generic_delete_inode+0xa2/0x170 [] generic_drop_inode+0x4f/0x70 [] iput+0x47/0x50 [] do_unlinkat+0xd5/0x160 [] ? up_read+0x16/0x30 [] ? do_page_fault+0x187/0x330 [] ? restore_all_notrace+0x0/0x18 [] ? do_page_fault+0x0/0x330 [] ? trace_hardirqs_on_caller+0x124/0x170 [] sys_unlink+0x10/0x20 [] sysenter_do_call+0x12/0x32 ---[ end trace 2e35d71a6cc69d0c ]--- Signed-off-by: Frederic Weisbecker Tested-by: Christian Kujau Cc: Alexander Beregalov Cc: Chris Mason Cc: Ingo Molnar diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index e296ff7..9d4dcf0 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c @@ -921,6 +921,7 @@ static int reiserfs_unlink(struct inode *dir, struct dentry *dentry) struct reiserfs_transaction_handle th; int jbegin_count; unsigned long savelink; + int depth; inode = dentry->d_inode; @@ -932,7 +933,7 @@ static int reiserfs_unlink(struct inode *dir, struct dentry *dentry) JOURNAL_PER_BALANCE_CNT * 2 + 2 + 4 * REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb); - reiserfs_write_lock(dir->i_sb); + depth = reiserfs_write_lock_once(dir->i_sb); retval = journal_begin(&th, dir->i_sb, jbegin_count); if (retval) goto out_unlink; @@ -993,7 +994,7 @@ static int reiserfs_unlink(struct inode *dir, struct dentry *dentry) retval = journal_end(&th, dir->i_sb, jbegin_count); reiserfs_check_path(&path); - reiserfs_write_unlock(dir->i_sb); + reiserfs_write_unlock_once(dir->i_sb, depth); return retval; end_unlink: @@ -1003,7 +1004,7 @@ static int reiserfs_unlink(struct inode *dir, struct dentry *dentry) if (err) retval = err; out_unlink: - reiserfs_write_unlock(dir->i_sb); + reiserfs_write_unlock_once(dir->i_sb, depth); return retval; } -- cgit v0.10.2 From 4dd859697f836cf62c8de08bd9a9f4b4f4beaa91 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Wed, 30 Dec 2009 07:26:28 +0100 Subject: reiserfs: Fix journal mutex <-> inode mutex lock inversion We need to relax the reiserfs lock before locking the inode mutex from xattr_unlink(), otherwise we'll face the usual bad dependencies: ======================================================= [ INFO: possible circular locking dependency detected ] 2.6.32-atom #178 ------------------------------------------------------- rm/3202 is trying to acquire lock: (&journal->j_mutex){+.+...}, at: [] do_journal_begin_r+0x94/0x360 but task is already holding lock: (&sb->s_type->i_mutex_key#4/2){+.+...}, at: [] xattr_unlink+0x57/0xb0 which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #2 (&sb->s_type->i_mutex_key#4/2){+.+...}: [] __lock_acquire+0x11ff/0x19e0 [] lock_acquire+0x68/0x90 [] mutex_lock_nested+0x5b/0x340 [] xattr_unlink+0x57/0xb0 [] delete_one_xattr+0x29/0x100 [] reiserfs_for_each_xattr+0x10b/0x290 [] reiserfs_delete_xattrs+0x1a/0x60 [] reiserfs_delete_inode+0x9f/0x150 [] generic_delete_inode+0xa2/0x170 [] generic_drop_inode+0x4f/0x70 [] iput+0x47/0x50 [] do_unlinkat+0xd5/0x160 [] sys_unlinkat+0x23/0x40 [] sysenter_do_call+0x12/0x32 -> #1 (&REISERFS_SB(s)->lock){+.+.+.}: [] __lock_acquire+0x11ff/0x19e0 [] lock_acquire+0x68/0x90 [] mutex_lock_nested+0x5b/0x340 [] reiserfs_write_lock+0x29/0x40 [] do_journal_begin_r+0x9c/0x360 [] journal_begin+0x80/0x130 [] reiserfs_remount+0x223/0x4e0 [] do_remount_sb+0xa6/0x140 [] do_mount+0x560/0x750 [] sys_mount+0x84/0xb0 [] sysenter_do_call+0x12/0x32 -> #0 (&journal->j_mutex){+.+...}: [] __lock_acquire+0x18f6/0x19e0 [] lock_acquire+0x68/0x90 [] mutex_lock_nested+0x5b/0x340 [] do_journal_begin_r+0x94/0x360 [] journal_begin+0x80/0x130 [] reiserfs_unlink+0x83/0x2e0 [] xattr_unlink+0x64/0xb0 [] delete_one_xattr+0x29/0x100 [] reiserfs_for_each_xattr+0x10b/0x290 [] reiserfs_delete_xattrs+0x1a/0x60 [] reiserfs_delete_inode+0x9f/0x150 [] generic_delete_inode+0xa2/0x170 [] generic_drop_inode+0x4f/0x70 [] iput+0x47/0x50 [] do_unlinkat+0xd5/0x160 [] sys_unlinkat+0x23/0x40 [] sysenter_do_call+0x12/0x32 other info that might help us debug this: 2 locks held by rm/3202: #0: (&sb->s_type->i_mutex_key#4/3){+.+.+.}, at: [] reiserfs_for_each_xattr+0x9b/0x290 #1: (&sb->s_type->i_mutex_key#4/2){+.+...}, at: [] xattr_unlink+0x57/0xb0 stack backtrace: Pid: 3202, comm: rm Not tainted 2.6.32-atom #178 Call Trace: [] ? printk+0x18/0x1a [] print_circular_bug+0xca/0xd0 [] __lock_acquire+0x18f6/0x19e0 [] ? xattr_unlink+0x57/0xb0 [] lock_acquire+0x68/0x90 [] ? do_journal_begin_r+0x94/0x360 [] ? do_journal_begin_r+0x94/0x360 [] mutex_lock_nested+0x5b/0x340 [] ? do_journal_begin_r+0x94/0x360 [] do_journal_begin_r+0x94/0x360 [] ? run_timer_softirq+0x1a6/0x220 [] ? __do_softirq+0x50/0x140 [] journal_begin+0x80/0x130 [] ? __do_softirq+0xf2/0x140 [] ? hrtimer_interrupt+0xdf/0x220 [] reiserfs_unlink+0x83/0x2e0 [] ? mark_held_locks+0x62/0x80 [] ? trace_hardirqs_on_thunk+0xc/0x10 [] ? restore_all_notrace+0x0/0x18 [] ? xattr_unlink+0x57/0xb0 [] xattr_unlink+0x64/0xb0 [] delete_one_xattr+0x29/0x100 [] reiserfs_for_each_xattr+0x10b/0x290 [] ? delete_one_xattr+0x0/0x100 [] ? mutex_lock_nested+0x299/0x340 [] reiserfs_delete_xattrs+0x1a/0x60 [] ? reiserfs_write_lock_once+0x29/0x50 [] reiserfs_delete_inode+0x9f/0x150 [] ? _atomic_dec_and_lock+0x4f/0x70 [] ? reiserfs_delete_inode+0x0/0x150 [] generic_delete_inode+0xa2/0x170 [] generic_drop_inode+0x4f/0x70 [] iput+0x47/0x50 [] do_unlinkat+0xd5/0x160 [] ? mutex_unlock+0x8/0x10 [] ? vfs_readdir+0x7d/0xb0 [] ? filldir64+0x0/0xf0 [] ? sysenter_exit+0xf/0x16 [] ? trace_hardirqs_on_caller+0x124/0x170 [] sys_unlinkat+0x23/0x40 [] sysenter_do_call+0x12/0x32 Signed-off-by: Frederic Weisbecker Tested-by: Christian Kujau Cc: Alexander Beregalov Cc: Chris Mason Cc: Ingo Molnar diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index 78a3f24..8b9631d 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c @@ -82,7 +82,8 @@ static int xattr_unlink(struct inode *dir, struct dentry *dentry) BUG_ON(!mutex_is_locked(&dir->i_mutex)); vfs_dq_init(dir); - mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_CHILD); + reiserfs_mutex_lock_nested_safe(&dentry->d_inode->i_mutex, + I_MUTEX_CHILD, dir->i_sb); error = dir->i_op->unlink(dir, dentry); mutex_unlock(&dentry->d_inode->i_mutex); -- cgit v0.10.2 From 8b513f56d4e117f11cf0760abcc030eedefc45c3 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Wed, 30 Dec 2009 07:28:58 +0100 Subject: reiserfs: Safely acquire i_mutex from reiserfs_for_each_xattr Relax the reiserfs lock before taking the inode mutex from reiserfs_for_each_xattr() to avoid the usual bad dependencies: ======================================================= [ INFO: possible circular locking dependency detected ] 2.6.32-atom #179 ------------------------------------------------------- rm/3242 is trying to acquire lock: (&sb->s_type->i_mutex_key#4/3){+.+.+.}, at: [] reiserfs_for_each_xattr+0x23f/0x290 but task is already holding lock: (&REISERFS_SB(s)->lock){+.+.+.}, at: [] reiserfs_write_lock+0x29/0x40 which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #1 (&REISERFS_SB(s)->lock){+.+.+.}: [] __lock_acquire+0x11ff/0x19e0 [] lock_acquire+0x68/0x90 [] mutex_lock_nested+0x5b/0x340 [] reiserfs_write_lock_once+0x29/0x50 [] reiserfs_lookup+0x62/0x140 [] __lookup_hash+0xef/0x110 [] lookup_one_len+0x8d/0xc0 [] open_xa_dir+0xea/0x1b0 [] reiserfs_for_each_xattr+0x70/0x290 [] reiserfs_delete_xattrs+0x1a/0x60 [] reiserfs_delete_inode+0x9f/0x150 [] generic_delete_inode+0xa2/0x170 [] generic_drop_inode+0x4f/0x70 [] iput+0x47/0x50 [] do_unlinkat+0xd5/0x160 [] sys_unlinkat+0x23/0x40 [] sysenter_do_call+0x12/0x32 -> #0 (&sb->s_type->i_mutex_key#4/3){+.+.+.}: [] __lock_acquire+0x18f6/0x19e0 [] lock_acquire+0x68/0x90 [] mutex_lock_nested+0x5b/0x340 [] reiserfs_for_each_xattr+0x23f/0x290 [] reiserfs_delete_xattrs+0x1a/0x60 [] reiserfs_delete_inode+0x9f/0x150 [] generic_delete_inode+0xa2/0x170 [] generic_drop_inode+0x4f/0x70 [] iput+0x47/0x50 [] do_unlinkat+0xd5/0x160 [] sys_unlinkat+0x23/0x40 [] sysenter_do_call+0x12/0x32 other info that might help us debug this: 1 lock held by rm/3242: #0: (&REISERFS_SB(s)->lock){+.+.+.}, at: [] reiserfs_write_lock+0x29/0x40 stack backtrace: Pid: 3242, comm: rm Not tainted 2.6.32-atom #179 Call Trace: [] ? printk+0x18/0x1a [] print_circular_bug+0xca/0xd0 [] __lock_acquire+0x18f6/0x19e0 [] ? mark_held_locks+0x62/0x80 [] ? trace_hardirqs_on+0xb/0x10 [] ? mutex_unlock+0x8/0x10 [] lock_acquire+0x68/0x90 [] ? reiserfs_for_each_xattr+0x23f/0x290 [] ? reiserfs_for_each_xattr+0x23f/0x290 [] mutex_lock_nested+0x5b/0x340 [] ? reiserfs_for_each_xattr+0x23f/0x290 [] reiserfs_for_each_xattr+0x23f/0x290 [] ? delete_one_xattr+0x0/0x100 [] reiserfs_delete_xattrs+0x1a/0x60 [] ? reiserfs_write_lock_once+0x29/0x50 [] reiserfs_delete_inode+0x9f/0x150 [] ? _atomic_dec_and_lock+0x4f/0x70 [] ? reiserfs_delete_inode+0x0/0x150 [] generic_delete_inode+0xa2/0x170 [] generic_drop_inode+0x4f/0x70 [] iput+0x47/0x50 [] do_unlinkat+0xd5/0x160 [] ? mutex_unlock+0x8/0x10 [] ? vfs_readdir+0x7d/0xb0 [] ? filldir64+0x0/0xf0 [] ? sysenter_exit+0xf/0x16 [] ? trace_hardirqs_on_caller+0x124/0x170 [] sys_unlinkat+0x23/0x40 [] sysenter_do_call+0x12/0x32 Signed-off-by: Frederic Weisbecker Tested-by: Christian Kujau Cc: Alexander Beregalov Cc: Chris Mason Cc: Ingo Molnar diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index 8b9631d..bfdac66 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c @@ -289,8 +289,9 @@ static int reiserfs_for_each_xattr(struct inode *inode, err = journal_begin(&th, inode->i_sb, blocks); if (!err) { int jerror; - mutex_lock_nested(&dir->d_parent->d_inode->i_mutex, - I_MUTEX_XATTR); + reiserfs_mutex_lock_nested_safe( + &dir->d_parent->d_inode->i_mutex, + I_MUTEX_XATTR, inode->i_sb); err = action(dir, data); jerror = journal_end(&th, inode->i_sb, blocks); mutex_unlock(&dir->d_parent->d_inode->i_mutex); -- cgit v0.10.2 From 835d5247d98f46e35d007dcfa6215e526ca33360 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Wed, 30 Dec 2009 07:40:39 +0100 Subject: reiserfs: Safely acquire i_mutex from xattr_rmdir Relax the reiserfs lock before taking the inode mutex from xattr_rmdir() to avoid the usual reiserfs lock <-> inode mutex bad dependency. Signed-off-by: Frederic Weisbecker Tested-by: Christian Kujau Cc: Alexander Beregalov Cc: Chris Mason Cc: Ingo Molnar diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index bfdac66..9623cfe 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c @@ -98,7 +98,8 @@ static int xattr_rmdir(struct inode *dir, struct dentry *dentry) BUG_ON(!mutex_is_locked(&dir->i_mutex)); vfs_dq_init(dir); - mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_CHILD); + reiserfs_mutex_lock_nested_safe(&dentry->d_inode->i_mutex, + I_MUTEX_CHILD, dir->i_sb); dentry_unhash(dentry); error = dir->i_op->rmdir(dir, dentry); if (!error) -- cgit v0.10.2 From 6aff43f817ddc54fcd6f0215bfba5d334b0bbbbd Mon Sep 17 00:00:00 2001 From: Ryusuke Konishi Date: Sat, 2 Jan 2010 21:41:53 +0900 Subject: nilfs2: update mailing list address This replaces the list address for nilfs discussion to linux-nilfs at vger.kernel.org from users at nilfs.org. Signed-off-by: Ryusuke Konishi diff --git a/Documentation/filesystems/nilfs2.txt b/Documentation/filesystems/nilfs2.txt index 4949fca..839efd8 100644 --- a/Documentation/filesystems/nilfs2.txt +++ b/Documentation/filesystems/nilfs2.txt @@ -28,7 +28,7 @@ described in the man pages included in the package. Project web page: http://www.nilfs.org/en/ Download page: http://www.nilfs.org/en/download.html Git tree web page: http://www.nilfs.org/git/ -NILFS mailing lists: http://www.nilfs.org/mailman/listinfo/users +List info: http://vger.kernel.org/vger-lists.html#linux-nilfs Caveats ======= diff --git a/MAINTAINERS b/MAINTAINERS index 66f5f7d..0121c61d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3882,7 +3882,7 @@ F: drivers/net/ni5010.* NILFS2 FILESYSTEM M: KONISHI Ryusuke -L: users@nilfs.org +L: linux-nilfs@vger.kernel.org W: http://www.nilfs.org/en/ S: Supported F: Documentation/filesystems/nilfs2.txt -- cgit v0.10.2 From 4b6764fa9e25cf628e42bbd192eca1e0b8e59061 Mon Sep 17 00:00:00 2001 From: Jaswinder Singh Rajput Date: Fri, 1 Jan 2010 20:35:23 -0800 Subject: writeback: add missing kernel-doc notation Fix the following htmldocs warning: Warning(fs/fs-writeback.c:255): No description found for parameter 'sb' Signed-off-by: Jaswinder Singh Rajput Signed-off-by: Randy Dunlap Acked-by: Wu Fengguang Cc: Peter Zijlstra Cc: Jan Kara Cc: Jens Axboe Signed-off-by: Linus Torvalds diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index f6c2155..1a7c42c 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -242,6 +242,7 @@ static void bdi_sync_writeback(struct backing_dev_info *bdi, /** * bdi_start_writeback - start writeback * @bdi: the backing device to write from + * @sb: write inodes from this super_block * @nr_pages: the number of pages to write * * Description: -- cgit v0.10.2 From 143724fd3d3c154009fe95846dcbf7afadca8ab1 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 1 Jan 2010 20:35:41 -0800 Subject: Documentation: fix ioremap return type ioremap() returns a void __iomem * not a char *. Update the documentation file to reflect this. Signed-off-by: H Hartley Sweeten Signed-off-by: Randy Dunlap Signed-off-by: Linus Torvalds diff --git a/Documentation/IO-mapping.txt b/Documentation/IO-mapping.txt index 78a4406..1b5aa10 100644 --- a/Documentation/IO-mapping.txt +++ b/Documentation/IO-mapping.txt @@ -157,7 +157,7 @@ For such memory, you can do things like * access only the 640k-1MB area, so anything else * has to be remapped. */ - char * baseptr = ioremap(0xFC000000, 1024*1024); + void __iomem *baseptr = ioremap(0xFC000000, 1024*1024); /* write a 'A' to the offset 10 of the area */ writeb('A',baseptr+10); -- cgit v0.10.2 From 8d9f99c335ef66e4c44afe8f61816b0edeafba91 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 1 Jan 2010 20:35:54 -0800 Subject: DocBook: fix ioremap return type ioremap() returns a void __iomem * not an unsigned long. Update the Documentation file to reflect this. Signed-off-by: H Hartley Sweeten Signed-off-by: Randy Dunlap Cc: David Woodhouse Signed-off-by: Linus Torvalds diff --git a/Documentation/DocBook/mtdnand.tmpl b/Documentation/DocBook/mtdnand.tmpl index f508a8a..5e7d84b 100644 --- a/Documentation/DocBook/mtdnand.tmpl +++ b/Documentation/DocBook/mtdnand.tmpl @@ -174,7 +174,7 @@ static struct mtd_info *board_mtd; -static unsigned long baseaddr; +static void __iomem *baseaddr; Static example @@ -182,7 +182,7 @@ static unsigned long baseaddr; static struct mtd_info board_mtd; static struct nand_chip board_chip; -static unsigned long baseaddr; +static void __iomem *baseaddr; @@ -283,8 +283,8 @@ int __init board_init (void) } /* map physical address */ - baseaddr = (unsigned long)ioremap(CHIP_PHYSICAL_ADDRESS, 1024); - if(!baseaddr){ + baseaddr = ioremap(CHIP_PHYSICAL_ADDRESS, 1024); + if (!baseaddr) { printk("Ioremap to access NAND chip failed\n"); err = -EIO; goto out_mtd; @@ -316,7 +316,7 @@ int __init board_init (void) goto out; out_ior: - iounmap((void *)baseaddr); + iounmap(baseaddr); out_mtd: kfree (board_mtd); out: @@ -341,7 +341,7 @@ static void __exit board_cleanup (void) nand_release (board_mtd); /* unmap physical address */ - iounmap((void *)baseaddr); + iounmap(baseaddr); /* Free the MTD device structure */ kfree (board_mtd); -- cgit v0.10.2 From 4207a152bc242effd0b8231143aa5b9f7a1593a9 Mon Sep 17 00:00:00 2001 From: Kusanagi Kouichi Date: Fri, 1 Jan 2010 20:36:09 -0800 Subject: Documentation: Rename Documentation/DMA-mapping.txt It seems that Documentation/DMA-mapping.txt was supposed to be renamed to Documentation/PCI/PCI-DMA-mapping.txt. Signed-off-by: Kusanagi Kouichi Signed-off-by: Randy Dunlap Signed-off-by: Linus Torvalds diff --git a/Documentation/DMA-mapping.txt b/Documentation/DMA-mapping.txt deleted file mode 100644 index ecad88d..0000000 --- a/Documentation/DMA-mapping.txt +++ /dev/null @@ -1,766 +0,0 @@ - Dynamic DMA mapping - =================== - - David S. Miller - Richard Henderson - Jakub Jelinek - -This document describes the DMA mapping system in terms of the pci_ -API. For a similar API that works for generic devices, see -DMA-API.txt. - -Most of the 64bit platforms have special hardware that translates bus -addresses (DMA addresses) into physical addresses. This is similar to -how page tables and/or a TLB translates virtual addresses to physical -addresses on a CPU. This is needed so that e.g. PCI devices can -access with a Single Address Cycle (32bit DMA address) any page in the -64bit physical address space. Previously in Linux those 64bit -platforms had to set artificial limits on the maximum RAM size in the -system, so that the virt_to_bus() static scheme works (the DMA address -translation tables were simply filled on bootup to map each bus -address to the physical page __pa(bus_to_virt())). - -So that Linux can use the dynamic DMA mapping, it needs some help from the -drivers, namely it has to take into account that DMA addresses should be -mapped only for the time they are actually used and unmapped after the DMA -transfer. - -The following API will work of course even on platforms where no such -hardware exists, see e.g. arch/x86/include/asm/pci.h for how it is implemented on -top of the virt_to_bus interface. - -First of all, you should make sure - -#include - -is in your driver. This file will obtain for you the definition of the -dma_addr_t (which can hold any valid DMA address for the platform) -type which should be used everywhere you hold a DMA (bus) address -returned from the DMA mapping functions. - - What memory is DMA'able? - -The first piece of information you must know is what kernel memory can -be used with the DMA mapping facilities. There has been an unwritten -set of rules regarding this, and this text is an attempt to finally -write them down. - -If you acquired your memory via the page allocator -(i.e. __get_free_page*()) or the generic memory allocators -(i.e. kmalloc() or kmem_cache_alloc()) then you may DMA to/from -that memory using the addresses returned from those routines. - -This means specifically that you may _not_ use the memory/addresses -returned from vmalloc() for DMA. It is possible to DMA to the -_underlying_ memory mapped into a vmalloc() area, but this requires -walking page tables to get the physical addresses, and then -translating each of those pages back to a kernel address using -something like __va(). [ EDIT: Update this when we integrate -Gerd Knorr's generic code which does this. ] - -This rule also means that you may use neither kernel image addresses -(items in data/text/bss segments), nor module image addresses, nor -stack addresses for DMA. These could all be mapped somewhere entirely -different than the rest of physical memory. Even if those classes of -memory could physically work with DMA, you'd need to ensure the I/O -buffers were cacheline-aligned. Without that, you'd see cacheline -sharing problems (data corruption) on CPUs with DMA-incoherent caches. -(The CPU could write to one word, DMA would write to a different one -in the same cache line, and one of them could be overwritten.) - -Also, this means that you cannot take the return of a kmap() -call and DMA to/from that. This is similar to vmalloc(). - -What about block I/O and networking buffers? The block I/O and -networking subsystems make sure that the buffers they use are valid -for you to DMA from/to. - - DMA addressing limitations - -Does your device have any DMA addressing limitations? For example, is -your device only capable of driving the low order 24-bits of address -on the PCI bus for SAC DMA transfers? If so, you need to inform the -PCI layer of this fact. - -By default, the kernel assumes that your device can address the full -32-bits in a SAC cycle. For a 64-bit DAC capable device, this needs -to be increased. And for a device with limitations, as discussed in -the previous paragraph, it needs to be decreased. - -pci_alloc_consistent() by default will return 32-bit DMA addresses. -PCI-X specification requires PCI-X devices to support 64-bit -addressing (DAC) for all transactions. And at least one platform (SGI -SN2) requires 64-bit consistent allocations to operate correctly when -the IO bus is in PCI-X mode. Therefore, like with pci_set_dma_mask(), -it's good practice to call pci_set_consistent_dma_mask() to set the -appropriate mask even if your device only supports 32-bit DMA -(default) and especially if it's a PCI-X device. - -For correct operation, you must interrogate the PCI layer in your -device probe routine to see if the PCI controller on the machine can -properly support the DMA addressing limitation your device has. It is -good style to do this even if your device holds the default setting, -because this shows that you did think about these issues wrt. your -device. - -The query is performed via a call to pci_set_dma_mask(): - - int pci_set_dma_mask(struct pci_dev *pdev, u64 device_mask); - -The query for consistent allocations is performed via a call to -pci_set_consistent_dma_mask(): - - int pci_set_consistent_dma_mask(struct pci_dev *pdev, u64 device_mask); - -Here, pdev is a pointer to the PCI device struct of your device, and -device_mask is a bit mask describing which bits of a PCI address your -device supports. It returns zero if your card can perform DMA -properly on the machine given the address mask you provided. - -If it returns non-zero, your device cannot perform DMA properly on -this platform, and attempting to do so will result in undefined -behavior. You must either use a different mask, or not use DMA. - -This means that in the failure case, you have three options: - -1) Use another DMA mask, if possible (see below). -2) Use some non-DMA mode for data transfer, if possible. -3) Ignore this device and do not initialize it. - -It is recommended that your driver print a kernel KERN_WARNING message -when you end up performing either #2 or #3. In this manner, if a user -of your driver reports that performance is bad or that the device is not -even detected, you can ask them for the kernel messages to find out -exactly why. - -The standard 32-bit addressing PCI device would do something like -this: - - if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) { - printk(KERN_WARNING - "mydev: No suitable DMA available.\n"); - goto ignore_this_device; - } - -Another common scenario is a 64-bit capable device. The approach -here is to try for 64-bit DAC addressing, but back down to a -32-bit mask should that fail. The PCI platform code may fail the -64-bit mask not because the platform is not capable of 64-bit -addressing. Rather, it may fail in this case simply because -32-bit SAC addressing is done more efficiently than DAC addressing. -Sparc64 is one platform which behaves in this way. - -Here is how you would handle a 64-bit capable device which can drive -all 64-bits when accessing streaming DMA: - - int using_dac; - - if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { - using_dac = 1; - } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) { - using_dac = 0; - } else { - printk(KERN_WARNING - "mydev: No suitable DMA available.\n"); - goto ignore_this_device; - } - -If a card is capable of using 64-bit consistent allocations as well, -the case would look like this: - - int using_dac, consistent_using_dac; - - if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { - using_dac = 1; - consistent_using_dac = 1; - pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)); - } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) { - using_dac = 0; - consistent_using_dac = 0; - pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); - } else { - printk(KERN_WARNING - "mydev: No suitable DMA available.\n"); - goto ignore_this_device; - } - -pci_set_consistent_dma_mask() will always be able to set the same or a -smaller mask as pci_set_dma_mask(). However for the rare case that a -device driver only uses consistent allocations, one would have to -check the return value from pci_set_consistent_dma_mask(). - -Finally, if your device can only drive the low 24-bits of -address during PCI bus mastering you might do something like: - - if (pci_set_dma_mask(pdev, DMA_BIT_MASK(24))) { - printk(KERN_WARNING - "mydev: 24-bit DMA addressing not available.\n"); - goto ignore_this_device; - } - -When pci_set_dma_mask() is successful, and returns zero, the PCI layer -saves away this mask you have provided. The PCI layer will use this -information later when you make DMA mappings. - -There is a case which we are aware of at this time, which is worth -mentioning in this documentation. If your device supports multiple -functions (for example a sound card provides playback and record -functions) and the various different functions have _different_ -DMA addressing limitations, you may wish to probe each mask and -only provide the functionality which the machine can handle. It -is important that the last call to pci_set_dma_mask() be for the -most specific mask. - -Here is pseudo-code showing how this might be done: - - #define PLAYBACK_ADDRESS_BITS DMA_BIT_MASK(32) - #define RECORD_ADDRESS_BITS DMA_BIT_MASK(24) - - struct my_sound_card *card; - struct pci_dev *pdev; - - ... - if (!pci_set_dma_mask(pdev, PLAYBACK_ADDRESS_BITS)) { - card->playback_enabled = 1; - } else { - card->playback_enabled = 0; - printk(KERN_WARNING "%s: Playback disabled due to DMA limitations.\n", - card->name); - } - if (!pci_set_dma_mask(pdev, RECORD_ADDRESS_BITS)) { - card->record_enabled = 1; - } else { - card->record_enabled = 0; - printk(KERN_WARNING "%s: Record disabled due to DMA limitations.\n", - card->name); - } - -A sound card was used as an example here because this genre of PCI -devices seems to be littered with ISA chips given a PCI front end, -and thus retaining the 16MB DMA addressing limitations of ISA. - - Types of DMA mappings - -There are two types of DMA mappings: - -- Consistent DMA mappings which are usually mapped at driver - initialization, unmapped at the end and for which the hardware should - guarantee that the device and the CPU can access the data - in parallel and will see updates made by each other without any - explicit software flushing. - - Think of "consistent" as "synchronous" or "coherent". - - The current default is to return consistent memory in the low 32 - bits of the PCI bus space. However, for future compatibility you - should set the consistent mask even if this default is fine for your - driver. - - Good examples of what to use consistent mappings for are: - - - Network card DMA ring descriptors. - - SCSI adapter mailbox command data structures. - - Device firmware microcode executed out of - main memory. - - The invariant these examples all require is that any CPU store - to memory is immediately visible to the device, and vice - versa. Consistent mappings guarantee this. - - IMPORTANT: Consistent DMA memory does not preclude the usage of - proper memory barriers. The CPU may reorder stores to - consistent memory just as it may normal memory. Example: - if it is important for the device to see the first word - of a descriptor updated before the second, you must do - something like: - - desc->word0 = address; - wmb(); - desc->word1 = DESC_VALID; - - in order to get correct behavior on all platforms. - - Also, on some platforms your driver may need to flush CPU write - buffers in much the same way as it needs to flush write buffers - found in PCI bridges (such as by reading a register's value - after writing it). - -- Streaming DMA mappings which are usually mapped for one DMA transfer, - unmapped right after it (unless you use pci_dma_sync_* below) and for which - hardware can optimize for sequential accesses. - - This of "streaming" as "asynchronous" or "outside the coherency - domain". - - Good examples of what to use streaming mappings for are: - - - Networking buffers transmitted/received by a device. - - Filesystem buffers written/read by a SCSI device. - - The interfaces for using this type of mapping were designed in - such a way that an implementation can make whatever performance - optimizations the hardware allows. To this end, when using - such mappings you must be explicit about what you want to happen. - -Neither type of DMA mapping has alignment restrictions that come -from PCI, although some devices may have such restrictions. -Also, systems with caches that aren't DMA-coherent will work better -when the underlying buffers don't share cache lines with other data. - - - Using Consistent DMA mappings. - -To allocate and map large (PAGE_SIZE or so) consistent DMA regions, -you should do: - - dma_addr_t dma_handle; - - cpu_addr = pci_alloc_consistent(pdev, size, &dma_handle); - -where pdev is a struct pci_dev *. This may be called in interrupt context. -You should use dma_alloc_coherent (see DMA-API.txt) for buses -where devices don't have struct pci_dev (like ISA, EISA). - -This argument is needed because the DMA translations may be bus -specific (and often is private to the bus which the device is attached -to). - -Size is the length of the region you want to allocate, in bytes. - -This routine will allocate RAM for that region, so it acts similarly to -__get_free_pages (but takes size instead of a page order). If your -driver needs regions sized smaller than a page, you may prefer using -the pci_pool interface, described below. - -The consistent DMA mapping interfaces, for non-NULL pdev, will by -default return a DMA address which is SAC (Single Address Cycle) -addressable. Even if the device indicates (via PCI dma mask) that it -may address the upper 32-bits and thus perform DAC cycles, consistent -allocation will only return > 32-bit PCI addresses for DMA if the -consistent dma mask has been explicitly changed via -pci_set_consistent_dma_mask(). This is true of the pci_pool interface -as well. - -pci_alloc_consistent returns two values: the virtual address which you -can use to access it from the CPU and dma_handle which you pass to the -card. - -The cpu return address and the DMA bus master address are both -guaranteed to be aligned to the smallest PAGE_SIZE order which -is greater than or equal to the requested size. This invariant -exists (for example) to guarantee that if you allocate a chunk -which is smaller than or equal to 64 kilobytes, the extent of the -buffer you receive will not cross a 64K boundary. - -To unmap and free such a DMA region, you call: - - pci_free_consistent(pdev, size, cpu_addr, dma_handle); - -where pdev, size are the same as in the above call and cpu_addr and -dma_handle are the values pci_alloc_consistent returned to you. -This function may not be called in interrupt context. - -If your driver needs lots of smaller memory regions, you can write -custom code to subdivide pages returned by pci_alloc_consistent, -or you can use the pci_pool API to do that. A pci_pool is like -a kmem_cache, but it uses pci_alloc_consistent not __get_free_pages. -Also, it understands common hardware constraints for alignment, -like queue heads needing to be aligned on N byte boundaries. - -Create a pci_pool like this: - - struct pci_pool *pool; - - pool = pci_pool_create(name, pdev, size, align, alloc); - -The "name" is for diagnostics (like a kmem_cache name); pdev and size -are as above. The device's hardware alignment requirement for this -type of data is "align" (which is expressed in bytes, and must be a -power of two). If your device has no boundary crossing restrictions, -pass 0 for alloc; passing 4096 says memory allocated from this pool -must not cross 4KByte boundaries (but at that time it may be better to -go for pci_alloc_consistent directly instead). - -Allocate memory from a pci pool like this: - - cpu_addr = pci_pool_alloc(pool, flags, &dma_handle); - -flags are SLAB_KERNEL if blocking is permitted (not in_interrupt nor -holding SMP locks), SLAB_ATOMIC otherwise. Like pci_alloc_consistent, -this returns two values, cpu_addr and dma_handle. - -Free memory that was allocated from a pci_pool like this: - - pci_pool_free(pool, cpu_addr, dma_handle); - -where pool is what you passed to pci_pool_alloc, and cpu_addr and -dma_handle are the values pci_pool_alloc returned. This function -may be called in interrupt context. - -Destroy a pci_pool by calling: - - pci_pool_destroy(pool); - -Make sure you've called pci_pool_free for all memory allocated -from a pool before you destroy the pool. This function may not -be called in interrupt context. - - DMA Direction - -The interfaces described in subsequent portions of this document -take a DMA direction argument, which is an integer and takes on -one of the following values: - - PCI_DMA_BIDIRECTIONAL - PCI_DMA_TODEVICE - PCI_DMA_FROMDEVICE - PCI_DMA_NONE - -One should provide the exact DMA direction if you know it. - -PCI_DMA_TODEVICE means "from main memory to the PCI device" -PCI_DMA_FROMDEVICE means "from the PCI device to main memory" -It is the direction in which the data moves during the DMA -transfer. - -You are _strongly_ encouraged to specify this as precisely -as you possibly can. - -If you absolutely cannot know the direction of the DMA transfer, -specify PCI_DMA_BIDIRECTIONAL. It means that the DMA can go in -either direction. The platform guarantees that you may legally -specify this, and that it will work, but this may be at the -cost of performance for example. - -The value PCI_DMA_NONE is to be used for debugging. One can -hold this in a data structure before you come to know the -precise direction, and this will help catch cases where your -direction tracking logic has failed to set things up properly. - -Another advantage of specifying this value precisely (outside of -potential platform-specific optimizations of such) is for debugging. -Some platforms actually have a write permission boolean which DMA -mappings can be marked with, much like page protections in the user -program address space. Such platforms can and do report errors in the -kernel logs when the PCI controller hardware detects violation of the -permission setting. - -Only streaming mappings specify a direction, consistent mappings -implicitly have a direction attribute setting of -PCI_DMA_BIDIRECTIONAL. - -The SCSI subsystem tells you the direction to use in the -'sc_data_direction' member of the SCSI command your driver is -working on. - -For Networking drivers, it's a rather simple affair. For transmit -packets, map/unmap them with the PCI_DMA_TODEVICE direction -specifier. For receive packets, just the opposite, map/unmap them -with the PCI_DMA_FROMDEVICE direction specifier. - - Using Streaming DMA mappings - -The streaming DMA mapping routines can be called from interrupt -context. There are two versions of each map/unmap, one which will -map/unmap a single memory region, and one which will map/unmap a -scatterlist. - -To map a single region, you do: - - struct pci_dev *pdev = mydev->pdev; - dma_addr_t dma_handle; - void *addr = buffer->ptr; - size_t size = buffer->len; - - dma_handle = pci_map_single(pdev, addr, size, direction); - -and to unmap it: - - pci_unmap_single(pdev, dma_handle, size, direction); - -You should call pci_unmap_single when the DMA activity is finished, e.g. -from the interrupt which told you that the DMA transfer is done. - -Using cpu pointers like this for single mappings has a disadvantage, -you cannot reference HIGHMEM memory in this way. Thus, there is a -map/unmap interface pair akin to pci_{map,unmap}_single. These -interfaces deal with page/offset pairs instead of cpu pointers. -Specifically: - - struct pci_dev *pdev = mydev->pdev; - dma_addr_t dma_handle; - struct page *page = buffer->page; - unsigned long offset = buffer->offset; - size_t size = buffer->len; - - dma_handle = pci_map_page(pdev, page, offset, size, direction); - - ... - - pci_unmap_page(pdev, dma_handle, size, direction); - -Here, "offset" means byte offset within the given page. - -With scatterlists, you map a region gathered from several regions by: - - int i, count = pci_map_sg(pdev, sglist, nents, direction); - struct scatterlist *sg; - - for_each_sg(sglist, sg, count, i) { - hw_address[i] = sg_dma_address(sg); - hw_len[i] = sg_dma_len(sg); - } - -where nents is the number of entries in the sglist. - -The implementation is free to merge several consecutive sglist entries -into one (e.g. if DMA mapping is done with PAGE_SIZE granularity, any -consecutive sglist entries can be merged into one provided the first one -ends and the second one starts on a page boundary - in fact this is a huge -advantage for cards which either cannot do scatter-gather or have very -limited number of scatter-gather entries) and returns the actual number -of sg entries it mapped them to. On failure 0 is returned. - -Then you should loop count times (note: this can be less than nents times) -and use sg_dma_address() and sg_dma_len() macros where you previously -accessed sg->address and sg->length as shown above. - -To unmap a scatterlist, just call: - - pci_unmap_sg(pdev, sglist, nents, direction); - -Again, make sure DMA activity has already finished. - -PLEASE NOTE: The 'nents' argument to the pci_unmap_sg call must be - the _same_ one you passed into the pci_map_sg call, - it should _NOT_ be the 'count' value _returned_ from the - pci_map_sg call. - -Every pci_map_{single,sg} call should have its pci_unmap_{single,sg} -counterpart, because the bus address space is a shared resource (although -in some ports the mapping is per each BUS so less devices contend for the -same bus address space) and you could render the machine unusable by eating -all bus addresses. - -If you need to use the same streaming DMA region multiple times and touch -the data in between the DMA transfers, the buffer needs to be synced -properly in order for the cpu and device to see the most uptodate and -correct copy of the DMA buffer. - -So, firstly, just map it with pci_map_{single,sg}, and after each DMA -transfer call either: - - pci_dma_sync_single_for_cpu(pdev, dma_handle, size, direction); - -or: - - pci_dma_sync_sg_for_cpu(pdev, sglist, nents, direction); - -as appropriate. - -Then, if you wish to let the device get at the DMA area again, -finish accessing the data with the cpu, and then before actually -giving the buffer to the hardware call either: - - pci_dma_sync_single_for_device(pdev, dma_handle, size, direction); - -or: - - pci_dma_sync_sg_for_device(dev, sglist, nents, direction); - -as appropriate. - -After the last DMA transfer call one of the DMA unmap routines -pci_unmap_{single,sg}. If you don't touch the data from the first pci_map_* -call till pci_unmap_*, then you don't have to call the pci_dma_sync_* -routines at all. - -Here is pseudo code which shows a situation in which you would need -to use the pci_dma_sync_*() interfaces. - - my_card_setup_receive_buffer(struct my_card *cp, char *buffer, int len) - { - dma_addr_t mapping; - - mapping = pci_map_single(cp->pdev, buffer, len, PCI_DMA_FROMDEVICE); - - cp->rx_buf = buffer; - cp->rx_len = len; - cp->rx_dma = mapping; - - give_rx_buf_to_card(cp); - } - - ... - - my_card_interrupt_handler(int irq, void *devid, struct pt_regs *regs) - { - struct my_card *cp = devid; - - ... - if (read_card_status(cp) == RX_BUF_TRANSFERRED) { - struct my_card_header *hp; - - /* Examine the header to see if we wish - * to accept the data. But synchronize - * the DMA transfer with the CPU first - * so that we see updated contents. - */ - pci_dma_sync_single_for_cpu(cp->pdev, cp->rx_dma, - cp->rx_len, - PCI_DMA_FROMDEVICE); - - /* Now it is safe to examine the buffer. */ - hp = (struct my_card_header *) cp->rx_buf; - if (header_is_ok(hp)) { - pci_unmap_single(cp->pdev, cp->rx_dma, cp->rx_len, - PCI_DMA_FROMDEVICE); - pass_to_upper_layers(cp->rx_buf); - make_and_setup_new_rx_buf(cp); - } else { - /* Just sync the buffer and give it back - * to the card. - */ - pci_dma_sync_single_for_device(cp->pdev, - cp->rx_dma, - cp->rx_len, - PCI_DMA_FROMDEVICE); - give_rx_buf_to_card(cp); - } - } - } - -Drivers converted fully to this interface should not use virt_to_bus any -longer, nor should they use bus_to_virt. Some drivers have to be changed a -little bit, because there is no longer an equivalent to bus_to_virt in the -dynamic DMA mapping scheme - you have to always store the DMA addresses -returned by the pci_alloc_consistent, pci_pool_alloc, and pci_map_single -calls (pci_map_sg stores them in the scatterlist itself if the platform -supports dynamic DMA mapping in hardware) in your driver structures and/or -in the card registers. - -All PCI drivers should be using these interfaces with no exceptions. -It is planned to completely remove virt_to_bus() and bus_to_virt() as -they are entirely deprecated. Some ports already do not provide these -as it is impossible to correctly support them. - - Optimizing Unmap State Space Consumption - -On many platforms, pci_unmap_{single,page}() is simply a nop. -Therefore, keeping track of the mapping address and length is a waste -of space. Instead of filling your drivers up with ifdefs and the like -to "work around" this (which would defeat the whole purpose of a -portable API) the following facilities are provided. - -Actually, instead of describing the macros one by one, we'll -transform some example code. - -1) Use DECLARE_PCI_UNMAP_{ADDR,LEN} in state saving structures. - Example, before: - - struct ring_state { - struct sk_buff *skb; - dma_addr_t mapping; - __u32 len; - }; - - after: - - struct ring_state { - struct sk_buff *skb; - DECLARE_PCI_UNMAP_ADDR(mapping) - DECLARE_PCI_UNMAP_LEN(len) - }; - - NOTE: DO NOT put a semicolon at the end of the DECLARE_*() - macro. - -2) Use pci_unmap_{addr,len}_set to set these values. - Example, before: - - ringp->mapping = FOO; - ringp->len = BAR; - - after: - - pci_unmap_addr_set(ringp, mapping, FOO); - pci_unmap_len_set(ringp, len, BAR); - -3) Use pci_unmap_{addr,len} to access these values. - Example, before: - - pci_unmap_single(pdev, ringp->mapping, ringp->len, - PCI_DMA_FROMDEVICE); - - after: - - pci_unmap_single(pdev, - pci_unmap_addr(ringp, mapping), - pci_unmap_len(ringp, len), - PCI_DMA_FROMDEVICE); - -It really should be self-explanatory. We treat the ADDR and LEN -separately, because it is possible for an implementation to only -need the address in order to perform the unmap operation. - - Platform Issues - -If you are just writing drivers for Linux and do not maintain -an architecture port for the kernel, you can safely skip down -to "Closing". - -1) Struct scatterlist requirements. - - Struct scatterlist must contain, at a minimum, the following - members: - - struct page *page; - unsigned int offset; - unsigned int length; - - The base address is specified by a "page+offset" pair. - - Previous versions of struct scatterlist contained a "void *address" - field that was sometimes used instead of page+offset. As of Linux - 2.5., page+offset is always used, and the "address" field has been - deleted. - -2) More to come... - - Handling Errors - -DMA address space is limited on some architectures and an allocation -failure can be determined by: - -- checking if pci_alloc_consistent returns NULL or pci_map_sg returns 0 - -- checking the returned dma_addr_t of pci_map_single and pci_map_page - by using pci_dma_mapping_error(): - - dma_addr_t dma_handle; - - dma_handle = pci_map_single(pdev, addr, size, direction); - if (pci_dma_mapping_error(pdev, dma_handle)) { - /* - * reduce current DMA mapping usage, - * delay and try again later or - * reset driver. - */ - } - - Closing - -This document, and the API itself, would not be in it's current -form without the feedback and suggestions from numerous individuals. -We would like to specifically mention, in no particular order, the -following people: - - Russell King - Leo Dagum - Ralf Baechle - Grant Grundler - Jay Estabrook - Thomas Sailer - Andrea Arcangeli - Jens Axboe - David Mosberger-Tang diff --git a/Documentation/PCI/PCI-DMA-mapping.txt b/Documentation/PCI/PCI-DMA-mapping.txt new file mode 100644 index 0000000..ecad88d --- /dev/null +++ b/Documentation/PCI/PCI-DMA-mapping.txt @@ -0,0 +1,766 @@ + Dynamic DMA mapping + =================== + + David S. Miller + Richard Henderson + Jakub Jelinek + +This document describes the DMA mapping system in terms of the pci_ +API. For a similar API that works for generic devices, see +DMA-API.txt. + +Most of the 64bit platforms have special hardware that translates bus +addresses (DMA addresses) into physical addresses. This is similar to +how page tables and/or a TLB translates virtual addresses to physical +addresses on a CPU. This is needed so that e.g. PCI devices can +access with a Single Address Cycle (32bit DMA address) any page in the +64bit physical address space. Previously in Linux those 64bit +platforms had to set artificial limits on the maximum RAM size in the +system, so that the virt_to_bus() static scheme works (the DMA address +translation tables were simply filled on bootup to map each bus +address to the physical page __pa(bus_to_virt())). + +So that Linux can use the dynamic DMA mapping, it needs some help from the +drivers, namely it has to take into account that DMA addresses should be +mapped only for the time they are actually used and unmapped after the DMA +transfer. + +The following API will work of course even on platforms where no such +hardware exists, see e.g. arch/x86/include/asm/pci.h for how it is implemented on +top of the virt_to_bus interface. + +First of all, you should make sure + +#include + +is in your driver. This file will obtain for you the definition of the +dma_addr_t (which can hold any valid DMA address for the platform) +type which should be used everywhere you hold a DMA (bus) address +returned from the DMA mapping functions. + + What memory is DMA'able? + +The first piece of information you must know is what kernel memory can +be used with the DMA mapping facilities. There has been an unwritten +set of rules regarding this, and this text is an attempt to finally +write them down. + +If you acquired your memory via the page allocator +(i.e. __get_free_page*()) or the generic memory allocators +(i.e. kmalloc() or kmem_cache_alloc()) then you may DMA to/from +that memory using the addresses returned from those routines. + +This means specifically that you may _not_ use the memory/addresses +returned from vmalloc() for DMA. It is possible to DMA to the +_underlying_ memory mapped into a vmalloc() area, but this requires +walking page tables to get the physical addresses, and then +translating each of those pages back to a kernel address using +something like __va(). [ EDIT: Update this when we integrate +Gerd Knorr's generic code which does this. ] + +This rule also means that you may use neither kernel image addresses +(items in data/text/bss segments), nor module image addresses, nor +stack addresses for DMA. These could all be mapped somewhere entirely +different than the rest of physical memory. Even if those classes of +memory could physically work with DMA, you'd need to ensure the I/O +buffers were cacheline-aligned. Without that, you'd see cacheline +sharing problems (data corruption) on CPUs with DMA-incoherent caches. +(The CPU could write to one word, DMA would write to a different one +in the same cache line, and one of them could be overwritten.) + +Also, this means that you cannot take the return of a kmap() +call and DMA to/from that. This is similar to vmalloc(). + +What about block I/O and networking buffers? The block I/O and +networking subsystems make sure that the buffers they use are valid +for you to DMA from/to. + + DMA addressing limitations + +Does your device have any DMA addressing limitations? For example, is +your device only capable of driving the low order 24-bits of address +on the PCI bus for SAC DMA transfers? If so, you need to inform the +PCI layer of this fact. + +By default, the kernel assumes that your device can address the full +32-bits in a SAC cycle. For a 64-bit DAC capable device, this needs +to be increased. And for a device with limitations, as discussed in +the previous paragraph, it needs to be decreased. + +pci_alloc_consistent() by default will return 32-bit DMA addresses. +PCI-X specification requires PCI-X devices to support 64-bit +addressing (DAC) for all transactions. And at least one platform (SGI +SN2) requires 64-bit consistent allocations to operate correctly when +the IO bus is in PCI-X mode. Therefore, like with pci_set_dma_mask(), +it's good practice to call pci_set_consistent_dma_mask() to set the +appropriate mask even if your device only supports 32-bit DMA +(default) and especially if it's a PCI-X device. + +For correct operation, you must interrogate the PCI layer in your +device probe routine to see if the PCI controller on the machine can +properly support the DMA addressing limitation your device has. It is +good style to do this even if your device holds the default setting, +because this shows that you did think about these issues wrt. your +device. + +The query is performed via a call to pci_set_dma_mask(): + + int pci_set_dma_mask(struct pci_dev *pdev, u64 device_mask); + +The query for consistent allocations is performed via a call to +pci_set_consistent_dma_mask(): + + int pci_set_consistent_dma_mask(struct pci_dev *pdev, u64 device_mask); + +Here, pdev is a pointer to the PCI device struct of your device, and +device_mask is a bit mask describing which bits of a PCI address your +device supports. It returns zero if your card can perform DMA +properly on the machine given the address mask you provided. + +If it returns non-zero, your device cannot perform DMA properly on +this platform, and attempting to do so will result in undefined +behavior. You must either use a different mask, or not use DMA. + +This means that in the failure case, you have three options: + +1) Use another DMA mask, if possible (see below). +2) Use some non-DMA mode for data transfer, if possible. +3) Ignore this device and do not initialize it. + +It is recommended that your driver print a kernel KERN_WARNING message +when you end up performing either #2 or #3. In this manner, if a user +of your driver reports that performance is bad or that the device is not +even detected, you can ask them for the kernel messages to find out +exactly why. + +The standard 32-bit addressing PCI device would do something like +this: + + if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) { + printk(KERN_WARNING + "mydev: No suitable DMA available.\n"); + goto ignore_this_device; + } + +Another common scenario is a 64-bit capable device. The approach +here is to try for 64-bit DAC addressing, but back down to a +32-bit mask should that fail. The PCI platform code may fail the +64-bit mask not because the platform is not capable of 64-bit +addressing. Rather, it may fail in this case simply because +32-bit SAC addressing is done more efficiently than DAC addressing. +Sparc64 is one platform which behaves in this way. + +Here is how you would handle a 64-bit capable device which can drive +all 64-bits when accessing streaming DMA: + + int using_dac; + + if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { + using_dac = 1; + } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) { + using_dac = 0; + } else { + printk(KERN_WARNING + "mydev: No suitable DMA available.\n"); + goto ignore_this_device; + } + +If a card is capable of using 64-bit consistent allocations as well, +the case would look like this: + + int using_dac, consistent_using_dac; + + if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { + using_dac = 1; + consistent_using_dac = 1; + pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)); + } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) { + using_dac = 0; + consistent_using_dac = 0; + pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); + } else { + printk(KERN_WARNING + "mydev: No suitable DMA available.\n"); + goto ignore_this_device; + } + +pci_set_consistent_dma_mask() will always be able to set the same or a +smaller mask as pci_set_dma_mask(). However for the rare case that a +device driver only uses consistent allocations, one would have to +check the return value from pci_set_consistent_dma_mask(). + +Finally, if your device can only drive the low 24-bits of +address during PCI bus mastering you might do something like: + + if (pci_set_dma_mask(pdev, DMA_BIT_MASK(24))) { + printk(KERN_WARNING + "mydev: 24-bit DMA addressing not available.\n"); + goto ignore_this_device; + } + +When pci_set_dma_mask() is successful, and returns zero, the PCI layer +saves away this mask you have provided. The PCI layer will use this +information later when you make DMA mappings. + +There is a case which we are aware of at this time, which is worth +mentioning in this documentation. If your device supports multiple +functions (for example a sound card provides playback and record +functions) and the various different functions have _different_ +DMA addressing limitations, you may wish to probe each mask and +only provide the functionality which the machine can handle. It +is important that the last call to pci_set_dma_mask() be for the +most specific mask. + +Here is pseudo-code showing how this might be done: + + #define PLAYBACK_ADDRESS_BITS DMA_BIT_MASK(32) + #define RECORD_ADDRESS_BITS DMA_BIT_MASK(24) + + struct my_sound_card *card; + struct pci_dev *pdev; + + ... + if (!pci_set_dma_mask(pdev, PLAYBACK_ADDRESS_BITS)) { + card->playback_enabled = 1; + } else { + card->playback_enabled = 0; + printk(KERN_WARNING "%s: Playback disabled due to DMA limitations.\n", + card->name); + } + if (!pci_set_dma_mask(pdev, RECORD_ADDRESS_BITS)) { + card->record_enabled = 1; + } else { + card->record_enabled = 0; + printk(KERN_WARNING "%s: Record disabled due to DMA limitations.\n", + card->name); + } + +A sound card was used as an example here because this genre of PCI +devices seems to be littered with ISA chips given a PCI front end, +and thus retaining the 16MB DMA addressing limitations of ISA. + + Types of DMA mappings + +There are two types of DMA mappings: + +- Consistent DMA mappings which are usually mapped at driver + initialization, unmapped at the end and for which the hardware should + guarantee that the device and the CPU can access the data + in parallel and will see updates made by each other without any + explicit software flushing. + + Think of "consistent" as "synchronous" or "coherent". + + The current default is to return consistent memory in the low 32 + bits of the PCI bus space. However, for future compatibility you + should set the consistent mask even if this default is fine for your + driver. + + Good examples of what to use consistent mappings for are: + + - Network card DMA ring descriptors. + - SCSI adapter mailbox command data structures. + - Device firmware microcode executed out of + main memory. + + The invariant these examples all require is that any CPU store + to memory is immediately visible to the device, and vice + versa. Consistent mappings guarantee this. + + IMPORTANT: Consistent DMA memory does not preclude the usage of + proper memory barriers. The CPU may reorder stores to + consistent memory just as it may normal memory. Example: + if it is important for the device to see the first word + of a descriptor updated before the second, you must do + something like: + + desc->word0 = address; + wmb(); + desc->word1 = DESC_VALID; + + in order to get correct behavior on all platforms. + + Also, on some platforms your driver may need to flush CPU write + buffers in much the same way as it needs to flush write buffers + found in PCI bridges (such as by reading a register's value + after writing it). + +- Streaming DMA mappings which are usually mapped for one DMA transfer, + unmapped right after it (unless you use pci_dma_sync_* below) and for which + hardware can optimize for sequential accesses. + + This of "streaming" as "asynchronous" or "outside the coherency + domain". + + Good examples of what to use streaming mappings for are: + + - Networking buffers transmitted/received by a device. + - Filesystem buffers written/read by a SCSI device. + + The interfaces for using this type of mapping were designed in + such a way that an implementation can make whatever performance + optimizations the hardware allows. To this end, when using + such mappings you must be explicit about what you want to happen. + +Neither type of DMA mapping has alignment restrictions that come +from PCI, although some devices may have such restrictions. +Also, systems with caches that aren't DMA-coherent will work better +when the underlying buffers don't share cache lines with other data. + + + Using Consistent DMA mappings. + +To allocate and map large (PAGE_SIZE or so) consistent DMA regions, +you should do: + + dma_addr_t dma_handle; + + cpu_addr = pci_alloc_consistent(pdev, size, &dma_handle); + +where pdev is a struct pci_dev *. This may be called in interrupt context. +You should use dma_alloc_coherent (see DMA-API.txt) for buses +where devices don't have struct pci_dev (like ISA, EISA). + +This argument is needed because the DMA translations may be bus +specific (and often is private to the bus which the device is attached +to). + +Size is the length of the region you want to allocate, in bytes. + +This routine will allocate RAM for that region, so it acts similarly to +__get_free_pages (but takes size instead of a page order). If your +driver needs regions sized smaller than a page, you may prefer using +the pci_pool interface, described below. + +The consistent DMA mapping interfaces, for non-NULL pdev, will by +default return a DMA address which is SAC (Single Address Cycle) +addressable. Even if the device indicates (via PCI dma mask) that it +may address the upper 32-bits and thus perform DAC cycles, consistent +allocation will only return > 32-bit PCI addresses for DMA if the +consistent dma mask has been explicitly changed via +pci_set_consistent_dma_mask(). This is true of the pci_pool interface +as well. + +pci_alloc_consistent returns two values: the virtual address which you +can use to access it from the CPU and dma_handle which you pass to the +card. + +The cpu return address and the DMA bus master address are both +guaranteed to be aligned to the smallest PAGE_SIZE order which +is greater than or equal to the requested size. This invariant +exists (for example) to guarantee that if you allocate a chunk +which is smaller than or equal to 64 kilobytes, the extent of the +buffer you receive will not cross a 64K boundary. + +To unmap and free such a DMA region, you call: + + pci_free_consistent(pdev, size, cpu_addr, dma_handle); + +where pdev, size are the same as in the above call and cpu_addr and +dma_handle are the values pci_alloc_consistent returned to you. +This function may not be called in interrupt context. + +If your driver needs lots of smaller memory regions, you can write +custom code to subdivide pages returned by pci_alloc_consistent, +or you can use the pci_pool API to do that. A pci_pool is like +a kmem_cache, but it uses pci_alloc_consistent not __get_free_pages. +Also, it understands common hardware constraints for alignment, +like queue heads needing to be aligned on N byte boundaries. + +Create a pci_pool like this: + + struct pci_pool *pool; + + pool = pci_pool_create(name, pdev, size, align, alloc); + +The "name" is for diagnostics (like a kmem_cache name); pdev and size +are as above. The device's hardware alignment requirement for this +type of data is "align" (which is expressed in bytes, and must be a +power of two). If your device has no boundary crossing restrictions, +pass 0 for alloc; passing 4096 says memory allocated from this pool +must not cross 4KByte boundaries (but at that time it may be better to +go for pci_alloc_consistent directly instead). + +Allocate memory from a pci pool like this: + + cpu_addr = pci_pool_alloc(pool, flags, &dma_handle); + +flags are SLAB_KERNEL if blocking is permitted (not in_interrupt nor +holding SMP locks), SLAB_ATOMIC otherwise. Like pci_alloc_consistent, +this returns two values, cpu_addr and dma_handle. + +Free memory that was allocated from a pci_pool like this: + + pci_pool_free(pool, cpu_addr, dma_handle); + +where pool is what you passed to pci_pool_alloc, and cpu_addr and +dma_handle are the values pci_pool_alloc returned. This function +may be called in interrupt context. + +Destroy a pci_pool by calling: + + pci_pool_destroy(pool); + +Make sure you've called pci_pool_free for all memory allocated +from a pool before you destroy the pool. This function may not +be called in interrupt context. + + DMA Direction + +The interfaces described in subsequent portions of this document +take a DMA direction argument, which is an integer and takes on +one of the following values: + + PCI_DMA_BIDIRECTIONAL + PCI_DMA_TODEVICE + PCI_DMA_FROMDEVICE + PCI_DMA_NONE + +One should provide the exact DMA direction if you know it. + +PCI_DMA_TODEVICE means "from main memory to the PCI device" +PCI_DMA_FROMDEVICE means "from the PCI device to main memory" +It is the direction in which the data moves during the DMA +transfer. + +You are _strongly_ encouraged to specify this as precisely +as you possibly can. + +If you absolutely cannot know the direction of the DMA transfer, +specify PCI_DMA_BIDIRECTIONAL. It means that the DMA can go in +either direction. The platform guarantees that you may legally +specify this, and that it will work, but this may be at the +cost of performance for example. + +The value PCI_DMA_NONE is to be used for debugging. One can +hold this in a data structure before you come to know the +precise direction, and this will help catch cases where your +direction tracking logic has failed to set things up properly. + +Another advantage of specifying this value precisely (outside of +potential platform-specific optimizations of such) is for debugging. +Some platforms actually have a write permission boolean which DMA +mappings can be marked with, much like page protections in the user +program address space. Such platforms can and do report errors in the +kernel logs when the PCI controller hardware detects violation of the +permission setting. + +Only streaming mappings specify a direction, consistent mappings +implicitly have a direction attribute setting of +PCI_DMA_BIDIRECTIONAL. + +The SCSI subsystem tells you the direction to use in the +'sc_data_direction' member of the SCSI command your driver is +working on. + +For Networking drivers, it's a rather simple affair. For transmit +packets, map/unmap them with the PCI_DMA_TODEVICE direction +specifier. For receive packets, just the opposite, map/unmap them +with the PCI_DMA_FROMDEVICE direction specifier. + + Using Streaming DMA mappings + +The streaming DMA mapping routines can be called from interrupt +context. There are two versions of each map/unmap, one which will +map/unmap a single memory region, and one which will map/unmap a +scatterlist. + +To map a single region, you do: + + struct pci_dev *pdev = mydev->pdev; + dma_addr_t dma_handle; + void *addr = buffer->ptr; + size_t size = buffer->len; + + dma_handle = pci_map_single(pdev, addr, size, direction); + +and to unmap it: + + pci_unmap_single(pdev, dma_handle, size, direction); + +You should call pci_unmap_single when the DMA activity is finished, e.g. +from the interrupt which told you that the DMA transfer is done. + +Using cpu pointers like this for single mappings has a disadvantage, +you cannot reference HIGHMEM memory in this way. Thus, there is a +map/unmap interface pair akin to pci_{map,unmap}_single. These +interfaces deal with page/offset pairs instead of cpu pointers. +Specifically: + + struct pci_dev *pdev = mydev->pdev; + dma_addr_t dma_handle; + struct page *page = buffer->page; + unsigned long offset = buffer->offset; + size_t size = buffer->len; + + dma_handle = pci_map_page(pdev, page, offset, size, direction); + + ... + + pci_unmap_page(pdev, dma_handle, size, direction); + +Here, "offset" means byte offset within the given page. + +With scatterlists, you map a region gathered from several regions by: + + int i, count = pci_map_sg(pdev, sglist, nents, direction); + struct scatterlist *sg; + + for_each_sg(sglist, sg, count, i) { + hw_address[i] = sg_dma_address(sg); + hw_len[i] = sg_dma_len(sg); + } + +where nents is the number of entries in the sglist. + +The implementation is free to merge several consecutive sglist entries +into one (e.g. if DMA mapping is done with PAGE_SIZE granularity, any +consecutive sglist entries can be merged into one provided the first one +ends and the second one starts on a page boundary - in fact this is a huge +advantage for cards which either cannot do scatter-gather or have very +limited number of scatter-gather entries) and returns the actual number +of sg entries it mapped them to. On failure 0 is returned. + +Then you should loop count times (note: this can be less than nents times) +and use sg_dma_address() and sg_dma_len() macros where you previously +accessed sg->address and sg->length as shown above. + +To unmap a scatterlist, just call: + + pci_unmap_sg(pdev, sglist, nents, direction); + +Again, make sure DMA activity has already finished. + +PLEASE NOTE: The 'nents' argument to the pci_unmap_sg call must be + the _same_ one you passed into the pci_map_sg call, + it should _NOT_ be the 'count' value _returned_ from the + pci_map_sg call. + +Every pci_map_{single,sg} call should have its pci_unmap_{single,sg} +counterpart, because the bus address space is a shared resource (although +in some ports the mapping is per each BUS so less devices contend for the +same bus address space) and you could render the machine unusable by eating +all bus addresses. + +If you need to use the same streaming DMA region multiple times and touch +the data in between the DMA transfers, the buffer needs to be synced +properly in order for the cpu and device to see the most uptodate and +correct copy of the DMA buffer. + +So, firstly, just map it with pci_map_{single,sg}, and after each DMA +transfer call either: + + pci_dma_sync_single_for_cpu(pdev, dma_handle, size, direction); + +or: + + pci_dma_sync_sg_for_cpu(pdev, sglist, nents, direction); + +as appropriate. + +Then, if you wish to let the device get at the DMA area again, +finish accessing the data with the cpu, and then before actually +giving the buffer to the hardware call either: + + pci_dma_sync_single_for_device(pdev, dma_handle, size, direction); + +or: + + pci_dma_sync_sg_for_device(dev, sglist, nents, direction); + +as appropriate. + +After the last DMA transfer call one of the DMA unmap routines +pci_unmap_{single,sg}. If you don't touch the data from the first pci_map_* +call till pci_unmap_*, then you don't have to call the pci_dma_sync_* +routines at all. + +Here is pseudo code which shows a situation in which you would need +to use the pci_dma_sync_*() interfaces. + + my_card_setup_receive_buffer(struct my_card *cp, char *buffer, int len) + { + dma_addr_t mapping; + + mapping = pci_map_single(cp->pdev, buffer, len, PCI_DMA_FROMDEVICE); + + cp->rx_buf = buffer; + cp->rx_len = len; + cp->rx_dma = mapping; + + give_rx_buf_to_card(cp); + } + + ... + + my_card_interrupt_handler(int irq, void *devid, struct pt_regs *regs) + { + struct my_card *cp = devid; + + ... + if (read_card_status(cp) == RX_BUF_TRANSFERRED) { + struct my_card_header *hp; + + /* Examine the header to see if we wish + * to accept the data. But synchronize + * the DMA transfer with the CPU first + * so that we see updated contents. + */ + pci_dma_sync_single_for_cpu(cp->pdev, cp->rx_dma, + cp->rx_len, + PCI_DMA_FROMDEVICE); + + /* Now it is safe to examine the buffer. */ + hp = (struct my_card_header *) cp->rx_buf; + if (header_is_ok(hp)) { + pci_unmap_single(cp->pdev, cp->rx_dma, cp->rx_len, + PCI_DMA_FROMDEVICE); + pass_to_upper_layers(cp->rx_buf); + make_and_setup_new_rx_buf(cp); + } else { + /* Just sync the buffer and give it back + * to the card. + */ + pci_dma_sync_single_for_device(cp->pdev, + cp->rx_dma, + cp->rx_len, + PCI_DMA_FROMDEVICE); + give_rx_buf_to_card(cp); + } + } + } + +Drivers converted fully to this interface should not use virt_to_bus any +longer, nor should they use bus_to_virt. Some drivers have to be changed a +little bit, because there is no longer an equivalent to bus_to_virt in the +dynamic DMA mapping scheme - you have to always store the DMA addresses +returned by the pci_alloc_consistent, pci_pool_alloc, and pci_map_single +calls (pci_map_sg stores them in the scatterlist itself if the platform +supports dynamic DMA mapping in hardware) in your driver structures and/or +in the card registers. + +All PCI drivers should be using these interfaces with no exceptions. +It is planned to completely remove virt_to_bus() and bus_to_virt() as +they are entirely deprecated. Some ports already do not provide these +as it is impossible to correctly support them. + + Optimizing Unmap State Space Consumption + +On many platforms, pci_unmap_{single,page}() is simply a nop. +Therefore, keeping track of the mapping address and length is a waste +of space. Instead of filling your drivers up with ifdefs and the like +to "work around" this (which would defeat the whole purpose of a +portable API) the following facilities are provided. + +Actually, instead of describing the macros one by one, we'll +transform some example code. + +1) Use DECLARE_PCI_UNMAP_{ADDR,LEN} in state saving structures. + Example, before: + + struct ring_state { + struct sk_buff *skb; + dma_addr_t mapping; + __u32 len; + }; + + after: + + struct ring_state { + struct sk_buff *skb; + DECLARE_PCI_UNMAP_ADDR(mapping) + DECLARE_PCI_UNMAP_LEN(len) + }; + + NOTE: DO NOT put a semicolon at the end of the DECLARE_*() + macro. + +2) Use pci_unmap_{addr,len}_set to set these values. + Example, before: + + ringp->mapping = FOO; + ringp->len = BAR; + + after: + + pci_unmap_addr_set(ringp, mapping, FOO); + pci_unmap_len_set(ringp, len, BAR); + +3) Use pci_unmap_{addr,len} to access these values. + Example, before: + + pci_unmap_single(pdev, ringp->mapping, ringp->len, + PCI_DMA_FROMDEVICE); + + after: + + pci_unmap_single(pdev, + pci_unmap_addr(ringp, mapping), + pci_unmap_len(ringp, len), + PCI_DMA_FROMDEVICE); + +It really should be self-explanatory. We treat the ADDR and LEN +separately, because it is possible for an implementation to only +need the address in order to perform the unmap operation. + + Platform Issues + +If you are just writing drivers for Linux and do not maintain +an architecture port for the kernel, you can safely skip down +to "Closing". + +1) Struct scatterlist requirements. + + Struct scatterlist must contain, at a minimum, the following + members: + + struct page *page; + unsigned int offset; + unsigned int length; + + The base address is specified by a "page+offset" pair. + + Previous versions of struct scatterlist contained a "void *address" + field that was sometimes used instead of page+offset. As of Linux + 2.5., page+offset is always used, and the "address" field has been + deleted. + +2) More to come... + + Handling Errors + +DMA address space is limited on some architectures and an allocation +failure can be determined by: + +- checking if pci_alloc_consistent returns NULL or pci_map_sg returns 0 + +- checking the returned dma_addr_t of pci_map_single and pci_map_page + by using pci_dma_mapping_error(): + + dma_addr_t dma_handle; + + dma_handle = pci_map_single(pdev, addr, size, direction); + if (pci_dma_mapping_error(pdev, dma_handle)) { + /* + * reduce current DMA mapping usage, + * delay and try again later or + * reset driver. + */ + } + + Closing + +This document, and the API itself, would not be in it's current +form without the feedback and suggestions from numerous individuals. +We would like to specifically mention, in no particular order, the +following people: + + Russell King + Leo Dagum + Ralf Baechle + Grant Grundler + Jay Estabrook + Thomas Sailer + Andrea Arcangeli + Jens Axboe + David Mosberger-Tang diff --git a/Documentation/block/biodoc.txt b/Documentation/block/biodoc.txt index 8d2158a..6fab97e 100644 --- a/Documentation/block/biodoc.txt +++ b/Documentation/block/biodoc.txt @@ -186,7 +186,7 @@ a virtual address mapping (unlike the earlier scheme of virtual address do not have a corresponding kernel virtual address space mapping) and low-memory pages. -Note: Please refer to Documentation/DMA-mapping.txt for a discussion +Note: Please refer to Documentation/PCI/PCI-DMA-mapping.txt for a discussion on PCI high mem DMA aspects and mapping of scatter gather lists, and support for 64 bit PCI. -- cgit v0.10.2 From f3e22f48f37c1e14441c9f72ca8e63b1d4516745 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Sun, 3 Jan 2010 03:44:53 +0100 Subject: reiserfs: Fix mistake in down_write() conversion Fix a mistake in commit 0719d3434747889b314a1e8add776418c4148bcf (reiserfs: Fix reiserfs lock <-> i_xattr_sem dependency inversion) that has converted a down_write() into a down_read() accidentally. Signed-off-by: Frederic Weisbecker Cc: Christian Kujau Cc: Alexander Beregalov Cc: Chris Mason Cc: Ingo Molnar diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index 9623cfe..75d3706 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c @@ -495,7 +495,7 @@ reiserfs_xattr_set_handle(struct reiserfs_transaction_handle *th, return PTR_ERR(dentry); } - down_read(&REISERFS_I(inode)->i_xattr_sem); + down_write(&REISERFS_I(inode)->i_xattr_sem); reiserfs_write_lock(inode->i_sb); -- cgit v0.10.2 From b4e2a2a2f39cc21ed898217ae2d256706723fabb Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 4 Jan 2010 11:13:54 +0900 Subject: sh: Disable PMB for SH4AL-DSP CPUs. While the PMB is available on SH-4A parts, SH4AL-DSP parts exclude it altogether. As such, explicitly disable PMB support for these parts. If this changes in the future for newer subtypes, this will have to be made more fine-grained. Signed-off-by: Paul Mundt diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig index 0e7ba8e..191d6d8 100644 --- a/arch/sh/mm/Kconfig +++ b/arch/sh/mm/Kconfig @@ -82,7 +82,7 @@ config 32BIT config PMB_ENABLE bool "Support 32-bit physical addressing through PMB" - depends on MMU && EXPERIMENTAL && CPU_SH4A + depends on MMU && EXPERIMENTAL && CPU_SH4A && !CPU_SH4AL_DSP default y help If you say Y here, physical addressing will be extended to @@ -96,7 +96,7 @@ choice config PMB bool "PMB" - depends on MMU && EXPERIMENTAL && CPU_SH4A + depends on MMU && EXPERIMENTAL && CPU_SH4A && !CPU_SH4AL_DSP help If you say Y here, physical addressing will be extended to 32-bits through the SH-4A PMB. If this is not set, legacy @@ -104,7 +104,7 @@ config PMB config PMB_FIXED bool "fixed PMB" - depends on MMU && EXPERIMENTAL && CPU_SH4A + depends on MMU && EXPERIMENTAL && CPU_SH4A && !CPU_SH4AL_DSP select 32BIT help If this option is enabled, fixed PMB mappings are inherited -- cgit v0.10.2 From 5e9daa0f26d69d22ffe8efeaba6932ea6ef01ec4 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 4 Jan 2010 11:16:33 +0900 Subject: sh: Don't default enable PMB support. This has the adverse effect of converting many 29bit configs to 32bit mode, while this is a change that needs to be done manually for each platform. Turn it off by default in order to cut down on spurious bug reports. Signed-off-by: Paul Mundt diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig index 191d6d8..986a71b 100644 --- a/arch/sh/mm/Kconfig +++ b/arch/sh/mm/Kconfig @@ -83,7 +83,6 @@ config 32BIT config PMB_ENABLE bool "Support 32-bit physical addressing through PMB" depends on MMU && EXPERIMENTAL && CPU_SH4A && !CPU_SH4AL_DSP - default y help If you say Y here, physical addressing will be extended to 32-bits through the SH-4A PMB. If this is not set, legacy -- cgit v0.10.2 From 2d51a521e64f91e42424b291fcae49d4d3f63d88 Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Mon, 4 Jan 2010 11:42:01 +0800 Subject: [ARM] pxa: update pwm_backlight->notify() to include missed 'struct device *' Signed-off-by: Eric Miao diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c index 8a38d60..189f330 100644 --- a/arch/arm/mach-pxa/magician.c +++ b/arch/arm/mach-pxa/magician.c @@ -381,7 +381,7 @@ err: return ret; } -static int magician_backlight_notify(int brightness) +static int magician_backlight_notify(struct device *dev, int brightness) { gpio_set_value(EGPIO_MAGICIAN_BL_POWER, brightness); if (brightness >= 200) { diff --git a/arch/arm/mach-pxa/palmld.c b/arch/arm/mach-pxa/palmld.c index 5914021..e100af7 100644 --- a/arch/arm/mach-pxa/palmld.c +++ b/arch/arm/mach-pxa/palmld.c @@ -270,7 +270,7 @@ err: return ret; } -static int palmld_backlight_notify(int brightness) +static int palmld_backlight_notify(struct device *dev, int brightness) { gpio_set_value(GPIO_NR_PALMLD_BL_POWER, brightness); gpio_set_value(GPIO_NR_PALMLD_LCD_POWER, brightness); diff --git a/arch/arm/mach-pxa/palmt5.c b/arch/arm/mach-pxa/palmt5.c index 7f89ca2..8fe3ec2 100644 --- a/arch/arm/mach-pxa/palmt5.c +++ b/arch/arm/mach-pxa/palmt5.c @@ -209,7 +209,7 @@ err: return ret; } -static int palmt5_backlight_notify(int brightness) +static int palmt5_backlight_notify(struct device *dev, int brightness) { gpio_set_value(GPIO_NR_PALMT5_BL_POWER, brightness); gpio_set_value(GPIO_NR_PALMT5_LCD_POWER, brightness); diff --git a/arch/arm/mach-pxa/palmtc.c b/arch/arm/mach-pxa/palmtc.c index 3084175..b992f07 100644 --- a/arch/arm/mach-pxa/palmtc.c +++ b/arch/arm/mach-pxa/palmtc.c @@ -185,7 +185,7 @@ err: return ret; } -static int palmtc_backlight_notify(int brightness) +static int palmtc_backlight_notify(struct device *dev, int brightness) { /* backlight is on when GPIO16 AF0 is high */ gpio_set_value(GPIO_NR_PALMTC_BL_POWER, brightness); diff --git a/arch/arm/mach-pxa/palmte2.c b/arch/arm/mach-pxa/palmte2.c index 265d62b..dc728d6 100644 --- a/arch/arm/mach-pxa/palmte2.c +++ b/arch/arm/mach-pxa/palmte2.c @@ -181,7 +181,7 @@ err: return ret; } -static int palmte2_backlight_notify(int brightness) +static int palmte2_backlight_notify(struct device *dev, int brightness) { gpio_set_value(GPIO_NR_PALMTE2_BL_POWER, brightness); gpio_set_value(GPIO_NR_PALMTE2_LCD_POWER, brightness); diff --git a/arch/arm/mach-pxa/palmtreo.c b/arch/arm/mach-pxa/palmtreo.c index 606eb7e..b433bb4 100644 --- a/arch/arm/mach-pxa/palmtreo.c +++ b/arch/arm/mach-pxa/palmtreo.c @@ -375,7 +375,7 @@ err: return ret; } -static int treo_backlight_notify(int brightness) +static int treo_backlight_notify(struct device *dev, int brightness) { gpio_set_value(GPIO_NR_TREO_BL_POWER, brightness); return TREO_MAX_INTENSITY - brightness; diff --git a/arch/arm/mach-pxa/palmtx.c b/arch/arm/mach-pxa/palmtx.c index 7bf18c2..b37a025 100644 --- a/arch/arm/mach-pxa/palmtx.c +++ b/arch/arm/mach-pxa/palmtx.c @@ -269,7 +269,7 @@ err: return ret; } -static int palmtx_backlight_notify(int brightness) +static int palmtx_backlight_notify(struct device *dev, int brightness) { gpio_set_value(GPIO_NR_PALMTX_BL_POWER, brightness); gpio_set_value(GPIO_NR_PALMTX_LCD_POWER, brightness); diff --git a/arch/arm/mach-pxa/palmz72.c b/arch/arm/mach-pxa/palmz72.c index d787ac7..1c5d68a 100644 --- a/arch/arm/mach-pxa/palmz72.c +++ b/arch/arm/mach-pxa/palmz72.c @@ -196,7 +196,7 @@ err: return ret; } -static int palmz72_backlight_notify(int brightness) +static int palmz72_backlight_notify(struct device *dev, int brightness) { gpio_set_value(GPIO_NR_PALMZ72_BL_POWER, brightness); gpio_set_value(GPIO_NR_PALMZ72_LCD_POWER, brightness); diff --git a/arch/arm/mach-pxa/viper.c b/arch/arm/mach-pxa/viper.c index 5352b4e..89f258c 100644 --- a/arch/arm/mach-pxa/viper.c +++ b/arch/arm/mach-pxa/viper.c @@ -379,7 +379,7 @@ err_request_bckl: return ret; } -static int viper_backlight_notify(int brightness) +static int viper_backlight_notify(struct device *dev, int brightness) { gpio_set_value(VIPER_LCD_EN_GPIO, !!brightness); gpio_set_value(VIPER_BCKLIGHT_EN_GPIO, !!brightness); -- cgit v0.10.2 From 35bb5cadc8c7b1462df57e32e08d964f1be7a75c Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 14 Dec 2009 16:05:09 +0000 Subject: via-velocity: Give RX descriptors to the NIC later on open or MTU change velocity_open() calls velocity_give_many_rx_descs(), which gives RX descriptors to the NIC, before installing an interrupt handler or calling velocity_init_registers(). I think this is very unsafe and it appears to explain the bug report . On MTU change, velocity_give_many_rx_descs() is again called before velocity_init_registers(). I'm not sure whether this is unsafe but it does look wrong. Therefore, move the calls to velocity_give_many_rx_descs() after request_irq() and velocity_init_registers(). Signed-off-by: Ben Hutchings Tested-by: Jan Ceuleers Signed-off-by: David S. Miller diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index 4ceb441..c93f58f 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c @@ -2237,8 +2237,6 @@ static int velocity_open(struct net_device *dev) /* Ensure chip is running */ pci_set_power_state(vptr->pdev, PCI_D0); - velocity_give_many_rx_descs(vptr); - velocity_init_registers(vptr, VELOCITY_INIT_COLD); ret = request_irq(vptr->pdev->irq, velocity_intr, IRQF_SHARED, @@ -2250,6 +2248,8 @@ static int velocity_open(struct net_device *dev) goto out; } + velocity_give_many_rx_descs(vptr); + mac_enable_int(vptr->mac_regs); netif_start_queue(dev); napi_enable(&vptr->napi); @@ -2339,10 +2339,10 @@ static int velocity_change_mtu(struct net_device *dev, int new_mtu) dev->mtu = new_mtu; - velocity_give_many_rx_descs(vptr); - velocity_init_registers(vptr, VELOCITY_INIT_COLD); + velocity_give_many_rx_descs(vptr); + mac_enable_int(vptr->mac_regs); netif_start_queue(dev); -- cgit v0.10.2 From 1f731b63752dac76ff4dbf568a08ff2e3663316f Mon Sep 17 00:00:00 2001 From: Bernard Pidoux F6BVP Date: Thu, 17 Dec 2009 05:25:18 +0000 Subject: rose_loopback_timer sets VC number <= ROSE_DEFAULT_MAXVC cat /proc/net/rose displayed a rose sockets abnormal lci value, i.e. greater than maximum number of VCs per neighbour allowed. This number prevents further test of lci value during rose operations. Example (lines shortened) : [bernard]# cat /proc/net/rose dest_addr dest_call src_addr src_call dev lci neigh st vs vr va * * 2080175520 F6BVP-1 rose0 000 00000 0 0 0 0 2080175520 FPAD-0 2080175520 WP-0 rose0 FFE 00001 3 0 0 0 Here are the default parameters : linux/include/net/rose.h:#define ROSE_DEFAULT_MAXVC 50 /* Maximum number of VCs per neighbour */ linux/net/rose/af_rose.c:int sysctl_rose_maximum_vcs = ROSE_DEFAULT_MAXVC; With the following patch, rose_loopback_timer() attributes a VC number within limits. Signed-off-by: Bernard Pidoux Signed-off-by: David S. Miller diff --git a/net/rose/rose_loopback.c b/net/rose/rose_loopback.c index 114df6e..968e8ba 100644 --- a/net/rose/rose_loopback.c +++ b/net/rose/rose_loopback.c @@ -75,7 +75,7 @@ static void rose_loopback_timer(unsigned long param) lci_i = ((skb->data[0] << 8) & 0xF00) + ((skb->data[1] << 0) & 0x0FF); frametype = skb->data[2]; dest = (rose_address *)(skb->data + 4); - lci_o = 0xFFF - lci_i; + lci_o = ROSE_DEFAULT_MAXVC + 1 - lci_i; skb_reset_transport_header(skb); -- cgit v0.10.2 From 8ffd32083c849dcf476e56e6c5f728c80797ecdd Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 21 Dec 2009 14:25:06 +0000 Subject: net/sctp/socket.c: squish warning net/sctp/socket.c: In function 'sctp_setsockopt_autoclose': net/sctp/socket.c:2090: warning: comparison is always false due to limited range of data type Cc: Andrei Pelinescu-Onciul Cc: Vlad Yasevich Cc: "David S. Miller" Signed-off-by: Andrew Morton Signed-off-by: David S. Miller diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 89ab66e..67fdac9 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -2087,8 +2087,7 @@ static int sctp_setsockopt_autoclose(struct sock *sk, char __user *optval, if (copy_from_user(&sp->autoclose, optval, optlen)) return -EFAULT; /* make sure it won't exceed MAX_SCHEDULE_TIMEOUT */ - if (sp->autoclose > (MAX_SCHEDULE_TIMEOUT / HZ) ) - sp->autoclose = (__u32)(MAX_SCHEDULE_TIMEOUT / HZ) ; + sp->autoclose = min_t(long, sp->autoclose, MAX_SCHEDULE_TIMEOUT / HZ); return 0; } -- cgit v0.10.2 From 073bd90f03d98bc3168865f21573c9b232777c13 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Mon, 21 Dec 2009 14:25:32 +0000 Subject: drivers/isdn: eliminate duplicated test The code checked slot_rx twice. Check slot_tx by analogy with the bank case. The semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @@ expression E; @@ ( *E && E | *E || E ) // Signed-off-by: Julia Lawall Cc: Karsten Keil Signed-off-by: Andrew Morton Signed-off-by: David S. Miller diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c index a6624ad..1a1420d 100644 --- a/drivers/isdn/hardware/mISDN/hfcmulti.c +++ b/drivers/isdn/hardware/mISDN/hfcmulti.c @@ -3152,7 +3152,7 @@ static void hfcmulti_pcm(struct hfc_multi *hc, int ch, int slot_tx, int bank_tx, int slot_rx, int bank_rx) { - if (slot_rx < 0 || slot_rx < 0 || bank_tx < 0 || bank_rx < 0) { + if (slot_tx < 0 || slot_rx < 0 || bank_tx < 0 || bank_rx < 0) { /* disable PCM */ mode_hfcmulti(hc, ch, hc->chan[ch].protocol, -1, 0, -1, 0); return; -- cgit v0.10.2 From ce739b473ce12d5ef067b39b8637bfd2b2174a15 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 27 Dec 2009 11:27:44 +0000 Subject: drivers/net/can: Correct NULL test Test the just-allocated value for NULL rather than some other value. The semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ expression x,y; statement S; @@ x = \(kmalloc\|kcalloc\|kzalloc\)(...); ( if ((x) == NULL) S | if ( - y + x == NULL) S ) // Signed-off-by: Julia Lawall Acked-by: Oliver Hartkopp Signed-off-by: David S. Miller diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c index 9c5a153..1a72ca0 100644 --- a/drivers/net/can/mcp251x.c +++ b/drivers/net/can/mcp251x.c @@ -990,7 +990,7 @@ static int __devinit mcp251x_can_probe(struct spi_device *spi) goto error_tx_buf; } priv->spi_rx_buf = kmalloc(SPI_TRANSFER_BUF_LEN, GFP_KERNEL); - if (!priv->spi_tx_buf) { + if (!priv->spi_rx_buf) { ret = -ENOMEM; goto error_rx_buf; } -- cgit v0.10.2 From c064efca9211d12bb9e6de8718fc39884eb883f2 Mon Sep 17 00:00:00 2001 From: roel kluin Date: Sun, 27 Dec 2009 11:22:08 +0000 Subject: usbnet: test off by one With `while (i++ < MII_TIMEOUT)' i reaches MII_TIMEOUT + 1 after the loop This is probably unlikely a problem in practice. Signed-off-by: Roel Kluin Signed-off-by: David S. Miller diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c index f14d225..fd19db0 100644 --- a/drivers/net/usb/rtl8150.c +++ b/drivers/net/usb/rtl8150.c @@ -270,7 +270,7 @@ static int read_mii_word(rtl8150_t * dev, u8 phy, __u8 indx, u16 * reg) get_registers(dev, PHYCNT, 1, data); } while ((data[0] & PHY_GO) && (i++ < MII_TIMEOUT)); - if (i < MII_TIMEOUT) { + if (i <= MII_TIMEOUT) { get_registers(dev, PHYDAT, 2, data); *reg = data[0] | (data[1] << 8); return 0; @@ -295,7 +295,7 @@ static int write_mii_word(rtl8150_t * dev, u8 phy, __u8 indx, u16 reg) get_registers(dev, PHYCNT, 1, data); } while ((data[0] & PHY_GO) && (i++ < MII_TIMEOUT)); - if (i < MII_TIMEOUT) + if (i <= MII_TIMEOUT) return 0; else return 1; -- cgit v0.10.2 From f65d1f082c8fb1bfae3f2cb51ec270da9b6366cf Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 28 Dec 2009 06:54:55 +0000 Subject: hamradio: avoid null deref v3 This should address the problems in version 1 (lazy) and version 2 (ugly). Bump the stats on orig_dev not on the newly assigned NULL dev variable. Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c index ae5f11c..bdadf3e 100644 --- a/drivers/net/hamradio/bpqether.c +++ b/drivers/net/hamradio/bpqether.c @@ -248,6 +248,7 @@ static netdev_tx_t bpq_xmit(struct sk_buff *skb, struct net_device *dev) { unsigned char *ptr; struct bpqdev *bpq; + struct net_device *orig_dev; int size; /* @@ -282,8 +283,9 @@ static netdev_tx_t bpq_xmit(struct sk_buff *skb, struct net_device *dev) bpq = netdev_priv(dev); + orig_dev = dev; if ((dev = bpq_get_ether_dev(dev)) == NULL) { - dev->stats.tx_dropped++; + orig_dev->stats.tx_dropped++; kfree_skb(skb); return NETDEV_TX_OK; } -- cgit v0.10.2 From 52ee264bca378835decb827d18b1d90b709ca4c9 Mon Sep 17 00:00:00 2001 From: Rakesh Ranjan Date: Sun, 27 Dec 2009 12:33:08 +0530 Subject: cxgb3i: Fix a login over vlan issue Fix a target login issue, when parent interface is vlan and we are using cxgb3i sepecific private ip address in '/etc/iscsi/ifaces/' iface file. Acked-by: Karen Xie Signed-off-by: Rakesh Ranjan Signed-off-by: David S. Miller diff --git a/drivers/scsi/cxgb3i/cxgb3i_offload.c b/drivers/scsi/cxgb3i/cxgb3i_offload.c index c1d5be4..4b8a513 100644 --- a/drivers/scsi/cxgb3i/cxgb3i_offload.c +++ b/drivers/scsi/cxgb3i/cxgb3i_offload.c @@ -1440,6 +1440,10 @@ void cxgb3i_c3cn_release(struct s3_conn *c3cn) static int is_cxgb3_dev(struct net_device *dev) { struct cxgb3i_sdev_data *cdata; + struct net_device *ndev = dev; + + if (dev->priv_flags && IFF_802_1Q_VLAN) + ndev = vlan_dev_real_dev(dev); write_lock(&cdata_rwlock); list_for_each_entry(cdata, &cdata_list, list) { @@ -1447,7 +1451,7 @@ static int is_cxgb3_dev(struct net_device *dev) int i; for (i = 0; i < ports->nports; i++) - if (dev == ports->lldevs[i]) { + if (ndev == ports->lldevs[i]) { write_unlock(&cdata_rwlock); return 1; } @@ -1566,6 +1570,26 @@ out_err: return -1; } +/* * + * cxgb3i_find_dev - find the interface associated with the given address + * @ipaddr: ip address + */ +static struct net_device * +cxgb3i_find_dev(struct net_device *dev, __be32 ipaddr) +{ + struct flowi fl; + int err; + struct rtable *rt; + + memset(&fl, 0, sizeof(fl)); + fl.nl_u.ip4_u.daddr = ipaddr; + + err = ip_route_output_key(dev ? dev_net(dev) : &init_net, &rt, &fl); + if (!err) + return (&rt->u.dst)->dev; + + return NULL; +} /** * cxgb3i_c3cn_connect - initiates an iscsi tcp connection to a given address @@ -1581,6 +1605,7 @@ int cxgb3i_c3cn_connect(struct net_device *dev, struct s3_conn *c3cn, struct cxgb3i_sdev_data *cdata; struct t3cdev *cdev; __be32 sipv4; + struct net_device *dstdev; int err; c3cn_conn_debug("c3cn 0x%p, dev 0x%p.\n", c3cn, dev); @@ -1591,6 +1616,13 @@ int cxgb3i_c3cn_connect(struct net_device *dev, struct s3_conn *c3cn, c3cn->daddr.sin_port = usin->sin_port; c3cn->daddr.sin_addr.s_addr = usin->sin_addr.s_addr; + dstdev = cxgb3i_find_dev(dev, usin->sin_addr.s_addr); + if (!dstdev || !is_cxgb3_dev(dstdev)) + return -ENETUNREACH; + + if (dstdev->priv_flags & IFF_802_1Q_VLAN) + dev = dstdev; + rt = find_route(dev, c3cn->saddr.sin_addr.s_addr, c3cn->daddr.sin_addr.s_addr, c3cn->saddr.sin_port, -- cgit v0.10.2 From 5d66fe92a19fb41373d13e75831169a6b5e5bef5 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Tue, 29 Dec 2009 09:15:42 +0000 Subject: drivers/net : Correct the size argument to kzalloc lp->rx_skb has type struct sk_buff **, not struct sk_buff *, so the elements of the array should have pointer type, not structure type. The semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @disable sizeof_type_expr@ type T; T **x; @@ x = <+...sizeof( - T + *x )...+> // Signed-off-by: Julia Lawall Signed-off-by: David S. Miller diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c index 336e7c7..a8522bd 100644 --- a/drivers/net/ll_temac_main.c +++ b/drivers/net/ll_temac_main.c @@ -134,7 +134,7 @@ static int temac_dma_bd_init(struct net_device *ndev) struct sk_buff *skb; int i; - lp->rx_skb = kzalloc(sizeof(struct sk_buff)*RX_BD_NUM, GFP_KERNEL); + lp->rx_skb = kzalloc(sizeof(*lp->rx_skb) * RX_BD_NUM, GFP_KERNEL); /* allocate the tx and rx ring buffer descriptors. */ /* returns a virtual addres and a physical address. */ lp->tx_bd_v = dma_alloc_coherent(ndev->dev.parent, -- cgit v0.10.2 From e145b98484f5c7444151e90cc0853f14e6d396a4 Mon Sep 17 00:00:00 2001 From: roel kluin Date: Sun, 27 Dec 2009 03:26:12 +0000 Subject: atarilance: timeout ignored in lance_open() With `while (--i > 0)' i reaches 0 after the loop, so upon timeout the error was not issued. Signed-off-by: Roel Kluin Signed-off-by: David S. Miller diff --git a/drivers/net/atarilance.c b/drivers/net/atarilance.c index c5721cb..cc9ed86 100644 --- a/drivers/net/atarilance.c +++ b/drivers/net/atarilance.c @@ -663,7 +663,7 @@ static int lance_open( struct net_device *dev ) while (--i > 0) if (DREG & CSR0_IDON) break; - if (i < 0 || (DREG & CSR0_ERR)) { + if (i <= 0 || (DREG & CSR0_ERR)) { DPRINTK( 2, ( "lance_open(): opening %s failed, i=%d, csr0=%04x\n", dev->name, i, DREG )); DREG = CSR0_STOP; -- cgit v0.10.2 From d2a928e4bfc75170af641f073475fc974cf176c2 Mon Sep 17 00:00:00 2001 From: roel kluin Date: Sun, 27 Dec 2009 04:10:59 +0000 Subject: niu: timeout ignored in tcam_wait_bit() With `while (--limit > 0)' i reaches 0 after the loop, so upon timeout the error was not returned. Signed-off-by: Roel Kluin Signed-off-by: David S. Miller diff --git a/drivers/net/niu.c b/drivers/net/niu.c index 8ce58c4..2aed2b3 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -2844,7 +2844,7 @@ static int tcam_wait_bit(struct niu *np, u64 bit) break; udelay(1); } - if (limit < 0) + if (limit <= 0) return -ENODEV; return 0; -- cgit v0.10.2 From 890c8c18986eb975a76aa8359a712596bc70e61c Mon Sep 17 00:00:00 2001 From: roel kluin Date: Wed, 30 Dec 2009 01:43:45 +0000 Subject: net: Test off by one in sh_eth_reset() If no break occurred, cnt reaches 0 after the loop. Signed-off-by: Roel Kluin Signed-off-by: David S. Miller diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index ca62850..7402b85 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c @@ -110,7 +110,7 @@ static void sh_eth_reset(struct net_device *ndev) mdelay(1); cnt--; } - if (cnt < 0) + if (cnt == 0) printk(KERN_ERR "Device reset fail\n"); /* Table Init */ -- cgit v0.10.2 From 7ec4e7d3cfee9d7846dbd02ad442c40cb58512e8 Mon Sep 17 00:00:00 2001 From: roel kluin Date: Wed, 30 Dec 2009 06:43:06 +0000 Subject: broadcom: Fix &&/|| confusion in bcm54xx_adjust_rxrefclk() This always evaluates to true. Signed-off-by: Roel Kluin Signed-off-by: David S. Miller diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c index c13cf64..33c4b12 100644 --- a/drivers/net/phy/broadcom.c +++ b/drivers/net/phy/broadcom.c @@ -331,8 +331,8 @@ static void bcm54xx_adjust_rxrefclk(struct phy_device *phydev) bool clk125en = true; /* Abort if we are using an untested phy. */ - if (BRCM_PHY_MODEL(phydev) != PHY_ID_BCM57780 || - BRCM_PHY_MODEL(phydev) != PHY_ID_BCM50610 || + if (BRCM_PHY_MODEL(phydev) != PHY_ID_BCM57780 && + BRCM_PHY_MODEL(phydev) != PHY_ID_BCM50610 && BRCM_PHY_MODEL(phydev) != PHY_ID_BCM50610M) return; -- cgit v0.10.2 From 2585e7e5e1fcf64fd2b2cac0bc1f1b609eabe96a Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 2 Jan 2010 04:08:46 +0000 Subject: rrunner: fix buffer overflow tx_skbuff is define as: struct sk_buff *tx_skbuff[TX_RING_ENTRIES]; EVT_RING_ENTRIES is 64 and TX_RING_ENTRIES is 32. This function is in a error path so that's why it wasn't noticed. Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller diff --git a/drivers/net/rrunner.c b/drivers/net/rrunner.c index 20a7174..1c25709 100644 --- a/drivers/net/rrunner.c +++ b/drivers/net/rrunner.c @@ -1293,7 +1293,7 @@ static void rr_dump(struct net_device *dev) printk("Error code 0x%x\n", readl(®s->Fail1)); - index = (((readl(®s->EvtPrd) >> 8) & 0xff ) - 1) % EVT_RING_ENTRIES; + index = (((readl(®s->EvtPrd) >> 8) & 0xff) - 1) % TX_RING_ENTRIES; cons = rrpriv->dirty_tx; printk("TX ring index %i, TX consumer %i\n", index, cons); -- cgit v0.10.2 From 2d2cf34681e65a2495946ebc90b407ba4088e8d0 Mon Sep 17 00:00:00 2001 From: Sucheta Chakraborty Date: Sat, 2 Jan 2010 03:25:18 +0000 Subject: netxen: fix ethtool register dump o Dump registers such as tx ring and rx ring counter, firmware state, niu regs, etc. which can be useful for debugging purpose. Signed-off-by: Sucheta Chakraborty Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c index ddd704a..72ced00 100644 --- a/drivers/net/netxen/netxen_nic_ethtool.c +++ b/drivers/net/netxen/netxen_nic_ethtool.c @@ -66,7 +66,7 @@ static const char netxen_nic_gstrings_test[][ETH_GSTRING_LEN] = { #define NETXEN_NIC_TEST_LEN ARRAY_SIZE(netxen_nic_gstrings_test) -#define NETXEN_NIC_REGS_COUNT 42 +#define NETXEN_NIC_REGS_COUNT 30 #define NETXEN_NIC_REGS_LEN (NETXEN_NIC_REGS_COUNT * sizeof(__le32)) #define NETXEN_MAX_EEPROM_LEN 1024 @@ -312,125 +312,73 @@ static int netxen_nic_get_regs_len(struct net_device *dev) return NETXEN_NIC_REGS_LEN; } -struct netxen_niu_regs { - __u32 reg[NETXEN_NIC_REGS_COUNT]; -}; - -static struct netxen_niu_regs niu_registers[] = { - { - /* GB Mode */ - { - NETXEN_NIU_GB_SERDES_RESET, - NETXEN_NIU_GB0_MII_MODE, - NETXEN_NIU_GB1_MII_MODE, - NETXEN_NIU_GB2_MII_MODE, - NETXEN_NIU_GB3_MII_MODE, - NETXEN_NIU_GB0_GMII_MODE, - NETXEN_NIU_GB1_GMII_MODE, - NETXEN_NIU_GB2_GMII_MODE, - NETXEN_NIU_GB3_GMII_MODE, - NETXEN_NIU_REMOTE_LOOPBACK, - NETXEN_NIU_GB0_HALF_DUPLEX, - NETXEN_NIU_GB1_HALF_DUPLEX, - NETXEN_NIU_RESET_SYS_FIFOS, - NETXEN_NIU_GB_CRC_DROP, - NETXEN_NIU_GB_DROP_WRONGADDR, - NETXEN_NIU_TEST_MUX_CTL, - - NETXEN_NIU_GB_MAC_CONFIG_0(0), - NETXEN_NIU_GB_MAC_CONFIG_1(0), - NETXEN_NIU_GB_HALF_DUPLEX_CTRL(0), - NETXEN_NIU_GB_MAX_FRAME_SIZE(0), - NETXEN_NIU_GB_TEST_REG(0), - NETXEN_NIU_GB_MII_MGMT_CONFIG(0), - NETXEN_NIU_GB_MII_MGMT_COMMAND(0), - NETXEN_NIU_GB_MII_MGMT_ADDR(0), - NETXEN_NIU_GB_MII_MGMT_CTRL(0), - NETXEN_NIU_GB_MII_MGMT_STATUS(0), - NETXEN_NIU_GB_MII_MGMT_INDICATE(0), - NETXEN_NIU_GB_INTERFACE_CTRL(0), - NETXEN_NIU_GB_INTERFACE_STATUS(0), - NETXEN_NIU_GB_STATION_ADDR_0(0), - NETXEN_NIU_GB_STATION_ADDR_1(0), - -1, - } - }, - { - /* XG Mode */ - { - NETXEN_NIU_XG_SINGLE_TERM, - NETXEN_NIU_XG_DRIVE_HI, - NETXEN_NIU_XG_DRIVE_LO, - NETXEN_NIU_XG_DTX, - NETXEN_NIU_XG_DEQ, - NETXEN_NIU_XG_WORD_ALIGN, - NETXEN_NIU_XG_RESET, - NETXEN_NIU_XG_POWER_DOWN, - NETXEN_NIU_XG_RESET_PLL, - NETXEN_NIU_XG_SERDES_LOOPBACK, - NETXEN_NIU_XG_DO_BYTE_ALIGN, - NETXEN_NIU_XG_TX_ENABLE, - NETXEN_NIU_XG_RX_ENABLE, - NETXEN_NIU_XG_STATUS, - NETXEN_NIU_XG_PAUSE_THRESHOLD, - NETXEN_NIU_XGE_CONFIG_0, - NETXEN_NIU_XGE_CONFIG_1, - NETXEN_NIU_XGE_IPG, - NETXEN_NIU_XGE_STATION_ADDR_0_HI, - NETXEN_NIU_XGE_STATION_ADDR_0_1, - NETXEN_NIU_XGE_STATION_ADDR_1_LO, - NETXEN_NIU_XGE_STATUS, - NETXEN_NIU_XGE_MAX_FRAME_SIZE, - NETXEN_NIU_XGE_PAUSE_FRAME_VALUE, - NETXEN_NIU_XGE_TX_BYTE_CNT, - NETXEN_NIU_XGE_TX_FRAME_CNT, - NETXEN_NIU_XGE_RX_BYTE_CNT, - NETXEN_NIU_XGE_RX_FRAME_CNT, - NETXEN_NIU_XGE_AGGR_ERROR_CNT, - NETXEN_NIU_XGE_MULTICAST_FRAME_CNT, - NETXEN_NIU_XGE_UNICAST_FRAME_CNT, - NETXEN_NIU_XGE_CRC_ERROR_CNT, - NETXEN_NIU_XGE_OVERSIZE_FRAME_ERR, - NETXEN_NIU_XGE_UNDERSIZE_FRAME_ERR, - NETXEN_NIU_XGE_LOCAL_ERROR_CNT, - NETXEN_NIU_XGE_REMOTE_ERROR_CNT, - NETXEN_NIU_XGE_CONTROL_CHAR_CNT, - NETXEN_NIU_XGE_PAUSE_FRAME_CNT, - -1, - } - } -}; - static void netxen_nic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p) { struct netxen_adapter *adapter = netdev_priv(dev); - __u32 mode, *regs_buff = p; - int i, window; + struct netxen_recv_context *recv_ctx = &adapter->recv_ctx; + struct nx_host_sds_ring *sds_ring; + u32 *regs_buff = p; + int ring, i = 0; + int port = adapter->physical_port; memset(p, 0, NETXEN_NIC_REGS_LEN); + regs->version = (1 << 24) | (adapter->ahw.revision_id << 16) | (adapter->pdev)->device; - /* which mode */ - regs_buff[0] = NXRD32(adapter, NETXEN_NIU_MODE); - mode = regs_buff[0]; - - /* Common registers to all the modes */ - regs_buff[2] = NXRD32(adapter, NETXEN_NIU_STRAP_VALUE_SAVE_HIGHER); - /* GB/XGB Mode */ - mode = (mode / 2) - 1; - window = 0; - if (mode <= 1) { - for (i = 3; niu_registers[mode].reg[i - 3] != -1; i++) { - /* GB: port specific registers */ - if (mode == 0 && i >= 19) - window = adapter->physical_port * - NETXEN_NIC_PORT_WINDOW; - - regs_buff[i] = NXRD32(adapter, - niu_registers[mode].reg[i - 3] + window); - } + if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC) + return; + + regs_buff[i++] = NXRD32(adapter, CRB_CMDPEG_STATE); + regs_buff[i++] = NXRD32(adapter, CRB_RCVPEG_STATE); + regs_buff[i++] = NXRD32(adapter, CRB_FW_CAPABILITIES_1); + regs_buff[i++] = NXRDIO(adapter, adapter->crb_int_state_reg); + regs_buff[i++] = NXRD32(adapter, NX_CRB_DEV_REF_COUNT); + regs_buff[i++] = NXRD32(adapter, NX_CRB_DEV_STATE); + regs_buff[i++] = NXRD32(adapter, NETXEN_PEG_ALIVE_COUNTER); + regs_buff[i++] = NXRD32(adapter, NETXEN_PEG_HALT_STATUS1); + regs_buff[i++] = NXRD32(adapter, NETXEN_PEG_HALT_STATUS2); + + regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_0+0x3c); + regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_1+0x3c); + regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_2+0x3c); + regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_3+0x3c); + + if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { + + regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_4+0x3c); + i += 2; + + regs_buff[i++] = NXRD32(adapter, CRB_XG_STATE_P3); + regs_buff[i++] = le32_to_cpu(*(adapter->tx_ring->hw_consumer)); + + } else { + i++; + + regs_buff[i++] = NXRD32(adapter, + NETXEN_NIU_XGE_CONFIG_0+(0x10000*port)); + regs_buff[i++] = NXRD32(adapter, + NETXEN_NIU_XGE_CONFIG_1+(0x10000*port)); + + regs_buff[i++] = NXRD32(adapter, CRB_XG_STATE); + regs_buff[i++] = NXRDIO(adapter, + adapter->tx_ring->crb_cmd_consumer); + } + + regs_buff[i++] = NXRDIO(adapter, adapter->tx_ring->crb_cmd_producer); + + regs_buff[i++] = NXRDIO(adapter, + recv_ctx->rds_rings[0].crb_rcv_producer); + regs_buff[i++] = NXRDIO(adapter, + recv_ctx->rds_rings[1].crb_rcv_producer); + + regs_buff[i++] = adapter->max_sds_rings; + + for (ring = 0; ring < adapter->max_sds_rings; ring++) { + sds_ring = &(recv_ctx->sds_rings[ring]); + regs_buff[i++] = NXRDIO(adapter, + sds_ring->crb_sts_consumer); } } -- cgit v0.10.2 From a4b751d87241c1b49ce43f819428223bfc22dc27 Mon Sep 17 00:00:00 2001 From: Sucheta Chakraborty Date: Sat, 2 Jan 2010 03:25:19 +0000 Subject: netxen: fix ethtool link test o Fix ethtool link test for NX3031 chip. o Remove unused code from phy interrupt callback Signed-off-by: Sucheta Chakraborty Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c index 72ced00..542f408 100644 --- a/drivers/net/netxen/netxen_nic_ethtool.c +++ b/drivers/net/netxen/netxen_nic_ethtool.c @@ -385,25 +385,18 @@ netxen_nic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p) static u32 netxen_nic_test_link(struct net_device *dev) { struct netxen_adapter *adapter = netdev_priv(dev); - __u32 status; - int val; + u32 val, port; - /* read which mode */ - if (adapter->ahw.port_type == NETXEN_NIC_GBE) { - if (adapter->phy_read && - adapter->phy_read(adapter, - NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, - &status) != 0) - return -EIO; - else { - val = netxen_get_phy_link(status); - return !val; - } - } else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) { + port = adapter->physical_port; + if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { + val = NXRD32(adapter, CRB_XG_STATE_P3); + val = XG_LINK_STATE_P3(adapter->ahw.pci_func, val); + return (val == XG_LINK_UP_P3) ? 0 : 1; + } else { val = NXRD32(adapter, CRB_XG_STATE); + val = (val >> port*8) & 0xff; return (val == XG_LINK_UP) ? 0 : 1; } - return -EIO; } static int diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 6cae26a..880fcd06 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -1898,12 +1898,8 @@ static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter) linkup = (val == XG_LINK_UP_P3); } else { val = NXRD32(adapter, CRB_XG_STATE); - if (adapter->ahw.port_type == NETXEN_NIC_GBE) - linkup = (val >> port) & 1; - else { - val = (val >> port*8) & 0xff; - linkup = (val == XG_LINK_UP); - } + val = (val >> port*8) & 0xff; + linkup = (val == XG_LINK_UP); } netxen_advert_link_change(adapter, linkup); -- cgit v0.10.2 From 7dbcd8c55fa9b39fe27383b697b8989697c1e1c5 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 4 Jan 2010 15:38:50 +0900 Subject: sh: update defconfigs. Signed-off-by: Paul Mundt diff --git a/arch/sh/configs/ap325rxa_defconfig b/arch/sh/configs/ap325rxa_defconfig index 2f78d01..8931a60 100644 --- a/arch/sh/configs/ap325rxa_defconfig +++ b/arch/sh/configs/ap325rxa_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31 -# Fri Sep 25 11:22:50 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 11:10:59 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_SYS_SUPPORTS_HUGETLBFS=y CONFIG_SYS_SUPPORTS_CMT=y CONFIG_SYS_SUPPORTS_TMU=y CONFIG_STACKTRACE_SUPPORT=y @@ -30,6 +31,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_DMA_NONCOHERENT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -62,6 +64,7 @@ CONFIG_BSD_PROCESS_ACCT=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -99,6 +102,7 @@ CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters @@ -116,6 +120,7 @@ CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -142,14 +147,41 @@ CONFIG_LBDAF=y # IO Schedulers # CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y -# CONFIG_DEFAULT_AS is not set # CONFIG_DEFAULT_DEADLINE is not set CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +# CONFIG_INLINE_SPIN_UNLOCK is not set +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +# CONFIG_INLINE_READ_UNLOCK is not set +# CONFIG_INLINE_READ_UNLOCK_BH is not set +# CONFIG_INLINE_READ_UNLOCK_IRQ is not set +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +# CONFIG_INLINE_WRITE_UNLOCK is not set +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set CONFIG_FREEZER=y # @@ -205,6 +237,7 @@ CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_MEMORY_START=0x08000000 CONFIG_MEMORY_SIZE=0x08000000 CONFIG_29BIT=y +# CONFIG_PMB_ENABLE is not set # CONFIG_X2TLB is not set CONFIG_VSYSCALL=y CONFIG_ARCH_FLATMEM_ENABLE=y @@ -229,8 +262,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -262,7 +293,6 @@ CONFIG_SH_AP325RXA=y # CONFIG_SH_TIMER_TMU=y # CONFIG_SH_TIMER_CMT is not set -CONFIG_SH_PCLK_FREQ=33333333 CONFIG_SH_CLK_CPG=y CONFIG_TICK_ONESHOT=y # CONFIG_NO_HZ is not set @@ -418,9 +448,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_AF_RXRPC is not set CONFIG_WIRELESS=y # CONFIG_CFG80211 is not set -CONFIG_CFG80211_DEFAULT_PS_VALUE=0 -# CONFIG_WIRELESS_OLD_REGULATORY is not set -# CONFIG_WIRELESS_EXT is not set # CONFIG_LIB80211 is not set # @@ -550,6 +577,10 @@ CONFIG_MTD_UBI_BEB_RESERVE=1 CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# # CONFIG_BLK_DEV_NBD is not set CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=4 @@ -559,9 +590,12 @@ CONFIG_BLK_DEV_RAM_SIZE=4096 # CONFIG_ATA_OVER_ETH is not set # CONFIG_BLK_DEV_HD is not set CONFIG_MISC_DEVICES=y +# CONFIG_AD525X_DPOT is not set # CONFIG_ICS932S401 is not set # CONFIG_ENCLOSURE_SERVICES is not set # CONFIG_ISL29003 is not set +# CONFIG_DS1682 is not set +# CONFIG_TI_DAC7512 is not set # CONFIG_C2PORT is not set # @@ -572,6 +606,7 @@ CONFIG_MISC_DEVICES=y # CONFIG_EEPROM_LEGACY is not set # CONFIG_EEPROM_MAX6875 is not set # CONFIG_EEPROM_93CX6 is not set +# CONFIG_IWMC3200TOP is not set CONFIG_HAVE_IDE=y # CONFIG_IDE is not set @@ -664,11 +699,11 @@ CONFIG_SMSC911X=y # CONFIG_B44 is not set # CONFIG_KS8842 is not set # CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set CONFIG_WLAN=y -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +# CONFIG_HOSTAP is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers @@ -688,6 +723,7 @@ CONFIG_WLAN=y CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set # CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set # # Userland interfaces @@ -782,7 +818,6 @@ CONFIG_I2C_SH_MOBILE=y # # Miscellaneous I2C Chip support # -# CONFIG_DS1682 is not set # CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set @@ -796,7 +831,10 @@ CONFIG_SPI_MASTER=y # CONFIG_SPI_BITBANG=y CONFIG_SPI_GPIO=y +# CONFIG_SPI_SH_MSIOF is not set # CONFIG_SPI_SH_SCI is not set +# CONFIG_SPI_XILINX is not set +# CONFIG_SPI_DESIGNWARE is not set # # SPI Protocol Masters @@ -854,11 +892,13 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_TPS65010 is not set # CONFIG_TWL4030_CORE is not set # CONFIG_MFD_TMIO is not set # CONFIG_PMIC_DA903X is not set +# CONFIG_PMIC_ADP5520 is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set @@ -866,6 +906,8 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_MC13783 is not set # CONFIG_AB3100_CORE is not set # CONFIG_EZX_PCAP is not set +# CONFIG_MFD_88PM8607 is not set +# CONFIG_AB4500_CORE is not set # CONFIG_REGULATOR is not set CONFIG_MEDIA_SUPPORT=y @@ -882,6 +924,8 @@ CONFIG_VIDEO_MEDIA=y # # Multimedia drivers # +CONFIG_IR_CORE=y +CONFIG_VIDEO_IR=y # CONFIG_MEDIA_ATTACH is not set CONFIG_MEDIA_TUNER=y # CONFIG_MEDIA_TUNER_CUSTOMISE is not set @@ -901,6 +945,7 @@ CONFIG_VIDEO_CAPTURE_DRIVERS=y # CONFIG_VIDEO_ADV_DEBUG is not set # CONFIG_VIDEO_FIXED_MINOR_RANGES is not set CONFIG_VIDEO_HELPER_CHIPS_AUTO=y +CONFIG_VIDEO_IR_I2C=y # CONFIG_VIDEO_VIVI is not set # CONFIG_VIDEO_SAA5246A is not set # CONFIG_VIDEO_SAA5249 is not set @@ -908,10 +953,13 @@ CONFIG_SOC_CAMERA=y # CONFIG_SOC_CAMERA_MT9M001 is not set # CONFIG_SOC_CAMERA_MT9M111 is not set # CONFIG_SOC_CAMERA_MT9T031 is not set +# CONFIG_SOC_CAMERA_MT9T112 is not set # CONFIG_SOC_CAMERA_MT9V022 is not set +# CONFIG_SOC_CAMERA_RJ54N1 is not set # CONFIG_SOC_CAMERA_TW9910 is not set CONFIG_SOC_CAMERA_PLATFORM=y CONFIG_SOC_CAMERA_OV772X=y +# CONFIG_SOC_CAMERA_OV9640 is not set CONFIG_VIDEO_SH_MOBILE_CEU=y # CONFIG_RADIO_ADAPTERS is not set # CONFIG_DAB is not set @@ -996,6 +1044,7 @@ CONFIG_MMC_BLOCK_BOUNCE=y # CONFIG_MMC_AT91 is not set # CONFIG_MMC_ATMELMCI is not set CONFIG_MMC_SPI=y +# CONFIG_MMC_TMIO is not set # CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set # CONFIG_ACCESSIBILITY is not set @@ -1027,6 +1076,7 @@ CONFIG_RTC_INTF_DEV=y CONFIG_RTC_DRV_PCF8563=y # CONFIG_RTC_DRV_PCF8583 is not set # CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set # CONFIG_RTC_DRV_S35390A is not set # CONFIG_RTC_DRV_FM3130 is not set # CONFIG_RTC_DRV_RX8581 is not set @@ -1055,7 +1105,9 @@ CONFIG_RTC_DRV_PCF8563=y # CONFIG_RTC_DRV_M48T86 is not set # CONFIG_RTC_DRV_M48T35 is not set # CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set # CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set # CONFIG_RTC_DRV_V3020 is not set # @@ -1248,7 +1300,7 @@ CONFIG_FRAME_WARN=1024 # CONFIG_DEBUG_FS is not set # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_LATENCYTOP is not set @@ -1265,7 +1317,6 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set -# CONFIG_EARLY_SCIF_CONSOLE is not set # CONFIG_DWARF_UNWINDER is not set # @@ -1274,7 +1325,11 @@ CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" CONFIG_CRYPTO=y # diff --git a/arch/sh/configs/cayman_defconfig b/arch/sh/configs/cayman_defconfig index 6b863cb..92589a9 100644 --- a/arch/sh/configs/cayman_defconfig +++ b/arch/sh/configs/cayman_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.30 -# Thu Jun 18 12:21:54 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 11:14:50 2010 # CONFIG_SUPERH=y # CONFIG_SUPERH32 is not set @@ -14,11 +14,13 @@ CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_IRQ_PER_CPU=y # CONFIG_GENERIC_GPIO is not set CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y # CONFIG_ARCH_SUSPEND_POSSIBLE is not set # CONFIG_ARCH_HIBERNATION_POSSIBLE is not set +CONFIG_SYS_SUPPORTS_HUGETLBFS=y CONFIG_SYS_SUPPORTS_PCI=y CONFIG_SYS_SUPPORTS_TMU=y CONFIG_STACKTRACE_SUPPORT=y @@ -28,7 +30,10 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y # CONFIG_ARCH_HAS_ILOG2_U64 is not set CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y +CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_DMA_NONCOHERENT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y # # General setup @@ -39,6 +44,12 @@ CONFIG_LOCK_KERNEL=y CONFIG_INIT_ENV_ARG_LIMIT=32 CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_BZIP2=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_BZIP2 is not set +# CONFIG_KERNEL_LZMA is not set CONFIG_SWAP=y # CONFIG_SYSVIPC is not set CONFIG_POSIX_MQUEUE=y @@ -50,11 +61,13 @@ CONFIG_POSIX_MQUEUE_SYSCTL=y # # RCU Subsystem # -CONFIG_CLASSIC_RCU=y -# CONFIG_TREE_RCU is not set -# CONFIG_PREEMPT_RCU is not set +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set # CONFIG_TREE_RCU_TRACE is not set -# CONFIG_PREEMPT_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_GROUP_SCHED is not set @@ -85,24 +98,32 @@ CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # -# Performance Counters +# Kernel Performance Events And Counters # +# CONFIG_PERF_EVENTS is not set +# CONFIG_PERF_COUNTERS is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_PCI_QUIRKS=y -# CONFIG_STRIP_ASM_SYMS is not set CONFIG_COMPAT_BRK=y CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set # CONFIG_PROFILING is not set -# CONFIG_MARKERS is not set CONFIG_HAVE_OPROFILE=y CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set # CONFIG_SLOW_WORK is not set CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y @@ -115,7 +136,7 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_BLOCK=y -# CONFIG_LBD is not set +CONFIG_LBDAF=y # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -123,14 +144,41 @@ CONFIG_BLOCK=y # IO Schedulers # CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y -# CONFIG_DEFAULT_AS is not set # CONFIG_DEFAULT_DEADLINE is not set CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +# CONFIG_INLINE_SPIN_UNLOCK is not set +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +# CONFIG_INLINE_READ_UNLOCK is not set +# CONFIG_INLINE_READ_UNLOCK_BH is not set +# CONFIG_INLINE_READ_UNLOCK_IRQ is not set +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +# CONFIG_INLINE_WRITE_UNLOCK is not set +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set # CONFIG_FREEZER is not set # @@ -178,8 +226,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y +# CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 # @@ -255,13 +302,13 @@ CONFIG_PREEMPT=y CONFIG_ZERO_PAGE_OFFSET=0x00001000 CONFIG_BOOT_LINK_OFFSET=0x00400000 CONFIG_ENTRY_OFFSET=0x00001000 -# CONFIG_CMDLINE_BOOL is not set +# CONFIG_CMDLINE_OVERWRITE is not set +# CONFIG_CMDLINE_EXTEND is not set # # Bus options # CONFIG_PCI=y -CONFIG_SH_PCIDMA_NONCOHERENT=y # CONFIG_PCIEPORTBUS is not set # CONFIG_ARCH_SUPPORTS_MSI is not set CONFIG_PCI_LEGACY=y @@ -330,6 +377,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_NETFILTER is not set # CONFIG_IP_DCCP is not set # CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set @@ -359,14 +407,11 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_AF_RXRPC is not set CONFIG_WIRELESS=y # CONFIG_CFG80211 is not set -# CONFIG_WIRELESS_OLD_REGULATORY is not set -# CONFIG_WIRELESS_EXT is not set # CONFIG_LIB80211 is not set # # CFG80211 needs to be enabled for MAC80211 # -CONFIG_MAC80211_DEFAULT_PS_VALUE=0 # CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -379,6 +424,7 @@ CONFIG_MAC80211_DEFAULT_PS_VALUE=0 # Generic Driver Options # CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_DEVTMPFS is not set CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER is not set @@ -395,6 +441,10 @@ CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_CRYPTOLOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_SX8 is not set CONFIG_BLK_DEV_RAM=y @@ -405,6 +455,7 @@ CONFIG_BLK_DEV_RAM_SIZE=4096 # CONFIG_ATA_OVER_ETH is not set # CONFIG_BLK_DEV_HD is not set CONFIG_MISC_DEVICES=y +# CONFIG_AD525X_DPOT is not set # CONFIG_PHANTOM is not set # CONFIG_SGI_IOC4 is not set # CONFIG_TIFM_CORE is not set @@ -412,6 +463,7 @@ CONFIG_MISC_DEVICES=y # CONFIG_ENCLOSURE_SERVICES is not set # CONFIG_HP_ILO is not set # CONFIG_ISL29003 is not set +# CONFIG_DS1682 is not set # CONFIG_C2PORT is not set # @@ -462,8 +514,11 @@ CONFIG_SCSI_LOWLEVEL=y # CONFIG_ISCSI_TCP is not set # CONFIG_SCSI_CXGB3_ISCSI is not set # CONFIG_SCSI_BNX2_ISCSI is not set +# CONFIG_BE2ISCSI is not set # CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_HPSA is not set # CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_3W_SAS is not set # CONFIG_SCSI_ACARD is not set # CONFIG_SCSI_AACRAID is not set # CONFIG_SCSI_AIC7XXX is not set @@ -495,7 +550,10 @@ CONFIG_SCSI_LOWLEVEL=y # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_PMCRAID is not set +# CONFIG_SCSI_PM8001 is not set # CONFIG_SCSI_SRP is not set +# CONFIG_SCSI_BFA_FC is not set # CONFIG_SCSI_DH is not set # CONFIG_SCSI_OSD_INITIATOR is not set # CONFIG_ATA is not set @@ -507,7 +565,11 @@ CONFIG_SCSI_LOWLEVEL=y # # -# Enable only one of the two stacks, unless you know what you are doing +# You can enable one or both FireWire driver stacks. +# + +# +# See the help texts for more information. # # CONFIG_FIREWIRE is not set # CONFIG_IEEE1394 is not set @@ -546,6 +608,7 @@ CONFIG_NET_ETHERNET=y # CONFIG_NET_PCI is not set # CONFIG_B44 is not set # CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set # CONFIG_ATL2 is not set CONFIG_NETDEV_1000=y # CONFIG_ACENIC is not set @@ -565,6 +628,7 @@ CONFIG_NETDEV_1000=y # CONFIG_VIA_VELOCITY is not set # CONFIG_TIGON3 is not set # CONFIG_BNX2 is not set +# CONFIG_CNIC is not set # CONFIG_QLA3XXX is not set # CONFIG_ATL1 is not set # CONFIG_ATL1E is not set @@ -590,12 +654,10 @@ CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_SFC is not set # CONFIG_BE2NET is not set # CONFIG_TR is not set - -# -# Wireless LAN -# -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +CONFIG_WLAN=y +# CONFIG_ATMEL is not set +# CONFIG_PRISM54 is not set +# CONFIG_HOSTAP is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers @@ -609,6 +671,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_VMXNET3 is not set # CONFIG_ISDN is not set # CONFIG_PHONE is not set @@ -618,6 +681,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set # CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set # # Userland interfaces @@ -682,6 +746,7 @@ CONFIG_HW_RANDOM=y CONFIG_DEVPORT=y CONFIG_I2C=m CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y # CONFIG_I2C_CHARDEV is not set CONFIG_I2C_HELPER_AUTO=y @@ -710,6 +775,7 @@ CONFIG_I2C_HELPER_AUTO=y # # I2C system bus drivers (mostly embedded / system-on-chip) # +# CONFIG_I2C_DESIGNWARE is not set # CONFIG_I2C_OCORES is not set # CONFIG_I2C_SH_MOBILE is not set # CONFIG_I2C_SIMTEC is not set @@ -721,11 +787,6 @@ CONFIG_I2C_HELPER_AUTO=y # CONFIG_I2C_TAOS_EVM is not set # -# Graphics adapter I2C/DDC channel drivers -# -# CONFIG_I2C_VOODOO3 is not set - -# # Other I2C/SMBus bus drivers # # CONFIG_I2C_PCA_PLATFORM is not set @@ -734,20 +795,26 @@ CONFIG_I2C_HELPER_AUTO=y # # Miscellaneous I2C Chip support # -# CONFIG_DS1682 is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_PCF8575 is not set -# CONFIG_SENSORS_PCA9539 is not set # CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set # CONFIG_I2C_DEBUG_CHIP is not set # CONFIG_SPI is not set + +# +# PPS support +# +# CONFIG_PPS is not set # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set CONFIG_HWMON=y # CONFIG_HWMON_VID is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Native drivers +# # CONFIG_SENSORS_AD7414 is not set # CONFIG_SENSORS_AD7418 is not set # CONFIG_SENSORS_ADM1021 is not set @@ -771,6 +838,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_GL520SM is not set # CONFIG_SENSORS_IT87 is not set # CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM73 is not set # CONFIG_SENSORS_LM75 is not set # CONFIG_SENSORS_LM77 is not set # CONFIG_SENSORS_LM78 is not set @@ -797,6 +865,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_ADS7828 is not set # CONFIG_SENSORS_THMC50 is not set # CONFIG_SENSORS_TMP401 is not set +# CONFIG_SENSORS_TMP421 is not set # CONFIG_SENSORS_VIA686A is not set # CONFIG_SENSORS_VT1211 is not set # CONFIG_SENSORS_VT8231 is not set @@ -808,9 +877,8 @@ CONFIG_HWMON=y # CONFIG_SENSORS_W83L786NG is not set # CONFIG_SENSORS_W83627HF is not set # CONFIG_SENSORS_W83627EHF is not set -# CONFIG_HWMON_DEBUG_CHIP is not set +# CONFIG_SENSORS_LIS3_I2C is not set # CONFIG_THERMAL is not set -# CONFIG_THERMAL_HWMON is not set CONFIG_WATCHDOG=y # CONFIG_WATCHDOG_NOWAYOUT is not set @@ -837,17 +905,20 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM8350_I2C is not set # CONFIG_MFD_PCF50633 is not set +# CONFIG_AB3100_CORE is not set # CONFIG_REGULATOR is not set # CONFIG_MEDIA_SUPPORT is not set # # Graphics support # +CONFIG_VGA_ARB=y # CONFIG_DRM is not set # CONFIG_VGASTATE is not set CONFIG_VIDEO_OUTPUT_CONTROL=y @@ -939,7 +1010,6 @@ CONFIG_LOGO_SUPERH_CLUT224=y # CONFIG_SOUND is not set CONFIG_HID_SUPPORT=y CONFIG_HID=y -# CONFIG_HID_DEBUG is not set # CONFIG_HIDRAW is not set # CONFIG_HID_PID is not set @@ -1002,8 +1072,10 @@ CONFIG_FS_MBCACHE=y # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set # CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set # CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set CONFIG_FILE_LOCKING=y CONFIG_FSNOTIFY=y CONFIG_DNOTIFY=y @@ -1067,7 +1139,6 @@ CONFIG_ROMFS_BACKED_BY_BLOCK=y CONFIG_ROMFS_ON_BLOCK=y # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set -# CONFIG_NILFS2_FS is not set CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=y CONFIG_NFS_V3=y @@ -1120,6 +1191,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y CONFIG_FRAME_WARN=1024 CONFIG_MAGIC_SYSRQ=y +# CONFIG_STRIP_ASM_SYMS is not set # CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set @@ -1155,21 +1227,25 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set # CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set CONFIG_FRAME_POINTER=y # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_BACKTRACE_SELF_TEST is not set # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set # CONFIG_FAULT_INJECTION is not set # CONFIG_LATENCYTOP is not set # CONFIG_SYSCTL_SYSCALL_CHECK is not set # CONFIG_PAGE_POISONING is not set +CONFIG_HAVE_SYSCALL_TRACEPOINTS=y CONFIG_TRACING_SUPPORT=y CONFIG_FTRACE=y # CONFIG_IRQSOFF_TRACER is not set # CONFIG_PREEMPT_TRACER is not set # CONFIG_SCHED_TRACER is not set # CONFIG_ENABLE_DEFAULT_TRACERS is not set +# CONFIG_FTRACE_SYSCALLS is not set # CONFIG_BOOT_TRACER is not set CONFIG_BRANCH_PROFILE_NONE=y # CONFIG_PROFILE_ANNOTATED_BRANCHES is not set @@ -1180,11 +1256,9 @@ CONFIG_BRANCH_PROFILE_NONE=y # CONFIG_DYNAMIC_DEBUG is not set # CONFIG_DMA_API_DEBUG is not set # CONFIG_SAMPLES is not set -# CONFIG_KMEMCHECK is not set -# CONFIG_EARLY_SCIF_CONSOLE is not set -# CONFIG_DEBUG_BOOTMEM is not set # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_4KSTACKS is not set +# CONFIG_DWARF_UNWINDER is not set # CONFIG_SH_NO_BSS_INIT is not set CONFIG_SH64_SR_WATCH=y @@ -1194,13 +1268,16 @@ CONFIG_SH64_SR_WATCH=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" CONFIG_CRYPTO=y # # Crypto core or helper # -# CONFIG_CRYPTO_FIPS is not set # CONFIG_CRYPTO_MANAGER is not set # CONFIG_CRYPTO_MANAGER2 is not set # CONFIG_CRYPTO_GF128MUL is not set @@ -1232,11 +1309,13 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_HMAC is not set # CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set # # Digest # # CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_GHASH is not set # CONFIG_CRYPTO_MD4 is not set # CONFIG_CRYPTO_MD5 is not set # CONFIG_CRYPTO_MICHAEL_MIC is not set @@ -1299,5 +1378,6 @@ CONFIG_CRC32=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y +CONFIG_HAVE_LMB=y CONFIG_NLATTR=y CONFIG_GENERIC_ATOMIC64=y diff --git a/arch/sh/configs/dreamcast_defconfig b/arch/sh/configs/dreamcast_defconfig index aedbd4f..55f652b 100644 --- a/arch/sh/configs/dreamcast_defconfig +++ b/arch/sh/configs/dreamcast_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31 -# Thu Sep 24 17:56:07 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 11:17:35 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -21,6 +21,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_CMOS_UPDATE=y # CONFIG_ARCH_SUSPEND_POSSIBLE is not set CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_SYS_SUPPORTS_HUGETLBFS=y CONFIG_SYS_SUPPORTS_PCI=y CONFIG_SYS_SUPPORTS_TMU=y CONFIG_STACKTRACE_SUPPORT=y @@ -31,6 +32,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_DMA_NONCOHERENT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -63,6 +65,7 @@ CONFIG_BSD_PROCESS_ACCT=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -97,6 +100,7 @@ CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters @@ -117,6 +121,7 @@ CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -143,14 +148,41 @@ CONFIG_LBDAF=y # IO Schedulers # CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +# CONFIG_INLINE_SPIN_UNLOCK is not set +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +# CONFIG_INLINE_READ_UNLOCK is not set +# CONFIG_INLINE_READ_UNLOCK_BH is not set +# CONFIG_INLINE_READ_UNLOCK_IRQ is not set +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +# CONFIG_INLINE_WRITE_UNLOCK is not set +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set # CONFIG_FREEZER is not set # @@ -232,8 +264,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -294,9 +324,9 @@ CONFIG_CPU_FREQ_GOV_USERSPACE=y # # DMA support # -CONFIG_SH_DMA_API=y CONFIG_SH_DMA=y CONFIG_SH_DMA_IRQ_MULTI=y +CONFIG_SH_DMA_API=y CONFIG_NR_ONCHIP_DMA_CHANNELS=4 CONFIG_NR_DMA_CHANNELS_BOOL=y CONFIG_NR_DMA_CHANNELS=9 @@ -338,7 +368,6 @@ CONFIG_GUSA=y CONFIG_ZERO_PAGE_OFFSET=0x00001000 CONFIG_BOOT_LINK_OFFSET=0x00800000 CONFIG_ENTRY_OFFSET=0x00001000 -# CONFIG_UBC_WAKEUP is not set CONFIG_CMDLINE_OVERWRITE=y # CONFIG_CMDLINE_EXTEND is not set CONFIG_CMDLINE="console=ttySC1,115200 panic=3" @@ -348,7 +377,6 @@ CONFIG_CMDLINE="console=ttySC1,115200 panic=3" # CONFIG_MAPLE=y CONFIG_PCI=y -CONFIG_SH_PCIDMA_NONCOHERENT=y # CONFIG_PCIEPORTBUS is not set # CONFIG_ARCH_SUPPORTS_MSI is not set CONFIG_PCI_LEGACY=y @@ -443,9 +471,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_AF_RXRPC is not set CONFIG_WIRELESS=y # CONFIG_CFG80211 is not set -CONFIG_CFG80211_DEFAULT_PS_VALUE=0 -# CONFIG_WIRELESS_OLD_REGULATORY is not set -# CONFIG_WIRELESS_EXT is not set # CONFIG_LIB80211 is not set # @@ -478,6 +503,10 @@ CONFIG_GDROM=y # CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_SX8 is not set # CONFIG_BLK_DEV_RAM is not set @@ -579,6 +608,7 @@ CONFIG_8139TOO=y # CONFIG_SUNDANCE is not set # CONFIG_TLAN is not set # CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set # CONFIG_VIA_RHINE is not set # CONFIG_SC92031 is not set # CONFIG_ATL2 is not set @@ -586,8 +616,9 @@ CONFIG_8139TOO=y # CONFIG_NETDEV_10000 is not set # CONFIG_TR is not set CONFIG_WLAN=y -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +# CONFIG_ATMEL is not set +# CONFIG_PRISM54 is not set +# CONFIG_HOSTAP is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers @@ -600,6 +631,7 @@ CONFIG_WLAN=y # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_VMXNET3 is not set # CONFIG_ISDN is not set # CONFIG_PHONE is not set @@ -609,6 +641,7 @@ CONFIG_WLAN=y CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set # CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set # # Userland interfaces @@ -655,6 +688,7 @@ CONFIG_SERIO=y # CONFIG_SERIO_PCIPS2 is not set CONFIG_SERIO_LIBPS2=y # CONFIG_SERIO_RAW is not set +# CONFIG_SERIO_ALTERA_PS2 is not set # CONFIG_GAMEPORT is not set # @@ -734,6 +768,7 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set # CONFIG_REGULATOR is not set @@ -883,6 +918,7 @@ CONFIG_RTC_LIB=y # CONFIG_EXT2_FS is not set # CONFIG_EXT3_FS is not set # CONFIG_EXT4_FS is not set +CONFIG_EXT4_USE_FOR_EXT23=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set @@ -981,10 +1017,11 @@ CONFIG_FRAME_WARN=1024 # CONFIG_DEBUG_FS is not set # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_LATENCYTOP is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y @@ -997,7 +1034,6 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set -# CONFIG_EARLY_SCIF_CONSOLE is not set # CONFIG_DWARF_UNWINDER is not set # @@ -1006,7 +1042,11 @@ CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" CONFIG_CRYPTO=y # diff --git a/arch/sh/configs/ecovec24-romimage_defconfig b/arch/sh/configs/ecovec24-romimage_defconfig index 4687470..662c1ad 100644 --- a/arch/sh/configs/ecovec24-romimage_defconfig +++ b/arch/sh/configs/ecovec24-romimage_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31 -# Thu Sep 24 17:56:41 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 11:18:17 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_SYS_SUPPORTS_HUGETLBFS=y CONFIG_SYS_SUPPORTS_CMT=y CONFIG_SYS_SUPPORTS_TMU=y CONFIG_STACKTRACE_SUPPORT=y @@ -30,6 +31,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_DMA_NONCOHERENT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -61,6 +63,7 @@ CONFIG_BSD_PROCESS_ACCT=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -103,6 +106,7 @@ CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters @@ -120,6 +124,7 @@ CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -142,14 +147,41 @@ CONFIG_BLOCK=y # IO Schedulers # CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y -# CONFIG_DEFAULT_AS is not set # CONFIG_DEFAULT_DEADLINE is not set CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +CONFIG_INLINE_SPIN_UNLOCK=y +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +CONFIG_INLINE_READ_UNLOCK=y +# CONFIG_INLINE_READ_UNLOCK_BH is not set +CONFIG_INLINE_READ_UNLOCK_IRQ=y +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +CONFIG_INLINE_WRITE_UNLOCK=y +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set # CONFIG_FREEZER is not set # @@ -205,6 +237,7 @@ CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_MEMORY_START=0x08000000 CONFIG_MEMORY_SIZE=0x10000000 CONFIG_29BIT=y +# CONFIG_PMB_ENABLE is not set # CONFIG_X2TLB is not set CONFIG_VSYSCALL=y CONFIG_ARCH_FLATMEM_ENABLE=y @@ -229,8 +262,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -264,7 +295,6 @@ CONFIG_SH_ECOVEC=y # # CONFIG_SH_TIMER_TMU is not set CONFIG_SH_TIMER_CMT=y -CONFIG_SH_PCLK_FREQ=33333333 CONFIG_SH_CLK_CPG=y # CONFIG_NO_HZ is not set # CONFIG_HIGH_RES_TIMERS is not set @@ -406,7 +436,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set -# CONFIG_WIRELESS is not set +CONFIG_WIRELESS=y +# CONFIG_CFG80211 is not set +# CONFIG_LIB80211 is not set + +# +# CFG80211 needs to be enabled for MAC80211 +# # CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -432,6 +468,10 @@ CONFIG_EXTRA_FIRMWARE="" CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_UB is not set # CONFIG_BLK_DEV_RAM is not set @@ -526,11 +566,12 @@ CONFIG_SH_ETH=y # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set # CONFIG_B44 is not set # CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set CONFIG_WLAN=y -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +# CONFIG_USB_ZD1201 is not set +# CONFIG_HOSTAP is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers @@ -559,6 +600,7 @@ CONFIG_WLAN=y CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set # CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set # # Userland interfaces @@ -652,7 +694,6 @@ CONFIG_I2C_SH_MOBILE=y # # Miscellaneous I2C Chip support # -# CONFIG_DS1682 is not set # CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set @@ -707,16 +748,19 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_TPS65010 is not set # CONFIG_TWL4030_CORE is not set # CONFIG_MFD_TMIO is not set # CONFIG_PMIC_DA903X is not set +# CONFIG_PMIC_ADP5520 is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set # CONFIG_MFD_PCF50633 is not set # CONFIG_AB3100_CORE is not set +# CONFIG_MFD_88PM8607 is not set # CONFIG_REGULATOR is not set # CONFIG_MEDIA_SUPPORT is not set @@ -867,6 +911,7 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XIP is not set # CONFIG_EXT3_FS is not set # CONFIG_EXT4_FS is not set +CONFIG_EXT4_USE_FOR_EXT23=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set @@ -979,7 +1024,7 @@ CONFIG_FRAME_WARN=1024 CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_LATENCYTOP is not set @@ -997,7 +1042,6 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set -# CONFIG_EARLY_SCIF_CONSOLE is not set # CONFIG_DWARF_UNWINDER is not set # @@ -1006,7 +1050,11 @@ CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" # CONFIG_CRYPTO is not set # CONFIG_BINARY_PRINTF is not set diff --git a/arch/sh/configs/ecovec24_defconfig b/arch/sh/configs/ecovec24_defconfig index cad9184..18e3356 100644 --- a/arch/sh/configs/ecovec24_defconfig +++ b/arch/sh/configs/ecovec24_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31 -# Thu Sep 24 17:45:39 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 11:20:36 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_SYS_SUPPORTS_HUGETLBFS=y CONFIG_SYS_SUPPORTS_CMT=y CONFIG_SYS_SUPPORTS_TMU=y CONFIG_STACKTRACE_SUPPORT=y @@ -30,6 +31,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_DMA_NONCOHERENT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -62,6 +64,7 @@ CONFIG_BSD_PROCESS_ACCT=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -99,6 +102,7 @@ CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters @@ -116,6 +120,7 @@ CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -143,14 +148,41 @@ CONFIG_LBDAF=y # IO Schedulers # CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y -# CONFIG_DEFAULT_AS is not set # CONFIG_DEFAULT_DEADLINE is not set CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +# CONFIG_INLINE_SPIN_UNLOCK is not set +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +# CONFIG_INLINE_READ_UNLOCK is not set +# CONFIG_INLINE_READ_UNLOCK_BH is not set +# CONFIG_INLINE_READ_UNLOCK_IRQ is not set +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +# CONFIG_INLINE_WRITE_UNLOCK is not set +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set CONFIG_FREEZER=y # @@ -206,6 +238,7 @@ CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_MEMORY_START=0x08000000 CONFIG_MEMORY_SIZE=0x10000000 CONFIG_29BIT=y +# CONFIG_PMB_ENABLE is not set # CONFIG_X2TLB is not set CONFIG_VSYSCALL=y CONFIG_ARCH_FLATMEM_ENABLE=y @@ -230,8 +263,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -265,7 +296,6 @@ CONFIG_SH_ECOVEC=y # CONFIG_SH_TIMER_TMU=y # CONFIG_SH_TIMER_CMT is not set -CONFIG_SH_PCLK_FREQ=33333333 CONFIG_SH_CLK_CPG=y # CONFIG_NO_HZ is not set # CONFIG_HIGH_RES_TIMERS is not set @@ -420,9 +450,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_AF_RXRPC is not set CONFIG_WIRELESS=y # CONFIG_CFG80211 is not set -CONFIG_CFG80211_DEFAULT_PS_VALUE=0 -# CONFIG_WIRELESS_OLD_REGULATORY is not set -# CONFIG_WIRELESS_EXT is not set # CONFIG_LIB80211 is not set # @@ -552,6 +579,10 @@ CONFIG_MTD_UBI_BEB_RESERVE=1 CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_UB is not set CONFIG_BLK_DEV_RAM=y @@ -562,9 +593,12 @@ CONFIG_BLK_DEV_RAM_SIZE=4096 # CONFIG_ATA_OVER_ETH is not set # CONFIG_BLK_DEV_HD is not set CONFIG_MISC_DEVICES=y +# CONFIG_AD525X_DPOT is not set # CONFIG_ICS932S401 is not set # CONFIG_ENCLOSURE_SERVICES is not set # CONFIG_ISL29003 is not set +# CONFIG_DS1682 is not set +# CONFIG_TI_DAC7512 is not set # CONFIG_C2PORT is not set # @@ -575,6 +609,7 @@ CONFIG_MISC_DEVICES=y # CONFIG_EEPROM_LEGACY is not set # CONFIG_EEPROM_MAX6875 is not set # CONFIG_EEPROM_93CX6 is not set +# CONFIG_IWMC3200TOP is not set CONFIG_HAVE_IDE=y # CONFIG_IDE is not set @@ -669,11 +704,12 @@ CONFIG_SH_ETH=y # CONFIG_B44 is not set # CONFIG_KS8842 is not set # CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set CONFIG_WLAN=y -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +# CONFIG_USB_ZD1201 is not set +# CONFIG_HOSTAP is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers @@ -702,6 +738,7 @@ CONFIG_WLAN=y CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set # CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set # # Userland interfaces @@ -810,7 +847,6 @@ CONFIG_I2C_SH_MOBILE=y # # Miscellaneous I2C Chip support # -# CONFIG_DS1682 is not set # CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set @@ -824,7 +860,10 @@ CONFIG_SPI_MASTER=y # CONFIG_SPI_BITBANG=y # CONFIG_SPI_GPIO is not set +# CONFIG_SPI_SH_MSIOF is not set # CONFIG_SPI_SH_SCI is not set +# CONFIG_SPI_XILINX is not set +# CONFIG_SPI_DESIGNWARE is not set # # SPI Protocol Masters @@ -882,11 +921,13 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_TPS65010 is not set # CONFIG_TWL4030_CORE is not set # CONFIG_MFD_TMIO is not set # CONFIG_PMIC_DA903X is not set +# CONFIG_PMIC_ADP5520 is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set @@ -894,6 +935,8 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_MC13783 is not set # CONFIG_AB3100_CORE is not set # CONFIG_EZX_PCAP is not set +# CONFIG_MFD_88PM8607 is not set +# CONFIG_AB4500_CORE is not set # CONFIG_REGULATOR is not set CONFIG_MEDIA_SUPPORT=y @@ -910,6 +953,8 @@ CONFIG_VIDEO_MEDIA=y # # Multimedia drivers # +CONFIG_IR_CORE=y +CONFIG_VIDEO_IR=y # CONFIG_MEDIA_ATTACH is not set CONFIG_MEDIA_TUNER=y # CONFIG_MEDIA_TUNER_CUSTOMISE is not set @@ -930,6 +975,7 @@ CONFIG_VIDEO_CAPTURE_DRIVERS=y # CONFIG_VIDEO_ADV_DEBUG is not set # CONFIG_VIDEO_FIXED_MINOR_RANGES is not set CONFIG_VIDEO_HELPER_CHIPS_AUTO=y +CONFIG_VIDEO_IR_I2C=y # CONFIG_VIDEO_VIVI is not set # CONFIG_VIDEO_CPIA is not set # CONFIG_VIDEO_CPIA2 is not set @@ -939,10 +985,13 @@ CONFIG_SOC_CAMERA=y # CONFIG_SOC_CAMERA_MT9M001 is not set # CONFIG_SOC_CAMERA_MT9M111 is not set # CONFIG_SOC_CAMERA_MT9T031 is not set +# CONFIG_SOC_CAMERA_MT9T112 is not set # CONFIG_SOC_CAMERA_MT9V022 is not set +# CONFIG_SOC_CAMERA_RJ54N1 is not set # CONFIG_SOC_CAMERA_TW9910 is not set # CONFIG_SOC_CAMERA_PLATFORM is not set # CONFIG_SOC_CAMERA_OV772X is not set +# CONFIG_SOC_CAMERA_OV9640 is not set CONFIG_VIDEO_SH_MOBILE_CEU=y # CONFIG_V4L_USB_DRIVERS is not set CONFIG_RADIO_ADAPTERS=y @@ -952,6 +1001,7 @@ CONFIG_RADIO_ADAPTERS=y # CONFIG_RADIO_SI470X is not set # CONFIG_USB_MR800 is not set # CONFIG_RADIO_TEA5764 is not set +# CONFIG_RADIO_TEF6862 is not set # CONFIG_DAB is not set # @@ -1177,6 +1227,7 @@ CONFIG_MMC_BLOCK_BOUNCE=y # CONFIG_MMC_AT91 is not set # CONFIG_MMC_ATMELMCI is not set CONFIG_MMC_SPI=y +# CONFIG_MMC_TMIO is not set # CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set # CONFIG_ACCESSIBILITY is not set @@ -1208,6 +1259,7 @@ CONFIG_RTC_INTF_DEV=y CONFIG_RTC_DRV_PCF8563=y # CONFIG_RTC_DRV_PCF8583 is not set # CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set # CONFIG_RTC_DRV_S35390A is not set # CONFIG_RTC_DRV_FM3130 is not set # CONFIG_RTC_DRV_RX8581 is not set @@ -1236,7 +1288,9 @@ CONFIG_RTC_DRV_PCF8563=y # CONFIG_RTC_DRV_M48T86 is not set # CONFIG_RTC_DRV_M48T35 is not set # CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set # CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set # CONFIG_RTC_DRV_V3020 is not set # @@ -1430,7 +1484,7 @@ CONFIG_FRAME_WARN=1024 CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_LATENCYTOP is not set @@ -1448,7 +1502,6 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set -# CONFIG_EARLY_SCIF_CONSOLE is not set # CONFIG_DWARF_UNWINDER is not set # @@ -1457,7 +1510,11 @@ CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" CONFIG_CRYPTO=y # diff --git a/arch/sh/configs/edosk7705_defconfig b/arch/sh/configs/edosk7705_defconfig index 86c9bc0..72f8718 100644 --- a/arch/sh/configs/edosk7705_defconfig +++ b/arch/sh/configs/edosk7705_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31 -# Thu Sep 24 17:57:13 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 11:24:26 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -28,6 +28,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_DMA_NONCOHERENT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -53,6 +54,7 @@ CONFIG_KERNEL_GZIP=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -66,7 +68,6 @@ CONFIG_LOG_BUF_SHIFT=17 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_EMBEDDED=y # CONFIG_UID16 is not set -# CONFIG_SYSCTL_SYSCALL is not set # CONFIG_KALLSYMS is not set # CONFIG_HOTPLUG is not set # CONFIG_PRINTK is not set @@ -81,6 +82,7 @@ CONFIG_EMBEDDED=y CONFIG_SHMEM=y # CONFIG_AIO is not set CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters @@ -98,6 +100,7 @@ CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -109,6 +112,35 @@ CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_BASE_SMALL=1 # CONFIG_MODULES is not set # CONFIG_BLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +CONFIG_INLINE_SPIN_UNLOCK=y +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +CONFIG_INLINE_READ_UNLOCK=y +# CONFIG_INLINE_READ_UNLOCK_BH is not set +CONFIG_INLINE_READ_UNLOCK_IRQ=y +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +CONFIG_INLINE_WRITE_UNLOCK=y +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set # CONFIG_FREEZER is not set # @@ -186,8 +218,6 @@ CONFIG_MIGRATION=y # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -359,6 +389,7 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set # CONFIG_REGULATOR is not set @@ -416,7 +447,6 @@ CONFIG_INOTIFY_USER=y # CONFIG_PROC_FS is not set # CONFIG_SYSFS is not set # CONFIG_TMPFS is not set -# CONFIG_HUGETLBFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_MISC_FILESYSTEMS=y # CONFIG_NLS is not set @@ -448,7 +478,6 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set -# CONFIG_EARLY_SCIF_CONSOLE is not set # CONFIG_DWARF_UNWINDER is not set # @@ -456,7 +485,11 @@ CONFIG_HAVE_ARCH_KGDB=y # # CONFIG_KEYS is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" # CONFIG_CRYPTO is not set # CONFIG_BINARY_PRINTF is not set diff --git a/arch/sh/configs/edosk7760_defconfig b/arch/sh/configs/edosk7760_defconfig index 4c0f82b..0932e6d 100644 --- a/arch/sh/configs/edosk7760_defconfig +++ b/arch/sh/configs/edosk7760_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31 -# Thu Sep 24 17:57:30 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 11:24:44 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y # CONFIG_ARCH_SUSPEND_POSSIBLE is not set CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_SYS_SUPPORTS_HUGETLBFS=y CONFIG_SYS_SUPPORTS_TMU=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_LOCKDEP_SUPPORT=y @@ -29,6 +30,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_DMA_NONCOHERENT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -62,6 +64,7 @@ CONFIG_BSD_PROCESS_ACCT=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -102,6 +105,7 @@ CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters @@ -121,6 +125,7 @@ CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -147,14 +152,41 @@ CONFIG_LBDAF=y # IO Schedulers # CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y -# CONFIG_DEFAULT_AS is not set # CONFIG_DEFAULT_DEADLINE is not set CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +# CONFIG_INLINE_SPIN_UNLOCK is not set +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +# CONFIG_INLINE_READ_UNLOCK is not set +# CONFIG_INLINE_READ_UNLOCK_BH is not set +# CONFIG_INLINE_READ_UNLOCK_IRQ is not set +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +# CONFIG_INLINE_WRITE_UNLOCK is not set +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set # CONFIG_FREEZER is not set # @@ -230,8 +262,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -278,9 +308,9 @@ CONFIG_GENERIC_CLOCKEVENTS_BUILD=y # # DMA support # -CONFIG_SH_DMA_API=y CONFIG_SH_DMA=y CONFIG_SH_DMA_IRQ_MULTI=y +CONFIG_SH_DMA_API=y CONFIG_NR_ONCHIP_DMA_CHANNELS=8 # CONFIG_NR_DMA_CHANNELS_BOOL is not set # CONFIG_SH_DMABRG is not set @@ -320,7 +350,6 @@ CONFIG_GUSA=y CONFIG_ZERO_PAGE_OFFSET=0x00001000 CONFIG_BOOT_LINK_OFFSET=0x02000000 CONFIG_ENTRY_OFFSET=0x00001000 -# CONFIG_UBC_WAKEUP is not set CONFIG_CMDLINE_OVERWRITE=y # CONFIG_CMDLINE_EXTEND is not set CONFIG_CMDLINE="mem=64M console=ttySC2,115200 root=/dev/nfs rw nfsroot=192.168.0.3:/scripts/filesys ip=192.168.0.4" @@ -415,9 +444,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_AF_RXRPC is not set CONFIG_WIRELESS=y # CONFIG_CFG80211 is not set -CONFIG_CFG80211_DEFAULT_PS_VALUE=0 -# CONFIG_WIRELESS_OLD_REGULATORY is not set -# CONFIG_WIRELESS_EXT is not set # CONFIG_LIB80211 is not set # @@ -534,6 +560,10 @@ CONFIG_MTD_PHYSMAP=y CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# # CONFIG_BLK_DEV_NBD is not set CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 @@ -581,11 +611,11 @@ CONFIG_SMC91X=y # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set # CONFIG_B44 is not set # CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set CONFIG_WLAN=y -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +# CONFIG_HOSTAP is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers @@ -605,6 +635,7 @@ CONFIG_WLAN=y CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set # CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set # # Userland interfaces @@ -698,7 +729,6 @@ CONFIG_I2C_SH7760=y # # Miscellaneous I2C Chip support # -# CONFIG_DS1682 is not set # CONFIG_SENSORS_TSL2550 is not set CONFIG_I2C_DEBUG_CORE=y CONFIG_I2C_DEBUG_ALGO=y @@ -727,15 +757,18 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_TWL4030_CORE is not set # CONFIG_MFD_TMIO is not set # CONFIG_PMIC_DA903X is not set +# CONFIG_PMIC_ADP5520 is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set # CONFIG_MFD_PCF50633 is not set # CONFIG_AB3100_CORE is not set +# CONFIG_MFD_88PM8607 is not set # CONFIG_REGULATOR is not set # CONFIG_MEDIA_SUPPORT is not set @@ -1072,9 +1105,6 @@ CONFIG_BRANCH_PROFILE_NONE=y CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set # CONFIG_SH_STANDARD_BIOS is not set -CONFIG_EARLY_SCIF_CONSOLE=y -CONFIG_EARLY_SCIF_CONSOLE_PORT=0xffe80000 -CONFIG_EARLY_PRINTK=y # CONFIG_STACK_DEBUG is not set # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_4KSTACKS is not set @@ -1088,7 +1118,11 @@ CONFIG_DUMP_CODE=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" CONFIG_CRYPTO=y # diff --git a/arch/sh/configs/espt_defconfig b/arch/sh/configs/espt_defconfig index 9b78551..f899e56 100644 --- a/arch/sh/configs/espt_defconfig +++ b/arch/sh/configs/espt_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31 -# Thu Sep 24 17:58:18 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 11:26:55 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y # CONFIG_ARCH_SUSPEND_POSSIBLE is not set CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_SYS_SUPPORTS_HUGETLBFS=y CONFIG_SYS_SUPPORTS_TMU=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_LOCKDEP_SUPPORT=y @@ -29,6 +30,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_DMA_NONCOHERENT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -59,6 +61,7 @@ CONFIG_SYSVIPC_SYSCTL=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -103,6 +106,7 @@ CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters @@ -124,6 +128,7 @@ CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -150,14 +155,41 @@ CONFIG_LBDAF=y # IO Schedulers # CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +CONFIG_INLINE_SPIN_UNLOCK=y +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +CONFIG_INLINE_READ_UNLOCK=y +# CONFIG_INLINE_READ_UNLOCK_BH is not set +CONFIG_INLINE_READ_UNLOCK_IRQ=y +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +CONFIG_INLINE_WRITE_UNLOCK=y +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set # CONFIG_FREEZER is not set # @@ -211,6 +243,7 @@ CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_MEMORY_START=0x0c000000 CONFIG_MEMORY_SIZE=0x04000000 CONFIG_29BIT=y +# CONFIG_PMB_ENABLE is not set CONFIG_VSYSCALL=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_ARCH_SPARSEMEM_ENABLE=y @@ -237,8 +270,6 @@ CONFIG_MIGRATION=y # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -419,7 +450,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set -# CONFIG_WIRELESS is not set +CONFIG_WIRELESS=y +# CONFIG_CFG80211 is not set +# CONFIG_LIB80211 is not set + +# +# CFG80211 needs to be enabled for MAC80211 +# # CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -498,7 +535,6 @@ CONFIG_MTD_CFI_UTIL=y CONFIG_MTD_COMPLEX_MAPPINGS=y CONFIG_MTD_PHYSMAP=y # CONFIG_MTD_PHYSMAP_COMPAT is not set -# CONFIG_MTD_GPIO_ADDR is not set # CONFIG_MTD_PLATRAM is not set # @@ -531,6 +567,10 @@ CONFIG_MTD_PHYSMAP=y CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_UB is not set # CONFIG_BLK_DEV_RAM is not set @@ -629,11 +669,12 @@ CONFIG_SH_ETH=y # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set # CONFIG_B44 is not set # CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set CONFIG_WLAN=y -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +# CONFIG_USB_ZD1201 is not set +# CONFIG_HOSTAP is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers @@ -662,6 +703,7 @@ CONFIG_WLAN=y CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set # CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set # # Userland interfaces @@ -745,6 +787,7 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set # CONFIG_REGULATOR is not set @@ -1102,10 +1145,11 @@ CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set CONFIG_STACKTRACE=y -# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_LATENCYTOP is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set CONFIG_NOP_TRACER=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y @@ -1125,7 +1169,6 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set -# CONFIG_EARLY_SCIF_CONSOLE is not set # CONFIG_DWARF_UNWINDER is not set # @@ -1134,7 +1177,11 @@ CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" CONFIG_CRYPTO=y # diff --git a/arch/sh/configs/hp6xx_defconfig b/arch/sh/configs/hp6xx_defconfig index f59be44..0664490 100644 --- a/arch/sh/configs/hp6xx_defconfig +++ b/arch/sh/configs/hp6xx_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31 -# Thu Sep 24 17:59:45 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 11:30:31 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -30,6 +30,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_DMA_NONCOHERENT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -57,6 +58,7 @@ CONFIG_BSD_PROCESS_ACCT=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -92,6 +94,7 @@ CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters @@ -109,6 +112,7 @@ CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -130,14 +134,41 @@ CONFIG_LBDAF=y # IO Schedulers # CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +CONFIG_INLINE_SPIN_UNLOCK=y +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +CONFIG_INLINE_READ_UNLOCK=y +# CONFIG_INLINE_READ_UNLOCK_BH is not set +CONFIG_INLINE_READ_UNLOCK_IRQ=y +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +CONFIG_INLINE_WRITE_UNLOCK=y +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set CONFIG_FREEZER=y # @@ -213,8 +244,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -261,8 +290,8 @@ CONFIG_GENERIC_CLOCKEVENTS_BUILD=y # # DMA support # -CONFIG_SH_DMA_API=y CONFIG_SH_DMA=y +CONFIG_SH_DMA_API=y CONFIG_NR_ONCHIP_DMA_CHANNELS=6 # CONFIG_NR_DMA_CHANNELS_BOOL is not set @@ -313,7 +342,6 @@ CONFIG_ENTRY_OFFSET=0x00001000 # # CONFIG_ARCH_SUPPORTS_MSI is not set CONFIG_PCCARD=y -# CONFIG_PCMCIA_DEBUG is not set CONFIG_PCMCIA=y CONFIG_PCMCIA_LOAD_CIS=y CONFIG_PCMCIA_IOCTL=y @@ -363,6 +391,10 @@ CONFIG_EXTRA_FIRMWARE="" CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# # CONFIG_BLK_DEV_RAM is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_BLK_DEV_HD is not set @@ -432,6 +464,7 @@ CONFIG_PATA_PLATFORM=y CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set CONFIG_INPUT_POLLDEV=y +# CONFIG_INPUT_SPARSEKMAP is not set # # Userland interfaces @@ -460,6 +493,7 @@ CONFIG_KEYBOARD_HP6XX=y # CONFIG_INPUT_TABLET is not set CONFIG_INPUT_TOUCHSCREEN=y # CONFIG_TOUCHSCREEN_AD7879 is not set +# CONFIG_TOUCHSCREEN_DYNAPRO is not set # CONFIG_TOUCHSCREEN_FUJITSU is not set # CONFIG_TOUCHSCREEN_GUNZE is not set # CONFIG_TOUCHSCREEN_ELO is not set @@ -483,6 +517,7 @@ CONFIG_SERIO=y # CONFIG_SERIO_SERPORT is not set # CONFIG_SERIO_LIBPS2 is not set # CONFIG_SERIO_RAW is not set +# CONFIG_SERIO_ALTERA_PS2 is not set # CONFIG_GAMEPORT is not set # @@ -550,6 +585,7 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set # CONFIG_REGULATOR is not set @@ -659,7 +695,9 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_M48T86 is not set # CONFIG_RTC_DRV_M48T35 is not set # CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set # CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set # CONFIG_RTC_DRV_V3020 is not set # @@ -684,6 +722,7 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XIP is not set # CONFIG_EXT3_FS is not set # CONFIG_EXT4_FS is not set +CONFIG_EXT4_USE_FOR_EXT23=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set @@ -731,7 +770,6 @@ CONFIG_PROC_SYSCTL=y CONFIG_PROC_PAGE_MONITOR=y CONFIG_SYSFS=y # CONFIG_TMPFS is not set -# CONFIG_HUGETLBFS is not set # CONFIG_HUGETLB_PAGE is not set # CONFIG_CONFIGFS_FS is not set CONFIG_MISC_FILESYSTEMS=y @@ -813,10 +851,11 @@ CONFIG_FRAME_WARN=1024 # CONFIG_DEBUG_FS is not set # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_LATENCYTOP is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y @@ -829,7 +868,6 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set -# CONFIG_EARLY_SCIF_CONSOLE is not set # CONFIG_DWARF_UNWINDER is not set # @@ -838,7 +876,11 @@ CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" CONFIG_CRYPTO=y # diff --git a/arch/sh/configs/kfr2r09-romimage_defconfig b/arch/sh/configs/kfr2r09-romimage_defconfig index 02590e1..3d834e5 100644 --- a/arch/sh/configs/kfr2r09-romimage_defconfig +++ b/arch/sh/configs/kfr2r09-romimage_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31 -# Thu Sep 24 18:01:48 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 11:31:09 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_SYS_SUPPORTS_HUGETLBFS=y CONFIG_SYS_SUPPORTS_CMT=y CONFIG_SYS_SUPPORTS_TMU=y CONFIG_STACKTRACE_SUPPORT=y @@ -30,6 +31,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_DMA_NONCOHERENT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -60,6 +62,7 @@ CONFIG_BSD_PROCESS_ACCT=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -102,6 +105,7 @@ CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters @@ -119,6 +123,7 @@ CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -133,6 +138,35 @@ CONFIG_RT_MUTEXES=y CONFIG_BASE_SMALL=0 # CONFIG_MODULES is not set # CONFIG_BLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +CONFIG_INLINE_SPIN_UNLOCK=y +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +CONFIG_INLINE_READ_UNLOCK=y +# CONFIG_INLINE_READ_UNLOCK_BH is not set +CONFIG_INLINE_READ_UNLOCK_IRQ=y +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +CONFIG_INLINE_WRITE_UNLOCK=y +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set # CONFIG_FREEZER is not set # @@ -188,6 +222,7 @@ CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_MEMORY_START=0x08000000 CONFIG_MEMORY_SIZE=0x08000000 CONFIG_29BIT=y +# CONFIG_PMB_ENABLE is not set # CONFIG_X2TLB is not set CONFIG_VSYSCALL=y CONFIG_ARCH_FLATMEM_ENABLE=y @@ -212,8 +247,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -247,7 +280,6 @@ CONFIG_SH_KFR2R09=y # # CONFIG_SH_TIMER_TMU is not set CONFIG_SH_TIMER_CMT=y -CONFIG_SH_PCLK_FREQ=33333333 CONFIG_SH_CLK_CPG=y # CONFIG_NO_HZ is not set # CONFIG_HIGH_RES_TIMERS is not set @@ -429,6 +461,7 @@ CONFIG_HAVE_IDE=y CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set # CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set # # Userland interfaces @@ -520,7 +553,6 @@ CONFIG_I2C_SH_MOBILE=y # # Miscellaneous I2C Chip support # -# CONFIG_DS1682 is not set # CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set @@ -575,16 +607,19 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_TPS65010 is not set # CONFIG_TWL4030_CORE is not set # CONFIG_MFD_TMIO is not set # CONFIG_PMIC_DA903X is not set +# CONFIG_PMIC_ADP5520 is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set # CONFIG_MFD_PCF50633 is not set # CONFIG_AB3100_CORE is not set +# CONFIG_MFD_88PM8607 is not set # CONFIG_REGULATOR is not set # CONFIG_MEDIA_SUPPORT is not set @@ -650,10 +685,12 @@ CONFIG_USB_GADGET_DUALSPEED=y # CONFIG_USB_ETH is not set # CONFIG_USB_GADGETFS is not set # CONFIG_USB_FILE_STORAGE is not set +# CONFIG_USB_MASS_STORAGE is not set # CONFIG_USB_G_SERIAL is not set # CONFIG_USB_MIDI_GADGET is not set # CONFIG_USB_G_PRINTER is not set CONFIG_USB_CDC_COMPOSITE=y +# CONFIG_USB_G_MULTI is not set # # OTG and related infrastructure @@ -725,7 +762,7 @@ CONFIG_FRAME_WARN=1024 CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_LATENCYTOP is not set @@ -743,7 +780,6 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set -# CONFIG_EARLY_SCIF_CONSOLE is not set # CONFIG_DWARF_UNWINDER is not set # @@ -752,7 +788,11 @@ CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" # CONFIG_CRYPTO is not set # CONFIG_BINARY_PRINTF is not set diff --git a/arch/sh/configs/kfr2r09_defconfig b/arch/sh/configs/kfr2r09_defconfig index 8ae65d2..f22be49 100644 --- a/arch/sh/configs/kfr2r09_defconfig +++ b/arch/sh/configs/kfr2r09_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31 -# Fri Sep 25 11:54:22 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 11:32:55 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_SYS_SUPPORTS_HUGETLBFS=y CONFIG_SYS_SUPPORTS_CMT=y CONFIG_SYS_SUPPORTS_TMU=y CONFIG_STACKTRACE_SUPPORT=y @@ -30,6 +31,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_DMA_NONCOHERENT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -62,6 +64,7 @@ CONFIG_BSD_PROCESS_ACCT=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -104,6 +107,7 @@ CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters @@ -121,6 +125,7 @@ CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -148,14 +153,41 @@ CONFIG_LBDAF=y # IO Schedulers # CONFIG_IOSCHED_NOOP=y -# CONFIG_IOSCHED_AS is not set # CONFIG_IOSCHED_DEADLINE is not set # CONFIG_IOSCHED_CFQ is not set -# CONFIG_DEFAULT_AS is not set # CONFIG_DEFAULT_DEADLINE is not set # CONFIG_DEFAULT_CFQ is not set CONFIG_DEFAULT_NOOP=y CONFIG_DEFAULT_IOSCHED="noop" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +# CONFIG_INLINE_SPIN_UNLOCK is not set +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +# CONFIG_INLINE_READ_UNLOCK is not set +# CONFIG_INLINE_READ_UNLOCK_BH is not set +# CONFIG_INLINE_READ_UNLOCK_IRQ is not set +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +# CONFIG_INLINE_WRITE_UNLOCK is not set +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set # CONFIG_FREEZER is not set # @@ -211,6 +243,7 @@ CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_MEMORY_START=0x08000000 CONFIG_MEMORY_SIZE=0x08000000 CONFIG_29BIT=y +# CONFIG_PMB_ENABLE is not set # CONFIG_X2TLB is not set CONFIG_VSYSCALL=y CONFIG_ARCH_FLATMEM_ENABLE=y @@ -235,8 +268,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -270,7 +301,6 @@ CONFIG_SH_KFR2R09=y # # CONFIG_SH_TIMER_TMU is not set CONFIG_SH_TIMER_CMT=y -CONFIG_SH_PCLK_FREQ=33333333 CONFIG_SH_CLK_CPG=y CONFIG_TICK_ONESHOT=y CONFIG_NO_HZ=y @@ -534,6 +564,10 @@ CONFIG_MTD_UBI_BEB_RESERVE=1 CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_RAM is not set # CONFIG_CDROM_PKTCDVD is not set @@ -562,6 +596,7 @@ CONFIG_HAVE_IDE=y CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set # CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set # # Userland interfaces @@ -668,7 +703,6 @@ CONFIG_I2C_SH_MOBILE=y # # Miscellaneous I2C Chip support # -# CONFIG_DS1682 is not set # CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set @@ -723,16 +757,19 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_TPS65010 is not set # CONFIG_TWL4030_CORE is not set # CONFIG_MFD_TMIO is not set # CONFIG_PMIC_DA903X is not set +# CONFIG_PMIC_ADP5520 is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set # CONFIG_MFD_PCF50633 is not set # CONFIG_AB3100_CORE is not set +# CONFIG_MFD_88PM8607 is not set # CONFIG_REGULATOR is not set # CONFIG_MEDIA_SUPPORT is not set @@ -847,10 +884,12 @@ CONFIG_USB_GADGET_DUALSPEED=y # CONFIG_USB_ETH is not set # CONFIG_USB_GADGETFS is not set # CONFIG_USB_FILE_STORAGE is not set +# CONFIG_USB_MASS_STORAGE is not set # CONFIG_USB_G_SERIAL is not set # CONFIG_USB_MIDI_GADGET is not set # CONFIG_USB_G_PRINTER is not set -CONFIG_USB_CDC_COMPOSITE=y +CONFIG_USB_CDC_COMPOSITE=m +# CONFIG_USB_G_MULTI is not set # # OTG and related infrastructure @@ -875,6 +914,7 @@ CONFIG_MMC_BLOCK_BOUNCE=y # CONFIG_MMC_SDHCI is not set # CONFIG_MMC_AT91 is not set # CONFIG_MMC_ATMELMCI is not set +# CONFIG_MMC_TMIO is not set # CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set # CONFIG_ACCESSIBILITY is not set @@ -906,6 +946,7 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_PCF8563 is not set # CONFIG_RTC_DRV_PCF8583 is not set # CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set # CONFIG_RTC_DRV_S35390A is not set # CONFIG_RTC_DRV_FM3130 is not set # CONFIG_RTC_DRV_RX8581 is not set @@ -926,7 +967,9 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_M48T86 is not set # CONFIG_RTC_DRV_M48T35 is not set # CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set # CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set # CONFIG_RTC_DRV_V3020 is not set # @@ -953,6 +996,7 @@ CONFIG_UIO_PDRV_GENIRQ=y # CONFIG_EXT2_FS is not set # CONFIG_EXT3_FS is not set # CONFIG_EXT4_FS is not set +CONFIG_EXT4_USE_FOR_EXT23=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set @@ -1027,7 +1071,7 @@ CONFIG_FRAME_WARN=1024 CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_LATENCYTOP is not set @@ -1045,7 +1089,6 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set -# CONFIG_EARLY_SCIF_CONSOLE is not set # CONFIG_DWARF_UNWINDER is not set # @@ -1054,7 +1097,11 @@ CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" # CONFIG_CRYPTO is not set # CONFIG_BINARY_PRINTF is not set diff --git a/arch/sh/configs/landisk_defconfig b/arch/sh/configs/landisk_defconfig index c2a9a39..2a42d49 100644 --- a/arch/sh/configs/landisk_defconfig +++ b/arch/sh/configs/landisk_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31 -# Thu Sep 24 18:05:49 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 11:35:31 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y # CONFIG_ARCH_SUSPEND_POSSIBLE is not set CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_SYS_SUPPORTS_HUGETLBFS=y CONFIG_SYS_SUPPORTS_PCI=y CONFIG_SYS_SUPPORTS_TMU=y CONFIG_STACKTRACE_SUPPORT=y @@ -30,6 +31,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_DMA_NONCOHERENT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -60,6 +62,7 @@ CONFIG_SYSVIPC_SYSCTL=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -94,6 +97,7 @@ CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters @@ -113,6 +117,7 @@ CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -139,14 +144,41 @@ CONFIG_LBDAF=y # IO Schedulers # CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +CONFIG_INLINE_SPIN_UNLOCK=y +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +CONFIG_INLINE_READ_UNLOCK=y +# CONFIG_INLINE_READ_UNLOCK_BH is not set +CONFIG_INLINE_READ_UNLOCK_IRQ=y +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +CONFIG_INLINE_WRITE_UNLOCK=y +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set # CONFIG_FREEZER is not set # @@ -222,8 +254,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -311,7 +341,6 @@ CONFIG_GUSA=y CONFIG_ZERO_PAGE_OFFSET=0x00001000 CONFIG_BOOT_LINK_OFFSET=0x00800000 CONFIG_ENTRY_OFFSET=0x00001000 -# CONFIG_UBC_WAKEUP is not set # CONFIG_CMDLINE_OVERWRITE is not set # CONFIG_CMDLINE_EXTEND is not set @@ -319,14 +348,12 @@ CONFIG_ENTRY_OFFSET=0x00001000 # Bus options # CONFIG_PCI=y -CONFIG_SH_PCIDMA_NONCOHERENT=y # CONFIG_PCIEPORTBUS is not set # CONFIG_ARCH_SUPPORTS_MSI is not set CONFIG_PCI_LEGACY=y # CONFIG_PCI_STUB is not set # CONFIG_PCI_IOV is not set CONFIG_PCCARD=y -# CONFIG_PCMCIA_DEBUG is not set CONFIG_PCMCIA=y CONFIG_PCMCIA_LOAD_CIS=y CONFIG_PCMCIA_IOCTL=y @@ -461,9 +488,6 @@ CONFIG_ATALK=m # CONFIG_AF_RXRPC is not set CONFIG_WIRELESS=y # CONFIG_CFG80211 is not set -CONFIG_CFG80211_DEFAULT_PS_VALUE=0 -# CONFIG_WIRELESS_OLD_REGULATORY is not set -# CONFIG_WIRELESS_EXT is not set # CONFIG_LIB80211 is not set # @@ -498,6 +522,10 @@ CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_CRYPTOLOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_SX8 is not set # CONFIG_BLK_DEV_UB is not set @@ -618,8 +646,11 @@ CONFIG_SCSI_LOWLEVEL=y # CONFIG_ISCSI_TCP is not set # CONFIG_SCSI_CXGB3_ISCSI is not set # CONFIG_SCSI_BNX2_ISCSI is not set +# CONFIG_BE2ISCSI is not set # CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_HPSA is not set # CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_3W_SAS is not set # CONFIG_SCSI_ACARD is not set # CONFIG_SCSI_AACRAID is not set # CONFIG_SCSI_AIC7XXX is not set @@ -652,7 +683,9 @@ CONFIG_SCSI_LOWLEVEL=y # CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set # CONFIG_SCSI_PMCRAID is not set +# CONFIG_SCSI_PM8001 is not set # CONFIG_SCSI_SRP is not set +# CONFIG_SCSI_BFA_FC is not set # CONFIG_SCSI_LOWLEVEL_PCMCIA is not set # CONFIG_SCSI_DH is not set # CONFIG_SCSI_OSD_INITIATOR is not set @@ -733,6 +766,7 @@ CONFIG_8139CP=y # CONFIG_SUNDANCE is not set # CONFIG_TLAN is not set # CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set # CONFIG_VIA_RHINE is not set # CONFIG_SC92031 is not set # CONFIG_ATL2 is not set @@ -781,8 +815,13 @@ CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_BE2NET is not set # CONFIG_TR is not set CONFIG_WLAN=y -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +# CONFIG_PCMCIA_RAYCS is not set +# CONFIG_ATMEL is not set +# CONFIG_AIRO_CS is not set +# CONFIG_PCMCIA_WL3501 is not set +# CONFIG_PRISM54 is not set +# CONFIG_USB_ZD1201 is not set +# CONFIG_HOSTAP is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers @@ -806,6 +845,7 @@ CONFIG_USB_RTL8150=m # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_VMXNET3 is not set # CONFIG_ISDN is not set # CONFIG_PHONE is not set @@ -815,6 +855,7 @@ CONFIG_USB_RTL8150=m CONFIG_INPUT=y CONFIG_INPUT_FF_MEMLESS=m # CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set # # Userland interfaces @@ -933,6 +974,7 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set # CONFIG_REGULATOR is not set @@ -1371,10 +1413,11 @@ CONFIG_FRAME_WARN=1024 # CONFIG_DEBUG_FS is not set # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_LATENCYTOP is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y @@ -1387,8 +1430,6 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y CONFIG_SH_STANDARD_BIOS=y -# CONFIG_EARLY_SCIF_CONSOLE is not set -# CONFIG_EARLY_PRINTK is not set # CONFIG_DWARF_UNWINDER is not set # @@ -1397,7 +1438,11 @@ CONFIG_SH_STANDARD_BIOS=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" CONFIG_CRYPTO=y # diff --git a/arch/sh/configs/lboxre2_defconfig b/arch/sh/configs/lboxre2_defconfig index ec0c0b4..f2f1f8c 100644 --- a/arch/sh/configs/lboxre2_defconfig +++ b/arch/sh/configs/lboxre2_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31 -# Thu Sep 24 18:09:59 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 11:37:01 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y # CONFIG_ARCH_SUSPEND_POSSIBLE is not set CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_SYS_SUPPORTS_HUGETLBFS=y CONFIG_SYS_SUPPORTS_PCI=y CONFIG_SYS_SUPPORTS_TMU=y CONFIG_STACKTRACE_SUPPORT=y @@ -30,6 +31,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_DMA_NONCOHERENT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -60,6 +62,7 @@ CONFIG_SYSVIPC_SYSCTL=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -94,6 +97,7 @@ CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters @@ -113,6 +117,7 @@ CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -139,14 +144,41 @@ CONFIG_LBDAF=y # IO Schedulers # CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +CONFIG_INLINE_SPIN_UNLOCK=y +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +CONFIG_INLINE_READ_UNLOCK=y +# CONFIG_INLINE_READ_UNLOCK_BH is not set +CONFIG_INLINE_READ_UNLOCK_IRQ=y +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +CONFIG_INLINE_WRITE_UNLOCK=y +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set # CONFIG_FREEZER is not set # @@ -222,8 +254,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -311,7 +341,6 @@ CONFIG_GUSA=y CONFIG_ZERO_PAGE_OFFSET=0x00001000 CONFIG_BOOT_LINK_OFFSET=0x00800000 CONFIG_ENTRY_OFFSET=0x00001000 -# CONFIG_UBC_WAKEUP is not set CONFIG_CMDLINE_OVERWRITE=y # CONFIG_CMDLINE_EXTEND is not set CONFIG_CMDLINE="console=ttySC1,115200 root=/dev/sda1" @@ -320,14 +349,12 @@ CONFIG_CMDLINE="console=ttySC1,115200 root=/dev/sda1" # Bus options # CONFIG_PCI=y -CONFIG_SH_PCIDMA_NONCOHERENT=y # CONFIG_PCIEPORTBUS is not set # CONFIG_ARCH_SUPPORTS_MSI is not set CONFIG_PCI_LEGACY=y # CONFIG_PCI_STUB is not set # CONFIG_PCI_IOV is not set CONFIG_PCCARD=y -CONFIG_PCMCIA_DEBUG=y CONFIG_PCMCIA=y CONFIG_PCMCIA_LOAD_CIS=y CONFIG_PCMCIA_IOCTL=y @@ -459,9 +486,6 @@ CONFIG_NETFILTER_ADVANCED=y # CONFIG_AF_RXRPC is not set CONFIG_WIRELESS=y # CONFIG_CFG80211 is not set -CONFIG_CFG80211_DEFAULT_PS_VALUE=0 -# CONFIG_WIRELESS_OLD_REGULATORY is not set -# CONFIG_WIRELESS_EXT is not set # CONFIG_LIB80211 is not set # @@ -496,6 +520,10 @@ CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_CRYPTOLOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_SX8 is not set CONFIG_BLK_DEV_RAM=y @@ -558,8 +586,11 @@ CONFIG_SCSI_LOWLEVEL=y # CONFIG_ISCSI_TCP is not set # CONFIG_SCSI_CXGB3_ISCSI is not set # CONFIG_SCSI_BNX2_ISCSI is not set +# CONFIG_BE2ISCSI is not set # CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_HPSA is not set # CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_3W_SAS is not set # CONFIG_SCSI_ACARD is not set # CONFIG_SCSI_AACRAID is not set # CONFIG_SCSI_AIC7XXX is not set @@ -593,7 +624,9 @@ CONFIG_SCSI_LOWLEVEL=y # CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set # CONFIG_SCSI_PMCRAID is not set +# CONFIG_SCSI_PM8001 is not set # CONFIG_SCSI_SRP is not set +# CONFIG_SCSI_BFA_FC is not set # CONFIG_SCSI_LOWLEVEL_PCMCIA is not set # CONFIG_SCSI_DH is not set # CONFIG_SCSI_OSD_INITIATOR is not set @@ -648,15 +681,16 @@ CONFIG_ATA_SFF=y # CONFIG_PATA_OPTI is not set # CONFIG_PATA_OPTIDMA is not set # CONFIG_PATA_PCMCIA is not set +# CONFIG_PATA_PDC2027X is not set # CONFIG_PATA_PDC_OLD is not set # CONFIG_PATA_RADISYS is not set # CONFIG_PATA_RDC is not set # CONFIG_PATA_RZ1000 is not set # CONFIG_PATA_SC1200 is not set # CONFIG_PATA_SERVERWORKS is not set -# CONFIG_PATA_PDC2027X is not set # CONFIG_PATA_SIL680 is not set # CONFIG_PATA_SIS is not set +# CONFIG_PATA_TOSHIBA is not set # CONFIG_PATA_VIA is not set # CONFIG_PATA_WINBOND is not set CONFIG_PATA_PLATFORM=y @@ -732,6 +766,7 @@ CONFIG_8139TOO_TUNE_TWISTER=y # CONFIG_SUNDANCE is not set # CONFIG_TLAN is not set # CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set # CONFIG_VIA_RHINE is not set # CONFIG_SC92031 is not set # CONFIG_ATL2 is not set @@ -780,8 +815,12 @@ CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_BE2NET is not set # CONFIG_TR is not set CONFIG_WLAN=y -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +# CONFIG_PCMCIA_RAYCS is not set +# CONFIG_ATMEL is not set +# CONFIG_AIRO_CS is not set +# CONFIG_PCMCIA_WL3501 is not set +# CONFIG_PRISM54 is not set +# CONFIG_HOSTAP is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers @@ -804,6 +843,7 @@ CONFIG_PCMCIA_PCNET=y # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_VMXNET3 is not set # CONFIG_ISDN is not set # CONFIG_PHONE is not set @@ -813,6 +853,7 @@ CONFIG_PCMCIA_PCNET=y CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set # CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set # # Userland interfaces @@ -931,6 +972,7 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set # CONFIG_REGULATOR is not set @@ -1020,7 +1062,9 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_M48T86 is not set # CONFIG_RTC_DRV_M48T35 is not set # CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set # CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set # CONFIG_RTC_DRV_V3020 is not set # @@ -1195,10 +1239,11 @@ CONFIG_FRAME_WARN=1024 # CONFIG_DEBUG_FS is not set # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_LATENCYTOP is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y @@ -1211,8 +1256,6 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y CONFIG_SH_STANDARD_BIOS=y -# CONFIG_EARLY_SCIF_CONSOLE is not set -# CONFIG_EARLY_PRINTK is not set # CONFIG_DWARF_UNWINDER is not set # @@ -1221,7 +1264,11 @@ CONFIG_SH_STANDARD_BIOS=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" CONFIG_CRYPTO=y # diff --git a/arch/sh/configs/magicpanelr2_defconfig b/arch/sh/configs/magicpanelr2_defconfig index 79091e3..a7a16ce 100644 --- a/arch/sh/configs/magicpanelr2_defconfig +++ b/arch/sh/configs/magicpanelr2_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31 -# Thu Sep 24 18:10:49 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 11:37:42 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -30,6 +30,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_DMA_NONCOHERENT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -63,6 +64,7 @@ CONFIG_AUDIT=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -102,6 +104,7 @@ CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters @@ -120,6 +123,7 @@ CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -146,14 +150,41 @@ CONFIG_LBDAF=y # IO Schedulers # CONFIG_IOSCHED_NOOP=y -# CONFIG_IOSCHED_AS is not set # CONFIG_IOSCHED_DEADLINE is not set # CONFIG_IOSCHED_CFQ is not set -# CONFIG_DEFAULT_AS is not set # CONFIG_DEFAULT_DEADLINE is not set # CONFIG_DEFAULT_CFQ is not set CONFIG_DEFAULT_NOOP=y CONFIG_DEFAULT_IOSCHED="noop" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +CONFIG_INLINE_SPIN_UNLOCK=y +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +CONFIG_INLINE_READ_UNLOCK=y +# CONFIG_INLINE_READ_UNLOCK_BH is not set +CONFIG_INLINE_READ_UNLOCK_IRQ=y +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +CONFIG_INLINE_WRITE_UNLOCK=y +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set # CONFIG_FREEZER is not set # @@ -229,8 +260,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -283,8 +312,8 @@ CONFIG_GENERIC_CLOCKEVENTS_BUILD=y # # DMA support # -CONFIG_SH_DMA_API=y CONFIG_SH_DMA=y +CONFIG_SH_DMA_API=y CONFIG_NR_ONCHIP_DMA_CHANNELS=6 # CONFIG_NR_DMA_CHANNELS_BOOL is not set @@ -416,9 +445,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_AF_RXRPC is not set CONFIG_WIRELESS=y # CONFIG_CFG80211 is not set -CONFIG_CFG80211_DEFAULT_PS_VALUE=0 -# CONFIG_WIRELESS_OLD_REGULATORY is not set -# CONFIG_WIRELESS_EXT is not set # CONFIG_LIB80211 is not set # @@ -534,6 +560,10 @@ CONFIG_MTD_PHYSMAP=y CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# # CONFIG_BLK_DEV_NBD is not set CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 @@ -607,11 +637,11 @@ CONFIG_SMSC911X=y # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set # CONFIG_B44 is not set # CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set CONFIG_WLAN=y -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +# CONFIG_HOSTAP is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers @@ -631,6 +661,7 @@ CONFIG_WLAN=y CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set # CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set # # Userland interfaces @@ -675,6 +706,7 @@ CONFIG_SERIO=y CONFIG_SERIO_SERPORT=y CONFIG_SERIO_LIBPS2=y # CONFIG_SERIO_RAW is not set +# CONFIG_SERIO_ALTERA_PS2 is not set # CONFIG_GAMEPORT is not set # @@ -766,6 +798,7 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set # CONFIG_REGULATOR is not set @@ -824,7 +857,9 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_M48T86 is not set # CONFIG_RTC_DRV_M48T35 is not set # CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set # CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set # CONFIG_RTC_DRV_V3020 is not set # @@ -898,7 +933,6 @@ CONFIG_PROC_PAGE_MONITOR=y CONFIG_SYSFS=y CONFIG_TMPFS=y # CONFIG_TMPFS_POSIX_ACL is not set -# CONFIG_HUGETLBFS is not set # CONFIG_HUGETLB_PAGE is not set # CONFIG_CONFIGFS_FS is not set CONFIG_MISC_FILESYSTEMS=y @@ -1072,9 +1106,6 @@ CONFIG_BRANCH_PROFILE_NONE=y CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set # CONFIG_SH_STANDARD_BIOS is not set -CONFIG_EARLY_SCIF_CONSOLE=y -CONFIG_EARLY_SCIF_CONSOLE_PORT=0xa4430000 -CONFIG_EARLY_PRINTK=y # CONFIG_STACK_DEBUG is not set # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_4KSTACKS is not set @@ -1088,7 +1119,11 @@ CONFIG_DUMP_CODE=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" # CONFIG_CRYPTO is not set # CONFIG_BINARY_PRINTF is not set diff --git a/arch/sh/configs/microdev_defconfig b/arch/sh/configs/microdev_defconfig index 6bb5976..7d43fab 100644 --- a/arch/sh/configs/microdev_defconfig +++ b/arch/sh/configs/microdev_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31 -# Thu Sep 24 18:14:35 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 11:40:41 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y # CONFIG_ARCH_SUSPEND_POSSIBLE is not set CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_SYS_SUPPORTS_HUGETLBFS=y CONFIG_SYS_SUPPORTS_TMU=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_LOCKDEP_SUPPORT=y @@ -29,6 +30,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_DMA_NONCOHERENT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -60,6 +62,7 @@ CONFIG_BSD_PROCESS_ACCT=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -98,6 +101,7 @@ CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters @@ -115,6 +119,7 @@ CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -136,14 +141,41 @@ CONFIG_LBDAF=y # IO Schedulers # CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +# CONFIG_INLINE_SPIN_UNLOCK is not set +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +# CONFIG_INLINE_READ_UNLOCK is not set +# CONFIG_INLINE_READ_UNLOCK_BH is not set +# CONFIG_INLINE_READ_UNLOCK_IRQ is not set +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +# CONFIG_INLINE_WRITE_UNLOCK is not set +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set # CONFIG_FREEZER is not set # @@ -225,8 +257,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -272,8 +302,8 @@ CONFIG_GENERIC_CLOCKEVENTS_BUILD=y # # DMA support # -CONFIG_SH_DMA_API=y CONFIG_SH_DMA=y +CONFIG_SH_DMA_API=y CONFIG_NR_ONCHIP_DMA_CHANNELS=6 # CONFIG_NR_DMA_CHANNELS_BOOL is not set @@ -312,7 +342,6 @@ CONFIG_GUSA=y CONFIG_ZERO_PAGE_OFFSET=0x00001000 CONFIG_BOOT_LINK_OFFSET=0x00800000 CONFIG_ENTRY_OFFSET=0x00001000 -# CONFIG_UBC_WAKEUP is not set CONFIG_CMDLINE_OVERWRITE=y # CONFIG_CMDLINE_EXTEND is not set CONFIG_CMDLINE="console=ttySC0,115200 root=/dev/hda1" @@ -412,9 +441,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_AF_RXRPC is not set CONFIG_WIRELESS=y # CONFIG_CFG80211 is not set -CONFIG_CFG80211_DEFAULT_PS_VALUE=0 -# CONFIG_WIRELESS_OLD_REGULATORY is not set -# CONFIG_WIRELESS_EXT is not set # CONFIG_LIB80211 is not set # @@ -443,6 +469,10 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# # CONFIG_BLK_DEV_NBD is not set CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 @@ -517,11 +547,11 @@ CONFIG_SMC91X=y # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set # CONFIG_B44 is not set # CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set CONFIG_NETDEV_1000=y CONFIG_NETDEV_10000=y CONFIG_WLAN=y -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +# CONFIG_HOSTAP is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers @@ -616,6 +646,7 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set # CONFIG_REGULATOR is not set @@ -835,10 +866,11 @@ CONFIG_FRAME_WARN=1024 # CONFIG_DEBUG_FS is not set # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_LATENCYTOP is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y @@ -851,7 +883,6 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set -# CONFIG_EARLY_SCIF_CONSOLE is not set # CONFIG_DWARF_UNWINDER is not set # @@ -860,7 +891,11 @@ CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" CONFIG_CRYPTO=y # diff --git a/arch/sh/configs/migor_defconfig b/arch/sh/configs/migor_defconfig index 6501828..d2b1831 100644 --- a/arch/sh/configs/migor_defconfig +++ b/arch/sh/configs/migor_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31 -# Thu Sep 24 18:17:41 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 11:41:41 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_SYS_SUPPORTS_HUGETLBFS=y CONFIG_SYS_SUPPORTS_NUMA=y CONFIG_SYS_SUPPORTS_CMT=y CONFIG_SYS_SUPPORTS_TMU=y @@ -31,6 +32,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_DMA_NONCOHERENT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -61,6 +63,7 @@ CONFIG_SYSVIPC_SYSCTL=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -100,6 +103,7 @@ CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters @@ -121,6 +125,7 @@ CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -147,14 +152,41 @@ CONFIG_LBDAF=y # IO Schedulers # CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +CONFIG_INLINE_SPIN_UNLOCK=y +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +CONFIG_INLINE_READ_UNLOCK=y +# CONFIG_INLINE_READ_UNLOCK_BH is not set +CONFIG_INLINE_READ_UNLOCK_IRQ=y +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +CONFIG_INLINE_WRITE_UNLOCK=y +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set CONFIG_FREEZER=y # @@ -240,8 +272,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -277,7 +307,6 @@ CONFIG_SH_MIGOR_QVGA=y # CONFIG_SH_TIMER_TMU=y # CONFIG_SH_TIMER_CMT is not set -CONFIG_SH_PCLK_FREQ=33333333 CONFIG_SH_CLK_CPG=y # CONFIG_NO_HZ is not set # CONFIG_HIGH_RES_TIMERS is not set @@ -433,10 +462,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_AF_RXRPC is not set CONFIG_WIRELESS=y # CONFIG_CFG80211 is not set -CONFIG_CFG80211_DEFAULT_PS_VALUE=0 -# CONFIG_WIRELESS_OLD_REGULATORY is not set -CONFIG_WIRELESS_EXT=y -CONFIG_WIRELESS_EXT_SYSFS=y # CONFIG_LIB80211 is not set # @@ -554,6 +579,10 @@ CONFIG_MTD_NAND_PLATFORM=y CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# # CONFIG_BLK_DEV_NBD is not set CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 @@ -563,9 +592,11 @@ CONFIG_BLK_DEV_RAM_SIZE=4096 # CONFIG_ATA_OVER_ETH is not set # CONFIG_BLK_DEV_HD is not set CONFIG_MISC_DEVICES=y +# CONFIG_AD525X_DPOT is not set # CONFIG_ICS932S401 is not set # CONFIG_ENCLOSURE_SERVICES is not set # CONFIG_ISL29003 is not set +# CONFIG_DS1682 is not set # CONFIG_C2PORT is not set # @@ -646,11 +677,11 @@ CONFIG_SMC91X=y # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set # CONFIG_B44 is not set # CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set CONFIG_WLAN=y -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +# CONFIG_HOSTAP is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers @@ -670,6 +701,7 @@ CONFIG_WLAN=y CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set # CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set # # Userland interfaces @@ -776,7 +808,6 @@ CONFIG_I2C_SH_MOBILE=y # # Miscellaneous I2C Chip support # -# CONFIG_DS1682 is not set # CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set @@ -831,16 +862,19 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_TPS65010 is not set # CONFIG_TWL4030_CORE is not set # CONFIG_MFD_TMIO is not set # CONFIG_PMIC_DA903X is not set +# CONFIG_PMIC_ADP5520 is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set # CONFIG_MFD_PCF50633 is not set # CONFIG_AB3100_CORE is not set +# CONFIG_MFD_88PM8607 is not set # CONFIG_REGULATOR is not set CONFIG_MEDIA_SUPPORT=y @@ -857,6 +891,8 @@ CONFIG_VIDEO_MEDIA=y # # Multimedia drivers # +CONFIG_IR_CORE=y +CONFIG_VIDEO_IR=y # CONFIG_MEDIA_ATTACH is not set CONFIG_MEDIA_TUNER=y # CONFIG_MEDIA_TUNER_CUSTOMISE is not set @@ -876,6 +912,7 @@ CONFIG_VIDEO_CAPTURE_DRIVERS=y # CONFIG_VIDEO_ADV_DEBUG is not set # CONFIG_VIDEO_FIXED_MINOR_RANGES is not set CONFIG_VIDEO_HELPER_CHIPS_AUTO=y +CONFIG_VIDEO_IR_I2C=y # CONFIG_VIDEO_VIVI is not set # CONFIG_VIDEO_SAA5246A is not set # CONFIG_VIDEO_SAA5249 is not set @@ -883,10 +920,13 @@ CONFIG_SOC_CAMERA=y # CONFIG_SOC_CAMERA_MT9M001 is not set # CONFIG_SOC_CAMERA_MT9M111 is not set # CONFIG_SOC_CAMERA_MT9T031 is not set +# CONFIG_SOC_CAMERA_MT9T112 is not set # CONFIG_SOC_CAMERA_MT9V022 is not set +# CONFIG_SOC_CAMERA_RJ54N1 is not set CONFIG_SOC_CAMERA_TW9910=y # CONFIG_SOC_CAMERA_PLATFORM is not set CONFIG_SOC_CAMERA_OV772X=y +# CONFIG_SOC_CAMERA_OV9640 is not set CONFIG_VIDEO_SH_MOBILE_CEU=y # CONFIG_RADIO_ADAPTERS is not set # CONFIG_DAB is not set @@ -1009,10 +1049,12 @@ CONFIG_USB_GADGET_DUALSPEED=y # CONFIG_USB_ETH is not set # CONFIG_USB_GADGETFS is not set # CONFIG_USB_FILE_STORAGE is not set -CONFIG_USB_G_SERIAL=y +# CONFIG_USB_MASS_STORAGE is not set +CONFIG_USB_G_SERIAL=m # CONFIG_USB_MIDI_GADGET is not set # CONFIG_USB_G_PRINTER is not set # CONFIG_USB_CDC_COMPOSITE is not set +# CONFIG_USB_G_MULTI is not set # # OTG and related infrastructure @@ -1051,6 +1093,7 @@ CONFIG_RTC_DRV_RS5C372=y # CONFIG_RTC_DRV_PCF8563 is not set # CONFIG_RTC_DRV_PCF8583 is not set # CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set # CONFIG_RTC_DRV_S35390A is not set # CONFIG_RTC_DRV_FM3130 is not set # CONFIG_RTC_DRV_RX8581 is not set @@ -1071,7 +1114,9 @@ CONFIG_RTC_DRV_RS5C372=y # CONFIG_RTC_DRV_M48T86 is not set # CONFIG_RTC_DRV_M48T35 is not set # CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set # CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set # CONFIG_RTC_DRV_V3020 is not set # @@ -1098,6 +1143,7 @@ CONFIG_UIO_PDRV_GENIRQ=y # CONFIG_EXT2_FS is not set # CONFIG_EXT3_FS is not set # CONFIG_EXT4_FS is not set +CONFIG_EXT4_USE_FOR_EXT23=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set @@ -1206,10 +1252,11 @@ CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set CONFIG_STACKTRACE=y -# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_LATENCYTOP is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set CONFIG_NOP_TRACER=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y @@ -1229,9 +1276,6 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set -CONFIG_EARLY_SCIF_CONSOLE=y -CONFIG_EARLY_SCIF_CONSOLE_PORT=0xffe00000 -CONFIG_EARLY_PRINTK=y # CONFIG_DWARF_UNWINDER is not set # @@ -1240,7 +1284,11 @@ CONFIG_EARLY_PRINTK=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" CONFIG_CRYPTO=y # diff --git a/arch/sh/configs/polaris_defconfig b/arch/sh/configs/polaris_defconfig index 7fc1952..d50c031 100644 --- a/arch/sh/configs/polaris_defconfig +++ b/arch/sh/configs/polaris_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31 -# Thu Sep 24 18:20:53 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 11:45:25 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -29,6 +29,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_DMA_NONCOHERENT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -63,6 +64,7 @@ CONFIG_AUDIT=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -102,6 +104,7 @@ CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters @@ -120,6 +123,7 @@ CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -146,14 +150,41 @@ CONFIG_LBDAF=y # IO Schedulers # CONFIG_IOSCHED_NOOP=y -# CONFIG_IOSCHED_AS is not set # CONFIG_IOSCHED_DEADLINE is not set CONFIG_IOSCHED_CFQ=y -# CONFIG_DEFAULT_AS is not set # CONFIG_DEFAULT_DEADLINE is not set CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +# CONFIG_INLINE_SPIN_UNLOCK is not set +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +# CONFIG_INLINE_READ_UNLOCK is not set +# CONFIG_INLINE_READ_UNLOCK_BH is not set +# CONFIG_INLINE_READ_UNLOCK_IRQ is not set +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +# CONFIG_INLINE_WRITE_UNLOCK is not set +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set # CONFIG_FREEZER is not set # @@ -225,12 +256,10 @@ CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_SPARSEMEM_STATIC=y CONFIG_PAGEFLAGS_EXTENDED=y -CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_SPLIT_PTLOCK_CPUS=999999 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -279,8 +308,8 @@ CONFIG_GENERIC_CLOCKEVENTS_BUILD=y # # DMA support # -CONFIG_SH_DMA_API=y CONFIG_SH_DMA=y +CONFIG_SH_DMA_API=y CONFIG_NR_ONCHIP_DMA_CHANNELS=6 # CONFIG_NR_DMA_CHANNELS_BOOL is not set @@ -409,7 +438,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set -# CONFIG_WIRELESS is not set +CONFIG_WIRELESS=y +# CONFIG_CFG80211 is not set +# CONFIG_LIB80211 is not set + +# +# CFG80211 needs to be enabled for MAC80211 +# # CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -525,6 +560,10 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2 CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_RAM is not set # CONFIG_CDROM_PKTCDVD is not set @@ -595,11 +634,11 @@ CONFIG_SMSC911X=y # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set # CONFIG_B44 is not set # CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set CONFIG_WLAN=y -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +# CONFIG_HOSTAP is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers @@ -619,6 +658,7 @@ CONFIG_WLAN=y CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set # CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set # # Userland interfaces @@ -657,7 +697,6 @@ CONFIG_SERIAL_NONSTANDARD=y # CONFIG_N_HDLC is not set # CONFIG_RISCOM8 is not set # CONFIG_SPECIALIX is not set -# CONFIG_RIO is not set # CONFIG_STALDRV is not set # @@ -705,6 +744,7 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set # CONFIG_REGULATOR is not set @@ -764,7 +804,9 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_M48T86 is not set # CONFIG_RTC_DRV_M48T35 is not set # CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set # CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set # CONFIG_RTC_DRV_V3020 is not set # @@ -787,6 +829,7 @@ CONFIG_RTC_DRV_SH=y # CONFIG_EXT2_FS is not set # CONFIG_EXT3_FS is not set # CONFIG_EXT4_FS is not set +CONFIG_EXT4_USE_FOR_EXT23=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set @@ -833,7 +876,6 @@ CONFIG_PROC_PAGE_MONITOR=y CONFIG_SYSFS=y CONFIG_TMPFS=y # CONFIG_TMPFS_POSIX_ACL is not set -# CONFIG_HUGETLBFS is not set # CONFIG_HUGETLB_PAGE is not set # CONFIG_CONFIGFS_FS is not set CONFIG_MISC_FILESYSTEMS=y @@ -977,9 +1019,6 @@ CONFIG_BRANCH_PROFILE_NONE=y CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set # CONFIG_SH_STANDARD_BIOS is not set -CONFIG_EARLY_SCIF_CONSOLE=y -CONFIG_EARLY_SCIF_CONSOLE_PORT=0xa4000150 -CONFIG_EARLY_PRINTK=y # CONFIG_STACK_DEBUG is not set # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_4KSTACKS is not set @@ -993,7 +1032,11 @@ CONFIG_DUMP_CODE=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" # CONFIG_CRYPTO is not set # CONFIG_BINARY_PRINTF is not set diff --git a/arch/sh/configs/r7780mp_defconfig b/arch/sh/configs/r7780mp_defconfig index 903b021..efda63d 100644 --- a/arch/sh/configs/r7780mp_defconfig +++ b/arch/sh/configs/r7780mp_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31 -# Thu Sep 24 18:24:31 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 13:16:13 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y # CONFIG_ARCH_SUSPEND_POSSIBLE is not set CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_SYS_SUPPORTS_HUGETLBFS=y CONFIG_SYS_SUPPORTS_PCI=y CONFIG_SYS_SUPPORTS_TMU=y CONFIG_STACKTRACE_SUPPORT=y @@ -31,6 +32,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_IO_TRAPPED=y +CONFIG_DMA_NONCOHERENT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -63,6 +65,7 @@ CONFIG_BSD_PROCESS_ACCT=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -103,6 +106,7 @@ CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters @@ -110,6 +114,7 @@ CONFIG_HAVE_PERF_EVENTS=y CONFIG_PERF_EVENTS=y CONFIG_EVENT_PROFILE=y # CONFIG_PERF_COUNTERS is not set +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_PCI_QUIRKS=y CONFIG_COMPAT_BRK=y @@ -125,6 +130,7 @@ CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -135,6 +141,7 @@ CONFIG_HAVE_DMA_API_DEBUG=y # CONFIG_SLOW_WORK is not set CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y CONFIG_BASE_SMALL=0 CONFIG_MODULES=y # CONFIG_MODULE_FORCE_LOAD is not set @@ -151,14 +158,41 @@ CONFIG_LBDAF=y # IO Schedulers # CONFIG_IOSCHED_NOOP=y -# CONFIG_IOSCHED_AS is not set # CONFIG_IOSCHED_DEADLINE is not set # CONFIG_IOSCHED_CFQ is not set -# CONFIG_DEFAULT_AS is not set # CONFIG_DEFAULT_DEADLINE is not set # CONFIG_DEFAULT_CFQ is not set CONFIG_DEFAULT_NOOP=y CONFIG_DEFAULT_IOSCHED="noop" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +# CONFIG_INLINE_SPIN_UNLOCK is not set +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +# CONFIG_INLINE_READ_UNLOCK is not set +# CONFIG_INLINE_READ_UNLOCK_BH is not set +# CONFIG_INLINE_READ_UNLOCK_IRQ is not set +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +# CONFIG_INLINE_WRITE_UNLOCK is not set +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set # CONFIG_FREEZER is not set # @@ -245,8 +279,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -342,7 +374,6 @@ CONFIG_CMDLINE="console=ttySC0,115200 root=/dev/sda1" # Bus options # CONFIG_PCI=y -CONFIG_SH_PCIDMA_NONCOHERENT=y # CONFIG_PCIEPORTBUS is not set # CONFIG_ARCH_SUPPORTS_MSI is not set CONFIG_PCI_LEGACY=y @@ -449,10 +480,6 @@ CONFIG_LLC=m # CONFIG_AF_RXRPC is not set CONFIG_WIRELESS=y # CONFIG_CFG80211 is not set -CONFIG_CFG80211_DEFAULT_PS_VALUE=0 -# CONFIG_WIRELESS_OLD_REGULATORY is not set -CONFIG_WIRELESS_EXT=y -CONFIG_WIRELESS_EXT_SYSFS=y # CONFIG_LIB80211 is not set # @@ -535,7 +562,6 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y CONFIG_MTD_PHYSMAP=y # CONFIG_MTD_PHYSMAP_COMPAT is not set # CONFIG_MTD_PCI is not set -# CONFIG_MTD_GPIO_ADDR is not set # CONFIG_MTD_INTEL_VR_NOR is not set # CONFIG_MTD_PLATRAM is not set @@ -573,6 +599,10 @@ CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_SX8 is not set CONFIG_BLK_DEV_RAM=y @@ -583,6 +613,7 @@ CONFIG_BLK_DEV_RAM_SIZE=4096 # CONFIG_ATA_OVER_ETH is not set # CONFIG_BLK_DEV_HD is not set CONFIG_MISC_DEVICES=y +# CONFIG_AD525X_DPOT is not set # CONFIG_PHANTOM is not set # CONFIG_SGI_IOC4 is not set # CONFIG_TIFM_CORE is not set @@ -590,6 +621,7 @@ CONFIG_MISC_DEVICES=y # CONFIG_ENCLOSURE_SERVICES is not set # CONFIG_HP_ILO is not set # CONFIG_ISL29003 is not set +# CONFIG_DS1682 is not set # CONFIG_C2PORT is not set # @@ -640,8 +672,11 @@ CONFIG_SCSI_LOWLEVEL=y # CONFIG_ISCSI_TCP is not set # CONFIG_SCSI_CXGB3_ISCSI is not set # CONFIG_SCSI_BNX2_ISCSI is not set +# CONFIG_BE2ISCSI is not set # CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_HPSA is not set # CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_3W_SAS is not set # CONFIG_SCSI_ACARD is not set # CONFIG_SCSI_AACRAID is not set # CONFIG_SCSI_AIC7XXX is not set @@ -675,7 +710,9 @@ CONFIG_SCSI_LOWLEVEL=y # CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set # CONFIG_SCSI_PMCRAID is not set +# CONFIG_SCSI_PM8001 is not set # CONFIG_SCSI_SRP is not set +# CONFIG_SCSI_BFA_FC is not set # CONFIG_SCSI_DH is not set # CONFIG_SCSI_OSD_INITIATOR is not set CONFIG_ATA=y @@ -728,15 +765,16 @@ CONFIG_SATA_SIL=y # CONFIG_PATA_NS87415 is not set # CONFIG_PATA_OPTI is not set # CONFIG_PATA_OPTIDMA is not set +# CONFIG_PATA_PDC2027X is not set # CONFIG_PATA_PDC_OLD is not set # CONFIG_PATA_RADISYS is not set # CONFIG_PATA_RDC is not set # CONFIG_PATA_RZ1000 is not set # CONFIG_PATA_SC1200 is not set # CONFIG_PATA_SERVERWORKS is not set -# CONFIG_PATA_PDC2027X is not set # CONFIG_PATA_SIL680 is not set # CONFIG_PATA_SIS is not set +# CONFIG_PATA_TOSHIBA is not set # CONFIG_PATA_VIA is not set # CONFIG_PATA_WINBOND is not set CONFIG_PATA_PLATFORM=y @@ -813,6 +851,7 @@ CONFIG_8139TOO_8129=y # CONFIG_SUNDANCE is not set # CONFIG_TLAN is not set # CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set CONFIG_VIA_RHINE=m CONFIG_VIA_RHINE_MMIO=y # CONFIG_SC92031 is not set @@ -862,8 +901,9 @@ CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_BE2NET is not set # CONFIG_TR is not set CONFIG_WLAN=y -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +# CONFIG_ATMEL is not set +# CONFIG_PRISM54 is not set +# CONFIG_HOSTAP is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers @@ -877,6 +917,7 @@ CONFIG_WLAN=y # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_VMXNET3 is not set # CONFIG_ISDN is not set # CONFIG_PHONE is not set @@ -886,6 +927,7 @@ CONFIG_WLAN=y CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set # CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set # # Userland interfaces @@ -928,6 +970,7 @@ CONFIG_SERIO=y # CONFIG_SERIO_PCIPS2 is not set CONFIG_SERIO_LIBPS2=y # CONFIG_SERIO_RAW is not set +# CONFIG_SERIO_ALTERA_PS2 is not set # CONFIG_GAMEPORT is not set # @@ -1008,11 +1051,6 @@ CONFIG_I2C_HIGHLANDER=y # CONFIG_I2C_TAOS_EVM is not set # -# Graphics adapter I2C/DDC channel drivers -# -# CONFIG_I2C_VOODOO3 is not set - -# # Other I2C/SMBus bus drivers # # CONFIG_I2C_PCA_PLATFORM is not set @@ -1021,7 +1059,6 @@ CONFIG_I2C_HIGHLANDER=y # # Miscellaneous I2C Chip support # -# CONFIG_DS1682 is not set # CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set @@ -1065,6 +1102,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_GL520SM is not set # CONFIG_SENSORS_IT87 is not set # CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM73 is not set # CONFIG_SENSORS_LM75 is not set # CONFIG_SENSORS_LM77 is not set # CONFIG_SENSORS_LM78 is not set @@ -1103,6 +1141,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_W83L786NG is not set # CONFIG_SENSORS_W83627HF is not set # CONFIG_SENSORS_W83627EHF is not set +# CONFIG_SENSORS_LIS3_I2C is not set CONFIG_THERMAL=y # CONFIG_THERMAL_HWMON is not set # CONFIG_WATCHDOG is not set @@ -1118,15 +1157,18 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_TWL4030_CORE is not set # CONFIG_MFD_TMIO is not set # CONFIG_PMIC_DA903X is not set +# CONFIG_PMIC_ADP5520 is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set # CONFIG_MFD_PCF50633 is not set # CONFIG_AB3100_CORE is not set +# CONFIG_MFD_88PM8607 is not set # CONFIG_REGULATOR is not set # CONFIG_MEDIA_SUPPORT is not set @@ -1211,6 +1253,7 @@ CONFIG_RTC_DRV_RS5C372=y # CONFIG_RTC_DRV_PCF8563 is not set # CONFIG_RTC_DRV_PCF8583 is not set # CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set # CONFIG_RTC_DRV_S35390A is not set # CONFIG_RTC_DRV_FM3130 is not set # CONFIG_RTC_DRV_RX8581 is not set @@ -1231,7 +1274,9 @@ CONFIG_RTC_DRV_RS5C372=y # CONFIG_RTC_DRV_M48T86 is not set # CONFIG_RTC_DRV_M48T35 is not set # CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set # CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set # CONFIG_RTC_DRV_V3020 is not set # @@ -1436,6 +1481,8 @@ CONFIG_SCHED_DEBUG=y # CONFIG_DEBUG_OBJECTS is not set # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_PREEMPT is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_MUTEXES is not set # CONFIG_DEBUG_LOCK_ALLOC is not set @@ -1462,6 +1509,7 @@ CONFIG_DEBUG_INFO=y # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set # CONFIG_FAULT_INJECTION is not set # CONFIG_LATENCYTOP is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set # CONFIG_PAGE_POISONING is not set CONFIG_NOP_TRACER=y CONFIG_HAVE_FUNCTION_TRACER=y @@ -1498,9 +1546,6 @@ CONFIG_BRANCH_PROFILE_NONE=y CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set # CONFIG_SH_STANDARD_BIOS is not set -CONFIG_EARLY_SCIF_CONSOLE=y -CONFIG_EARLY_SCIF_CONSOLE_PORT=0xffe00000 -# CONFIG_EARLY_PRINTK is not set # CONFIG_STACK_DEBUG is not set # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_4KSTACKS is not set @@ -1514,7 +1559,11 @@ CONFIG_DUMP_CODE=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" CONFIG_CRYPTO=y # diff --git a/arch/sh/configs/r7785rp_defconfig b/arch/sh/configs/r7785rp_defconfig index 27ff46c..f4b0045 100644 --- a/arch/sh/configs/r7785rp_defconfig +++ b/arch/sh/configs/r7785rp_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31 -# Thu Sep 24 18:29:23 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 13:19:35 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y # CONFIG_ARCH_SUSPEND_POSSIBLE is not set CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_SYS_SUPPORTS_HUGETLBFS=y CONFIG_SYS_SUPPORTS_NUMA=y CONFIG_SYS_SUPPORTS_PCI=y CONFIG_SYS_SUPPORTS_TMU=y @@ -32,6 +33,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_IO_TRAPPED=y +CONFIG_DMA_NONCOHERENT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -67,6 +69,7 @@ CONFIG_AUDIT_TREE=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set CONFIG_RCU_TRACE=y CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -103,6 +106,7 @@ CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters @@ -110,6 +114,7 @@ CONFIG_HAVE_PERF_EVENTS=y CONFIG_PERF_EVENTS=y CONFIG_EVENT_PROFILE=y # CONFIG_PERF_COUNTERS is not set +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_PCI_QUIRKS=y CONFIG_COMPAT_BRK=y @@ -126,6 +131,7 @@ CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -153,14 +159,41 @@ CONFIG_LBDAF=y # IO Schedulers # CONFIG_IOSCHED_NOOP=y -# CONFIG_IOSCHED_AS is not set # CONFIG_IOSCHED_DEADLINE is not set # CONFIG_IOSCHED_CFQ is not set -# CONFIG_DEFAULT_AS is not set # CONFIG_DEFAULT_DEADLINE is not set # CONFIG_DEFAULT_CFQ is not set CONFIG_DEFAULT_NOOP=y CONFIG_DEFAULT_IOSCHED="noop" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +# CONFIG_INLINE_SPIN_UNLOCK is not set +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +# CONFIG_INLINE_READ_UNLOCK is not set +# CONFIG_INLINE_READ_UNLOCK_BH is not set +# CONFIG_INLINE_READ_UNLOCK_IRQ is not set +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +# CONFIG_INLINE_WRITE_UNLOCK is not set +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set # CONFIG_FREEZER is not set # @@ -248,13 +281,11 @@ CONFIG_SPARSEMEM=y CONFIG_HAVE_MEMORY_PRESENT=y CONFIG_SPARSEMEM_STATIC=y # CONFIG_MEMORY_HOTPLUG is not set -CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_SPLIT_PTLOCK_CPUS=999999 CONFIG_MIGRATION=y # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -289,7 +320,6 @@ CONFIG_SH_R7785RP=y # Timer and clock configuration # CONFIG_SH_TIMER_TMU=y -CONFIG_SH_PCLK_FREQ=33333333 CONFIG_SH_CLK_CPG=y CONFIG_TICK_ONESHOT=y CONFIG_NO_HZ=y @@ -363,7 +393,6 @@ CONFIG_CMDLINE="console=ttySC0,115200 root=/dev/sda1" # Bus options # CONFIG_PCI=y -CONFIG_SH_PCIDMA_NONCOHERENT=y # CONFIG_PCIEPORTBUS is not set # CONFIG_ARCH_SUPPORTS_MSI is not set # CONFIG_PCI_LEGACY is not set @@ -471,10 +500,6 @@ CONFIG_LLC=m # CONFIG_AF_RXRPC is not set CONFIG_WIRELESS=y # CONFIG_CFG80211 is not set -CONFIG_CFG80211_DEFAULT_PS_VALUE=0 -# CONFIG_WIRELESS_OLD_REGULATORY is not set -CONFIG_WIRELESS_EXT=y -CONFIG_WIRELESS_EXT_SYSFS=y # CONFIG_LIB80211 is not set # @@ -510,6 +535,10 @@ CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_SX8 is not set CONFIG_BLK_DEV_RAM=y @@ -520,6 +549,7 @@ CONFIG_BLK_DEV_RAM_SIZE=4096 # CONFIG_ATA_OVER_ETH is not set # CONFIG_BLK_DEV_HD is not set CONFIG_MISC_DEVICES=y +# CONFIG_AD525X_DPOT is not set # CONFIG_PHANTOM is not set # CONFIG_SGI_IOC4 is not set # CONFIG_TIFM_CORE is not set @@ -527,6 +557,7 @@ CONFIG_MISC_DEVICES=y # CONFIG_ENCLOSURE_SERVICES is not set # CONFIG_HP_ILO is not set # CONFIG_ISL29003 is not set +# CONFIG_DS1682 is not set # CONFIG_C2PORT is not set # @@ -577,8 +608,11 @@ CONFIG_SCSI_LOWLEVEL=y # CONFIG_ISCSI_TCP is not set # CONFIG_SCSI_CXGB3_ISCSI is not set # CONFIG_SCSI_BNX2_ISCSI is not set +# CONFIG_BE2ISCSI is not set # CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_HPSA is not set # CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_3W_SAS is not set # CONFIG_SCSI_ACARD is not set # CONFIG_SCSI_AACRAID is not set # CONFIG_SCSI_AIC7XXX is not set @@ -612,7 +646,9 @@ CONFIG_SCSI_LOWLEVEL=y # CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set # CONFIG_SCSI_PMCRAID is not set +# CONFIG_SCSI_PM8001 is not set # CONFIG_SCSI_SRP is not set +# CONFIG_SCSI_BFA_FC is not set # CONFIG_SCSI_DH is not set # CONFIG_SCSI_OSD_INITIATOR is not set CONFIG_ATA=y @@ -665,15 +701,16 @@ CONFIG_SATA_SIL=y # CONFIG_PATA_NS87415 is not set # CONFIG_PATA_OPTI is not set # CONFIG_PATA_OPTIDMA is not set +# CONFIG_PATA_PDC2027X is not set # CONFIG_PATA_PDC_OLD is not set # CONFIG_PATA_RADISYS is not set # CONFIG_PATA_RDC is not set # CONFIG_PATA_RZ1000 is not set # CONFIG_PATA_SC1200 is not set # CONFIG_PATA_SERVERWORKS is not set -# CONFIG_PATA_PDC2027X is not set # CONFIG_PATA_SIL680 is not set # CONFIG_PATA_SIS is not set +# CONFIG_PATA_TOSHIBA is not set # CONFIG_PATA_VIA is not set # CONFIG_PATA_WINBOND is not set CONFIG_PATA_PLATFORM=y @@ -730,6 +767,7 @@ CONFIG_AX88796_93CX6=y # CONFIG_NET_PCI is not set # CONFIG_B44 is not set # CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set # CONFIG_ATL2 is not set CONFIG_NETDEV_1000=y # CONFIG_ACENIC is not set @@ -776,8 +814,9 @@ CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_BE2NET is not set # CONFIG_TR is not set CONFIG_WLAN=y -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +# CONFIG_ATMEL is not set +# CONFIG_PRISM54 is not set +# CONFIG_HOSTAP is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers @@ -791,6 +830,7 @@ CONFIG_WLAN=y # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_VMXNET3 is not set # CONFIG_ISDN is not set # CONFIG_PHONE is not set @@ -800,6 +840,7 @@ CONFIG_WLAN=y CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set # CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set # # Userland interfaces @@ -844,6 +885,7 @@ CONFIG_SERIO=y # CONFIG_SERIO_PCIPS2 is not set CONFIG_SERIO_LIBPS2=y # CONFIG_SERIO_RAW is not set +# CONFIG_SERIO_ALTERA_PS2 is not set # CONFIG_GAMEPORT is not set # @@ -925,11 +967,6 @@ CONFIG_I2C_HIGHLANDER=y # CONFIG_I2C_TAOS_EVM is not set # -# Graphics adapter I2C/DDC channel drivers -# -# CONFIG_I2C_VOODOO3 is not set - -# # Other I2C/SMBus bus drivers # # CONFIG_I2C_PCA_PLATFORM is not set @@ -938,7 +975,6 @@ CONFIG_I2C_HIGHLANDER=y # # Miscellaneous I2C Chip support # -# CONFIG_DS1682 is not set # CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set @@ -969,6 +1005,7 @@ CONFIG_GPIOLIB=y # # PCI GPIO expanders: # +# CONFIG_GPIO_CS5535 is not set # CONFIG_GPIO_BT8XX is not set # CONFIG_GPIO_LANGWELL is not set @@ -1011,6 +1048,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_GL520SM is not set # CONFIG_SENSORS_IT87 is not set # CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM73 is not set # CONFIG_SENSORS_LM75 is not set # CONFIG_SENSORS_LM77 is not set # CONFIG_SENSORS_LM78 is not set @@ -1050,6 +1088,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_W83L786NG is not set # CONFIG_SENSORS_W83627HF is not set # CONFIG_SENSORS_W83627EHF is not set +# CONFIG_SENSORS_LIS3_I2C is not set # CONFIG_THERMAL is not set # CONFIG_WATCHDOG is not set CONFIG_SSB_POSSIBLE=y @@ -1064,16 +1103,19 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_TPS65010 is not set # CONFIG_TWL4030_CORE is not set # CONFIG_MFD_TMIO is not set # CONFIG_PMIC_DA903X is not set +# CONFIG_PMIC_ADP5520 is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set # CONFIG_MFD_PCF50633 is not set # CONFIG_AB3100_CORE is not set +# CONFIG_MFD_88PM8607 is not set # CONFIG_REGULATOR is not set # CONFIG_MEDIA_SUPPORT is not set @@ -1211,6 +1253,7 @@ CONFIG_RTC_DRV_RS5C372=y # CONFIG_RTC_DRV_PCF8563 is not set # CONFIG_RTC_DRV_PCF8583 is not set # CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set # CONFIG_RTC_DRV_S35390A is not set # CONFIG_RTC_DRV_FM3130 is not set # CONFIG_RTC_DRV_RX8581 is not set @@ -1231,7 +1274,9 @@ CONFIG_RTC_DRV_RS5C372=y # CONFIG_RTC_DRV_M48T86 is not set # CONFIG_RTC_DRV_M48T35 is not set # CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set # CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set # CONFIG_RTC_DRV_V3020 is not set # @@ -1463,6 +1508,7 @@ CONFIG_FRAME_POINTER=y # CONFIG_LKDTM is not set # CONFIG_FAULT_INJECTION is not set # CONFIG_LATENCYTOP is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set # CONFIG_PAGE_POISONING is not set CONFIG_NOP_TRACER=y CONFIG_HAVE_FUNCTION_TRACER=y @@ -1499,8 +1545,6 @@ CONFIG_BRANCH_PROFILE_NONE=y CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set CONFIG_SH_STANDARD_BIOS=y -# CONFIG_EARLY_SCIF_CONSOLE is not set -CONFIG_EARLY_PRINTK=y # CONFIG_STACK_DEBUG is not set CONFIG_DEBUG_STACK_USAGE=y CONFIG_4KSTACKS=y @@ -1514,7 +1558,11 @@ CONFIG_DUMP_CODE=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" CONFIG_CRYPTO=y # diff --git a/arch/sh/configs/rsk7201_defconfig b/arch/sh/configs/rsk7201_defconfig index c40db12..2fc635a 100644 --- a/arch/sh/configs/rsk7201_defconfig +++ b/arch/sh/configs/rsk7201_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31 -# Thu Sep 24 18:34:29 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 13:23:12 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -29,6 +29,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_DMA_NONCOHERENT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -56,6 +57,7 @@ CONFIG_BSD_PROCESS_ACCT=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -97,6 +99,7 @@ CONFIG_TIMERFD=y CONFIG_EVENTFD=y # CONFIG_AIO is not set CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters @@ -109,6 +112,7 @@ CONFIG_COMPAT_BRK=y # CONFIG_SLAB is not set # CONFIG_SLUB is not set CONFIG_SLOB=y +# CONFIG_MMAP_ALLOW_UNINITIALIZED is not set CONFIG_PROFILING=y CONFIG_TRACEPOINTS=y CONFIG_OPROFILE=y @@ -117,6 +121,7 @@ CONFIG_HAVE_OPROFILE=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -142,14 +147,41 @@ CONFIG_LBDAF=y # IO Schedulers # CONFIG_IOSCHED_NOOP=y -# CONFIG_IOSCHED_AS is not set # CONFIG_IOSCHED_DEADLINE is not set # CONFIG_IOSCHED_CFQ is not set -# CONFIG_DEFAULT_AS is not set # CONFIG_DEFAULT_DEADLINE is not set # CONFIG_DEFAULT_CFQ is not set CONFIG_DEFAULT_NOOP=y CONFIG_DEFAULT_IOSCHED="noop" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +CONFIG_INLINE_SPIN_UNLOCK=y +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +CONFIG_INLINE_READ_UNLOCK=y +# CONFIG_INLINE_READ_UNLOCK_BH is not set +CONFIG_INLINE_READ_UNLOCK_IRQ=y +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +CONFIG_INLINE_WRITE_UNLOCK=y +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set # CONFIG_FREEZER is not set # @@ -224,7 +256,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 -CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 CONFIG_NOMMU_INITIAL_TRIM_EXCESS=1 # @@ -433,6 +464,10 @@ CONFIG_MTD_PHYSMAP=y CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# # CONFIG_BLK_DEV_RAM is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_BLK_DEV_HD is not set @@ -464,6 +499,7 @@ CONFIG_HAVE_IDE=y CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set # CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set # # Userland interfaces @@ -540,6 +576,7 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set # CONFIG_REGULATOR is not set @@ -594,7 +631,9 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_M48T86 is not set # CONFIG_RTC_DRV_M48T35 is not set # CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set # CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set # CONFIG_RTC_DRV_V3020 is not set # @@ -618,6 +657,7 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set # CONFIG_EXT3_FS is not set # CONFIG_EXT4_FS is not set +CONFIG_EXT4_USE_FOR_EXT23=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set @@ -717,7 +757,7 @@ CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set CONFIG_STACKTRACE=y -# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_LATENCYTOP is not set @@ -741,7 +781,6 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set -# CONFIG_EARLY_SCIF_CONSOLE is not set # CONFIG_DWARF_UNWINDER is not set # @@ -750,7 +789,11 @@ CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" # CONFIG_CRYPTO is not set CONFIG_BINARY_PRINTF=y diff --git a/arch/sh/configs/rsk7203_defconfig b/arch/sh/configs/rsk7203_defconfig index 5cabdb3..0169e60 100644 --- a/arch/sh/configs/rsk7203_defconfig +++ b/arch/sh/configs/rsk7203_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31 -# Thu Sep 24 18:35:04 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 13:23:54 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -30,6 +30,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_DMA_NONCOHERENT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -61,6 +62,7 @@ CONFIG_BSD_PROCESS_ACCT=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -104,6 +106,7 @@ CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_AIO=y CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters @@ -111,11 +114,13 @@ CONFIG_HAVE_PERF_EVENTS=y CONFIG_PERF_EVENTS=y CONFIG_EVENT_PROFILE=y # CONFIG_PERF_COUNTERS is not set +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_COMPAT_BRK=y # CONFIG_SLAB is not set # CONFIG_SLUB is not set CONFIG_SLOB=y +# CONFIG_MMAP_ALLOW_UNINITIALIZED is not set CONFIG_PROFILING=y CONFIG_TRACEPOINTS=y CONFIG_OPROFILE=y @@ -124,6 +129,7 @@ CONFIG_HAVE_OPROFILE=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -149,14 +155,41 @@ CONFIG_LBDAF=y # IO Schedulers # CONFIG_IOSCHED_NOOP=y -# CONFIG_IOSCHED_AS is not set # CONFIG_IOSCHED_DEADLINE is not set # CONFIG_IOSCHED_CFQ is not set -# CONFIG_DEFAULT_AS is not set # CONFIG_DEFAULT_DEADLINE is not set # CONFIG_DEFAULT_CFQ is not set CONFIG_DEFAULT_NOOP=y CONFIG_DEFAULT_IOSCHED="noop" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +CONFIG_INLINE_SPIN_UNLOCK=y +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +CONFIG_INLINE_READ_UNLOCK=y +# CONFIG_INLINE_READ_UNLOCK_BH is not set +CONFIG_INLINE_READ_UNLOCK_IRQ=y +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +CONFIG_INLINE_WRITE_UNLOCK=y +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set # CONFIG_FREEZER is not set # @@ -231,7 +264,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 -CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 CONFIG_NOMMU_INITIAL_TRIM_EXCESS=1 # @@ -424,9 +456,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_AF_RXRPC is not set CONFIG_WIRELESS=y # CONFIG_CFG80211 is not set -CONFIG_CFG80211_DEFAULT_PS_VALUE=0 -# CONFIG_WIRELESS_OLD_REGULATORY is not set -# CONFIG_WIRELESS_EXT is not set # CONFIG_LIB80211 is not set # @@ -539,6 +568,10 @@ CONFIG_MTD_PHYSMAP=y CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_UB is not set # CONFIG_BLK_DEV_RAM is not set @@ -610,11 +643,12 @@ CONFIG_SMSC911X=y # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set # CONFIG_B44 is not set # CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set CONFIG_WLAN=y -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +# CONFIG_USB_ZD1201 is not set +# CONFIG_HOSTAP is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers @@ -643,6 +677,7 @@ CONFIG_WLAN=y CONFIG_INPUT=y CONFIG_INPUT_FF_MEMLESS=m # CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set # # Userland interfaces @@ -743,6 +778,7 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set CONFIG_REGULATOR=y @@ -910,6 +946,8 @@ CONFIG_LEDS_CLASS=y # CONFIG_LEDS_GPIO=y CONFIG_LEDS_GPIO_PLATFORM=y +# CONFIG_LEDS_REGULATOR is not set +# CONFIG_LEDS_LT3593 is not set # # LED Triggers @@ -955,7 +993,9 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_M48T86 is not set # CONFIG_RTC_DRV_M48T35 is not set # CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set # CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set # CONFIG_RTC_DRV_V3020 is not set # @@ -978,6 +1018,7 @@ CONFIG_RTC_DRV_SH=y # CONFIG_EXT2_FS is not set # CONFIG_EXT3_FS is not set # CONFIG_EXT4_FS is not set +CONFIG_EXT4_USE_FOR_EXT23=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set @@ -1137,6 +1178,7 @@ CONFIG_DEBUG_OBJECTS=y # CONFIG_DEBUG_OBJECTS_SELFTEST is not set # CONFIG_DEBUG_OBJECTS_FREE is not set # CONFIG_DEBUG_OBJECTS_TIMERS is not set +# CONFIG_DEBUG_OBJECTS_WORK is not set CONFIG_DEBUG_OBJECTS_ENABLE_DEFAULT=1 # CONFIG_DEBUG_RT_MUTEXES is not set # CONFIG_RT_MUTEX_TESTER is not set @@ -1203,9 +1245,6 @@ CONFIG_BRANCH_PROFILE_NONE=y CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set # CONFIG_SH_STANDARD_BIOS is not set -CONFIG_EARLY_SCIF_CONSOLE=y -CONFIG_EARLY_SCIF_CONSOLE_PORT=0xfffe8000 -CONFIG_EARLY_PRINTK=y # CONFIG_STACK_DEBUG is not set CONFIG_DEBUG_STACK_USAGE=y CONFIG_DUMP_CODE=y @@ -1218,7 +1257,11 @@ CONFIG_DUMP_CODE=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" # CONFIG_CRYPTO is not set CONFIG_BINARY_PRINTF=y diff --git a/arch/sh/configs/rts7751r2d1_defconfig b/arch/sh/configs/rts7751r2d1_defconfig index 6f1126b..fba1f62 100644 --- a/arch/sh/configs/rts7751r2d1_defconfig +++ b/arch/sh/configs/rts7751r2d1_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31 -# Thu Sep 24 18:36:25 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 13:25:36 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y # CONFIG_ARCH_SUSPEND_POSSIBLE is not set CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_SYS_SUPPORTS_HUGETLBFS=y CONFIG_SYS_SUPPORTS_PCI=y CONFIG_SYS_SUPPORTS_TMU=y CONFIG_STACKTRACE_SUPPORT=y @@ -31,6 +32,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_IO_TRAPPED=y +CONFIG_DMA_NONCOHERENT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -61,6 +63,7 @@ CONFIG_SYSVIPC_SYSCTL=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -95,6 +98,7 @@ CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters @@ -117,6 +121,7 @@ CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -143,14 +148,41 @@ CONFIG_LBDAF=y # IO Schedulers # CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +CONFIG_INLINE_SPIN_UNLOCK=y +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +CONFIG_INLINE_READ_UNLOCK=y +# CONFIG_INLINE_READ_UNLOCK_BH is not set +CONFIG_INLINE_READ_UNLOCK_IRQ=y +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +CONFIG_INLINE_WRITE_UNLOCK=y +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set # CONFIG_FREEZER is not set # @@ -226,8 +258,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -321,7 +351,6 @@ CONFIG_GUSA=y CONFIG_ZERO_PAGE_OFFSET=0x00010000 CONFIG_BOOT_LINK_OFFSET=0x00800000 CONFIG_ENTRY_OFFSET=0x00001000 -# CONFIG_UBC_WAKEUP is not set CONFIG_CMDLINE_OVERWRITE=y # CONFIG_CMDLINE_EXTEND is not set CONFIG_CMDLINE="console=tty0 console=ttySC1,115200 root=/dev/sda1" @@ -330,7 +359,6 @@ CONFIG_CMDLINE="console=tty0 console=ttySC1,115200 root=/dev/sda1" # Bus options # CONFIG_PCI=y -CONFIG_SH_PCIDMA_NONCOHERENT=y # CONFIG_PCIEPORTBUS is not set # CONFIG_ARCH_SUPPORTS_MSI is not set CONFIG_PCI_LEGACY=y @@ -429,10 +457,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_AF_RXRPC is not set CONFIG_WIRELESS=y # CONFIG_CFG80211 is not set -CONFIG_CFG80211_DEFAULT_PS_VALUE=0 -# CONFIG_WIRELESS_OLD_REGULATORY is not set -CONFIG_WIRELESS_EXT=y -CONFIG_WIRELESS_EXT_SYSFS=y # CONFIG_LIB80211 is not set # @@ -466,6 +490,10 @@ CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_SX8 is not set # CONFIG_BLK_DEV_UB is not set @@ -482,6 +510,7 @@ CONFIG_MISC_DEVICES=y # CONFIG_TIFM_CORE is not set # CONFIG_ENCLOSURE_SERVICES is not set # CONFIG_HP_ILO is not set +# CONFIG_TI_DAC7512 is not set # CONFIG_C2PORT is not set # @@ -530,8 +559,11 @@ CONFIG_SCSI_LOWLEVEL=y # CONFIG_ISCSI_TCP is not set # CONFIG_SCSI_CXGB3_ISCSI is not set # CONFIG_SCSI_BNX2_ISCSI is not set +# CONFIG_BE2ISCSI is not set # CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_HPSA is not set # CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_3W_SAS is not set # CONFIG_SCSI_ACARD is not set # CONFIG_SCSI_AACRAID is not set # CONFIG_SCSI_AIC7XXX is not set @@ -565,7 +597,9 @@ CONFIG_SCSI_LOWLEVEL=y # CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set # CONFIG_SCSI_PMCRAID is not set +# CONFIG_SCSI_PM8001 is not set # CONFIG_SCSI_SRP is not set +# CONFIG_SCSI_BFA_FC is not set # CONFIG_SCSI_DH is not set # CONFIG_SCSI_OSD_INITIATOR is not set CONFIG_ATA=y @@ -618,15 +652,16 @@ CONFIG_ATA_SFF=y # CONFIG_PATA_NS87415 is not set # CONFIG_PATA_OPTI is not set # CONFIG_PATA_OPTIDMA is not set +# CONFIG_PATA_PDC2027X is not set # CONFIG_PATA_PDC_OLD is not set # CONFIG_PATA_RADISYS is not set # CONFIG_PATA_RDC is not set # CONFIG_PATA_RZ1000 is not set # CONFIG_PATA_SC1200 is not set # CONFIG_PATA_SERVERWORKS is not set -# CONFIG_PATA_PDC2027X is not set # CONFIG_PATA_SIL680 is not set # CONFIG_PATA_SIS is not set +# CONFIG_PATA_TOSHIBA is not set # CONFIG_PATA_VIA is not set # CONFIG_PATA_WINBOND is not set CONFIG_PATA_PLATFORM=y @@ -704,6 +739,7 @@ CONFIG_8139TOO=y # CONFIG_TLAN is not set # CONFIG_KS8842 is not set # CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set # CONFIG_VIA_RHINE is not set # CONFIG_SC92031 is not set # CONFIG_ATL2 is not set @@ -752,8 +788,10 @@ CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_BE2NET is not set # CONFIG_TR is not set CONFIG_WLAN=y -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +# CONFIG_ATMEL is not set +# CONFIG_PRISM54 is not set +# CONFIG_USB_ZD1201 is not set +# CONFIG_HOSTAP is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers @@ -776,6 +814,7 @@ CONFIG_WLAN=y # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_VMXNET3 is not set # CONFIG_ISDN is not set # CONFIG_PHONE is not set @@ -785,6 +824,7 @@ CONFIG_WLAN=y CONFIG_INPUT=y CONFIG_INPUT_FF_MEMLESS=m # CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set # # Userland interfaces @@ -862,7 +902,10 @@ CONFIG_SPI_MASTER=y # SPI Master Controller Drivers # CONFIG_SPI_BITBANG=y +# CONFIG_SPI_SH_MSIOF is not set CONFIG_SPI_SH_SCI=y +# CONFIG_SPI_XILINX is not set +# CONFIG_SPI_DESIGNWARE is not set # # SPI Protocol Masters @@ -915,10 +958,12 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_MFD_CORE is not set CONFIG_MFD_SM501=y +# CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set # CONFIG_MFD_MC13783 is not set # CONFIG_EZX_PCAP is not set +# CONFIG_AB4500_CORE is not set # CONFIG_REGULATOR is not set # CONFIG_MEDIA_SUPPORT is not set @@ -1055,6 +1100,7 @@ CONFIG_SND_PCI=y # CONFIG_SND_OXYGEN is not set # CONFIG_SND_CS4281 is not set # CONFIG_SND_CS46XX is not set +# CONFIG_SND_CS5535AUDIO is not set # CONFIG_SND_CTXFI is not set # CONFIG_SND_DARLA20 is not set # CONFIG_SND_GINA20 is not set @@ -1308,7 +1354,9 @@ CONFIG_RTC_DRV_R9701=y # CONFIG_RTC_DRV_M48T86 is not set # CONFIG_RTC_DRV_M48T35 is not set # CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set # CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set # CONFIG_RTC_DRV_V3020 is not set # @@ -1333,6 +1381,7 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XIP is not set # CONFIG_EXT3_FS is not set # CONFIG_EXT4_FS is not set +CONFIG_EXT4_USE_FOR_EXT23=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set @@ -1474,10 +1523,11 @@ CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set CONFIG_STACKTRACE=y -# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_LATENCYTOP is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set CONFIG_NOP_TRACER=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y @@ -1497,9 +1547,6 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set -CONFIG_EARLY_SCIF_CONSOLE=y -CONFIG_EARLY_SCIF_CONSOLE_PORT=0xffe80000 -CONFIG_EARLY_PRINTK=y # CONFIG_DWARF_UNWINDER is not set # @@ -1508,7 +1555,11 @@ CONFIG_EARLY_PRINTK=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" CONFIG_CRYPTO=y # diff --git a/arch/sh/configs/rts7751r2dplus_defconfig b/arch/sh/configs/rts7751r2dplus_defconfig index 9215bbb1..a8d538f 100644 --- a/arch/sh/configs/rts7751r2dplus_defconfig +++ b/arch/sh/configs/rts7751r2dplus_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31 -# Thu Sep 24 18:39:48 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 13:26:39 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y # CONFIG_ARCH_SUSPEND_POSSIBLE is not set CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_SYS_SUPPORTS_HUGETLBFS=y CONFIG_SYS_SUPPORTS_PCI=y CONFIG_SYS_SUPPORTS_TMU=y CONFIG_STACKTRACE_SUPPORT=y @@ -31,6 +32,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_IO_TRAPPED=y +CONFIG_DMA_NONCOHERENT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -61,6 +63,7 @@ CONFIG_SYSVIPC_SYSCTL=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -95,6 +98,7 @@ CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters @@ -117,6 +121,7 @@ CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -143,14 +148,41 @@ CONFIG_LBDAF=y # IO Schedulers # CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +CONFIG_INLINE_SPIN_UNLOCK=y +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +CONFIG_INLINE_READ_UNLOCK=y +# CONFIG_INLINE_READ_UNLOCK_BH is not set +CONFIG_INLINE_READ_UNLOCK_IRQ=y +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +CONFIG_INLINE_WRITE_UNLOCK=y +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set # CONFIG_FREEZER is not set # @@ -226,8 +258,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -321,7 +351,6 @@ CONFIG_GUSA=y CONFIG_ZERO_PAGE_OFFSET=0x00010000 CONFIG_BOOT_LINK_OFFSET=0x00800000 CONFIG_ENTRY_OFFSET=0x00001000 -# CONFIG_UBC_WAKEUP is not set CONFIG_CMDLINE_OVERWRITE=y # CONFIG_CMDLINE_EXTEND is not set CONFIG_CMDLINE="console=tty0 console=ttySC1,115200 root=/dev/sda1" @@ -330,7 +359,6 @@ CONFIG_CMDLINE="console=tty0 console=ttySC1,115200 root=/dev/sda1" # Bus options # CONFIG_PCI=y -CONFIG_SH_PCIDMA_NONCOHERENT=y # CONFIG_PCIEPORTBUS is not set # CONFIG_ARCH_SUPPORTS_MSI is not set CONFIG_PCI_LEGACY=y @@ -429,10 +457,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_AF_RXRPC is not set CONFIG_WIRELESS=y # CONFIG_CFG80211 is not set -CONFIG_CFG80211_DEFAULT_PS_VALUE=0 -# CONFIG_WIRELESS_OLD_REGULATORY is not set -CONFIG_WIRELESS_EXT=y -CONFIG_WIRELESS_EXT_SYSFS=y # CONFIG_LIB80211 is not set # @@ -552,6 +576,10 @@ CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_SX8 is not set # CONFIG_BLK_DEV_UB is not set @@ -568,6 +596,7 @@ CONFIG_MISC_DEVICES=y # CONFIG_TIFM_CORE is not set # CONFIG_ENCLOSURE_SERVICES is not set # CONFIG_HP_ILO is not set +# CONFIG_TI_DAC7512 is not set # CONFIG_C2PORT is not set # @@ -616,8 +645,11 @@ CONFIG_SCSI_LOWLEVEL=y # CONFIG_ISCSI_TCP is not set # CONFIG_SCSI_CXGB3_ISCSI is not set # CONFIG_SCSI_BNX2_ISCSI is not set +# CONFIG_BE2ISCSI is not set # CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_HPSA is not set # CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_3W_SAS is not set # CONFIG_SCSI_ACARD is not set # CONFIG_SCSI_AACRAID is not set # CONFIG_SCSI_AIC7XXX is not set @@ -651,7 +683,9 @@ CONFIG_SCSI_LOWLEVEL=y # CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set # CONFIG_SCSI_PMCRAID is not set +# CONFIG_SCSI_PM8001 is not set # CONFIG_SCSI_SRP is not set +# CONFIG_SCSI_BFA_FC is not set # CONFIG_SCSI_DH is not set # CONFIG_SCSI_OSD_INITIATOR is not set CONFIG_ATA=y @@ -704,15 +738,16 @@ CONFIG_ATA_SFF=y # CONFIG_PATA_NS87415 is not set # CONFIG_PATA_OPTI is not set # CONFIG_PATA_OPTIDMA is not set +# CONFIG_PATA_PDC2027X is not set # CONFIG_PATA_PDC_OLD is not set # CONFIG_PATA_RADISYS is not set # CONFIG_PATA_RDC is not set # CONFIG_PATA_RZ1000 is not set # CONFIG_PATA_SC1200 is not set # CONFIG_PATA_SERVERWORKS is not set -# CONFIG_PATA_PDC2027X is not set # CONFIG_PATA_SIL680 is not set # CONFIG_PATA_SIS is not set +# CONFIG_PATA_TOSHIBA is not set # CONFIG_PATA_VIA is not set # CONFIG_PATA_WINBOND is not set CONFIG_PATA_PLATFORM=y @@ -790,6 +825,7 @@ CONFIG_8139TOO=y # CONFIG_TLAN is not set # CONFIG_KS8842 is not set # CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set # CONFIG_VIA_RHINE is not set # CONFIG_SC92031 is not set # CONFIG_ATL2 is not set @@ -838,8 +874,10 @@ CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_BE2NET is not set # CONFIG_TR is not set CONFIG_WLAN=y -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +# CONFIG_ATMEL is not set +# CONFIG_PRISM54 is not set +# CONFIG_USB_ZD1201 is not set +# CONFIG_HOSTAP is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers @@ -862,6 +900,7 @@ CONFIG_WLAN=y # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_VMXNET3 is not set # CONFIG_ISDN is not set # CONFIG_PHONE is not set @@ -871,6 +910,7 @@ CONFIG_WLAN=y CONFIG_INPUT=y CONFIG_INPUT_FF_MEMLESS=m # CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set # # Userland interfaces @@ -948,7 +988,10 @@ CONFIG_SPI_MASTER=y # SPI Master Controller Drivers # CONFIG_SPI_BITBANG=y +# CONFIG_SPI_SH_MSIOF is not set CONFIG_SPI_SH_SCI=y +# CONFIG_SPI_XILINX is not set +# CONFIG_SPI_DESIGNWARE is not set # # SPI Protocol Masters @@ -1001,10 +1044,12 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_MFD_CORE is not set CONFIG_MFD_SM501=y +# CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set # CONFIG_MFD_MC13783 is not set # CONFIG_EZX_PCAP is not set +# CONFIG_AB4500_CORE is not set # CONFIG_REGULATOR is not set # CONFIG_MEDIA_SUPPORT is not set @@ -1141,6 +1186,7 @@ CONFIG_SND_PCI=y # CONFIG_SND_OXYGEN is not set # CONFIG_SND_CS4281 is not set # CONFIG_SND_CS46XX is not set +# CONFIG_SND_CS5535AUDIO is not set # CONFIG_SND_CTXFI is not set # CONFIG_SND_DARLA20 is not set # CONFIG_SND_GINA20 is not set @@ -1394,7 +1440,9 @@ CONFIG_RTC_DRV_R9701=y # CONFIG_RTC_DRV_M48T86 is not set # CONFIG_RTC_DRV_M48T35 is not set # CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set # CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set # CONFIG_RTC_DRV_V3020 is not set # @@ -1419,6 +1467,7 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XIP is not set # CONFIG_EXT3_FS is not set # CONFIG_EXT4_FS is not set +CONFIG_EXT4_USE_FOR_EXT23=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set @@ -1561,10 +1610,11 @@ CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set CONFIG_STACKTRACE=y -# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_LATENCYTOP is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set CONFIG_NOP_TRACER=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y @@ -1584,9 +1634,6 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set -CONFIG_EARLY_SCIF_CONSOLE=y -CONFIG_EARLY_SCIF_CONSOLE_PORT=0xffe80000 -CONFIG_EARLY_PRINTK=y # CONFIG_DWARF_UNWINDER is not set # @@ -1595,7 +1642,11 @@ CONFIG_EARLY_PRINTK=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" CONFIG_CRYPTO=y # diff --git a/arch/sh/configs/sdk7780_defconfig b/arch/sh/configs/sdk7780_defconfig index 055536b..1859ba0 100644 --- a/arch/sh/configs/sdk7780_defconfig +++ b/arch/sh/configs/sdk7780_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31 -# Thu Sep 24 18:40:25 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 13:27:20 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y # CONFIG_ARCH_SUSPEND_POSSIBLE is not set CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_SYS_SUPPORTS_HUGETLBFS=y CONFIG_SYS_SUPPORTS_PCI=y CONFIG_SYS_SUPPORTS_TMU=y CONFIG_STACKTRACE_SUPPORT=y @@ -30,6 +31,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_DMA_NONCOHERENT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -63,6 +65,7 @@ CONFIG_BSD_PROCESS_ACCT=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -99,6 +102,7 @@ CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters @@ -119,6 +123,7 @@ CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -145,14 +150,41 @@ CONFIG_LBDAF=y # IO Schedulers # CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +# CONFIG_INLINE_SPIN_UNLOCK is not set +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +# CONFIG_INLINE_READ_UNLOCK is not set +# CONFIG_INLINE_READ_UNLOCK_BH is not set +# CONFIG_INLINE_READ_UNLOCK_IRQ is not set +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +# CONFIG_INLINE_WRITE_UNLOCK is not set +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set # CONFIG_FREEZER is not set # @@ -239,8 +271,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -291,9 +321,9 @@ CONFIG_GENERIC_CLOCKEVENTS_BUILD=y # # DMA support # -CONFIG_SH_DMA_API=y CONFIG_SH_DMA=y CONFIG_SH_DMA_IRQ_MULTI=y +CONFIG_SH_DMA_API=y CONFIG_NR_ONCHIP_DMA_CHANNELS=12 # CONFIG_NR_DMA_CHANNELS_BOOL is not set @@ -339,7 +369,6 @@ CONFIG_CMDLINE="mem=128M console=tty0 console=ttySC0,115200 ip=bootp root=/dev/n # Bus options # CONFIG_PCI=y -CONFIG_SH_PCIDMA_NONCOHERENT=y # CONFIG_PCIEPORTBUS is not set # CONFIG_ARCH_SUPPORTS_MSI is not set # CONFIG_PCI_LEGACY is not set @@ -347,7 +376,6 @@ CONFIG_PCI_DEBUG=y # CONFIG_PCI_STUB is not set # CONFIG_PCI_IOV is not set CONFIG_PCCARD=y -# CONFIG_PCMCIA_DEBUG is not set CONFIG_PCMCIA=y CONFIG_PCMCIA_LOAD_CIS=y CONFIG_PCMCIA_IOCTL=y @@ -445,6 +473,7 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=y # CONFIG_INET6_XFRM_MODE_BEET is not set # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set CONFIG_IPV6_SIT=y +# CONFIG_IPV6_SIT_6RD is not set CONFIG_IPV6_NDISC_NODETYPE=y # CONFIG_IPV6_TUNNEL is not set # CONFIG_IPV6_MULTIPLE_TABLES is not set @@ -515,9 +544,6 @@ CONFIG_NET_SCH_FIFO=y # CONFIG_AF_RXRPC is not set CONFIG_WIRELESS=y # CONFIG_CFG80211 is not set -CONFIG_CFG80211_DEFAULT_PS_VALUE=0 -# CONFIG_WIRELESS_OLD_REGULATORY is not set -# CONFIG_WIRELESS_EXT is not set # CONFIG_LIB80211 is not set # @@ -558,6 +584,10 @@ CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_CRYPTOLOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_SX8 is not set # CONFIG_BLK_DEV_UB is not set @@ -663,8 +693,11 @@ CONFIG_SCSI_FC_ATTRS=y CONFIG_SCSI_LOWLEVEL=y # CONFIG_ISCSI_TCP is not set # CONFIG_SCSI_BNX2_ISCSI is not set +# CONFIG_BE2ISCSI is not set # CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_HPSA is not set # CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_3W_SAS is not set # CONFIG_SCSI_ACARD is not set # CONFIG_SCSI_AACRAID is not set # CONFIG_SCSI_AIC7XXX is not set @@ -698,7 +731,9 @@ CONFIG_SCSI_LOWLEVEL=y # CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set # CONFIG_SCSI_PMCRAID is not set +# CONFIG_SCSI_PM8001 is not set # CONFIG_SCSI_SRP is not set +# CONFIG_SCSI_BFA_FC is not set # CONFIG_SCSI_LOWLEVEL_PCMCIA is not set # CONFIG_SCSI_DH is not set # CONFIG_SCSI_OSD_INITIATOR is not set @@ -753,15 +788,16 @@ CONFIG_ATA_SFF=y # CONFIG_PATA_OPTI is not set # CONFIG_PATA_OPTIDMA is not set # CONFIG_PATA_PCMCIA is not set +# CONFIG_PATA_PDC2027X is not set # CONFIG_PATA_PDC_OLD is not set # CONFIG_PATA_RADISYS is not set # CONFIG_PATA_RDC is not set # CONFIG_PATA_RZ1000 is not set # CONFIG_PATA_SC1200 is not set # CONFIG_PATA_SERVERWORKS is not set -# CONFIG_PATA_PDC2027X is not set # CONFIG_PATA_SIL680 is not set # CONFIG_PATA_SIS is not set +# CONFIG_PATA_TOSHIBA is not set # CONFIG_PATA_VIA is not set # CONFIG_PATA_WINBOND is not set # CONFIG_PATA_PLATFORM is not set @@ -827,14 +863,20 @@ CONFIG_SMC91X=y # CONFIG_NET_PCI is not set # CONFIG_B44 is not set # CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set # CONFIG_NET_POCKET is not set # CONFIG_ATL2 is not set # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set # CONFIG_TR is not set CONFIG_WLAN=y -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +# CONFIG_PCMCIA_RAYCS is not set +# CONFIG_ATMEL is not set +# CONFIG_AIRO_CS is not set +# CONFIG_PCMCIA_WL3501 is not set +# CONFIG_PRISM54 is not set +# CONFIG_USB_ZD1201 is not set +# CONFIG_HOSTAP is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers @@ -861,6 +903,7 @@ CONFIG_NETCONSOLE=y CONFIG_NETPOLL=y # CONFIG_NETPOLL_TRAP is not set CONFIG_NET_POLL_CONTROLLER=y +# CONFIG_VMXNET3 is not set # CONFIG_ISDN is not set # CONFIG_PHONE is not set @@ -870,6 +913,7 @@ CONFIG_NET_POLL_CONTROLLER=y CONFIG_INPUT=y CONFIG_INPUT_FF_MEMLESS=m # CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set # # Userland interfaces @@ -922,6 +966,7 @@ CONFIG_SERIO=y # CONFIG_SERIO_PCIPS2 is not set CONFIG_SERIO_LIBPS2=y # CONFIG_SERIO_RAW is not set +# CONFIG_SERIO_ALTERA_PS2 is not set # CONFIG_GAMEPORT is not set # @@ -1009,6 +1054,7 @@ CONFIG_SSB_DRIVER_PCICORE=y # # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set # CONFIG_REGULATOR is not set @@ -1534,8 +1580,6 @@ CONFIG_BRANCH_PROFILE_NONE=y CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set CONFIG_SH_STANDARD_BIOS=y -# CONFIG_EARLY_SCIF_CONSOLE is not set -# CONFIG_EARLY_PRINTK is not set # CONFIG_STACK_DEBUG is not set # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_4KSTACKS is not set @@ -1549,7 +1593,11 @@ CONFIG_DUMP_CODE=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" CONFIG_CRYPTO=y # diff --git a/arch/sh/configs/se7206_defconfig b/arch/sh/configs/se7206_defconfig index 1cd1777..43e6780 100644 --- a/arch/sh/configs/se7206_defconfig +++ b/arch/sh/configs/se7206_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31 -# Thu Sep 24 18:45:28 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 13:30:00 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -30,6 +30,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_DMA_NONCOHERENT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -64,6 +65,7 @@ CONFIG_AUDIT_TREE=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set CONFIG_RCU_TRACE=y CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -115,6 +117,7 @@ CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_AIO=y CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters @@ -122,11 +125,13 @@ CONFIG_HAVE_PERF_EVENTS=y CONFIG_PERF_EVENTS=y CONFIG_EVENT_PROFILE=y # CONFIG_PERF_COUNTERS is not set +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set CONFIG_VM_EVENT_COUNTERS=y # CONFIG_COMPAT_BRK is not set # CONFIG_SLAB is not set # CONFIG_SLUB is not set CONFIG_SLOB=y +# CONFIG_MMAP_ALLOW_UNINITIALIZED is not set CONFIG_PROFILING=y CONFIG_TRACEPOINTS=y CONFIG_OPROFILE=y @@ -135,6 +140,7 @@ CONFIG_HAVE_OPROFILE=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -156,19 +162,47 @@ CONFIG_BLOCK=y CONFIG_LBDAF=y # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set +# CONFIG_BLK_CGROUP is not set # # IO Schedulers # CONFIG_IOSCHED_NOOP=y -# CONFIG_IOSCHED_AS is not set # CONFIG_IOSCHED_DEADLINE is not set # CONFIG_IOSCHED_CFQ is not set -# CONFIG_DEFAULT_AS is not set # CONFIG_DEFAULT_DEADLINE is not set # CONFIG_DEFAULT_CFQ is not set CONFIG_DEFAULT_NOOP=y CONFIG_DEFAULT_IOSCHED="noop" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +# CONFIG_INLINE_SPIN_UNLOCK is not set +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +# CONFIG_INLINE_READ_UNLOCK is not set +# CONFIG_INLINE_READ_UNLOCK_BH is not set +# CONFIG_INLINE_READ_UNLOCK_IRQ is not set +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +# CONFIG_INLINE_WRITE_UNLOCK is not set +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set # CONFIG_FREEZER is not set # @@ -243,7 +277,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 -CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 CONFIG_NOMMU_INITIAL_TRIM_EXCESS=1 # @@ -438,9 +471,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_AF_RXRPC is not set CONFIG_WIRELESS=y # CONFIG_CFG80211 is not set -CONFIG_CFG80211_DEFAULT_PS_VALUE=0 -# CONFIG_WIRELESS_OLD_REGULATORY is not set -# CONFIG_WIRELESS_EXT is not set # CONFIG_LIB80211 is not set # @@ -551,6 +581,10 @@ CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_CRYPTOLOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# # CONFIG_BLK_DEV_NBD is not set CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 @@ -605,11 +639,11 @@ CONFIG_SMC91X=y # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set # CONFIG_B44 is not set # CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set CONFIG_WLAN=y -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +# CONFIG_HOSTAP is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers @@ -685,6 +719,7 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set # CONFIG_REGULATOR is not set @@ -738,7 +773,9 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_M48T86 is not set # CONFIG_RTC_DRV_M48T35 is not set # CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set # CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set # CONFIG_RTC_DRV_V3020 is not set # @@ -762,6 +799,7 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set # CONFIG_EXT3_FS is not set # CONFIG_EXT4_FS is not set +CONFIG_EXT4_USE_FOR_EXT23=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set @@ -911,6 +949,7 @@ CONFIG_FRAME_POINTER=y # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set # CONFIG_FAULT_INJECTION is not set # CONFIG_LATENCYTOP is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set # CONFIG_PAGE_POISONING is not set CONFIG_NOP_TRACER=y CONFIG_HAVE_FUNCTION_TRACER=y @@ -947,7 +986,6 @@ CONFIG_BRANCH_PROFILE_NONE=y CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set # CONFIG_SH_STANDARD_BIOS is not set -# CONFIG_EARLY_SCIF_CONSOLE is not set # CONFIG_STACK_DEBUG is not set CONFIG_DEBUG_STACK_USAGE=y CONFIG_DUMP_CODE=y @@ -960,7 +998,11 @@ CONFIG_DUMP_CODE=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" CONFIG_CRYPTO=y # diff --git a/arch/sh/configs/se7343_defconfig b/arch/sh/configs/se7343_defconfig index 5531444..ec494e3 100644 --- a/arch/sh/configs/se7343_defconfig +++ b/arch/sh/configs/se7343_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31 -# Thu Sep 24 18:46:55 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 13:30:41 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_SYS_SUPPORTS_HUGETLBFS=y CONFIG_SYS_SUPPORTS_CMT=y CONFIG_SYS_SUPPORTS_TMU=y CONFIG_STACKTRACE_SUPPORT=y @@ -30,6 +31,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_DMA_NONCOHERENT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -61,6 +63,7 @@ CONFIG_POSIX_MQUEUE_SYSCTL=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -99,6 +102,7 @@ CONFIG_EVENTFD=y # CONFIG_SHMEM is not set CONFIG_AIO=y CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters @@ -117,6 +121,7 @@ CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -126,6 +131,7 @@ CONFIG_HAVE_DMA_API_DEBUG=y # CONFIG_SLOW_WORK is not set CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y CONFIG_BASE_SMALL=0 CONFIG_MODULES=y # CONFIG_MODULE_FORCE_LOAD is not set @@ -142,14 +148,41 @@ CONFIG_LBDAF=y # IO Schedulers # CONFIG_IOSCHED_NOOP=y -# CONFIG_IOSCHED_AS is not set CONFIG_IOSCHED_DEADLINE=y # CONFIG_IOSCHED_CFQ is not set -# CONFIG_DEFAULT_AS is not set CONFIG_DEFAULT_DEADLINE=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="deadline" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +CONFIG_INLINE_SPIN_UNLOCK=y +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +CONFIG_INLINE_READ_UNLOCK=y +# CONFIG_INLINE_READ_UNLOCK_BH is not set +CONFIG_INLINE_READ_UNLOCK_IRQ=y +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +CONFIG_INLINE_WRITE_UNLOCK=y +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set CONFIG_FREEZER=y # @@ -228,8 +261,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -263,7 +294,6 @@ CONFIG_SH_7343_SOLUTION_ENGINE=y # CONFIG_SH_TIMER_TMU=y # CONFIG_SH_TIMER_CMT is not set -CONFIG_SH_PCLK_FREQ=33333333 CONFIG_SH_CLK_CPG=y # CONFIG_NO_HZ is not set # CONFIG_HIGH_RES_TIMERS is not set @@ -413,9 +443,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_AF_RXRPC is not set CONFIG_WIRELESS=y # CONFIG_CFG80211 is not set -CONFIG_CFG80211_DEFAULT_PS_VALUE=0 -# CONFIG_WIRELESS_OLD_REGULATORY is not set -# CONFIG_WIRELESS_EXT is not set # CONFIG_LIB80211 is not set # @@ -525,6 +552,10 @@ CONFIG_MTD_PHYSMAP=y CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_UB is not set # CONFIG_BLK_DEV_RAM is not set @@ -585,8 +616,8 @@ CONFIG_MII=y # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set CONFIG_WLAN=y -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +# CONFIG_USB_ZD1201 is not set +# CONFIG_HOSTAP is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers @@ -628,6 +659,7 @@ CONFIG_USB_NET_DM9601=y CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set # CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set # # Userland interfaces @@ -724,7 +756,6 @@ CONFIG_I2C_SH_MOBILE=y # # Miscellaneous I2C Chip support # -# CONFIG_DS1682 is not set # CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set @@ -753,15 +784,18 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_TWL4030_CORE is not set # CONFIG_MFD_TMIO is not set # CONFIG_PMIC_DA903X is not set +# CONFIG_PMIC_ADP5520 is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set # CONFIG_MFD_PCF50633 is not set # CONFIG_AB3100_CORE is not set +# CONFIG_MFD_88PM8607 is not set # CONFIG_REGULATOR is not set # CONFIG_MEDIA_SUPPORT is not set @@ -1173,10 +1207,11 @@ CONFIG_FRAME_WARN=1024 # CONFIG_DEBUG_FS is not set # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_LATENCYTOP is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y @@ -1189,9 +1224,6 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set -CONFIG_EARLY_SCIF_CONSOLE=y -CONFIG_EARLY_SCIF_CONSOLE_PORT=0xffe00000 -CONFIG_EARLY_PRINTK=y # CONFIG_DWARF_UNWINDER is not set # @@ -1200,7 +1232,11 @@ CONFIG_EARLY_PRINTK=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" CONFIG_CRYPTO=y # diff --git a/arch/sh/configs/se7619_defconfig b/arch/sh/configs/se7619_defconfig index 6921b19..ee87e2b 100644 --- a/arch/sh/configs/se7619_defconfig +++ b/arch/sh/configs/se7619_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31 -# Thu Sep 24 18:50:05 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 13:34:15 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -29,6 +29,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_DMA_NONCOHERENT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -54,6 +55,7 @@ CONFIG_KERNEL_GZIP=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -84,6 +86,7 @@ CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_AIO=y CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters @@ -95,11 +98,13 @@ CONFIG_COMPAT_BRK=y CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set +# CONFIG_MMAP_ALLOW_UNINITIALIZED is not set # CONFIG_PROFILING is not set CONFIG_HAVE_OPROFILE=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -120,14 +125,41 @@ CONFIG_LBDAF=y # IO Schedulers # CONFIG_IOSCHED_NOOP=y -# CONFIG_IOSCHED_AS is not set # CONFIG_IOSCHED_DEADLINE is not set # CONFIG_IOSCHED_CFQ is not set -# CONFIG_DEFAULT_AS is not set # CONFIG_DEFAULT_DEADLINE is not set # CONFIG_DEFAULT_CFQ is not set CONFIG_DEFAULT_NOOP=y CONFIG_DEFAULT_IOSCHED="noop" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +CONFIG_INLINE_SPIN_UNLOCK=y +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +CONFIG_INLINE_READ_UNLOCK=y +# CONFIG_INLINE_READ_UNLOCK_BH is not set +CONFIG_INLINE_READ_UNLOCK_IRQ=y +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +CONFIG_INLINE_WRITE_UNLOCK=y +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set # CONFIG_FREEZER is not set # @@ -201,7 +233,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 -CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 CONFIG_NOMMU_INITIAL_TRIM_EXCESS=1 # @@ -401,6 +432,10 @@ CONFIG_MTD_PHYSMAP=y CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# # CONFIG_BLK_DEV_RAM is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_BLK_DEV_HD is not set @@ -432,6 +467,7 @@ CONFIG_HAVE_IDE=y CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set # CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set # # Userland interfaces @@ -508,6 +544,7 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set # CONFIG_REGULATOR is not set @@ -575,6 +612,7 @@ CONFIG_RTC_LIB=y # CONFIG_EXT2_FS is not set # CONFIG_EXT3_FS is not set # CONFIG_EXT4_FS is not set +CONFIG_EXT4_USE_FOR_EXT23=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set @@ -661,10 +699,11 @@ CONFIG_FRAME_WARN=1024 # CONFIG_UNUSED_SYMBOLS is not set # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_LATENCYTOP is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y @@ -677,7 +716,6 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set -# CONFIG_EARLY_SCIF_CONSOLE is not set # CONFIG_DWARF_UNWINDER is not set # @@ -685,7 +723,11 @@ CONFIG_HAVE_ARCH_KGDB=y # # CONFIG_KEYS is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" # CONFIG_CRYPTO is not set # CONFIG_BINARY_PRINTF is not set diff --git a/arch/sh/configs/se7705_defconfig b/arch/sh/configs/se7705_defconfig index 3abb068..03f4219 100644 --- a/arch/sh/configs/se7705_defconfig +++ b/arch/sh/configs/se7705_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31 -# Thu Sep 24 18:50:52 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 13:34:37 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -29,6 +29,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_DMA_NONCOHERENT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -59,6 +60,7 @@ CONFIG_KERNEL_GZIP=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -94,6 +96,7 @@ CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters @@ -111,6 +114,7 @@ CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -136,14 +140,41 @@ CONFIG_LBDAF=y # IO Schedulers # CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y # CONFIG_IOSCHED_DEADLINE is not set # CONFIG_IOSCHED_CFQ is not set -CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_DEADLINE is not set # CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_DEFAULT_NOOP=y +CONFIG_DEFAULT_IOSCHED="noop" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +# CONFIG_INLINE_SPIN_UNLOCK is not set +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +# CONFIG_INLINE_READ_UNLOCK is not set +# CONFIG_INLINE_READ_UNLOCK_BH is not set +# CONFIG_INLINE_READ_UNLOCK_IRQ is not set +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +# CONFIG_INLINE_WRITE_UNLOCK is not set +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set # CONFIG_FREEZER is not set # @@ -219,8 +250,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -403,9 +432,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_AF_RXRPC is not set CONFIG_WIRELESS=y # CONFIG_CFG80211 is not set -CONFIG_CFG80211_DEFAULT_PS_VALUE=0 -# CONFIG_WIRELESS_OLD_REGULATORY is not set -# CONFIG_WIRELESS_EXT is not set # CONFIG_LIB80211 is not set # @@ -510,6 +536,10 @@ CONFIG_MTD_CFI_UTIL=y CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# # CONFIG_BLK_DEV_NBD is not set CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 @@ -564,11 +594,11 @@ CONFIG_STNIC=y # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set # CONFIG_B44 is not set # CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set CONFIG_NETDEV_1000=y CONFIG_NETDEV_10000=y CONFIG_WLAN=y -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +# CONFIG_HOSTAP is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers @@ -598,6 +628,7 @@ CONFIG_SLHC=y CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set # CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set # # Userland interfaces @@ -625,6 +656,7 @@ CONFIG_SERIO=y # CONFIG_SERIO_SERPORT is not set # CONFIG_SERIO_LIBPS2 is not set # CONFIG_SERIO_RAW is not set +# CONFIG_SERIO_ALTERA_PS2 is not set # CONFIG_GAMEPORT is not set # @@ -696,6 +728,7 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set # CONFIG_REGULATOR is not set @@ -765,6 +798,7 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XIP is not set # CONFIG_EXT3_FS is not set # CONFIG_EXT4_FS is not set +CONFIG_EXT4_USE_FOR_EXT23=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set @@ -809,7 +843,6 @@ CONFIG_PROC_SYSCTL=y CONFIG_PROC_PAGE_MONITOR=y # CONFIG_SYSFS is not set # CONFIG_TMPFS is not set -# CONFIG_HUGETLBFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_MISC_FILESYSTEMS=y # CONFIG_ADFS_FS is not set @@ -877,10 +910,11 @@ CONFIG_FRAME_WARN=1024 # CONFIG_UNUSED_SYMBOLS is not set # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_LATENCYTOP is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y @@ -893,7 +927,6 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set -# CONFIG_EARLY_SCIF_CONSOLE is not set # CONFIG_DWARF_UNWINDER is not set # @@ -901,7 +934,11 @@ CONFIG_HAVE_ARCH_KGDB=y # # CONFIG_KEYS is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" CONFIG_CRYPTO=y # diff --git a/arch/sh/configs/se7712_defconfig b/arch/sh/configs/se7712_defconfig index 1a43cfe..cfa5819 100644 --- a/arch/sh/configs/se7712_defconfig +++ b/arch/sh/configs/se7712_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31 -# Thu Sep 24 18:53:32 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 13:44:56 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -28,6 +28,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_DMA_NONCOHERENT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -60,6 +61,7 @@ CONFIG_BSD_PROCESS_ACCT=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -95,6 +97,7 @@ CONFIG_EVENTFD=y # CONFIG_SHMEM is not set CONFIG_AIO=y CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters @@ -113,6 +116,7 @@ CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -138,14 +142,41 @@ CONFIG_LBDAF=y # IO Schedulers # CONFIG_IOSCHED_NOOP=y -# CONFIG_IOSCHED_AS is not set # CONFIG_IOSCHED_DEADLINE is not set # CONFIG_IOSCHED_CFQ is not set -# CONFIG_DEFAULT_AS is not set # CONFIG_DEFAULT_DEADLINE is not set # CONFIG_DEFAULT_CFQ is not set CONFIG_DEFAULT_NOOP=y CONFIG_DEFAULT_IOSCHED="noop" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +CONFIG_INLINE_SPIN_UNLOCK=y +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +CONFIG_INLINE_READ_UNLOCK=y +# CONFIG_INLINE_READ_UNLOCK_BH is not set +CONFIG_INLINE_READ_UNLOCK_IRQ=y +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +CONFIG_INLINE_WRITE_UNLOCK=y +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set # CONFIG_FREEZER is not set # @@ -221,8 +252,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -452,9 +481,6 @@ CONFIG_NET_SCH_FIFO=y CONFIG_FIB_RULES=y CONFIG_WIRELESS=y # CONFIG_CFG80211 is not set -CONFIG_CFG80211_DEFAULT_PS_VALUE=0 -# CONFIG_WIRELESS_OLD_REGULATORY is not set -# CONFIG_WIRELESS_EXT is not set # CONFIG_LIB80211 is not set # @@ -565,6 +591,10 @@ CONFIG_MTD_CFI_UTIL=y CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_RAM is not set # CONFIG_CDROM_PKTCDVD is not set @@ -675,11 +705,11 @@ CONFIG_SH_ETH=y # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set # CONFIG_B44 is not set # CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set CONFIG_NETDEV_1000=y CONFIG_NETDEV_10000=y CONFIG_WLAN=y -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +# CONFIG_HOSTAP is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers @@ -757,6 +787,7 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set # CONFIG_REGULATOR is not set @@ -888,7 +919,6 @@ CONFIG_PROC_FS=y CONFIG_PROC_SYSCTL=y CONFIG_PROC_PAGE_MONITOR=y CONFIG_SYSFS=y -# CONFIG_HUGETLBFS is not set # CONFIG_HUGETLB_PAGE is not set # CONFIG_CONFIGFS_FS is not set CONFIG_MISC_FILESYSTEMS=y @@ -1021,7 +1051,6 @@ CONFIG_BRANCH_PROFILE_NONE=y CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set # CONFIG_SH_STANDARD_BIOS is not set -# CONFIG_EARLY_SCIF_CONSOLE is not set # CONFIG_STACK_DEBUG is not set # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_4KSTACKS is not set @@ -1035,7 +1064,11 @@ CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" CONFIG_CRYPTO=y # diff --git a/arch/sh/configs/se7721_defconfig b/arch/sh/configs/se7721_defconfig index b8a3c8c..201283c 100644 --- a/arch/sh/configs/se7721_defconfig +++ b/arch/sh/configs/se7721_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31 -# Thu Sep 24 18:57:11 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 13:46:58 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -29,6 +29,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_DMA_NONCOHERENT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -61,6 +62,7 @@ CONFIG_BSD_PROCESS_ACCT=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -100,6 +102,7 @@ CONFIG_EVENTFD=y # CONFIG_SHMEM is not set CONFIG_AIO=y CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters @@ -118,6 +121,7 @@ CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -143,14 +147,41 @@ CONFIG_LBDAF=y # IO Schedulers # CONFIG_IOSCHED_NOOP=y -# CONFIG_IOSCHED_AS is not set # CONFIG_IOSCHED_DEADLINE is not set # CONFIG_IOSCHED_CFQ is not set -# CONFIG_DEFAULT_AS is not set # CONFIG_DEFAULT_DEADLINE is not set # CONFIG_DEFAULT_CFQ is not set CONFIG_DEFAULT_NOOP=y CONFIG_DEFAULT_IOSCHED="noop" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +CONFIG_INLINE_SPIN_UNLOCK=y +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +CONFIG_INLINE_READ_UNLOCK=y +# CONFIG_INLINE_READ_UNLOCK_BH is not set +CONFIG_INLINE_READ_UNLOCK_IRQ=y +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +CONFIG_INLINE_WRITE_UNLOCK=y +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set # CONFIG_FREEZER is not set # @@ -226,8 +257,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -457,9 +486,6 @@ CONFIG_NET_SCH_FIFO=y CONFIG_FIB_RULES=y CONFIG_WIRELESS=y # CONFIG_CFG80211 is not set -CONFIG_CFG80211_DEFAULT_PS_VALUE=0 -# CONFIG_WIRELESS_OLD_REGULATORY is not set -# CONFIG_WIRELESS_EXT is not set # CONFIG_LIB80211 is not set # @@ -570,6 +596,10 @@ CONFIG_MTD_CFI_UTIL=y CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_UB is not set # CONFIG_BLK_DEV_RAM is not set @@ -642,8 +672,8 @@ CONFIG_NETDEVICES=y CONFIG_NETDEV_1000=y CONFIG_NETDEV_10000=y CONFIG_WLAN=y -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +# CONFIG_USB_ZD1201 is not set +# CONFIG_HOSTAP is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers @@ -672,6 +702,7 @@ CONFIG_WLAN=y CONFIG_INPUT=y CONFIG_INPUT_FF_MEMLESS=m # CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set # # Userland interfaces @@ -765,6 +796,7 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set # CONFIG_REGULATOR is not set @@ -1029,7 +1061,6 @@ CONFIG_PROC_FS=y CONFIG_PROC_SYSCTL=y CONFIG_PROC_PAGE_MONITOR=y CONFIG_SYSFS=y -# CONFIG_HUGETLBFS is not set # CONFIG_HUGETLB_PAGE is not set # CONFIG_CONFIGFS_FS is not set CONFIG_MISC_FILESYSTEMS=y @@ -1186,7 +1217,6 @@ CONFIG_BRANCH_PROFILE_NONE=y CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set # CONFIG_SH_STANDARD_BIOS is not set -# CONFIG_EARLY_SCIF_CONSOLE is not set # CONFIG_STACK_DEBUG is not set # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_4KSTACKS is not set @@ -1200,7 +1230,11 @@ CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" CONFIG_CRYPTO=y # diff --git a/arch/sh/configs/se7722_defconfig b/arch/sh/configs/se7722_defconfig index d709b7f..4a4efd2 100644 --- a/arch/sh/configs/se7722_defconfig +++ b/arch/sh/configs/se7722_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31 -# Thu Sep 24 18:57:41 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 13:49:15 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_SYS_SUPPORTS_HUGETLBFS=y CONFIG_SYS_SUPPORTS_NUMA=y CONFIG_SYS_SUPPORTS_CMT=y CONFIG_SYS_SUPPORTS_TMU=y @@ -31,6 +32,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_DMA_NONCOHERENT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -63,6 +65,7 @@ CONFIG_BSD_PROCESS_ACCT=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -102,6 +105,7 @@ CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters @@ -122,6 +126,7 @@ CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -149,14 +154,41 @@ CONFIG_LBDAF=y # IO Schedulers # CONFIG_IOSCHED_NOOP=y -# CONFIG_IOSCHED_AS is not set # CONFIG_IOSCHED_DEADLINE is not set # CONFIG_IOSCHED_CFQ is not set -# CONFIG_DEFAULT_AS is not set # CONFIG_DEFAULT_DEADLINE is not set # CONFIG_DEFAULT_CFQ is not set CONFIG_DEFAULT_NOOP=y CONFIG_DEFAULT_IOSCHED="noop" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +# CONFIG_INLINE_SPIN_UNLOCK is not set +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +# CONFIG_INLINE_READ_UNLOCK is not set +# CONFIG_INLINE_READ_UNLOCK_BH is not set +# CONFIG_INLINE_READ_UNLOCK_IRQ is not set +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +# CONFIG_INLINE_WRITE_UNLOCK is not set +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set CONFIG_FREEZER=y # @@ -248,8 +280,6 @@ CONFIG_MIGRATION=y # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -284,7 +314,6 @@ CONFIG_SH_7722_SOLUTION_ENGINE=y # CONFIG_SH_TIMER_TMU=y # CONFIG_SH_TIMER_CMT is not set -CONFIG_SH_PCLK_FREQ=33333333 CONFIG_SH_CLK_CPG=y CONFIG_TICK_ONESHOT=y CONFIG_NO_HZ=y @@ -436,9 +465,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_AF_RXRPC is not set CONFIG_WIRELESS=y # CONFIG_CFG80211 is not set -CONFIG_CFG80211_DEFAULT_PS_VALUE=0 -# CONFIG_WIRELESS_OLD_REGULATORY is not set -# CONFIG_WIRELESS_EXT is not set # CONFIG_LIB80211 is not set # @@ -467,6 +493,10 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# # CONFIG_BLK_DEV_NBD is not set CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 @@ -560,11 +590,11 @@ CONFIG_SMC91X=y # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set # CONFIG_B44 is not set # CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set CONFIG_NETDEV_1000=y CONFIG_NETDEV_10000=y CONFIG_WLAN=y -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +# CONFIG_HOSTAP is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers @@ -584,6 +614,7 @@ CONFIG_WLAN=y CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set # CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set # # Userland interfaces @@ -622,6 +653,7 @@ CONFIG_SERIO=y # CONFIG_SERIO_SERPORT is not set CONFIG_SERIO_LIBPS2=y # CONFIG_SERIO_RAW is not set +# CONFIG_SERIO_ALTERA_PS2 is not set # CONFIG_GAMEPORT is not set # @@ -694,6 +726,7 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set # CONFIG_REGULATOR is not set @@ -774,7 +807,9 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_M48T86 is not set # CONFIG_RTC_DRV_M48T35 is not set # CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set # CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set # CONFIG_RTC_DRV_V3020 is not set # @@ -906,7 +941,7 @@ CONFIG_DEBUG_FS=y # CONFIG_DEBUG_KERNEL is not set # CONFIG_SLUB_DEBUG_ON is not set # CONFIG_SLUB_STATS is not set -# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_LATENCYTOP is not set @@ -924,8 +959,6 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y CONFIG_SH_STANDARD_BIOS=y -# CONFIG_EARLY_SCIF_CONSOLE is not set -# CONFIG_EARLY_PRINTK is not set # CONFIG_DWARF_UNWINDER is not set # @@ -934,7 +967,11 @@ CONFIG_SH_STANDARD_BIOS=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" CONFIG_CRYPTO=y # diff --git a/arch/sh/configs/se7724_defconfig b/arch/sh/configs/se7724_defconfig index 56b0b9f..ab371af 100644 --- a/arch/sh/configs/se7724_defconfig +++ b/arch/sh/configs/se7724_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31 -# Fri Sep 25 11:50:59 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 14:36:56 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_SYS_SUPPORTS_HUGETLBFS=y CONFIG_SYS_SUPPORTS_CMT=y CONFIG_SYS_SUPPORTS_TMU=y CONFIG_STACKTRACE_SUPPORT=y @@ -30,6 +31,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_DMA_NONCOHERENT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -62,6 +64,7 @@ CONFIG_BSD_PROCESS_ACCT=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -99,6 +102,7 @@ CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters @@ -116,6 +120,7 @@ CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -142,14 +147,41 @@ CONFIG_LBDAF=y # IO Schedulers # CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y -# CONFIG_DEFAULT_AS is not set # CONFIG_DEFAULT_DEADLINE is not set CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +# CONFIG_INLINE_SPIN_UNLOCK is not set +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +# CONFIG_INLINE_READ_UNLOCK is not set +# CONFIG_INLINE_READ_UNLOCK_BH is not set +# CONFIG_INLINE_READ_UNLOCK_IRQ is not set +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +# CONFIG_INLINE_WRITE_UNLOCK is not set +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set CONFIG_FREEZER=y # @@ -205,6 +237,7 @@ CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_MEMORY_START=0x08000000 CONFIG_MEMORY_SIZE=0x08000000 CONFIG_29BIT=y +# CONFIG_PMB_ENABLE is not set # CONFIG_X2TLB is not set CONFIG_VSYSCALL=y CONFIG_ARCH_FLATMEM_ENABLE=y @@ -229,8 +262,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -265,7 +296,6 @@ CONFIG_SH_7724_SOLUTION_ENGINE=y # CONFIG_SH_TIMER_TMU=y # CONFIG_SH_TIMER_CMT is not set -CONFIG_SH_PCLK_FREQ=33333333 CONFIG_SH_CLK_CPG=y # CONFIG_NO_HZ is not set # CONFIG_HIGH_RES_TIMERS is not set @@ -279,8 +309,8 @@ CONFIG_GENERIC_CLOCKEVENTS_BUILD=y # # DMA support # -CONFIG_SH_DMA_API=y CONFIG_SH_DMA=y +CONFIG_SH_DMA_API=y CONFIG_NR_ONCHIP_DMA_CHANNELS=12 # CONFIG_NR_DMA_CHANNELS_BOOL is not set @@ -423,9 +453,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_AF_RXRPC is not set CONFIG_WIRELESS=y # CONFIG_CFG80211 is not set -CONFIG_CFG80211_DEFAULT_PS_VALUE=0 -# CONFIG_WIRELESS_OLD_REGULATORY is not set -# CONFIG_WIRELESS_EXT is not set # CONFIG_LIB80211 is not set # @@ -555,6 +582,10 @@ CONFIG_MTD_UBI_BEB_RESERVE=1 CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_UB is not set CONFIG_BLK_DEV_RAM=y @@ -565,9 +596,12 @@ CONFIG_BLK_DEV_RAM_SIZE=4096 # CONFIG_ATA_OVER_ETH is not set # CONFIG_BLK_DEV_HD is not set CONFIG_MISC_DEVICES=y +# CONFIG_AD525X_DPOT is not set # CONFIG_ICS932S401 is not set # CONFIG_ENCLOSURE_SERVICES is not set # CONFIG_ISL29003 is not set +# CONFIG_DS1682 is not set +# CONFIG_TI_DAC7512 is not set # CONFIG_C2PORT is not set # @@ -578,6 +612,7 @@ CONFIG_MISC_DEVICES=y # CONFIG_EEPROM_LEGACY is not set # CONFIG_EEPROM_MAX6875 is not set # CONFIG_EEPROM_93CX6 is not set +# CONFIG_IWMC3200TOP is not set CONFIG_HAVE_IDE=y # CONFIG_IDE is not set @@ -672,11 +707,12 @@ CONFIG_SMC91X=y # CONFIG_B44 is not set # CONFIG_KS8842 is not set # CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set CONFIG_WLAN=y -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +# CONFIG_USB_ZD1201 is not set +# CONFIG_HOSTAP is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers @@ -705,6 +741,7 @@ CONFIG_WLAN=y CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set # CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set # # Userland interfaces @@ -813,7 +850,6 @@ CONFIG_I2C_SH_MOBILE=y # # Miscellaneous I2C Chip support # -# CONFIG_DS1682 is not set # CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set @@ -827,7 +863,10 @@ CONFIG_SPI_MASTER=y # CONFIG_SPI_BITBANG=y # CONFIG_SPI_GPIO is not set +# CONFIG_SPI_SH_MSIOF is not set # CONFIG_SPI_SH_SCI is not set +# CONFIG_SPI_XILINX is not set +# CONFIG_SPI_DESIGNWARE is not set # # SPI Protocol Masters @@ -885,11 +924,13 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_TPS65010 is not set # CONFIG_TWL4030_CORE is not set # CONFIG_MFD_TMIO is not set # CONFIG_PMIC_DA903X is not set +# CONFIG_PMIC_ADP5520 is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set @@ -897,6 +938,8 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_MC13783 is not set # CONFIG_AB3100_CORE is not set # CONFIG_EZX_PCAP is not set +# CONFIG_MFD_88PM8607 is not set +# CONFIG_AB4500_CORE is not set # CONFIG_REGULATOR is not set CONFIG_MEDIA_SUPPORT=y @@ -913,6 +956,8 @@ CONFIG_VIDEO_MEDIA=m # # Multimedia drivers # +CONFIG_IR_CORE=y +CONFIG_VIDEO_IR=y # CONFIG_MEDIA_ATTACH is not set CONFIG_MEDIA_TUNER=m # CONFIG_MEDIA_TUNER_CUSTOMISE is not set @@ -932,6 +977,7 @@ CONFIG_VIDEO_CAPTURE_DRIVERS=y # CONFIG_VIDEO_ADV_DEBUG is not set # CONFIG_VIDEO_FIXED_MINOR_RANGES is not set CONFIG_VIDEO_HELPER_CHIPS_AUTO=y +CONFIG_VIDEO_IR_I2C=y # CONFIG_VIDEO_VIVI is not set # CONFIG_VIDEO_SAA5246A is not set # CONFIG_VIDEO_SAA5249 is not set @@ -940,10 +986,13 @@ CONFIG_SOC_CAMERA=y # CONFIG_SOC_CAMERA_MT9M001 is not set # CONFIG_SOC_CAMERA_MT9M111 is not set # CONFIG_SOC_CAMERA_MT9T031 is not set +# CONFIG_SOC_CAMERA_MT9T112 is not set # CONFIG_SOC_CAMERA_MT9V022 is not set +# CONFIG_SOC_CAMERA_RJ54N1 is not set # CONFIG_SOC_CAMERA_TW9910 is not set # CONFIG_SOC_CAMERA_PLATFORM is not set CONFIG_SOC_CAMERA_OV772X=y +# CONFIG_SOC_CAMERA_OV9640 is not set CONFIG_VIDEO_SH_MOBILE_CEU=y CONFIG_V4L_USB_DRIVERS=y # CONFIG_USB_VIDEO_CLASS is not set @@ -961,6 +1010,7 @@ CONFIG_USB_GSPCA=m # CONFIG_USB_GSPCA_OV519 is not set # CONFIG_USB_GSPCA_OV534 is not set # CONFIG_USB_GSPCA_PAC207 is not set +# CONFIG_USB_GSPCA_PAC7302 is not set # CONFIG_USB_GSPCA_PAC7311 is not set # CONFIG_USB_GSPCA_SN9C20X is not set # CONFIG_USB_GSPCA_SONIXB is not set @@ -974,6 +1024,7 @@ CONFIG_USB_GSPCA=m # CONFIG_USB_GSPCA_SQ905 is not set # CONFIG_USB_GSPCA_SQ905C is not set # CONFIG_USB_GSPCA_STK014 is not set +# CONFIG_USB_GSPCA_STV0680 is not set # CONFIG_USB_GSPCA_SUNPLUS is not set # CONFIG_USB_GSPCA_T613 is not set # CONFIG_USB_GSPCA_TV8532 is not set @@ -1110,9 +1161,11 @@ CONFIG_SND_SOC_WM_HUBS=m CONFIG_SND_SOC_AD1836=m CONFIG_SND_SOC_AD1938=m CONFIG_SND_SOC_AD73311=m +CONFIG_SND_SOC_ADS117X=m CONFIG_SND_SOC_AK4104=m CONFIG_SND_SOC_AK4535=m CONFIG_SND_SOC_AK4642=m +CONFIG_SND_SOC_AK4671=m CONFIG_SND_SOC_CS4270=m CONFIG_SND_SOC_L3=m CONFIG_SND_SOC_PCM3008=m @@ -1121,11 +1174,14 @@ CONFIG_SND_SOC_SSM2602=m CONFIG_SND_SOC_TLV320AIC23=m CONFIG_SND_SOC_TLV320AIC26=m CONFIG_SND_SOC_TLV320AIC3X=m +CONFIG_SND_SOC_TLV320DAC33=m CONFIG_SND_SOC_UDA134X=m CONFIG_SND_SOC_UDA1380=m CONFIG_SND_SOC_WM8510=m CONFIG_SND_SOC_WM8523=m CONFIG_SND_SOC_WM8580=m +CONFIG_SND_SOC_WM8711=m +CONFIG_SND_SOC_WM8727=m CONFIG_SND_SOC_WM8728=m CONFIG_SND_SOC_WM8731=m CONFIG_SND_SOC_WM8750=m @@ -1143,6 +1199,7 @@ CONFIG_SND_SOC_WM8990=m CONFIG_SND_SOC_WM8993=m CONFIG_SND_SOC_WM9081=m CONFIG_SND_SOC_MAX9877=m +CONFIG_SND_SOC_TPA6130A2=m # CONFIG_SOUND_PRIME is not set CONFIG_HID_SUPPORT=y CONFIG_HID=y @@ -1316,10 +1373,12 @@ CONFIG_USB_ETH_RNDIS=y CONFIG_USB_GADGETFS=m CONFIG_USB_FILE_STORAGE=m # CONFIG_USB_FILE_STORAGE_TEST is not set +# CONFIG_USB_MASS_STORAGE is not set CONFIG_USB_G_SERIAL=m # CONFIG_USB_MIDI_GADGET is not set # CONFIG_USB_G_PRINTER is not set # CONFIG_USB_CDC_COMPOSITE is not set +# CONFIG_USB_G_MULTI is not set # # OTG and related infrastructure @@ -1345,6 +1404,7 @@ CONFIG_MMC_BLOCK_BOUNCE=y # CONFIG_MMC_AT91 is not set # CONFIG_MMC_ATMELMCI is not set CONFIG_MMC_SPI=y +# CONFIG_MMC_TMIO is not set # CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set # CONFIG_ACCESSIBILITY is not set @@ -1376,6 +1436,7 @@ CONFIG_RTC_INTF_DEV=y CONFIG_RTC_DRV_PCF8563=y # CONFIG_RTC_DRV_PCF8583 is not set # CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set # CONFIG_RTC_DRV_S35390A is not set # CONFIG_RTC_DRV_FM3130 is not set # CONFIG_RTC_DRV_RX8581 is not set @@ -1404,7 +1465,9 @@ CONFIG_RTC_DRV_PCF8563=y # CONFIG_RTC_DRV_M48T86 is not set # CONFIG_RTC_DRV_M48T35 is not set # CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set # CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set # CONFIG_RTC_DRV_V3020 is not set # @@ -1597,7 +1660,7 @@ CONFIG_FRAME_WARN=1024 # CONFIG_DEBUG_FS is not set # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_LATENCYTOP is not set @@ -1614,7 +1677,6 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set -# CONFIG_EARLY_SCIF_CONSOLE is not set # CONFIG_DWARF_UNWINDER is not set # @@ -1623,7 +1685,11 @@ CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" CONFIG_CRYPTO=y # diff --git a/arch/sh/configs/se7750_defconfig b/arch/sh/configs/se7750_defconfig index 7bc926c..b15a44e 100644 --- a/arch/sh/configs/se7750_defconfig +++ b/arch/sh/configs/se7750_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31 -# Thu Sep 24 18:58:58 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 14:39:10 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y # CONFIG_ARCH_SUSPEND_POSSIBLE is not set CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_SYS_SUPPORTS_HUGETLBFS=y CONFIG_SYS_SUPPORTS_TMU=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_LOCKDEP_SUPPORT=y @@ -29,6 +30,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_DMA_NONCOHERENT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -60,6 +62,7 @@ CONFIG_BSD_PROCESS_ACCT=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -95,6 +98,7 @@ CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters @@ -113,6 +117,7 @@ CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -138,14 +143,41 @@ CONFIG_LBDAF=y # IO Schedulers # CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +CONFIG_INLINE_SPIN_UNLOCK=y +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +CONFIG_INLINE_READ_UNLOCK=y +# CONFIG_INLINE_READ_UNLOCK_BH is not set +CONFIG_INLINE_READ_UNLOCK_IRQ=y +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +CONFIG_INLINE_WRITE_UNLOCK=y +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set # CONFIG_FREEZER is not set # @@ -221,8 +253,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -307,7 +337,6 @@ CONFIG_GUSA=y CONFIG_ZERO_PAGE_OFFSET=0x00001000 CONFIG_BOOT_LINK_OFFSET=0x00800000 CONFIG_ENTRY_OFFSET=0x00001000 -# CONFIG_UBC_WAKEUP is not set # CONFIG_CMDLINE_OVERWRITE is not set # CONFIG_CMDLINE_EXTEND is not set @@ -406,9 +435,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_AF_RXRPC is not set CONFIG_WIRELESS=y # CONFIG_CFG80211 is not set -CONFIG_CFG80211_DEFAULT_PS_VALUE=0 -# CONFIG_WIRELESS_OLD_REGULATORY is not set -# CONFIG_WIRELESS_EXT is not set # CONFIG_LIB80211 is not set # @@ -513,6 +539,10 @@ CONFIG_MTD_ROM=y CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_RAM is not set # CONFIG_CDROM_PKTCDVD is not set @@ -615,11 +645,11 @@ CONFIG_STNIC=y # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set # CONFIG_B44 is not set # CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set CONFIG_NETDEV_1000=y CONFIG_NETDEV_10000=y CONFIG_WLAN=y -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +# CONFIG_HOSTAP is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers @@ -726,6 +756,7 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set # CONFIG_REGULATOR is not set @@ -785,6 +816,7 @@ CONFIG_RTC_LIB=y # CONFIG_EXT2_FS is not set # CONFIG_EXT3_FS is not set # CONFIG_EXT4_FS is not set +CONFIG_EXT4_USE_FOR_EXT23=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set @@ -914,10 +946,11 @@ CONFIG_FRAME_WARN=1024 # CONFIG_DEBUG_FS is not set # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_LATENCYTOP is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y @@ -930,7 +963,6 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set -# CONFIG_EARLY_SCIF_CONSOLE is not set # CONFIG_DWARF_UNWINDER is not set # @@ -939,7 +971,11 @@ CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" CONFIG_CRYPTO=y # diff --git a/arch/sh/configs/se7751_defconfig b/arch/sh/configs/se7751_defconfig index c20ae5e..d1effde 100644 --- a/arch/sh/configs/se7751_defconfig +++ b/arch/sh/configs/se7751_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31 -# Thu Sep 24 19:01:41 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 14:39:56 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y # CONFIG_ARCH_SUSPEND_POSSIBLE is not set CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_SYS_SUPPORTS_HUGETLBFS=y CONFIG_SYS_SUPPORTS_TMU=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_LOCKDEP_SUPPORT=y @@ -29,6 +30,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_DMA_NONCOHERENT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -60,6 +62,7 @@ CONFIG_BSD_PROCESS_ACCT=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -98,6 +101,7 @@ CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters @@ -116,6 +120,7 @@ CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -141,14 +146,41 @@ CONFIG_LBDAF=y # IO Schedulers # CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +CONFIG_INLINE_SPIN_UNLOCK=y +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +CONFIG_INLINE_READ_UNLOCK=y +# CONFIG_INLINE_READ_UNLOCK_BH is not set +CONFIG_INLINE_READ_UNLOCK_IRQ=y +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +CONFIG_INLINE_WRITE_UNLOCK=y +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set # CONFIG_FREEZER is not set # @@ -224,8 +256,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -311,7 +341,6 @@ CONFIG_GUSA=y CONFIG_ZERO_PAGE_OFFSET=0x00010000 CONFIG_BOOT_LINK_OFFSET=0x00800000 CONFIG_ENTRY_OFFSET=0x00001000 -# CONFIG_UBC_WAKEUP is not set CONFIG_CMDLINE_OVERWRITE=y # CONFIG_CMDLINE_EXTEND is not set CONFIG_CMDLINE="console=ttySC1,38400" @@ -430,9 +459,6 @@ CONFIG_IP_NF_QUEUE=y # CONFIG_AF_RXRPC is not set CONFIG_WIRELESS=y # CONFIG_CFG80211 is not set -CONFIG_CFG80211_DEFAULT_PS_VALUE=0 -# CONFIG_WIRELESS_OLD_REGULATORY is not set -# CONFIG_WIRELESS_EXT is not set # CONFIG_LIB80211 is not set # @@ -537,6 +563,10 @@ CONFIG_MTD_RAM=y CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# # CONFIG_BLK_DEV_NBD is not set CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 @@ -591,11 +621,11 @@ CONFIG_MII=y # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set # CONFIG_B44 is not set # CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set CONFIG_NETDEV_1000=y CONFIG_NETDEV_10000=y CONFIG_WLAN=y -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +# CONFIG_HOSTAP is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers @@ -693,6 +723,7 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set # CONFIG_REGULATOR is not set @@ -754,6 +785,7 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XIP is not set # CONFIG_EXT3_FS is not set # CONFIG_EXT4_FS is not set +CONFIG_EXT4_USE_FOR_EXT23=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set @@ -863,10 +895,11 @@ CONFIG_FRAME_WARN=1024 # CONFIG_DEBUG_FS is not set # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_LATENCYTOP is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y @@ -879,7 +912,6 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set -# CONFIG_EARLY_SCIF_CONSOLE is not set # CONFIG_DWARF_UNWINDER is not set # @@ -888,7 +920,11 @@ CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" CONFIG_CRYPTO=y # diff --git a/arch/sh/configs/se7780_defconfig b/arch/sh/configs/se7780_defconfig index 82baeef..58533d5 100644 --- a/arch/sh/configs/se7780_defconfig +++ b/arch/sh/configs/se7780_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31 -# Thu Sep 24 19:03:59 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 14:40:32 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y # CONFIG_ARCH_SUSPEND_POSSIBLE is not set CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_SYS_SUPPORTS_HUGETLBFS=y CONFIG_SYS_SUPPORTS_PCI=y CONFIG_SYS_SUPPORTS_TMU=y CONFIG_STACKTRACE_SUPPORT=y @@ -30,6 +31,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_DMA_NONCOHERENT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -59,6 +61,7 @@ CONFIG_SYSVIPC_SYSCTL=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -92,6 +95,7 @@ CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters @@ -110,6 +114,7 @@ CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -136,14 +141,41 @@ CONFIG_BLK_DEV_BSG=y # IO Schedulers # CONFIG_IOSCHED_NOOP=y -# CONFIG_IOSCHED_AS is not set CONFIG_IOSCHED_DEADLINE=y # CONFIG_IOSCHED_CFQ is not set -# CONFIG_DEFAULT_AS is not set CONFIG_DEFAULT_DEADLINE=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="deadline" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +CONFIG_INLINE_SPIN_UNLOCK=y +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +CONFIG_INLINE_READ_UNLOCK=y +# CONFIG_INLINE_READ_UNLOCK_BH is not set +CONFIG_INLINE_READ_UNLOCK_IRQ=y +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +CONFIG_INLINE_WRITE_UNLOCK=y +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set # CONFIG_FREEZER is not set # @@ -222,8 +254,6 @@ CONFIG_MIGRATION=y # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -313,7 +343,6 @@ CONFIG_CMDLINE="console=ttySC0,115200 root=/dev/sda1" # Bus options # CONFIG_PCI=y -CONFIG_SH_PCIDMA_NONCOHERENT=y # CONFIG_PCIEPORTBUS is not set # CONFIG_ARCH_SUPPORTS_MSI is not set CONFIG_PCI_LEGACY=y @@ -401,9 +430,6 @@ CONFIG_IPV6=y # CONFIG_BT is not set CONFIG_WIRELESS=y # CONFIG_CFG80211 is not set -CONFIG_CFG80211_DEFAULT_PS_VALUE=0 -# CONFIG_WIRELESS_OLD_REGULATORY is not set -# CONFIG_WIRELESS_EXT is not set # CONFIG_LIB80211 is not set # @@ -517,6 +543,10 @@ CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_CRYPTOLOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_SX8 is not set # CONFIG_BLK_DEV_UB is not set @@ -574,8 +604,11 @@ CONFIG_SCSI_WAIT_SCAN=m CONFIG_SCSI_LOWLEVEL=y # CONFIG_ISCSI_TCP is not set # CONFIG_SCSI_BNX2_ISCSI is not set +# CONFIG_BE2ISCSI is not set # CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_HPSA is not set # CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_3W_SAS is not set # CONFIG_SCSI_ACARD is not set # CONFIG_SCSI_AACRAID is not set # CONFIG_SCSI_AIC7XXX is not set @@ -608,7 +641,9 @@ CONFIG_SCSI_LOWLEVEL=y # CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set # CONFIG_SCSI_PMCRAID is not set +# CONFIG_SCSI_PM8001 is not set # CONFIG_SCSI_SRP is not set +# CONFIG_SCSI_BFA_FC is not set # CONFIG_SCSI_DH is not set # CONFIG_SCSI_OSD_INITIATOR is not set CONFIG_ATA=y @@ -642,6 +677,8 @@ CONFIG_SATA_SIL=y # CONFIG_PATA_EFAR is not set # CONFIG_ATA_GENERIC is not set # CONFIG_PATA_HPT366 is not set +# CONFIG_PATA_HPT37X is not set +# CONFIG_PATA_HPT3X2N is not set # CONFIG_PATA_HPT3X3 is not set # CONFIG_PATA_IT821X is not set # CONFIG_PATA_JMICRON is not set @@ -650,14 +687,15 @@ CONFIG_SATA_SIL=y # CONFIG_PATA_MPIIX is not set # CONFIG_PATA_OLDPIIX is not set # CONFIG_PATA_NETCELL is not set +# CONFIG_PATA_NINJA32 is not set # CONFIG_PATA_NS87410 is not set # CONFIG_PATA_NS87415 is not set +# CONFIG_PATA_PDC2027X is not set # CONFIG_PATA_PDC_OLD is not set # CONFIG_PATA_RDC is not set # CONFIG_PATA_RZ1000 is not set # CONFIG_PATA_SC1200 is not set # CONFIG_PATA_SERVERWORKS is not set -# CONFIG_PATA_PDC2027X is not set # CONFIG_PATA_SIL680 is not set # CONFIG_PATA_SIS is not set # CONFIG_PATA_VIA is not set @@ -748,14 +786,16 @@ CONFIG_NET_PCI=y # CONFIG_SUNDANCE is not set # CONFIG_TLAN is not set # CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set # CONFIG_VIA_RHINE is not set # CONFIG_ATL2 is not set # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set # CONFIG_TR is not set CONFIG_WLAN=y -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +# CONFIG_ATMEL is not set +# CONFIG_USB_ZD1201 is not set +# CONFIG_HOSTAP is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers @@ -774,6 +814,7 @@ CONFIG_WLAN=y # CONFIG_NET_FC is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_VMXNET3 is not set # CONFIG_ISDN is not set # CONFIG_PHONE is not set @@ -783,6 +824,7 @@ CONFIG_WLAN=y CONFIG_INPUT=y CONFIG_INPUT_FF_MEMLESS=m # CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set # # Userland interfaces @@ -883,6 +925,7 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set # CONFIG_REGULATOR is not set @@ -1149,6 +1192,7 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XIP is not set # CONFIG_EXT3_FS is not set # CONFIG_EXT4_FS is not set +CONFIG_EXT4_USE_FOR_EXT23=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set @@ -1285,7 +1329,7 @@ CONFIG_FRAME_WARN=1024 CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_LATENCYTOP is not set @@ -1303,7 +1347,6 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set -# CONFIG_EARLY_SCIF_CONSOLE is not set # CONFIG_DWARF_UNWINDER is not set # @@ -1312,7 +1355,11 @@ CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" CONFIG_CRYPTO=y # diff --git a/arch/sh/configs/sh03_defconfig b/arch/sh/configs/sh03_defconfig index dd0e890..666fde1 100644 --- a/arch/sh/configs/sh03_defconfig +++ b/arch/sh/configs/sh03_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31 -# Thu Sep 24 19:07:14 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 14:41:25 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -21,6 +21,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_CMOS_UPDATE=y # CONFIG_ARCH_SUSPEND_POSSIBLE is not set CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_SYS_SUPPORTS_HUGETLBFS=y CONFIG_SYS_SUPPORTS_PCI=y CONFIG_SYS_SUPPORTS_TMU=y CONFIG_STACKTRACE_SUPPORT=y @@ -31,6 +32,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_DMA_NONCOHERENT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -64,6 +66,7 @@ CONFIG_BSD_PROCESS_ACCT=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -102,6 +105,7 @@ CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters @@ -124,6 +128,7 @@ CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -151,14 +156,41 @@ CONFIG_LBDAF=y # IO Schedulers # CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +# CONFIG_INLINE_SPIN_UNLOCK is not set +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +# CONFIG_INLINE_READ_UNLOCK is not set +# CONFIG_INLINE_READ_UNLOCK_BH is not set +# CONFIG_INLINE_READ_UNLOCK_IRQ is not set +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +# CONFIG_INLINE_WRITE_UNLOCK is not set +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set # CONFIG_FREEZER is not set # @@ -234,8 +266,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -320,7 +350,6 @@ CONFIG_GUSA=y CONFIG_ZERO_PAGE_OFFSET=0x00004000 CONFIG_BOOT_LINK_OFFSET=0x00800000 CONFIG_ENTRY_OFFSET=0x00001000 -# CONFIG_UBC_WAKEUP is not set CONFIG_CMDLINE_OVERWRITE=y # CONFIG_CMDLINE_EXTEND is not set CONFIG_CMDLINE="console=ttySC1,115200 mem=64M root=/dev/nfs" @@ -329,7 +358,6 @@ CONFIG_CMDLINE="console=ttySC1,115200 mem=64M root=/dev/nfs" # Bus options # CONFIG_PCI=y -CONFIG_SH_PCIDMA_NONCOHERENT=y # CONFIG_PCIEPORTBUS is not set # CONFIG_ARCH_SUPPORTS_MSI is not set CONFIG_PCI_LEGACY=y @@ -433,9 +461,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_AF_RXRPC is not set CONFIG_WIRELESS=y # CONFIG_CFG80211 is not set -CONFIG_CFG80211_DEFAULT_PS_VALUE=0 -# CONFIG_WIRELESS_OLD_REGULATORY is not set -# CONFIG_WIRELESS_EXT is not set # CONFIG_LIB80211 is not set # @@ -468,6 +493,10 @@ CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_CRYPTOLOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# CONFIG_BLK_DEV_NBD=y # CONFIG_BLK_DEV_SX8 is not set CONFIG_BLK_DEV_RAM=y @@ -580,8 +609,11 @@ CONFIG_SCSI_LOWLEVEL=y # CONFIG_ISCSI_TCP is not set # CONFIG_SCSI_CXGB3_ISCSI is not set # CONFIG_SCSI_BNX2_ISCSI is not set +# CONFIG_BE2ISCSI is not set # CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_HPSA is not set # CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_3W_SAS is not set # CONFIG_SCSI_ACARD is not set # CONFIG_SCSI_AACRAID is not set # CONFIG_SCSI_AIC7XXX is not set @@ -614,7 +646,9 @@ CONFIG_SCSI_LOWLEVEL=y # CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set # CONFIG_SCSI_PMCRAID is not set +# CONFIG_SCSI_PM8001 is not set # CONFIG_SCSI_SRP is not set +# CONFIG_SCSI_BFA_FC is not set # CONFIG_SCSI_DH is not set # CONFIG_SCSI_OSD_INITIATOR is not set # CONFIG_ATA is not set @@ -685,6 +719,7 @@ CONFIG_8139CP=y # CONFIG_SUNDANCE is not set # CONFIG_TLAN is not set # CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set # CONFIG_VIA_RHINE is not set # CONFIG_SC92031 is not set # CONFIG_ATL2 is not set @@ -733,8 +768,9 @@ CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_BE2NET is not set # CONFIG_TR is not set CONFIG_WLAN=y -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +# CONFIG_ATMEL is not set +# CONFIG_PRISM54 is not set +# CONFIG_HOSTAP is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers @@ -748,6 +784,7 @@ CONFIG_WLAN=y # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_VMXNET3 is not set # CONFIG_ISDN is not set # CONFIG_PHONE is not set @@ -757,6 +794,7 @@ CONFIG_WLAN=y CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set # CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set # # Userland interfaces @@ -886,6 +924,7 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set # CONFIG_REGULATOR is not set @@ -1149,10 +1188,11 @@ CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set CONFIG_STACKTRACE=y -# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_LATENCYTOP is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set CONFIG_NOP_TRACER=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y @@ -1172,8 +1212,6 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y CONFIG_SH_STANDARD_BIOS=y -# CONFIG_EARLY_SCIF_CONSOLE is not set -# CONFIG_EARLY_PRINTK is not set # CONFIG_DWARF_UNWINDER is not set # @@ -1182,7 +1220,11 @@ CONFIG_SH_STANDARD_BIOS=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" CONFIG_CRYPTO=y # diff --git a/arch/sh/configs/sh7710voipgw_defconfig b/arch/sh/configs/sh7710voipgw_defconfig index 662156e..35a3bee 100644 --- a/arch/sh/configs/sh7710voipgw_defconfig +++ b/arch/sh/configs/sh7710voipgw_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31 -# Thu Sep 24 19:11:49 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 14:43:04 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -29,6 +29,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_DMA_NONCOHERENT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -60,6 +61,7 @@ CONFIG_POSIX_MQUEUE_SYSCTL=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -98,6 +100,7 @@ CONFIG_EVENTFD=y # CONFIG_SHMEM is not set CONFIG_AIO=y CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters @@ -116,6 +119,7 @@ CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -142,14 +146,41 @@ CONFIG_LBDAF=y # IO Schedulers # CONFIG_IOSCHED_NOOP=y -# CONFIG_IOSCHED_AS is not set CONFIG_IOSCHED_DEADLINE=y # CONFIG_IOSCHED_CFQ is not set -# CONFIG_DEFAULT_AS is not set CONFIG_DEFAULT_DEADLINE=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="deadline" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +CONFIG_INLINE_SPIN_UNLOCK=y +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +CONFIG_INLINE_READ_UNLOCK=y +# CONFIG_INLINE_READ_UNLOCK_BH is not set +CONFIG_INLINE_READ_UNLOCK_IRQ=y +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +CONFIG_INLINE_WRITE_UNLOCK=y +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set # CONFIG_FREEZER is not set # @@ -225,8 +256,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -460,9 +489,6 @@ CONFIG_NET_SCH_FIFO=y # CONFIG_AF_RXRPC is not set CONFIG_WIRELESS=y # CONFIG_CFG80211 is not set -CONFIG_CFG80211_DEFAULT_PS_VALUE=0 -# CONFIG_WIRELESS_OLD_REGULATORY is not set -# CONFIG_WIRELESS_EXT is not set # CONFIG_LIB80211 is not set # @@ -571,6 +597,10 @@ CONFIG_MTD_RAM=y CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_RAM is not set # CONFIG_CDROM_PKTCDVD is not set @@ -623,11 +653,11 @@ CONFIG_NET_ETHERNET=y # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set # CONFIG_B44 is not set # CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set CONFIG_NETDEV_1000=y CONFIG_NETDEV_10000=y CONFIG_WLAN=y -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +# CONFIG_HOSTAP is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers @@ -647,6 +677,7 @@ CONFIG_PHONE=y CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set # CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set # # Userland interfaces @@ -725,6 +756,7 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set # CONFIG_REGULATOR is not set @@ -792,6 +824,7 @@ CONFIG_RTC_LIB=y # CONFIG_EXT2_FS is not set # CONFIG_EXT3_FS is not set # CONFIG_EXT4_FS is not set +CONFIG_EXT4_USE_FOR_EXT23=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set @@ -836,7 +869,6 @@ CONFIG_PROC_FS=y CONFIG_PROC_SYSCTL=y CONFIG_PROC_PAGE_MONITOR=y CONFIG_SYSFS=y -# CONFIG_HUGETLBFS is not set # CONFIG_HUGETLB_PAGE is not set # CONFIG_CONFIGFS_FS is not set CONFIG_MISC_FILESYSTEMS=y @@ -899,10 +931,11 @@ CONFIG_FRAME_WARN=1024 CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_LATENCYTOP is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y @@ -916,7 +949,6 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set -# CONFIG_EARLY_SCIF_CONSOLE is not set # CONFIG_DWARF_UNWINDER is not set # @@ -925,7 +957,11 @@ CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" CONFIG_CRYPTO=y # diff --git a/arch/sh/configs/sh7724_generic_defconfig b/arch/sh/configs/sh7724_generic_defconfig index e06719a..a3056b6 100644 --- a/arch/sh/configs/sh7724_generic_defconfig +++ b/arch/sh/configs/sh7724_generic_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31 -# Thu Sep 24 19:14:00 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 15:03:45 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_SYS_SUPPORTS_HUGETLBFS=y CONFIG_SYS_SUPPORTS_CMT=y CONFIG_SYS_SUPPORTS_TMU=y CONFIG_STACKTRACE_SUPPORT=y @@ -30,6 +31,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_DMA_NONCOHERENT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -49,7 +51,6 @@ CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_LZMA is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y -CONFIG_SYSVIPC_SYSCTL=y # CONFIG_BSD_PROCESS_ACCT is not set # @@ -57,6 +58,7 @@ CONFIG_SYSVIPC_SYSCTL=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -80,11 +82,9 @@ CONFIG_CGROUPS=y # CONFIG_NAMESPACES is not set # CONFIG_BLK_DEV_INITRD is not set CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_SYSCTL=y CONFIG_ANON_INODES=y CONFIG_EMBEDDED=y # CONFIG_UID16 is not set -CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set CONFIG_HOTPLUG=y @@ -100,6 +100,7 @@ CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters @@ -120,6 +121,7 @@ CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -136,19 +138,48 @@ CONFIG_BLOCK=y CONFIG_LBDAF=y # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set +# CONFIG_BLK_CGROUP is not set # # IO Schedulers # CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y +# CONFIG_CFQ_GROUP_IOSCHED is not set # CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +CONFIG_INLINE_SPIN_UNLOCK=y +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +CONFIG_INLINE_READ_UNLOCK=y +# CONFIG_INLINE_READ_UNLOCK_BH is not set +CONFIG_INLINE_READ_UNLOCK_IRQ=y +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +CONFIG_INLINE_WRITE_UNLOCK=y +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set CONFIG_FREEZER=y # @@ -204,6 +235,7 @@ CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_MEMORY_START=0x08000000 CONFIG_MEMORY_SIZE=0x04000000 CONFIG_29BIT=y +# CONFIG_PMB_ENABLE is not set # CONFIG_X2TLB is not set CONFIG_VSYSCALL=y CONFIG_ARCH_FLATMEM_ENABLE=y @@ -225,17 +257,12 @@ CONFIG_SPARSEMEM_MANUAL=y CONFIG_SPARSEMEM=y CONFIG_HAVE_MEMORY_PRESENT=y CONFIG_SPARSEMEM_STATIC=y - -# -# Memory hotplug is currently incompatible with Software Suspend -# +# CONFIG_MEMORY_HOTPLUG is not set CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_MIGRATION=y # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -269,7 +296,6 @@ CONFIG_CPU_HAS_FPU=y # CONFIG_SH_TIMER_TMU=y CONFIG_SH_TIMER_CMT=y -CONFIG_SH_PCLK_FREQ=41666666 CONFIG_SH_CLK_CPG=y CONFIG_TICK_ONESHOT=y CONFIG_NO_HZ=y @@ -388,6 +414,10 @@ CONFIG_EXTRA_FIRMWARE="" CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# # CONFIG_BLK_DEV_RAM is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_BLK_DEV_HD is not set @@ -476,7 +506,6 @@ CONFIG_I2C_SH_MOBILE=y # # Miscellaneous I2C Chip support # -# CONFIG_DS1682 is not set # CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set @@ -505,15 +534,18 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_TWL4030_CORE is not set # CONFIG_MFD_TMIO is not set # CONFIG_PMIC_DA903X is not set +# CONFIG_PMIC_ADP5520 is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set # CONFIG_MFD_PCF50633 is not set # CONFIG_AB3100_CORE is not set +# CONFIG_MFD_88PM8607 is not set # CONFIG_REGULATOR is not set # CONFIG_MEDIA_SUPPORT is not set @@ -561,6 +593,7 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_PCF8563 is not set # CONFIG_RTC_DRV_PCF8583 is not set # CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set # CONFIG_RTC_DRV_S35390A is not set # CONFIG_RTC_DRV_FM3130 is not set # CONFIG_RTC_DRV_RX8581 is not set @@ -581,7 +614,9 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_M48T86 is not set # CONFIG_RTC_DRV_M48T35 is not set # CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set # CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set # CONFIG_RTC_DRV_V3020 is not set # @@ -608,6 +643,7 @@ CONFIG_UIO_PDRV_GENIRQ=y # CONFIG_EXT2_FS is not set # CONFIG_EXT3_FS is not set # CONFIG_EXT4_FS is not set +CONFIG_EXT4_USE_FOR_EXT23=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set @@ -675,11 +711,10 @@ CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set CONFIG_STACKTRACE=y -# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_LATENCYTOP is not set -# CONFIG_SYSCTL_SYSCALL_CHECK is not set CONFIG_NOP_TRACER=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y @@ -699,7 +734,6 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set -# CONFIG_EARLY_SCIF_CONSOLE is not set # CONFIG_DWARF_UNWINDER is not set # @@ -707,7 +741,11 @@ CONFIG_HAVE_ARCH_KGDB=y # # CONFIG_KEYS is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" # CONFIG_CRYPTO is not set CONFIG_BINARY_PRINTF=y diff --git a/arch/sh/configs/sh7763rdp_defconfig b/arch/sh/configs/sh7763rdp_defconfig index 194ff70..04b841b 100644 --- a/arch/sh/configs/sh7763rdp_defconfig +++ b/arch/sh/configs/sh7763rdp_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31 -# Thu Sep 24 19:15:37 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 15:05:29 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y # CONFIG_ARCH_SUSPEND_POSSIBLE is not set CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_SYS_SUPPORTS_HUGETLBFS=y CONFIG_SYS_SUPPORTS_TMU=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_LOCKDEP_SUPPORT=y @@ -29,6 +30,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_DMA_NONCOHERENT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -59,6 +61,7 @@ CONFIG_SYSVIPC_SYSCTL=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -103,6 +106,7 @@ CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters @@ -124,6 +128,7 @@ CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -150,14 +155,41 @@ CONFIG_LBDAF=y # IO Schedulers # CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +CONFIG_INLINE_SPIN_UNLOCK=y +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +CONFIG_INLINE_READ_UNLOCK=y +# CONFIG_INLINE_READ_UNLOCK_BH is not set +CONFIG_INLINE_READ_UNLOCK_IRQ=y +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +CONFIG_INLINE_WRITE_UNLOCK=y +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set # CONFIG_FREEZER is not set # @@ -211,6 +243,7 @@ CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_MEMORY_START=0x0c000000 CONFIG_MEMORY_SIZE=0x04000000 CONFIG_29BIT=y +# CONFIG_PMB_ENABLE is not set CONFIG_VSYSCALL=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_ARCH_SPARSEMEM_ENABLE=y @@ -237,8 +270,6 @@ CONFIG_MIGRATION=y # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -421,10 +452,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_AF_RXRPC is not set CONFIG_WIRELESS=y # CONFIG_CFG80211 is not set -CONFIG_CFG80211_DEFAULT_PS_VALUE=0 -# CONFIG_WIRELESS_OLD_REGULATORY is not set -CONFIG_WIRELESS_EXT=y -CONFIG_WIRELESS_EXT_SYSFS=y # CONFIG_LIB80211 is not set # @@ -509,7 +536,6 @@ CONFIG_MTD_CFI_UTIL=y CONFIG_MTD_COMPLEX_MAPPINGS=y CONFIG_MTD_PHYSMAP=y # CONFIG_MTD_PHYSMAP_COMPAT is not set -# CONFIG_MTD_GPIO_ADDR is not set # CONFIG_MTD_PLATRAM is not set # @@ -542,6 +568,10 @@ CONFIG_MTD_PHYSMAP=y CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_UB is not set # CONFIG_BLK_DEV_RAM is not set @@ -640,11 +670,12 @@ CONFIG_SH_ETH=y # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set # CONFIG_B44 is not set # CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set CONFIG_WLAN=y -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +# CONFIG_USB_ZD1201 is not set +# CONFIG_HOSTAP is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers @@ -673,6 +704,7 @@ CONFIG_WLAN=y CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set # CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set # # Userland interfaces @@ -756,6 +788,7 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set # CONFIG_REGULATOR is not set @@ -949,6 +982,7 @@ CONFIG_MMC_BLOCK_BOUNCE=y # CONFIG_MMC_SDHCI is not set # CONFIG_MMC_AT91 is not set # CONFIG_MMC_ATMELMCI is not set +# CONFIG_MMC_TMIO is not set # CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set # CONFIG_ACCESSIBILITY is not set @@ -1129,10 +1163,11 @@ CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set CONFIG_STACKTRACE=y -# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_LATENCYTOP is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set CONFIG_NOP_TRACER=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y @@ -1152,7 +1187,6 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set -# CONFIG_EARLY_SCIF_CONSOLE is not set # CONFIG_DWARF_UNWINDER is not set # @@ -1161,7 +1195,11 @@ CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" CONFIG_CRYPTO=y # diff --git a/arch/sh/configs/sh7770_generic_defconfig b/arch/sh/configs/sh7770_generic_defconfig index 34bed55..7b24705 100644 --- a/arch/sh/configs/sh7770_generic_defconfig +++ b/arch/sh/configs/sh7770_generic_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31 -# Thu Sep 24 19:17:16 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 15:06:28 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y # CONFIG_ARCH_SUSPEND_POSSIBLE is not set CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_SYS_SUPPORTS_HUGETLBFS=y CONFIG_SYS_SUPPORTS_TMU=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_LOCKDEP_SUPPORT=y @@ -29,6 +30,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_DMA_NONCOHERENT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -48,7 +50,6 @@ CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_LZMA is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y -CONFIG_SYSVIPC_SYSCTL=y # CONFIG_BSD_PROCESS_ACCT is not set # @@ -56,6 +57,7 @@ CONFIG_SYSVIPC_SYSCTL=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -79,11 +81,9 @@ CONFIG_CGROUPS=y # CONFIG_NAMESPACES is not set # CONFIG_BLK_DEV_INITRD is not set CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_SYSCTL=y CONFIG_ANON_INODES=y CONFIG_EMBEDDED=y # CONFIG_UID16 is not set -CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set CONFIG_HOTPLUG=y @@ -99,6 +99,7 @@ CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters @@ -119,6 +120,7 @@ CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -135,19 +137,48 @@ CONFIG_BLOCK=y CONFIG_LBDAF=y # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set +# CONFIG_BLK_CGROUP is not set # # IO Schedulers # CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y +# CONFIG_CFQ_GROUP_IOSCHED is not set # CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +CONFIG_INLINE_SPIN_UNLOCK=y +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +CONFIG_INLINE_READ_UNLOCK=y +# CONFIG_INLINE_READ_UNLOCK_BH is not set +CONFIG_INLINE_READ_UNLOCK_IRQ=y +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +CONFIG_INLINE_WRITE_UNLOCK=y +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set CONFIG_FREEZER=y # @@ -201,6 +232,7 @@ CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_MEMORY_START=0x08000000 CONFIG_MEMORY_SIZE=0x04000000 CONFIG_29BIT=y +# CONFIG_PMB_ENABLE is not set CONFIG_VSYSCALL=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_ARCH_SPARSEMEM_ENABLE=y @@ -221,17 +253,12 @@ CONFIG_SPARSEMEM_MANUAL=y CONFIG_SPARSEMEM=y CONFIG_HAVE_MEMORY_PRESENT=y CONFIG_SPARSEMEM_STATIC=y - -# -# Memory hotplug is currently incompatible with Software Suspend -# +# CONFIG_MEMORY_HOTPLUG is not set CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_MIGRATION=y # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -379,6 +406,10 @@ CONFIG_EXTRA_FIRMWARE="" CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# # CONFIG_BLK_DEV_RAM is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_BLK_DEV_HD is not set @@ -467,7 +498,6 @@ CONFIG_I2C_SH_MOBILE=y # # Miscellaneous I2C Chip support # -# CONFIG_DS1682 is not set # CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set @@ -496,15 +526,18 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_TWL4030_CORE is not set # CONFIG_MFD_TMIO is not set # CONFIG_PMIC_DA903X is not set +# CONFIG_PMIC_ADP5520 is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set # CONFIG_MFD_PCF50633 is not set # CONFIG_AB3100_CORE is not set +# CONFIG_MFD_88PM8607 is not set # CONFIG_REGULATOR is not set # CONFIG_MEDIA_SUPPORT is not set @@ -552,6 +585,7 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_PCF8563 is not set # CONFIG_RTC_DRV_PCF8583 is not set # CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set # CONFIG_RTC_DRV_S35390A is not set # CONFIG_RTC_DRV_FM3130 is not set # CONFIG_RTC_DRV_RX8581 is not set @@ -572,7 +606,9 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_M48T86 is not set # CONFIG_RTC_DRV_M48T35 is not set # CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set # CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set # CONFIG_RTC_DRV_V3020 is not set # @@ -599,6 +635,7 @@ CONFIG_UIO_PDRV_GENIRQ=y # CONFIG_EXT2_FS is not set # CONFIG_EXT3_FS is not set # CONFIG_EXT4_FS is not set +CONFIG_EXT4_USE_FOR_EXT23=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set @@ -666,11 +703,10 @@ CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set CONFIG_STACKTRACE=y -# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_LATENCYTOP is not set -# CONFIG_SYSCTL_SYSCALL_CHECK is not set CONFIG_NOP_TRACER=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y @@ -690,7 +726,6 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set -# CONFIG_EARLY_SCIF_CONSOLE is not set # CONFIG_DWARF_UNWINDER is not set # @@ -698,7 +733,11 @@ CONFIG_HAVE_ARCH_KGDB=y # # CONFIG_KEYS is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" # CONFIG_CRYPTO is not set CONFIG_BINARY_PRINTF=y diff --git a/arch/sh/configs/sh7785lcr_32bit_defconfig b/arch/sh/configs/sh7785lcr_32bit_defconfig index 51cbaed..8330813 100644 --- a/arch/sh/configs/sh7785lcr_32bit_defconfig +++ b/arch/sh/configs/sh7785lcr_32bit_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31 -# Fri Sep 25 11:39:20 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 15:07:40 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y # CONFIG_ARCH_SUSPEND_POSSIBLE is not set CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_SYS_SUPPORTS_HUGETLBFS=y CONFIG_SYS_SUPPORTS_NUMA=y CONFIG_SYS_SUPPORTS_PCI=y CONFIG_SYS_SUPPORTS_TMU=y @@ -31,6 +32,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_DMA_NONCOHERENT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -64,6 +66,7 @@ CONFIG_BSD_PROCESS_ACCT=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -103,6 +106,7 @@ CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters @@ -126,6 +130,7 @@ CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -153,14 +158,41 @@ CONFIG_BLOCK=y # IO Schedulers # CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y -# CONFIG_DEFAULT_AS is not set # CONFIG_DEFAULT_DEADLINE is not set CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +# CONFIG_INLINE_SPIN_UNLOCK is not set +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +# CONFIG_INLINE_READ_UNLOCK is not set +# CONFIG_INLINE_READ_UNLOCK_BH is not set +# CONFIG_INLINE_READ_UNLOCK_IRQ is not set +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +# CONFIG_INLINE_WRITE_UNLOCK is not set +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set # CONFIG_FREEZER is not set # @@ -253,8 +285,6 @@ CONFIG_MIGRATION=y # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -287,7 +317,6 @@ CONFIG_SH_SH7785LCR=y # Timer and clock configuration # CONFIG_SH_TIMER_TMU=y -CONFIG_SH_PCLK_FREQ=50000000 CONFIG_SH_CLK_CPG=y CONFIG_TICK_ONESHOT=y CONFIG_NO_HZ=y @@ -360,7 +389,6 @@ CONFIG_ENTRY_OFFSET=0x00001000 # Bus options # CONFIG_PCI=y -CONFIG_SH_PCIDMA_NONCOHERENT=y # CONFIG_PCIEPORTBUS is not set # CONFIG_ARCH_SUPPORTS_MSI is not set # CONFIG_PCI_LEGACY is not set @@ -470,10 +498,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_AF_RXRPC is not set CONFIG_WIRELESS=y # CONFIG_CFG80211 is not set -CONFIG_CFG80211_DEFAULT_PS_VALUE=0 -# CONFIG_WIRELESS_OLD_REGULATORY is not set -CONFIG_WIRELESS_EXT=y -CONFIG_WIRELESS_EXT_SYSFS=y # CONFIG_LIB80211 is not set # @@ -588,6 +612,10 @@ CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_CRYPTOLOOP=m + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_SX8 is not set # CONFIG_BLK_DEV_UB is not set @@ -688,15 +716,16 @@ CONFIG_SATA_SIL=y # CONFIG_PATA_NS87415 is not set # CONFIG_PATA_OPTI is not set # CONFIG_PATA_OPTIDMA is not set +# CONFIG_PATA_PDC2027X is not set # CONFIG_PATA_PDC_OLD is not set # CONFIG_PATA_RADISYS is not set # CONFIG_PATA_RDC is not set # CONFIG_PATA_RZ1000 is not set # CONFIG_PATA_SC1200 is not set # CONFIG_PATA_SERVERWORKS is not set -# CONFIG_PATA_PDC2027X is not set # CONFIG_PATA_SIL680 is not set # CONFIG_PATA_SIS is not set +# CONFIG_PATA_TOSHIBA is not set # CONFIG_PATA_VIA is not set # CONFIG_PATA_WINBOND is not set # CONFIG_PATA_PLATFORM is not set @@ -777,6 +806,7 @@ CONFIG_R8169=y # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_VMXNET3 is not set # CONFIG_ISDN is not set # CONFIG_PHONE is not set @@ -786,6 +816,7 @@ CONFIG_R8169=y CONFIG_INPUT=y CONFIG_INPUT_FF_MEMLESS=m # CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set # # Userland interfaces @@ -841,6 +872,7 @@ CONFIG_SERIO_SERPORT=y # CONFIG_SERIO_PCIPS2 is not set CONFIG_SERIO_LIBPS2=y # CONFIG_SERIO_RAW is not set +# CONFIG_SERIO_ALTERA_PS2 is not set # CONFIG_GAMEPORT is not set # @@ -924,11 +956,6 @@ CONFIG_I2C_ALGOPCA=y # CONFIG_I2C_TINY_USB is not set # -# Graphics adapter I2C/DDC channel drivers -# -# CONFIG_I2C_VOODOO3 is not set - -# # Other I2C/SMBus bus drivers # CONFIG_I2C_PCA_PLATFORM=y @@ -937,7 +964,6 @@ CONFIG_I2C_PCA_PLATFORM=y # # Miscellaneous I2C Chip support # -# CONFIG_DS1682 is not set # CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set @@ -986,15 +1012,18 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_MFD_CORE is not set CONFIG_MFD_SM501=y +# CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_TWL4030_CORE is not set # CONFIG_MFD_TMIO is not set # CONFIG_PMIC_DA903X is not set +# CONFIG_PMIC_ADP5520 is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set # CONFIG_MFD_PCF50633 is not set # CONFIG_AB3100_CORE is not set +# CONFIG_MFD_88PM8607 is not set # CONFIG_REGULATOR is not set # CONFIG_MEDIA_SUPPORT is not set @@ -1129,6 +1158,7 @@ CONFIG_SND_CMIPCI=y # CONFIG_SND_OXYGEN is not set # CONFIG_SND_CS4281 is not set # CONFIG_SND_CS46XX is not set +# CONFIG_SND_CS5535AUDIO is not set # CONFIG_SND_CTXFI is not set # CONFIG_SND_DARLA20 is not set # CONFIG_SND_GINA20 is not set @@ -1363,6 +1393,7 @@ CONFIG_MMC_SDHCI_PLTFM=m # CONFIG_MMC_AT91 is not set # CONFIG_MMC_ATMELMCI is not set # CONFIG_MMC_TIFM_SD is not set +# CONFIG_MMC_TMIO is not set # CONFIG_MMC_CB710 is not set # CONFIG_MMC_VIA_SDMMC is not set # CONFIG_MEMSTICK is not set @@ -1397,6 +1428,7 @@ CONFIG_RTC_DRV_RS5C372=y # CONFIG_RTC_DRV_PCF8563 is not set # CONFIG_RTC_DRV_PCF8583 is not set # CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set # CONFIG_RTC_DRV_S35390A is not set # CONFIG_RTC_DRV_FM3130 is not set # CONFIG_RTC_DRV_RX8581 is not set @@ -1417,7 +1449,9 @@ CONFIG_RTC_DRV_RS5C372=y # CONFIG_RTC_DRV_M48T86 is not set # CONFIG_RTC_DRV_M48T35 is not set # CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set # CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set # CONFIG_RTC_DRV_V3020 is not set # @@ -1622,13 +1656,14 @@ CONFIG_SCHED_DEBUG=y CONFIG_SCHEDSTATS=y CONFIG_TRACE_IRQFLAGS=y CONFIG_STACKTRACE=y -# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set CONFIG_FRAME_POINTER=y # CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_LATENCYTOP=y CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_NOP_TRACER=y +CONFIG_HAVE_FTRACE_NMI_ENTER=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y @@ -1637,6 +1672,7 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y CONFIG_HAVE_SYSCALL_TRACEPOINTS=y CONFIG_TRACER_MAX_TRACE=y CONFIG_RING_BUFFER=y +CONFIG_FTRACE_NMI_ENTER=y CONFIG_EVENT_TRACING=y CONFIG_CONTEXT_SWITCH_TRACER=y CONFIG_RING_BUFFER_ALLOW_SWAP=y @@ -1668,7 +1704,6 @@ CONFIG_FTRACE_MCOUNT_RECORD=y # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set -# CONFIG_EARLY_SCIF_CONSOLE is not set CONFIG_DWARF_UNWINDER=y CONFIG_MCOUNT=y @@ -1678,7 +1713,11 @@ CONFIG_MCOUNT=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" CONFIG_CRYPTO=y # diff --git a/arch/sh/configs/sh7785lcr_defconfig b/arch/sh/configs/sh7785lcr_defconfig index 8c2c47e..f196e87 100644 --- a/arch/sh/configs/sh7785lcr_defconfig +++ b/arch/sh/configs/sh7785lcr_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31 -# Thu Sep 24 19:23:18 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 15:09:09 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y # CONFIG_ARCH_SUSPEND_POSSIBLE is not set CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_SYS_SUPPORTS_HUGETLBFS=y CONFIG_SYS_SUPPORTS_NUMA=y CONFIG_SYS_SUPPORTS_PCI=y CONFIG_SYS_SUPPORTS_TMU=y @@ -31,6 +32,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_DMA_NONCOHERENT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -63,6 +65,7 @@ CONFIG_BSD_PROCESS_ACCT=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -103,12 +106,14 @@ CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters # CONFIG_PERF_EVENTS=y # CONFIG_PERF_COUNTERS is not set +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_PCI_QUIRKS=y CONFIG_COMPAT_BRK=y @@ -123,6 +128,7 @@ CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -149,14 +155,41 @@ CONFIG_LBDAF=y # IO Schedulers # CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y -# CONFIG_DEFAULT_AS is not set # CONFIG_DEFAULT_DEADLINE is not set CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +# CONFIG_INLINE_SPIN_UNLOCK is not set +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +# CONFIG_INLINE_READ_UNLOCK is not set +# CONFIG_INLINE_READ_UNLOCK_BH is not set +# CONFIG_INLINE_READ_UNLOCK_IRQ is not set +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +# CONFIG_INLINE_WRITE_UNLOCK is not set +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set # CONFIG_FREEZER is not set # @@ -237,8 +270,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -271,7 +302,6 @@ CONFIG_SH_SH7785LCR_29BIT_PHYSMAPS=y # Timer and clock configuration # CONFIG_SH_TIMER_TMU=y -CONFIG_SH_PCLK_FREQ=50000000 CONFIG_SH_CLK_CPG=y CONFIG_TICK_ONESHOT=y # CONFIG_NO_HZ is not set @@ -329,7 +359,6 @@ CONFIG_ENTRY_OFFSET=0x00001000 # Bus options # CONFIG_PCI=y -CONFIG_SH_PCIDMA_NONCOHERENT=y # CONFIG_PCIEPORTBUS is not set # CONFIG_ARCH_SUPPORTS_MSI is not set CONFIG_PCI_LEGACY=y @@ -433,10 +462,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_AF_RXRPC is not set CONFIG_WIRELESS=y # CONFIG_CFG80211 is not set -CONFIG_CFG80211_DEFAULT_PS_VALUE=0 -# CONFIG_WIRELESS_OLD_REGULATORY is not set -CONFIG_WIRELESS_EXT=y -CONFIG_WIRELESS_EXT_SYSFS=y # CONFIG_LIB80211 is not set # @@ -552,6 +577,10 @@ CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_SX8 is not set # CONFIG_BLK_DEV_UB is not set @@ -652,15 +681,16 @@ CONFIG_SATA_SIL=y # CONFIG_PATA_NS87415 is not set # CONFIG_PATA_OPTI is not set # CONFIG_PATA_OPTIDMA is not set +# CONFIG_PATA_PDC2027X is not set # CONFIG_PATA_PDC_OLD is not set # CONFIG_PATA_RADISYS is not set # CONFIG_PATA_RDC is not set # CONFIG_PATA_RZ1000 is not set # CONFIG_PATA_SC1200 is not set # CONFIG_PATA_SERVERWORKS is not set -# CONFIG_PATA_PDC2027X is not set # CONFIG_PATA_SIL680 is not set # CONFIG_PATA_SIS is not set +# CONFIG_PATA_TOSHIBA is not set # CONFIG_PATA_VIA is not set # CONFIG_PATA_WINBOND is not set # CONFIG_PATA_PLATFORM is not set @@ -719,8 +749,10 @@ CONFIG_R8169=y # CONFIG_NETDEV_10000 is not set # CONFIG_TR is not set CONFIG_WLAN=y -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +# CONFIG_ATMEL is not set +# CONFIG_PRISM54 is not set +# CONFIG_USB_ZD1201 is not set +# CONFIG_HOSTAP is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers @@ -743,6 +775,7 @@ CONFIG_WLAN=y # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_VMXNET3 is not set # CONFIG_ISDN is not set # CONFIG_PHONE is not set @@ -752,6 +785,7 @@ CONFIG_WLAN=y CONFIG_INPUT=y CONFIG_INPUT_FF_MEMLESS=m # CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set # # Userland interfaces @@ -874,11 +908,6 @@ CONFIG_I2C_ALGOPCA=y # CONFIG_I2C_TINY_USB is not set # -# Graphics adapter I2C/DDC channel drivers -# -# CONFIG_I2C_VOODOO3 is not set - -# # Other I2C/SMBus bus drivers # CONFIG_I2C_PCA_PLATFORM=y @@ -887,7 +916,6 @@ CONFIG_I2C_PCA_PLATFORM=y # # Miscellaneous I2C Chip support # -# CONFIG_DS1682 is not set # CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set @@ -916,15 +944,18 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_MFD_CORE is not set CONFIG_MFD_SM501=y +# CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_TWL4030_CORE is not set # CONFIG_MFD_TMIO is not set # CONFIG_PMIC_DA903X is not set +# CONFIG_PMIC_ADP5520 is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set # CONFIG_MFD_PCF50633 is not set # CONFIG_AB3100_CORE is not set +# CONFIG_MFD_88PM8607 is not set # CONFIG_REGULATOR is not set # CONFIG_MEDIA_SUPPORT is not set @@ -1205,6 +1236,7 @@ CONFIG_RTC_DRV_RS5C372=y # CONFIG_RTC_DRV_PCF8563 is not set # CONFIG_RTC_DRV_PCF8583 is not set # CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set # CONFIG_RTC_DRV_S35390A is not set # CONFIG_RTC_DRV_FM3130 is not set # CONFIG_RTC_DRV_RX8581 is not set @@ -1225,7 +1257,9 @@ CONFIG_RTC_DRV_RS5C372=y # CONFIG_RTC_DRV_M48T86 is not set # CONFIG_RTC_DRV_M48T35 is not set # CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set # CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set # CONFIG_RTC_DRV_V3020 is not set # @@ -1484,7 +1518,6 @@ CONFIG_BRANCH_PROFILE_NONE=y CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set # CONFIG_SH_STANDARD_BIOS is not set -# CONFIG_EARLY_SCIF_CONSOLE is not set # CONFIG_STACK_DEBUG is not set # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_4KSTACKS is not set @@ -1498,7 +1531,11 @@ CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" CONFIG_CRYPTO=y # diff --git a/arch/sh/configs/shmin_defconfig b/arch/sh/configs/shmin_defconfig index 92115e6..45441c0 100644 --- a/arch/sh/configs/shmin_defconfig +++ b/arch/sh/configs/shmin_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31 -# Thu Sep 24 19:27:17 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 15:10:09 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -28,6 +28,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_DMA_NONCOHERENT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -57,6 +58,7 @@ CONFIG_KERNEL_GZIP=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -88,6 +90,7 @@ CONFIG_EVENTFD=y # CONFIG_SHMEM is not set CONFIG_AIO=y CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters @@ -105,6 +108,7 @@ CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -124,14 +128,41 @@ CONFIG_LBDAF=y # IO Schedulers # CONFIG_IOSCHED_NOOP=y -# CONFIG_IOSCHED_AS is not set # CONFIG_IOSCHED_DEADLINE is not set # CONFIG_IOSCHED_CFQ is not set -# CONFIG_DEFAULT_AS is not set # CONFIG_DEFAULT_DEADLINE is not set # CONFIG_DEFAULT_CFQ is not set CONFIG_DEFAULT_NOOP=y CONFIG_DEFAULT_IOSCHED="noop" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +CONFIG_INLINE_SPIN_UNLOCK=y +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +CONFIG_INLINE_READ_UNLOCK=y +# CONFIG_INLINE_READ_UNLOCK_BH is not set +CONFIG_INLINE_READ_UNLOCK_IRQ=y +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +CONFIG_INLINE_WRITE_UNLOCK=y +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set # CONFIG_FREEZER is not set # @@ -207,8 +238,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -387,9 +416,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_AF_RXRPC is not set CONFIG_WIRELESS=y # CONFIG_CFG80211 is not set -CONFIG_CFG80211_DEFAULT_PS_VALUE=0 -# CONFIG_WIRELESS_OLD_REGULATORY is not set -# CONFIG_WIRELESS_EXT is not set # CONFIG_LIB80211 is not set # @@ -495,6 +521,10 @@ CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_CRYPTOLOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_RAM is not set # CONFIG_CDROM_PKTCDVD is not set @@ -546,11 +576,11 @@ CONFIG_NET_ETHERNET=y # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set # CONFIG_B44 is not set # CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set CONFIG_NETDEV_1000=y CONFIG_NETDEV_10000=y CONFIG_WLAN=y -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +# CONFIG_HOSTAP is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers @@ -629,6 +659,7 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set # CONFIG_REGULATOR is not set @@ -688,6 +719,7 @@ CONFIG_RTC_LIB=y # CONFIG_EXT2_FS is not set # CONFIG_EXT3_FS is not set # CONFIG_EXT4_FS is not set +CONFIG_EXT4_USE_FOR_EXT23=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set @@ -731,7 +763,6 @@ CONFIG_PROC_FS=y CONFIG_PROC_SYSCTL=y CONFIG_PROC_PAGE_MONITOR=y # CONFIG_SYSFS is not set -# CONFIG_HUGETLBFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_MISC_FILESYSTEMS=y # CONFIG_ADFS_FS is not set @@ -794,6 +825,7 @@ CONFIG_FRAME_WARN=1024 # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_LATENCYTOP is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y @@ -806,8 +838,6 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y CONFIG_SH_STANDARD_BIOS=y -# CONFIG_EARLY_SCIF_CONSOLE is not set -CONFIG_EARLY_PRINTK=y # CONFIG_DWARF_UNWINDER is not set # @@ -815,7 +845,11 @@ CONFIG_EARLY_PRINTK=y # # CONFIG_KEYS is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" CONFIG_CRYPTO=y # diff --git a/arch/sh/configs/shx3_defconfig b/arch/sh/configs/shx3_defconfig index e3858d7..ecf50cd 100644 --- a/arch/sh/configs/shx3_defconfig +++ b/arch/sh/configs/shx3_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31 -# Thu Sep 24 19:29:26 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 15:10:45 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -22,6 +22,7 @@ CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y CONFIG_GENERIC_LOCKBREAK=y # CONFIG_ARCH_SUSPEND_POSSIBLE is not set CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_SYS_SUPPORTS_HUGETLBFS=y CONFIG_SYS_SUPPORTS_SMP=y CONFIG_SYS_SUPPORTS_NUMA=y CONFIG_SYS_SUPPORTS_TMU=y @@ -32,6 +33,8 @@ CONFIG_LOCKDEP_SUPPORT=y CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_DMA_COHERENT=y +# CONFIG_DMA_NONCOHERENT is not set CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -66,6 +69,7 @@ CONFIG_AUDIT_TREE=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set CONFIG_RCU_TRACE=y CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -121,6 +125,7 @@ CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters @@ -128,6 +133,7 @@ CONFIG_HAVE_PERF_EVENTS=y CONFIG_PERF_EVENTS=y CONFIG_EVENT_PROFILE=y # CONFIG_PERF_COUNTERS is not set +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_COMPAT_BRK=y # CONFIG_SLAB is not set @@ -143,6 +149,7 @@ CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_USE_GENERIC_SMP_HELPERS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -166,19 +173,48 @@ CONFIG_BLOCK=y CONFIG_LBDAF=y # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set +# CONFIG_BLK_CGROUP is not set # # IO Schedulers # CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y +# CONFIG_CFQ_GROUP_IOSCHED is not set # CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +# CONFIG_INLINE_SPIN_UNLOCK is not set +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +# CONFIG_INLINE_READ_UNLOCK is not set +# CONFIG_INLINE_READ_UNLOCK_BH is not set +# CONFIG_INLINE_READ_UNLOCK_IRQ is not set +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +# CONFIG_INLINE_WRITE_UNLOCK is not set +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +CONFIG_MUTEX_SPIN_ON_OWNER=y CONFIG_FREEZER=y # @@ -233,6 +269,7 @@ CONFIG_FORCE_MAX_ZONEORDER=7 CONFIG_MEMORY_START=0x0c000000 CONFIG_MEMORY_SIZE=0x04000000 CONFIG_29BIT=y +# CONFIG_PMB_ENABLE is not set # CONFIG_X2TLB is not set CONFIG_VSYSCALL=y CONFIG_NUMA=y @@ -271,10 +308,9 @@ CONFIG_MIGRATION=y # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_SCHED_MC=y # # Cache configuration @@ -449,6 +485,7 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=m CONFIG_INET6_XFRM_MODE_BEET=m # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set CONFIG_IPV6_SIT=m +# CONFIG_IPV6_SIT_6RD is not set CONFIG_IPV6_NDISC_NODETYPE=y # CONFIG_IPV6_TUNNEL is not set # CONFIG_IPV6_MULTIPLE_TABLES is not set @@ -496,7 +533,13 @@ CONFIG_CAN_VCAN=m # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set -# CONFIG_WIRELESS is not set +CONFIG_WIRELESS=y +# CONFIG_CFG80211 is not set +# CONFIG_LIB80211 is not set + +# +# CFG80211 needs to be enabled for MAC80211 +# # CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -522,6 +565,10 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_UB is not set CONFIG_BLK_DEV_RAM=y @@ -532,9 +579,12 @@ CONFIG_BLK_DEV_RAM_SIZE=4096 # CONFIG_ATA_OVER_ETH is not set # CONFIG_BLK_DEV_HD is not set CONFIG_MISC_DEVICES=y +# CONFIG_AD525X_DPOT is not set # CONFIG_ICS932S401 is not set # CONFIG_ENCLOSURE_SERVICES is not set # CONFIG_ISL29003 is not set +# CONFIG_DS1682 is not set +# CONFIG_TI_DAC7512 is not set # CONFIG_C2PORT is not set # @@ -624,11 +674,12 @@ CONFIG_SMC91X=y # CONFIG_B44 is not set # CONFIG_KS8842 is not set # CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set CONFIG_WLAN=y -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +# CONFIG_USB_ZD1201 is not set +# CONFIG_HOSTAP is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers @@ -726,7 +777,6 @@ CONFIG_I2C_HELPER_AUTO=y # # Miscellaneous I2C Chip support # -# CONFIG_DS1682 is not set # CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set @@ -740,7 +790,10 @@ CONFIG_SPI_MASTER=y # SPI Master Controller Drivers # # CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_SH_MSIOF is not set # CONFIG_SPI_SH_SCI is not set +# CONFIG_SPI_XILINX is not set +# CONFIG_SPI_DESIGNWARE is not set # # SPI Protocol Masters @@ -781,15 +834,16 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set # CONFIG_MFD_WM8400 is not set -# CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set # CONFIG_MFD_PCF50633 is not set # CONFIG_MFD_MC13783 is not set # CONFIG_AB3100_CORE is not set # CONFIG_EZX_PCAP is not set +# CONFIG_AB4500_CORE is not set # CONFIG_REGULATOR is not set # CONFIG_MEDIA_SUPPORT is not set @@ -924,10 +978,12 @@ CONFIG_USB_GADGET_DUALSPEED=y # CONFIG_USB_ETH is not set # CONFIG_USB_GADGETFS is not set # CONFIG_USB_FILE_STORAGE is not set +# CONFIG_USB_MASS_STORAGE is not set # CONFIG_USB_G_SERIAL is not set # CONFIG_USB_MIDI_GADGET is not set # CONFIG_USB_G_PRINTER is not set # CONFIG_USB_CDC_COMPOSITE is not set +# CONFIG_USB_G_MULTI is not set # # OTG and related infrastructure @@ -965,6 +1021,7 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_PCF8563 is not set # CONFIG_RTC_DRV_PCF8583 is not set # CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set # CONFIG_RTC_DRV_S35390A is not set # CONFIG_RTC_DRV_FM3130 is not set # CONFIG_RTC_DRV_RX8581 is not set @@ -993,7 +1050,9 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_M48T86 is not set # CONFIG_RTC_DRV_M48T35 is not set # CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set # CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set # CONFIG_RTC_DRV_V3020 is not set # @@ -1244,8 +1303,6 @@ CONFIG_BRANCH_PROFILE_NONE=y CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set CONFIG_SH_STANDARD_BIOS=y -# CONFIG_EARLY_SCIF_CONSOLE is not set -CONFIG_EARLY_PRINTK=y # CONFIG_STACK_DEBUG is not set CONFIG_DEBUG_STACK_USAGE=y CONFIG_DUMP_CODE=y @@ -1258,7 +1315,11 @@ CONFIG_DUMP_CODE=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" CONFIG_CRYPTO=y # diff --git a/arch/sh/configs/snapgear_defconfig b/arch/sh/configs/snapgear_defconfig index cb919a0..98352d7 100644 --- a/arch/sh/configs/snapgear_defconfig +++ b/arch/sh/configs/snapgear_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31 -# Thu Sep 24 19:33:00 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 15:14:18 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y # CONFIG_ARCH_SUSPEND_POSSIBLE is not set CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_SYS_SUPPORTS_HUGETLBFS=y CONFIG_SYS_SUPPORTS_PCI=y CONFIG_SYS_SUPPORTS_TMU=y CONFIG_STACKTRACE_SUPPORT=y @@ -30,6 +31,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_DMA_NONCOHERENT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -59,6 +61,7 @@ CONFIG_KERNEL_GZIP=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -97,6 +100,7 @@ CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters @@ -115,6 +119,7 @@ CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -136,14 +141,41 @@ CONFIG_LBDAF=y # IO Schedulers # CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +CONFIG_INLINE_SPIN_UNLOCK=y +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +CONFIG_INLINE_READ_UNLOCK=y +# CONFIG_INLINE_READ_UNLOCK_BH is not set +CONFIG_INLINE_READ_UNLOCK_IRQ=y +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +CONFIG_INLINE_WRITE_UNLOCK=y +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set # CONFIG_FREEZER is not set # @@ -219,8 +251,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -272,9 +302,9 @@ CONFIG_GENERIC_CLOCKEVENTS_BUILD=y # # DMA support # -CONFIG_SH_DMA_API=y CONFIG_SH_DMA=y CONFIG_SH_DMA_IRQ_MULTI=y +CONFIG_SH_DMA_API=y CONFIG_NR_ONCHIP_DMA_CHANNELS=8 # CONFIG_NR_DMA_CHANNELS_BOOL is not set @@ -313,7 +343,6 @@ CONFIG_GUSA=y CONFIG_ZERO_PAGE_OFFSET=0x00001000 CONFIG_BOOT_LINK_OFFSET=0x00800000 CONFIG_ENTRY_OFFSET=0x00001000 -# CONFIG_UBC_WAKEUP is not set # CONFIG_CMDLINE_OVERWRITE is not set # CONFIG_CMDLINE_EXTEND is not set @@ -321,7 +350,6 @@ CONFIG_ENTRY_OFFSET=0x00001000 # Bus options # CONFIG_PCI=y -CONFIG_SH_PCIDMA_NONCOHERENT=y # CONFIG_PCIEPORTBUS is not set # CONFIG_ARCH_SUPPORTS_MSI is not set CONFIG_PCI_LEGACY=y @@ -407,9 +435,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_AF_RXRPC is not set CONFIG_WIRELESS=y # CONFIG_CFG80211 is not set -CONFIG_CFG80211_DEFAULT_PS_VALUE=0 -# CONFIG_WIRELESS_OLD_REGULATORY is not set -# CONFIG_WIRELESS_EXT is not set # CONFIG_LIB80211 is not set # @@ -524,6 +549,10 @@ CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_SX8 is not set CONFIG_BLK_DEV_RAM=y @@ -616,6 +645,7 @@ CONFIG_8139TOO_PIO=y # CONFIG_SUNDANCE is not set # CONFIG_TLAN is not set # CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set # CONFIG_VIA_RHINE is not set # CONFIG_SC92031 is not set # CONFIG_ATL2 is not set @@ -623,8 +653,9 @@ CONFIG_8139TOO_PIO=y # CONFIG_NETDEV_10000 is not set # CONFIG_TR is not set CONFIG_WLAN=y -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +# CONFIG_ATMEL is not set +# CONFIG_PRISM54 is not set +# CONFIG_HOSTAP is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers @@ -637,6 +668,7 @@ CONFIG_WLAN=y # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_VMXNET3 is not set # CONFIG_ISDN is not set # CONFIG_PHONE is not set @@ -646,6 +678,7 @@ CONFIG_WLAN=y CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set # CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set # # Userland interfaces @@ -728,6 +761,7 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set # CONFIG_REGULATOR is not set @@ -787,7 +821,9 @@ CONFIG_RTC_DRV_DS1302=y # CONFIG_RTC_DRV_M48T86 is not set # CONFIG_RTC_DRV_M48T35 is not set # CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set # CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set # CONFIG_RTC_DRV_V3020 is not set # @@ -812,6 +848,7 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XIP is not set # CONFIG_EXT3_FS is not set # CONFIG_EXT4_FS is not set +CONFIG_EXT4_USE_FOR_EXT23=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set @@ -915,10 +952,11 @@ CONFIG_FRAME_WARN=1024 # CONFIG_DEBUG_FS is not set # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_LATENCYTOP is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y @@ -931,7 +969,6 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set -# CONFIG_EARLY_SCIF_CONSOLE is not set # CONFIG_DWARF_UNWINDER is not set # @@ -940,7 +977,11 @@ CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" # CONFIG_CRYPTO is not set # CONFIG_BINARY_PRINTF is not set diff --git a/arch/sh/configs/systemh_defconfig b/arch/sh/configs/systemh_defconfig index b9fe960..72982e3 100644 --- a/arch/sh/configs/systemh_defconfig +++ b/arch/sh/configs/systemh_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31 -# Thu Sep 24 19:35:03 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 15:14:50 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y # CONFIG_ARCH_SUSPEND_POSSIBLE is not set CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_SYS_SUPPORTS_HUGETLBFS=y CONFIG_SYS_SUPPORTS_TMU=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_LOCKDEP_SUPPORT=y @@ -29,6 +30,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_DMA_NONCOHERENT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -56,6 +58,7 @@ CONFIG_SWAP=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -94,6 +97,7 @@ CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters @@ -112,6 +116,7 @@ CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -138,14 +143,41 @@ CONFIG_LBDAF=y # IO Schedulers # CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +# CONFIG_INLINE_SPIN_UNLOCK is not set +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +# CONFIG_INLINE_READ_UNLOCK is not set +# CONFIG_INLINE_READ_UNLOCK_BH is not set +# CONFIG_INLINE_READ_UNLOCK_IRQ is not set +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +# CONFIG_INLINE_WRITE_UNLOCK is not set +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set # CONFIG_FREEZER is not set # @@ -221,8 +253,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -310,7 +340,6 @@ CONFIG_GUSA=y CONFIG_ZERO_PAGE_OFFSET=0x00001000 CONFIG_BOOT_LINK_OFFSET=0x00800000 CONFIG_ENTRY_OFFSET=0x00001000 -# CONFIG_UBC_WAKEUP is not set # CONFIG_CMDLINE_OVERWRITE is not set # CONFIG_CMDLINE_EXTEND is not set @@ -349,6 +378,10 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=1024 @@ -390,6 +423,7 @@ CONFIG_SERIO=y # CONFIG_SERIO_SERPORT is not set # CONFIG_SERIO_LIBPS2 is not set # CONFIG_SERIO_RAW is not set +# CONFIG_SERIO_ALTERA_PS2 is not set # CONFIG_GAMEPORT is not set # @@ -458,6 +492,7 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set # CONFIG_REGULATOR is not set @@ -517,6 +552,7 @@ CONFIG_RTC_LIB=y # CONFIG_EXT2_FS is not set # CONFIG_EXT3_FS is not set # CONFIG_EXT4_FS is not set +CONFIG_EXT4_USE_FOR_EXT23=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set @@ -609,10 +645,11 @@ CONFIG_FRAME_WARN=1024 # CONFIG_DEBUG_FS is not set # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_LATENCYTOP is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y @@ -625,7 +662,6 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set -# CONFIG_EARLY_SCIF_CONSOLE is not set # CONFIG_DWARF_UNWINDER is not set # @@ -634,7 +670,11 @@ CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" # CONFIG_CRYPTO is not set # CONFIG_BINARY_PRINTF is not set diff --git a/arch/sh/configs/titan_defconfig b/arch/sh/configs/titan_defconfig index 2ca79ed..78c2570 100644 --- a/arch/sh/configs/titan_defconfig +++ b/arch/sh/configs/titan_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31 -# Thu Sep 24 19:36:36 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 15:17:20 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y # CONFIG_ARCH_SUSPEND_POSSIBLE is not set CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_SYS_SUPPORTS_HUGETLBFS=y CONFIG_SYS_SUPPORTS_PCI=y CONFIG_SYS_SUPPORTS_TMU=y CONFIG_STACKTRACE_SUPPORT=y @@ -30,6 +31,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_DMA_NONCOHERENT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -61,6 +63,7 @@ CONFIG_POSIX_MQUEUE_SYSCTL=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -101,6 +104,7 @@ CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters @@ -120,13 +124,14 @@ CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y # # GCOV-based kernel profiling # -# CONFIG_SLOW_WORK is not set +CONFIG_SLOW_WORK=y CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y @@ -146,14 +151,41 @@ CONFIG_LBDAF=y # IO Schedulers # CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +CONFIG_INLINE_SPIN_UNLOCK=y +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +CONFIG_INLINE_READ_UNLOCK=y +# CONFIG_INLINE_READ_UNLOCK_BH is not set +CONFIG_INLINE_READ_UNLOCK_IRQ=y +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +CONFIG_INLINE_WRITE_UNLOCK=y +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set # CONFIG_FREEZER is not set # @@ -229,8 +261,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -282,9 +312,9 @@ CONFIG_GENERIC_CLOCKEVENTS_BUILD=y # # DMA support # -CONFIG_SH_DMA_API=y CONFIG_SH_DMA=y CONFIG_SH_DMA_IRQ_MULTI=y +CONFIG_SH_DMA_API=y CONFIG_NR_ONCHIP_DMA_CHANNELS=8 # CONFIG_NR_DMA_CHANNELS_BOOL is not set @@ -323,7 +353,6 @@ CONFIG_GUSA=y CONFIG_ZERO_PAGE_OFFSET=0x00001000 CONFIG_BOOT_LINK_OFFSET=0x009e0000 CONFIG_ENTRY_OFFSET=0x00001000 -# CONFIG_UBC_WAKEUP is not set CONFIG_CMDLINE_OVERWRITE=y # CONFIG_CMDLINE_EXTEND is not set CONFIG_CMDLINE="console=ttySC1,38400N81 root=/dev/nfs ip=:::::eth1:autoconf rw" @@ -332,7 +361,6 @@ CONFIG_CMDLINE="console=ttySC1,38400N81 root=/dev/nfs ip=:::::eth1:autoconf rw" # Bus options # CONFIG_PCI=y -CONFIG_SH_PCIDMA_NONCOHERENT=y # CONFIG_PCIEPORTBUS is not set # CONFIG_ARCH_SUPPORTS_MSI is not set CONFIG_PCI_LEGACY=y @@ -425,6 +453,7 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=y CONFIG_INET6_XFRM_MODE_BEET=y # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set CONFIG_IPV6_SIT=m +# CONFIG_IPV6_SIT_6RD is not set CONFIG_IPV6_NDISC_NODETYPE=y CONFIG_IPV6_TUNNEL=y # CONFIG_IPV6_MULTIPLE_TABLES is not set @@ -614,10 +643,6 @@ CONFIG_NET_SCH_FIFO=y CONFIG_FIB_RULES=y CONFIG_WIRELESS=y # CONFIG_CFG80211 is not set -CONFIG_CFG80211_DEFAULT_PS_VALUE=0 -# CONFIG_WIRELESS_OLD_REGULATORY is not set -CONFIG_WIRELESS_EXT=y -CONFIG_WIRELESS_EXT_SYSFS=y # CONFIG_LIB80211 is not set # @@ -743,6 +768,11 @@ CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=m CONFIG_BLK_DEV_CRYPTOLOOP=m + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# +# CONFIG_BLK_DEV_DRBD is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_SX8 is not set # CONFIG_BLK_DEV_UB is not set @@ -807,8 +837,11 @@ CONFIG_SCSI_LOWLEVEL=y # CONFIG_ISCSI_TCP is not set # CONFIG_SCSI_CXGB3_ISCSI is not set # CONFIG_SCSI_BNX2_ISCSI is not set +# CONFIG_BE2ISCSI is not set # CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_HPSA is not set # CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_3W_SAS is not set # CONFIG_SCSI_ACARD is not set # CONFIG_SCSI_AACRAID is not set # CONFIG_SCSI_AIC7XXX is not set @@ -841,7 +874,9 @@ CONFIG_SCSI_LOWLEVEL=y # CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set # CONFIG_SCSI_PMCRAID is not set +# CONFIG_SCSI_PM8001 is not set # CONFIG_SCSI_SRP is not set +# CONFIG_SCSI_BFA_FC is not set # CONFIG_SCSI_DH is not set # CONFIG_SCSI_OSD_INITIATOR is not set # CONFIG_ATA is not set @@ -935,6 +970,7 @@ CONFIG_8139_OLD_RX_RESET=y # CONFIG_SUNDANCE is not set # CONFIG_TLAN is not set # CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set # CONFIG_VIA_RHINE is not set # CONFIG_SC92031 is not set # CONFIG_ATL2 is not set @@ -983,8 +1019,10 @@ CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_BE2NET is not set # CONFIG_TR is not set CONFIG_WLAN=y -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +# CONFIG_ATMEL is not set +# CONFIG_PRISM54 is not set +# CONFIG_USB_ZD1201 is not set +# CONFIG_HOSTAP is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers @@ -1033,6 +1071,7 @@ CONFIG_SLIP_SMART=y # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_VMXNET3 is not set # CONFIG_ISDN is not set # CONFIG_PHONE is not set @@ -1042,6 +1081,7 @@ CONFIG_SLIP_SMART=y CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set # CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set # # Userland interfaces @@ -1172,6 +1212,7 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set # CONFIG_REGULATOR is not set @@ -1409,7 +1450,9 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_M48T86 is not set # CONFIG_RTC_DRV_M48T35 is not set # CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set # CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set # CONFIG_RTC_DRV_V3020 is not set # @@ -1664,6 +1707,7 @@ CONFIG_SCHED_DEBUG=y # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set # CONFIG_FAULT_INJECTION is not set # CONFIG_LATENCYTOP is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set # CONFIG_PAGE_POISONING is not set CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y @@ -1691,7 +1735,6 @@ CONFIG_BRANCH_PROFILE_NONE=y CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set # CONFIG_SH_STANDARD_BIOS is not set -# CONFIG_EARLY_SCIF_CONSOLE is not set # CONFIG_STACK_DEBUG is not set # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_4KSTACKS is not set @@ -1705,7 +1748,11 @@ CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" CONFIG_CRYPTO=y # diff --git a/arch/sh/configs/ul2_defconfig b/arch/sh/configs/ul2_defconfig index b012ca7..4fa03bf 100644 --- a/arch/sh/configs/ul2_defconfig +++ b/arch/sh/configs/ul2_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31 -# Thu Sep 24 19:42:33 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 15:18:53 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_SYS_SUPPORTS_HUGETLBFS=y CONFIG_SYS_SUPPORTS_NUMA=y CONFIG_SYS_SUPPORTS_CMT=y CONFIG_SYS_SUPPORTS_TMU=y @@ -31,6 +32,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_DMA_NONCOHERENT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -63,6 +65,7 @@ CONFIG_BSD_PROCESS_ACCT=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -102,6 +105,7 @@ CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters @@ -122,6 +126,7 @@ CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -148,14 +153,41 @@ CONFIG_LBDAF=y # IO Schedulers # CONFIG_IOSCHED_NOOP=y -# CONFIG_IOSCHED_AS is not set # CONFIG_IOSCHED_DEADLINE is not set # CONFIG_IOSCHED_CFQ is not set -# CONFIG_DEFAULT_AS is not set # CONFIG_DEFAULT_DEADLINE is not set # CONFIG_DEFAULT_CFQ is not set CONFIG_DEFAULT_NOOP=y CONFIG_DEFAULT_IOSCHED="noop" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +# CONFIG_INLINE_SPIN_UNLOCK is not set +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +# CONFIG_INLINE_READ_UNLOCK is not set +# CONFIG_INLINE_READ_UNLOCK_BH is not set +# CONFIG_INLINE_READ_UNLOCK_IRQ is not set +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +# CONFIG_INLINE_WRITE_UNLOCK is not set +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set CONFIG_FREEZER=y # @@ -247,8 +279,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -280,7 +310,6 @@ CONFIG_CPU_HAS_DSP=y # CONFIG_SH_TIMER_TMU=y # CONFIG_SH_TIMER_CMT is not set -CONFIG_SH_PCLK_FREQ=33333333 CONFIG_SH_CLK_CPG=y CONFIG_TICK_ONESHOT=y # CONFIG_NO_HZ is not set @@ -435,14 +464,17 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set CONFIG_WIRELESS=y +CONFIG_WIRELESS_EXT=y +CONFIG_WEXT_CORE=y +CONFIG_WEXT_PROC=y +CONFIG_WEXT_SPY=y CONFIG_CFG80211=y # CONFIG_NL80211_TESTMODE is not set # CONFIG_CFG80211_DEVELOPER_WARNINGS is not set # CONFIG_CFG80211_REG_DEBUG is not set CONFIG_CFG80211_DEFAULT_PS=y -CONFIG_CFG80211_DEFAULT_PS_VALUE=1 # CONFIG_WIRELESS_OLD_REGULATORY is not set -CONFIG_WIRELESS_EXT=y +CONFIG_CFG80211_WEXT=y CONFIG_WIRELESS_EXT_SYSFS=y CONFIG_LIB80211=m # CONFIG_LIB80211_DEBUG is not set @@ -559,6 +591,10 @@ CONFIG_MTD_RAM=y CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_UB is not set CONFIG_BLK_DEV_RAM=y @@ -576,6 +612,7 @@ CONFIG_MISC_DEVICES=y # EEPROM support # # CONFIG_EEPROM_93CX6 is not set +# CONFIG_IWMC3200TOP is not set CONFIG_HAVE_IDE=y # CONFIG_IDE is not set @@ -653,30 +690,29 @@ CONFIG_MII=y # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set # CONFIG_B44 is not set # CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set CONFIG_WLAN=y -# CONFIG_WLAN_PRE80211 is not set -CONFIG_WLAN_80211=y -CONFIG_LIBERTAS=m -# CONFIG_LIBERTAS_USB is not set -CONFIG_LIBERTAS_SDIO=m -CONFIG_LIBERTAS_DEBUG=y # CONFIG_LIBERTAS_THINFIRM is not set # CONFIG_AT76C50X_USB is not set # CONFIG_USB_ZD1201 is not set # CONFIG_USB_NET_RNDIS_WLAN is not set # CONFIG_RTL8187 is not set # CONFIG_MAC80211_HWSIM is not set -# CONFIG_P54_COMMON is not set # CONFIG_ATH_COMMON is not set -# CONFIG_HOSTAP is not set # CONFIG_B43 is not set # CONFIG_B43LEGACY is not set -# CONFIG_ZD1211RW is not set +# CONFIG_HOSTAP is not set +# CONFIG_IWM is not set +CONFIG_LIBERTAS=m +# CONFIG_LIBERTAS_USB is not set +CONFIG_LIBERTAS_SDIO=m +CONFIG_LIBERTAS_DEBUG=y +# CONFIG_P54_COMMON is not set # CONFIG_RT2X00 is not set # CONFIG_WL12XX is not set -# CONFIG_IWM is not set +# CONFIG_ZD1211RW is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers @@ -718,6 +754,7 @@ CONFIG_USB_NET_CDCETHER=y CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set # CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set # # Userland interfaces @@ -810,6 +847,7 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set # CONFIG_REGULATOR is not set @@ -951,6 +989,7 @@ CONFIG_MMC_BLOCK_BOUNCE=y # CONFIG_MMC_SDHCI is not set # CONFIG_MMC_AT91 is not set # CONFIG_MMC_ATMELMCI is not set +# CONFIG_MMC_TMIO is not set # CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set # CONFIG_ACCESSIBILITY is not set @@ -1133,7 +1172,7 @@ CONFIG_FRAME_WARN=1024 # CONFIG_DEBUG_KERNEL is not set # CONFIG_SLUB_DEBUG_ON is not set # CONFIG_SLUB_STATS is not set -# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_LATENCYTOP is not set @@ -1150,7 +1189,6 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set -# CONFIG_EARLY_SCIF_CONSOLE is not set # CONFIG_DWARF_UNWINDER is not set # @@ -1159,7 +1197,11 @@ CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" CONFIG_CRYPTO=y # diff --git a/arch/sh/configs/urquell_defconfig b/arch/sh/configs/urquell_defconfig index 9f8aee5..23bda19 100644 --- a/arch/sh/configs/urquell_defconfig +++ b/arch/sh/configs/urquell_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31 -# Thu Sep 24 19:46:13 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 15:27:53 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y # CONFIG_ARCH_SUSPEND_POSSIBLE is not set CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_SYS_SUPPORTS_HUGETLBFS=y CONFIG_SYS_SUPPORTS_SMP=y CONFIG_SYS_SUPPORTS_NUMA=y CONFIG_SYS_SUPPORTS_PCI=y @@ -32,6 +33,8 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_DMA_COHERENT=y +# CONFIG_DMA_NONCOHERENT is not set CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -66,6 +69,7 @@ CONFIG_AUDIT_TREE=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -120,12 +124,14 @@ CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters # CONFIG_PERF_EVENTS=y # CONFIG_PERF_COUNTERS is not set +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_PCI_QUIRKS=y CONFIG_COMPAT_BRK=y @@ -140,6 +146,7 @@ CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -162,19 +169,48 @@ CONFIG_BLOCK=y CONFIG_LBDAF=y # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set +# CONFIG_BLK_CGROUP is not set # # IO Schedulers # CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y +# CONFIG_CFQ_GROUP_IOSCHED is not set # CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +CONFIG_INLINE_SPIN_UNLOCK=y +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +CONFIG_INLINE_READ_UNLOCK=y +# CONFIG_INLINE_READ_UNLOCK_BH is not set +CONFIG_INLINE_READ_UNLOCK_IRQ=y +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +CONFIG_INLINE_WRITE_UNLOCK=y +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set CONFIG_FREEZER=y # @@ -229,6 +265,7 @@ CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_MEMORY_START=0x08000000 CONFIG_MEMORY_SIZE=0x08000000 CONFIG_29BIT=y +# CONFIG_PMB_ENABLE is not set # CONFIG_X2TLB is not set CONFIG_VSYSCALL=y # CONFIG_NUMA is not set @@ -263,8 +300,6 @@ CONFIG_MIGRATION=y # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -356,7 +391,6 @@ CONFIG_ENTRY_OFFSET=0x00001000 # Bus options # CONFIG_PCI=y -# CONFIG_SH_PCIDMA_NONCOHERENT is not set CONFIG_PCIEPORTBUS=y CONFIG_PCIEAER=y # CONFIG_PCIE_ECRC is not set @@ -469,10 +503,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_AF_RXRPC is not set CONFIG_WIRELESS=y # CONFIG_CFG80211 is not set -CONFIG_CFG80211_DEFAULT_PS_VALUE=0 -# CONFIG_WIRELESS_OLD_REGULATORY is not set -CONFIG_WIRELESS_EXT=y -CONFIG_WIRELESS_EXT_SYSFS=y # CONFIG_LIB80211 is not set # @@ -588,6 +618,10 @@ CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_SX8 is not set # CONFIG_BLK_DEV_UB is not set @@ -688,15 +722,16 @@ CONFIG_ATA_SFF=y # CONFIG_PATA_NS87415 is not set # CONFIG_PATA_OPTI is not set # CONFIG_PATA_OPTIDMA is not set +# CONFIG_PATA_PDC2027X is not set # CONFIG_PATA_PDC_OLD is not set # CONFIG_PATA_RADISYS is not set # CONFIG_PATA_RDC is not set # CONFIG_PATA_RZ1000 is not set # CONFIG_PATA_SC1200 is not set # CONFIG_PATA_SERVERWORKS is not set -# CONFIG_PATA_PDC2027X is not set # CONFIG_PATA_SIL680 is not set # CONFIG_PATA_SIS is not set +# CONFIG_PATA_TOSHIBA is not set # CONFIG_PATA_VIA is not set # CONFIG_PATA_WINBOND is not set # CONFIG_PATA_PLATFORM is not set @@ -787,6 +822,7 @@ CONFIG_8139CP=y # CONFIG_SUNDANCE is not set # CONFIG_TLAN is not set # CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set # CONFIG_VIA_RHINE is not set # CONFIG_SC92031 is not set # CONFIG_ATL2 is not set @@ -818,8 +854,10 @@ CONFIG_SKY2_DEBUG=y # CONFIG_NETDEV_10000 is not set # CONFIG_TR is not set CONFIG_WLAN=y -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +# CONFIG_ATMEL is not set +# CONFIG_PRISM54 is not set +# CONFIG_USB_ZD1201 is not set +# CONFIG_HOSTAP is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers @@ -842,6 +880,7 @@ CONFIG_WLAN=y # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_VMXNET3 is not set # CONFIG_ISDN is not set # CONFIG_PHONE is not set @@ -851,6 +890,7 @@ CONFIG_WLAN=y CONFIG_INPUT=y CONFIG_INPUT_FF_MEMLESS=m # CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set # # Userland interfaces @@ -976,11 +1016,6 @@ CONFIG_I2C_ALGOPCA=y # CONFIG_I2C_TINY_USB is not set # -# Graphics adapter I2C/DDC channel drivers -# -# CONFIG_I2C_VOODOO3 is not set - -# # Other I2C/SMBus bus drivers # CONFIG_I2C_PCA_PLATFORM=y @@ -989,7 +1024,6 @@ CONFIG_I2C_PCA_PLATFORM=y # # Miscellaneous I2C Chip support # -# CONFIG_DS1682 is not set # CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set @@ -1020,6 +1054,7 @@ CONFIG_GPIOLIB=y # # PCI GPIO expanders: # +# CONFIG_GPIO_CS5535 is not set # CONFIG_GPIO_BT8XX is not set # CONFIG_GPIO_LANGWELL is not set @@ -1062,6 +1097,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_GL520SM is not set # CONFIG_SENSORS_IT87 is not set # CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM73 is not set # CONFIG_SENSORS_LM75 is not set # CONFIG_SENSORS_LM77 is not set # CONFIG_SENSORS_LM78 is not set @@ -1101,6 +1137,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_W83L786NG is not set # CONFIG_SENSORS_W83627HF is not set # CONFIG_SENSORS_W83627EHF is not set +# CONFIG_SENSORS_LIS3_I2C is not set # CONFIG_THERMAL is not set # CONFIG_WATCHDOG is not set CONFIG_SSB_POSSIBLE=y @@ -1116,16 +1153,19 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_CORE is not set CONFIG_MFD_SM501=y # CONFIG_MFD_SM501_GPIO is not set +# CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_TPS65010 is not set # CONFIG_TWL4030_CORE is not set # CONFIG_MFD_TMIO is not set # CONFIG_PMIC_DA903X is not set +# CONFIG_PMIC_ADP5520 is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set # CONFIG_MFD_PCF50633 is not set # CONFIG_AB3100_CORE is not set +# CONFIG_MFD_88PM8607 is not set # CONFIG_REGULATOR is not set CONFIG_MEDIA_SUPPORT=y @@ -1139,6 +1179,8 @@ CONFIG_MEDIA_SUPPORT=y # # Multimedia drivers # +CONFIG_IR_CORE=y +CONFIG_VIDEO_IR=y # CONFIG_DAB is not set # @@ -1417,6 +1459,7 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_PCF8563 is not set # CONFIG_RTC_DRV_PCF8583 is not set # CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set # CONFIG_RTC_DRV_S35390A is not set # CONFIG_RTC_DRV_FM3130 is not set # CONFIG_RTC_DRV_RX8581 is not set @@ -1437,7 +1480,9 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_M48T86 is not set # CONFIG_RTC_DRV_M48T35 is not set # CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set # CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set # CONFIG_RTC_DRV_V3020 is not set # @@ -1466,7 +1511,6 @@ CONFIG_EXT3_FS_XATTR=y # CONFIG_EXT3_FS_POSIX_ACL is not set # CONFIG_EXT3_FS_SECURITY is not set CONFIG_EXT4_FS=y -# CONFIG_EXT4DEV_COMPAT is not set CONFIG_EXT4_FS_XATTR=y # CONFIG_EXT4_FS_POSIX_ACL is not set # CONFIG_EXT4_FS_SECURITY is not set @@ -1687,9 +1731,6 @@ CONFIG_TRACING_SUPPORT=y CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set # CONFIG_SH_STANDARD_BIOS is not set -CONFIG_EARLY_SCIF_CONSOLE=y -CONFIG_EARLY_SCIF_CONSOLE_PORT=0xffeb0000 -CONFIG_EARLY_PRINTK=y # CONFIG_STACK_DEBUG is not set # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_4KSTACKS is not set @@ -1703,7 +1744,11 @@ CONFIG_EARLY_PRINTK=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" CONFIG_CRYPTO=y # -- cgit v0.10.2 From 2f48912d1443a796f10c42c89cb386f0e3eca04d Mon Sep 17 00:00:00 2001 From: Daisuke HATAYAMA Date: Mon, 4 Jan 2010 15:42:14 +0900 Subject: binfmt_elf_fdpic: Fix build breakage introduced by coredump changes. Commit f6151dfea21496d43dbaba32cfcd9c9f404769bc introduces build breakage, so this patch fixes it together with some printk formatting cleanup. Signed-off-by: Daisuke HATAYAMA Signed-off-by: Paul Mundt diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index c25256a..7dc8599 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c @@ -1798,11 +1798,11 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm) ELF_CORE_WRITE_EXTRA_DATA; #endif - if (file->f_pos != offset) { + if (cprm->file->f_pos != offset) { /* Sanity check */ printk(KERN_WARNING "elf_core_dump: file->f_pos (%lld) != offset (%lld)\n", - file->f_pos, offset); + cprm->file->f_pos, offset); } end_coredump: -- cgit v0.10.2 From 0dfc84c9f54d8784f5bc6d303c079d88000ee5f7 Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Mon, 4 Jan 2010 14:44:42 +0800 Subject: [ARM] pxa: fix compiler warnings of unused variable 'id' in cpu_is_pxa9*() Signed-off-by: Eric Miao diff --git a/arch/arm/mach-pxa/include/mach/hardware.h b/arch/arm/mach-pxa/include/mach/hardware.h index 50f1297..e741bf1 100644 --- a/arch/arm/mach-pxa/include/mach/hardware.h +++ b/arch/arm/mach-pxa/include/mach/hardware.h @@ -250,20 +250,17 @@ #define cpu_is_pxa930() \ ({ \ - unsigned int id = read_cpuid(CPUID_ID); \ - __cpu_is_pxa930(id); \ + __cpu_is_pxa930(read_cpuid_id()); \ }) #define cpu_is_pxa935() \ ({ \ - unsigned int id = read_cpuid(CPUID_ID); \ - __cpu_is_pxa935(id); \ + __cpu_is_pxa935(read_cpuid_id()); \ }) #define cpu_is_pxa950() \ ({ \ - unsigned int id = read_cpuid(CPUID_ID); \ - __cpu_is_pxa950(id); \ + __cpu_is_pxa950(read_cpuid_id()); \ }) -- cgit v0.10.2 From 6486cda6c6b15368e2c925d89b4e9ed13e67b91b Mon Sep 17 00:00:00 2001 From: Jan Glauber Date: Mon, 4 Jan 2010 09:05:42 +0100 Subject: [S390] qdio: convert global statistics to per-device stats Revamp the qdio performance statistics and move them from procfs to debugfs using the seq_file interface. Since the statistics are not intended for the general user the removal of /proc/qdio_perf should not surprise anyone. The per device statistics are disabled by default, writing 1 to //qdio//statistics enables the statistics for the given device. Signed-off-by: Jan Glauber Signed-off-by: Martin Schwidefsky diff --git a/drivers/s390/cio/Makefile b/drivers/s390/cio/Makefile index d033414..e1b700a 100644 --- a/drivers/s390/cio/Makefile +++ b/drivers/s390/cio/Makefile @@ -10,5 +10,5 @@ obj-y += ccw_device.o cmf.o obj-$(CONFIG_CHSC_SCH) += chsc_sch.o obj-$(CONFIG_CCWGROUP) += ccwgroup.o -qdio-objs := qdio_main.o qdio_thinint.o qdio_debug.o qdio_perf.o qdio_setup.o +qdio-objs := qdio_main.o qdio_thinint.o qdio_debug.o qdio_setup.o obj-$(CONFIG_QDIO) += qdio.o diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h index ff7748a..44f2f6a 100644 --- a/drivers/s390/cio/qdio.h +++ b/drivers/s390/cio/qdio.h @@ -182,6 +182,34 @@ struct scssc_area { u32:32; } __attribute__ ((packed)); +struct qdio_dev_perf_stat { + unsigned int adapter_int; + unsigned int qdio_int; + unsigned int pci_request_int; + + unsigned int tasklet_inbound; + unsigned int tasklet_inbound_resched; + unsigned int tasklet_inbound_resched2; + unsigned int tasklet_outbound; + + unsigned int siga_read; + unsigned int siga_write; + unsigned int siga_sync; + + unsigned int inbound_call; + unsigned int inbound_handler; + unsigned int stop_polling; + unsigned int inbound_queue_full; + unsigned int outbound_call; + unsigned int outbound_handler; + unsigned int fast_requeue; + unsigned int target_full; + unsigned int eqbs; + unsigned int eqbs_partial; + unsigned int sqbs; + unsigned int sqbs_partial; +}; + struct qdio_input_q { /* input buffer acknowledgement flag */ int polling; @@ -269,6 +297,7 @@ struct qdio_irq { u32 *dsci; /* address of device state change indicator */ struct ccw_device *cdev; struct dentry *debugfs_dev; + struct dentry *debugfs_perf; unsigned long int_parm; struct subchannel_id schid; @@ -286,9 +315,10 @@ struct qdio_irq { struct ciw aqueue; struct qdio_ssqd_desc ssqd_desc; - void (*orig_handler) (struct ccw_device *, unsigned long, struct irb *); + struct qdio_dev_perf_stat perf_stat; + int perf_stat_enabled; /* * Warning: Leave these members together at the end so they won't be * cleared in qdio_setup_irq. @@ -311,6 +341,10 @@ struct qdio_irq { (irq->qib.qfmt == QDIO_IQDIO_QFMT || \ css_general_characteristics.aif_osa) +#define qperf(qdev,attr) qdev->perf_stat.attr +#define qperf_inc(q,attr) if (q->irq_ptr->perf_stat_enabled) \ + q->irq_ptr->perf_stat.attr++ + /* the highest iqdio queue is used for multicast */ static inline int multicast_outbound(struct qdio_q *q) { diff --git a/drivers/s390/cio/qdio_debug.c b/drivers/s390/cio/qdio_debug.c index 7676997..f49761f 100644 --- a/drivers/s390/cio/qdio_debug.c +++ b/drivers/s390/cio/qdio_debug.c @@ -55,13 +55,11 @@ static int qstat_show(struct seq_file *m, void *v) if (!q) return 0; - seq_printf(m, "device state indicator: %d\n", *(u32 *)q->irq_ptr->dsci); - seq_printf(m, "nr_used: %d\n", atomic_read(&q->nr_buf_used)); - seq_printf(m, "ftc: %d\n", q->first_to_check); - seq_printf(m, "last_move: %d\n", q->last_move); - seq_printf(m, "polling: %d\n", q->u.in.polling); - seq_printf(m, "ack start: %d\n", q->u.in.ack_start); - seq_printf(m, "ack count: %d\n", q->u.in.ack_count); + seq_printf(m, "DSCI: %d nr_used: %d\n", + *(u32 *)q->irq_ptr->dsci, atomic_read(&q->nr_buf_used)); + seq_printf(m, "ftc: %d last_move: %d\n", q->first_to_check, q->last_move); + seq_printf(m, "polling: %d ack start: %d ack count: %d\n", + q->u.in.polling, q->u.in.ack_start, q->u.in.ack_count); seq_printf(m, "slsb buffer states:\n"); seq_printf(m, "|0 |8 |16 |24 |32 |40 |48 |56 63|\n"); @@ -110,7 +108,6 @@ static ssize_t qstat_seq_write(struct file *file, const char __user *buf, if (!q) return 0; - if (q->is_input_q) xchg(q->irq_ptr->dsci, 1); local_bh_disable(); @@ -134,6 +131,98 @@ static const struct file_operations debugfs_fops = { .release = single_release, }; +static char *qperf_names[] = { + "Assumed adapter interrupts", + "QDIO interrupts", + "Requested PCIs", + "Inbound tasklet runs", + "Inbound tasklet resched", + "Inbound tasklet resched2", + "Outbound tasklet runs", + "SIGA read", + "SIGA write", + "SIGA sync", + "Inbound calls", + "Inbound handler", + "Inbound stop_polling", + "Inbound queue full", + "Outbound calls", + "Outbound handler", + "Outbound fast_requeue", + "Outbound target_full", + "QEBSM eqbs", + "QEBSM eqbs partial", + "QEBSM sqbs", + "QEBSM sqbs partial" +}; + +static int qperf_show(struct seq_file *m, void *v) +{ + struct qdio_irq *irq_ptr = m->private; + unsigned int *stat; + int i; + + if (!irq_ptr) + return 0; + if (!irq_ptr->perf_stat_enabled) { + seq_printf(m, "disabled\n"); + return 0; + } + stat = (unsigned int *)&irq_ptr->perf_stat; + + for (i = 0; i < ARRAY_SIZE(qperf_names); i++) + seq_printf(m, "%26s:\t%u\n", + qperf_names[i], *(stat + i)); + return 0; +} + +static ssize_t qperf_seq_write(struct file *file, const char __user *ubuf, + size_t count, loff_t *off) +{ + struct seq_file *seq = file->private_data; + struct qdio_irq *irq_ptr = seq->private; + unsigned long val; + char buf[8]; + int ret; + + if (!irq_ptr) + return 0; + if (count >= sizeof(buf)) + return -EINVAL; + if (copy_from_user(&buf, ubuf, count)) + return -EFAULT; + buf[count] = 0; + + ret = strict_strtoul(buf, 10, &val); + if (ret < 0) + return ret; + + switch (val) { + case 0: + irq_ptr->perf_stat_enabled = 0; + memset(&irq_ptr->perf_stat, 0, sizeof(irq_ptr->perf_stat)); + break; + case 1: + irq_ptr->perf_stat_enabled = 1; + break; + } + return count; +} + +static int qperf_seq_open(struct inode *inode, struct file *filp) +{ + return single_open(filp, qperf_show, + filp->f_path.dentry->d_inode->i_private); +} + +static struct file_operations debugfs_perf_fops = { + .owner = THIS_MODULE, + .open = qperf_seq_open, + .read = seq_read, + .write = qperf_seq_write, + .llseek = seq_lseek, + .release = single_release, +}; static void setup_debugfs_entry(struct qdio_q *q, struct ccw_device *cdev) { char name[QDIO_DEBUGFS_NAME_LEN]; @@ -156,6 +245,14 @@ void qdio_setup_debug_entries(struct qdio_irq *irq_ptr, struct ccw_device *cdev) debugfs_root); if (IS_ERR(irq_ptr->debugfs_dev)) irq_ptr->debugfs_dev = NULL; + + irq_ptr->debugfs_perf = debugfs_create_file("statistics", + S_IFREG | S_IRUGO | S_IWUSR, + irq_ptr->debugfs_dev, irq_ptr, + &debugfs_perf_fops); + if (IS_ERR(irq_ptr->debugfs_perf)) + irq_ptr->debugfs_perf = NULL; + for_each_input_queue(irq_ptr, q, i) setup_debugfs_entry(q, cdev); for_each_output_queue(irq_ptr, q, i) @@ -171,6 +268,7 @@ void qdio_shutdown_debug_entries(struct qdio_irq *irq_ptr, struct ccw_device *cd debugfs_remove(q->debugfs_q); for_each_output_queue(irq_ptr, q, i) debugfs_remove(q->debugfs_q); + debugfs_remove(irq_ptr->debugfs_perf); debugfs_remove(irq_ptr->debugfs_dev); } diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c index b2275c5..999fe80 100644 --- a/drivers/s390/cio/qdio_main.c +++ b/drivers/s390/cio/qdio_main.c @@ -22,7 +22,6 @@ #include "device.h" #include "qdio.h" #include "qdio_debug.h" -#include "qdio_perf.h" MODULE_AUTHOR("Utz Bacher ,"\ "Jan Glauber "); @@ -126,7 +125,7 @@ static int qdio_do_eqbs(struct qdio_q *q, unsigned char *state, int rc; BUG_ON(!q->irq_ptr->sch_token); - qdio_perf_stat_inc(&perf_stats.debug_eqbs_all); + qperf_inc(q, eqbs); if (!q->is_input_q) nr += q->irq_ptr->nr_input_qs; @@ -139,7 +138,7 @@ again: * buffers later. */ if ((ccq == 96) && (count != tmp_count)) { - qdio_perf_stat_inc(&perf_stats.debug_eqbs_incomplete); + qperf_inc(q, eqbs_partial); return (count - tmp_count); } @@ -182,7 +181,7 @@ static int qdio_do_sqbs(struct qdio_q *q, unsigned char state, int start, return 0; BUG_ON(!q->irq_ptr->sch_token); - qdio_perf_stat_inc(&perf_stats.debug_sqbs_all); + qperf_inc(q, sqbs); if (!q->is_input_q) nr += q->irq_ptr->nr_input_qs; @@ -191,7 +190,7 @@ again: rc = qdio_check_ccq(q, ccq); if (rc == 1) { DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "SQBS again:%2d", ccq); - qdio_perf_stat_inc(&perf_stats.debug_sqbs_incomplete); + qperf_inc(q, sqbs_partial); goto again; } if (rc < 0) { @@ -285,7 +284,7 @@ static inline int qdio_siga_sync(struct qdio_q *q, unsigned int output, return 0; DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-s:%1d", q->nr); - qdio_perf_stat_inc(&perf_stats.siga_sync); + qperf_inc(q, siga_sync); cc = do_siga_sync(q->irq_ptr->schid, output, input); if (cc) @@ -350,7 +349,7 @@ static inline int qdio_siga_input(struct qdio_q *q) int cc; DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-r:%1d", q->nr); - qdio_perf_stat_inc(&perf_stats.siga_in); + qperf_inc(q, siga_read); cc = do_siga_input(q->irq_ptr->schid, q->mask); if (cc) @@ -382,7 +381,7 @@ static inline void qdio_stop_polling(struct qdio_q *q) return; q->u.in.polling = 0; - qdio_perf_stat_inc(&perf_stats.debug_stop_polling); + qperf_inc(q, stop_polling); /* show the card that we are not polling anymore */ if (is_qebsm(q)) { @@ -400,7 +399,7 @@ static void announce_buffer_error(struct qdio_q *q, int count) /* special handling for no target buffer empty */ if ((!q->is_input_q && (q->sbal[q->first_to_check]->element[15].flags & 0xff) == 0x10)) { - qdio_perf_stat_inc(&perf_stats.outbound_target_full); + qperf_inc(q, target_full); DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "OUTFULL FTC:%02x", q->first_to_check); return; @@ -487,7 +486,7 @@ static int get_inbound_buffer_frontier(struct qdio_q *q) inbound_primed(q, count); q->first_to_check = add_buf(q->first_to_check, count); if (atomic_sub(count, &q->nr_buf_used) == 0) - qdio_perf_stat_inc(&perf_stats.inbound_queue_full); + qperf_inc(q, inbound_queue_full); break; case SLSB_P_INPUT_ERROR: announce_buffer_error(q, count); @@ -567,9 +566,10 @@ static void qdio_kick_handler(struct qdio_q *q) count = sub_buf(end, start); if (q->is_input_q) { - qdio_perf_stat_inc(&perf_stats.inbound_handler); + qperf_inc(q, inbound_handler); DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "kih s:%02x c:%02x", start, count); } else + qperf_inc(q, outbound_handler); DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "koh: s:%02x c:%02x", start, count); @@ -583,24 +583,28 @@ static void qdio_kick_handler(struct qdio_q *q) static void __qdio_inbound_processing(struct qdio_q *q) { - qdio_perf_stat_inc(&perf_stats.tasklet_inbound); + qperf_inc(q, tasklet_inbound); again: if (!qdio_inbound_q_moved(q)) return; qdio_kick_handler(q); - if (!qdio_inbound_q_done(q)) + if (!qdio_inbound_q_done(q)) { /* means poll time is not yet over */ + qperf_inc(q, tasklet_inbound_resched); goto again; + } qdio_stop_polling(q); /* * We need to check again to not lose initiative after * resetting the ACK state. */ - if (!qdio_inbound_q_done(q)) + if (!qdio_inbound_q_done(q)) { + qperf_inc(q, tasklet_inbound_resched2); goto again; + } } void qdio_inbound_processing(unsigned long data) @@ -688,7 +692,7 @@ static int qdio_kick_outbound_q(struct qdio_q *q) return 0; DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-w:%1d", q->nr); - qdio_perf_stat_inc(&perf_stats.siga_out); + qperf_inc(q, siga_write); cc = qdio_siga_output(q, &busy_bit); switch (cc) { @@ -711,7 +715,7 @@ static int qdio_kick_outbound_q(struct qdio_q *q) static void __qdio_outbound_processing(struct qdio_q *q) { - qdio_perf_stat_inc(&perf_stats.tasklet_outbound); + qperf_inc(q, tasklet_outbound); BUG_ON(atomic_read(&q->nr_buf_used) < 0); if (qdio_outbound_q_moved(q)) @@ -739,12 +743,9 @@ static void __qdio_outbound_processing(struct qdio_q *q) */ if (qdio_outbound_q_done(q)) del_timer(&q->u.out.timer); - else { - if (!timer_pending(&q->u.out.timer)) { + else + if (!timer_pending(&q->u.out.timer)) mod_timer(&q->u.out.timer, jiffies + 10 * HZ); - qdio_perf_stat_inc(&perf_stats.debug_tl_out_timer); - } - } return; sched: @@ -784,7 +785,7 @@ static inline void qdio_check_outbound_after_thinint(struct qdio_q *q) static void __tiqdio_inbound_processing(struct qdio_q *q) { - qdio_perf_stat_inc(&perf_stats.thinint_inbound); + qperf_inc(q, tasklet_inbound); qdio_sync_after_thinint(q); /* @@ -799,7 +800,7 @@ static void __tiqdio_inbound_processing(struct qdio_q *q) qdio_kick_handler(q); if (!qdio_inbound_q_done(q)) { - qdio_perf_stat_inc(&perf_stats.thinint_inbound_loop); + qperf_inc(q, tasklet_inbound_resched); if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED)) { tasklet_schedule(&q->tasklet); return; @@ -812,7 +813,7 @@ static void __tiqdio_inbound_processing(struct qdio_q *q) * resetting the ACK state. */ if (!qdio_inbound_q_done(q)) { - qdio_perf_stat_inc(&perf_stats.thinint_inbound_loop2); + qperf_inc(q, tasklet_inbound_resched2); if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED)) tasklet_schedule(&q->tasklet); } @@ -851,8 +852,6 @@ static void qdio_int_handler_pci(struct qdio_irq *irq_ptr) if (unlikely(irq_ptr->state == QDIO_IRQ_STATE_STOPPED)) return; - qdio_perf_stat_inc(&perf_stats.pci_int); - for_each_input_queue(irq_ptr, q, i) tasklet_schedule(&q->tasklet); @@ -923,8 +922,6 @@ void qdio_int_handler(struct ccw_device *cdev, unsigned long intparm, struct qdio_irq *irq_ptr = cdev->private->qdio_data; int cstat, dstat; - qdio_perf_stat_inc(&perf_stats.qdio_int); - if (!intparm || !irq_ptr) { DBF_ERROR("qint:%4x", cdev->private->schid.sch_no); return; @@ -1383,6 +1380,8 @@ static int handle_inbound(struct qdio_q *q, unsigned int callflags, { int used, diff; + qperf_inc(q, inbound_call); + if (!q->u.in.polling) goto set; @@ -1438,14 +1437,16 @@ static int handle_outbound(struct qdio_q *q, unsigned int callflags, unsigned char state; int used, rc = 0; - qdio_perf_stat_inc(&perf_stats.outbound_handler); + qperf_inc(q, outbound_call); count = set_buf_states(q, bufnr, SLSB_CU_OUTPUT_PRIMED, count); used = atomic_add_return(count, &q->nr_buf_used); BUG_ON(used > QDIO_MAX_BUFFERS_PER_Q); - if (callflags & QDIO_FLAG_PCI_OUT) + if (callflags & QDIO_FLAG_PCI_OUT) { q->u.out.pci_out_enabled = 1; + qperf_inc(q, pci_request_int); + } else q->u.out.pci_out_enabled = 0; @@ -1484,7 +1485,7 @@ static int handle_outbound(struct qdio_q *q, unsigned int callflags, if (state != SLSB_CU_OUTPUT_PRIMED) rc = qdio_kick_outbound_q(q); else - qdio_perf_stat_inc(&perf_stats.fast_requeue); + qperf_inc(q, fast_requeue); out: tasklet_schedule(&q->tasklet); @@ -1540,16 +1541,11 @@ static int __init init_QDIO(void) rc = qdio_debug_init(); if (rc) goto out_ti; - rc = qdio_setup_perf_stats(); - if (rc) - goto out_debug; rc = tiqdio_register_thinints(); if (rc) - goto out_perf; + goto out_debug; return 0; -out_perf: - qdio_remove_perf_stats(); out_debug: qdio_debug_exit(); out_ti: @@ -1563,7 +1559,6 @@ static void __exit exit_QDIO(void) { tiqdio_unregister_thinints(); tiqdio_free_memory(); - qdio_remove_perf_stats(); qdio_debug_exit(); qdio_setup_exit(); } diff --git a/drivers/s390/cio/qdio_perf.c b/drivers/s390/cio/qdio_perf.c deleted file mode 100644 index 54f7c32..0000000 --- a/drivers/s390/cio/qdio_perf.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - * drivers/s390/cio/qdio_perf.c - * - * Copyright IBM Corp. 2008 - * - * Author: Jan Glauber (jang@linux.vnet.ibm.com) - */ -#include -#include -#include -#include - -#include "cio.h" -#include "css.h" -#include "device.h" -#include "ioasm.h" -#include "chsc.h" -#include "qdio_debug.h" -#include "qdio_perf.h" - -int qdio_performance_stats; -struct qdio_perf_stats perf_stats; - -#ifdef CONFIG_PROC_FS -static struct proc_dir_entry *qdio_perf_pde; -#endif - -/* - * procfs functions - */ -static int qdio_perf_proc_show(struct seq_file *m, void *v) -{ - seq_printf(m, "Number of qdio interrupts\t\t\t: %li\n", - (long)atomic_long_read(&perf_stats.qdio_int)); - seq_printf(m, "Number of PCI interrupts\t\t\t: %li\n", - (long)atomic_long_read(&perf_stats.pci_int)); - seq_printf(m, "Number of adapter interrupts\t\t\t: %li\n", - (long)atomic_long_read(&perf_stats.thin_int)); - seq_printf(m, "\n"); - seq_printf(m, "Inbound tasklet runs\t\t\t\t: %li\n", - (long)atomic_long_read(&perf_stats.tasklet_inbound)); - seq_printf(m, "Outbound tasklet runs\t\t\t\t: %li\n", - (long)atomic_long_read(&perf_stats.tasklet_outbound)); - seq_printf(m, "Adapter interrupt tasklet runs/loops\t\t: %li/%li\n", - (long)atomic_long_read(&perf_stats.tasklet_thinint), - (long)atomic_long_read(&perf_stats.tasklet_thinint_loop)); - seq_printf(m, "Adapter interrupt inbound tasklet runs/loops\t: %li/%li\n", - (long)atomic_long_read(&perf_stats.thinint_inbound), - (long)atomic_long_read(&perf_stats.thinint_inbound_loop)); - seq_printf(m, "\n"); - seq_printf(m, "Number of SIGA In issued\t\t\t: %li\n", - (long)atomic_long_read(&perf_stats.siga_in)); - seq_printf(m, "Number of SIGA Out issued\t\t\t: %li\n", - (long)atomic_long_read(&perf_stats.siga_out)); - seq_printf(m, "Number of SIGA Sync issued\t\t\t: %li\n", - (long)atomic_long_read(&perf_stats.siga_sync)); - seq_printf(m, "\n"); - seq_printf(m, "Number of inbound transfers\t\t\t: %li\n", - (long)atomic_long_read(&perf_stats.inbound_handler)); - seq_printf(m, "Number of outbound transfers\t\t\t: %li\n", - (long)atomic_long_read(&perf_stats.outbound_handler)); - seq_printf(m, "\n"); - seq_printf(m, "Number of fast requeues (outg. SBAL w/o SIGA)\t: %li\n", - (long)atomic_long_read(&perf_stats.fast_requeue)); - seq_printf(m, "Number of outbound target full condition\t: %li\n", - (long)atomic_long_read(&perf_stats.outbound_target_full)); - seq_printf(m, "Number of inbound queue full condition\t\t: %li\n", - (long)atomic_long_read(&perf_stats.inbound_queue_full)); - seq_printf(m, "Number of outbound tasklet mod_timer calls\t: %li\n", - (long)atomic_long_read(&perf_stats.debug_tl_out_timer)); - seq_printf(m, "Number of stop polling calls\t\t\t: %li\n", - (long)atomic_long_read(&perf_stats.debug_stop_polling)); - seq_printf(m, "AI inbound tasklet loops after stop polling\t: %li\n", - (long)atomic_long_read(&perf_stats.thinint_inbound_loop2)); - seq_printf(m, "QEBSM EQBS total/incomplete\t\t\t: %li/%li\n", - (long)atomic_long_read(&perf_stats.debug_eqbs_all), - (long)atomic_long_read(&perf_stats.debug_eqbs_incomplete)); - seq_printf(m, "QEBSM SQBS total/incomplete\t\t\t: %li/%li\n", - (long)atomic_long_read(&perf_stats.debug_sqbs_all), - (long)atomic_long_read(&perf_stats.debug_sqbs_incomplete)); - seq_printf(m, "\n"); - return 0; -} -static int qdio_perf_seq_open(struct inode *inode, struct file *filp) -{ - return single_open(filp, qdio_perf_proc_show, NULL); -} - -static const struct file_operations qdio_perf_proc_fops = { - .owner = THIS_MODULE, - .open = qdio_perf_seq_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -/* - * sysfs functions - */ -static ssize_t qdio_perf_stats_show(struct bus_type *bus, char *buf) -{ - return sprintf(buf, "%i\n", qdio_performance_stats ? 1 : 0); -} - -static ssize_t qdio_perf_stats_store(struct bus_type *bus, - const char *buf, size_t count) -{ - unsigned long i; - - if (strict_strtoul(buf, 16, &i) != 0) - return -EINVAL; - if ((i != 0) && (i != 1)) - return -EINVAL; - if (i == qdio_performance_stats) - return count; - - qdio_performance_stats = i; - /* reset performance statistics */ - if (i == 0) - memset(&perf_stats, 0, sizeof(struct qdio_perf_stats)); - return count; -} - -static BUS_ATTR(qdio_performance_stats, 0644, qdio_perf_stats_show, - qdio_perf_stats_store); - -int __init qdio_setup_perf_stats(void) -{ - int rc; - - rc = bus_create_file(&ccw_bus_type, &bus_attr_qdio_performance_stats); - if (rc) - return rc; - -#ifdef CONFIG_PROC_FS - memset(&perf_stats, 0, sizeof(struct qdio_perf_stats)); - qdio_perf_pde = proc_create("qdio_perf", S_IFREG | S_IRUGO, - NULL, &qdio_perf_proc_fops); -#endif - return 0; -} - -void qdio_remove_perf_stats(void) -{ -#ifdef CONFIG_PROC_FS - remove_proc_entry("qdio_perf", NULL); -#endif - bus_remove_file(&ccw_bus_type, &bus_attr_qdio_performance_stats); -} diff --git a/drivers/s390/cio/qdio_perf.h b/drivers/s390/cio/qdio_perf.h deleted file mode 100644 index 1245423..0000000 --- a/drivers/s390/cio/qdio_perf.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * drivers/s390/cio/qdio_perf.h - * - * Copyright IBM Corp. 2008 - * - * Author: Jan Glauber (jang@linux.vnet.ibm.com) - */ -#ifndef QDIO_PERF_H -#define QDIO_PERF_H - -#include -#include - -struct qdio_perf_stats { - /* interrupt handler calls */ - atomic_long_t qdio_int; - atomic_long_t pci_int; - atomic_long_t thin_int; - - /* tasklet runs */ - atomic_long_t tasklet_inbound; - atomic_long_t tasklet_outbound; - atomic_long_t tasklet_thinint; - atomic_long_t tasklet_thinint_loop; - atomic_long_t thinint_inbound; - atomic_long_t thinint_inbound_loop; - atomic_long_t thinint_inbound_loop2; - - /* signal adapter calls */ - atomic_long_t siga_out; - atomic_long_t siga_in; - atomic_long_t siga_sync; - - /* misc */ - atomic_long_t inbound_handler; - atomic_long_t outbound_handler; - atomic_long_t fast_requeue; - atomic_long_t outbound_target_full; - atomic_long_t inbound_queue_full; - - /* for debugging */ - atomic_long_t debug_tl_out_timer; - atomic_long_t debug_stop_polling; - atomic_long_t debug_eqbs_all; - atomic_long_t debug_eqbs_incomplete; - atomic_long_t debug_sqbs_all; - atomic_long_t debug_sqbs_incomplete; -}; - -extern struct qdio_perf_stats perf_stats; -extern int qdio_performance_stats; - -static inline void qdio_perf_stat_inc(atomic_long_t *count) -{ - if (qdio_performance_stats) - atomic_long_inc(count); -} - -int qdio_setup_perf_stats(void); -void qdio_remove_perf_stats(void); - -#endif diff --git a/drivers/s390/cio/qdio_thinint.c b/drivers/s390/cio/qdio_thinint.c index 981a77e..091d904 100644 --- a/drivers/s390/cio/qdio_thinint.c +++ b/drivers/s390/cio/qdio_thinint.c @@ -1,9 +1,7 @@ /* * linux/drivers/s390/cio/thinint_qdio.c * - * thin interrupt support for qdio - * - * Copyright 2000-2008 IBM Corp. + * Copyright 2000,2009 IBM Corp. * Author(s): Utz Bacher * Cornelia Huck * Jan Glauber @@ -19,7 +17,6 @@ #include "ioasm.h" #include "qdio.h" #include "qdio_debug.h" -#include "qdio_perf.h" /* * Restriction: only 63 iqdio subchannels would have its own indicator, @@ -132,8 +129,6 @@ static void tiqdio_thinint_handler(void *ind, void *drv_data) { struct qdio_q *q; - qdio_perf_stat_inc(&perf_stats.thin_int); - /* * SVS only when needed: issue SVS to benefit from iqdio interrupt * avoidance (SVS clears adapter interrupt suppression overwrite) @@ -154,6 +149,7 @@ static void tiqdio_thinint_handler(void *ind, void *drv_data) list_for_each_entry_rcu(q, &tiq_list, entry) /* only process queues from changed sets */ if (*q->irq_ptr->dsci) { + qperf_inc(q, adapter_int); /* only clear it if the indicator is non-shared */ if (!shared_ind(q->irq_ptr)) -- cgit v0.10.2 From f5cae7b0fb6927981a839443dfa6d73c30415cba Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Mon, 4 Jan 2010 09:05:43 +0100 Subject: [S390] Have param.h simply include . Since the files have identical content, might as well simplify. Signed-off-by: Robert P. J. Day Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky diff --git a/arch/s390/include/asm/param.h b/arch/s390/include/asm/param.h index 34aaa46..c616821 100644 --- a/arch/s390/include/asm/param.h +++ b/arch/s390/include/asm/param.h @@ -1,30 +1,6 @@ -/* - * include/asm-s390/param.h - * - * S390 version - * - * Derived from "include/asm-i386/param.h" - */ - #ifndef _ASMS390_PARAM_H #define _ASMS390_PARAM_H -#ifdef __KERNEL__ -# define HZ CONFIG_HZ /* Internal kernel timer frequency */ -# define USER_HZ 100 /* .. some user interfaces are in "ticks" */ -# define CLOCKS_PER_SEC (USER_HZ) /* like times() */ -#endif - -#ifndef HZ -#define HZ 100 -#endif - -#define EXEC_PAGESIZE 4096 - -#ifndef NOGROUP -#define NOGROUP (-1) -#endif - -#define MAXHOSTNAMELEN 64 /* max length of hostname */ +#include -#endif +#endif /* _ASMS390_PARAM_H */ -- cgit v0.10.2 From cc4707b31198d27baae650db1721a2f05701db37 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Mon, 4 Jan 2010 09:05:44 +0100 Subject: [S390] Update default configuration. Signed-off-by: Martin Schwidefsky diff --git a/arch/s390/defconfig b/arch/s390/defconfig index f4e53c6..b416aa1 100644 --- a/arch/s390/defconfig +++ b/arch/s390/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31 -# Tue Sep 22 17:43:13 2009 +# Linux kernel version: 2.6.33-rc2 +# Mon Jan 4 09:03:07 2010 # CONFIG_SCHED_MC=y CONFIG_MMU=y @@ -51,6 +51,7 @@ CONFIG_AUDIT=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=64 # CONFIG_RCU_FANOUT_EXACT is not set @@ -113,7 +114,6 @@ CONFIG_HAVE_PERF_EVENTS=y # CONFIG_PERF_EVENTS is not set # CONFIG_PERF_COUNTERS is not set CONFIG_VM_EVENT_COUNTERS=y -# CONFIG_STRIP_ASM_SYMS is not set # CONFIG_COMPAT_BRK is not set CONFIG_SLAB=y # CONFIG_SLUB is not set @@ -149,21 +149,78 @@ CONFIG_STOP_MACHINE=y CONFIG_BLOCK=y CONFIG_BLK_DEV_BSG=y # CONFIG_BLK_DEV_INTEGRITY is not set +# CONFIG_BLK_CGROUP is not set CONFIG_BLOCK_COMPAT=y # # IO Schedulers # CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y -# CONFIG_DEFAULT_AS is not set +# CONFIG_CFQ_GROUP_IOSCHED is not set CONFIG_DEFAULT_DEADLINE=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="deadline" CONFIG_PREEMPT_NOTIFIERS=y +CONFIG_ARCH_INLINE_SPIN_TRYLOCK=y +CONFIG_ARCH_INLINE_SPIN_TRYLOCK_BH=y +CONFIG_ARCH_INLINE_SPIN_LOCK=y +CONFIG_ARCH_INLINE_SPIN_LOCK_BH=y +CONFIG_ARCH_INLINE_SPIN_LOCK_IRQ=y +CONFIG_ARCH_INLINE_SPIN_LOCK_IRQSAVE=y +CONFIG_ARCH_INLINE_SPIN_UNLOCK=y +CONFIG_ARCH_INLINE_SPIN_UNLOCK_BH=y +CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQ=y +CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE=y +CONFIG_ARCH_INLINE_READ_TRYLOCK=y +CONFIG_ARCH_INLINE_READ_LOCK=y +CONFIG_ARCH_INLINE_READ_LOCK_BH=y +CONFIG_ARCH_INLINE_READ_LOCK_IRQ=y +CONFIG_ARCH_INLINE_READ_LOCK_IRQSAVE=y +CONFIG_ARCH_INLINE_READ_UNLOCK=y +CONFIG_ARCH_INLINE_READ_UNLOCK_BH=y +CONFIG_ARCH_INLINE_READ_UNLOCK_IRQ=y +CONFIG_ARCH_INLINE_READ_UNLOCK_IRQRESTORE=y +CONFIG_ARCH_INLINE_WRITE_TRYLOCK=y +CONFIG_ARCH_INLINE_WRITE_LOCK=y +CONFIG_ARCH_INLINE_WRITE_LOCK_BH=y +CONFIG_ARCH_INLINE_WRITE_LOCK_IRQ=y +CONFIG_ARCH_INLINE_WRITE_LOCK_IRQSAVE=y +CONFIG_ARCH_INLINE_WRITE_UNLOCK=y +CONFIG_ARCH_INLINE_WRITE_UNLOCK_BH=y +CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQ=y +CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE=y +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +# CONFIG_INLINE_SPIN_UNLOCK is not set +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +# CONFIG_INLINE_READ_UNLOCK is not set +# CONFIG_INLINE_READ_UNLOCK_BH is not set +# CONFIG_INLINE_READ_UNLOCK_IRQ is not set +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +# CONFIG_INLINE_WRITE_UNLOCK is not set +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set CONFIG_FREEZER=y # @@ -227,14 +284,13 @@ CONFIG_MEMORY_HOTPLUG=y CONFIG_MEMORY_HOTPLUG_SPARSE=y CONFIG_MEMORY_HOTREMOVE=y CONFIG_PAGEFLAGS_EXTENDED=y -CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_SPLIT_PTLOCK_CPUS=999999 CONFIG_MIGRATION=y CONFIG_PHYS_ADDR_T_64BIT=y CONFIG_ZONE_DMA_FLAG=1 CONFIG_BOUNCE=y CONFIG_VIRT_TO_BUS=y -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y +# CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 # @@ -339,6 +395,7 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=y CONFIG_INET6_XFRM_MODE_BEET=y # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set CONFIG_IPV6_SIT=y +# CONFIG_IPV6_SIT_6RD is not set CONFIG_IPV6_NDISC_NODETYPE=y # CONFIG_IPV6_TUNNEL is not set # CONFIG_IPV6_MULTIPLE_TABLES is not set @@ -504,6 +561,10 @@ CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=m # CONFIG_BLK_DEV_CRYPTOLOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# CONFIG_BLK_DEV_NBD=m # CONFIG_BLK_DEV_OSD is not set CONFIG_BLK_DEV_RAM=y @@ -710,7 +771,6 @@ CONFIG_S390_VMUR=m # CONFIG_PPS is not set # CONFIG_POWER_SUPPLY is not set # CONFIG_THERMAL is not set -# CONFIG_THERMAL_HWMON is not set # CONFIG_WATCHDOG is not set # CONFIG_REGULATOR is not set # CONFIG_MEMSTICK is not set @@ -864,6 +924,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y CONFIG_FRAME_WARN=2048 CONFIG_MAGIC_SYSRQ=y +# CONFIG_STRIP_ASM_SYMS is not set # CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set @@ -931,7 +992,6 @@ CONFIG_BRANCH_PROFILE_NONE=y CONFIG_SAMPLES=y # CONFIG_SAMPLE_KOBJECT is not set # CONFIG_SAMPLE_KPROBES is not set -# CONFIG_KMEMCHECK is not set # # Security options @@ -939,7 +999,11 @@ CONFIG_SAMPLES=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" CONFIG_CRYPTO=y # -- cgit v0.10.2 From 17740d89785aeb4143770923d67c293849414710 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 28 Aug 2009 10:47:16 +0200 Subject: SECURITY: selinux, fix update_rlimit_cpu parameter Don't pass current RLIMIT_RTTIME to update_rlimit_cpu() in selinux_bprm_committing_creds, since update_rlimit_cpu expects RLIMIT_CPU limit. Use proper rlim[RLIMIT_CPU].rlim_cur instead to fix that. Signed-off-by: Jiri Slaby Acked-by: James Morris Cc: Stephen Smalley Cc: Eric Paris Cc: David Howells diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 7a374c2..9a2ee84 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -2365,7 +2365,7 @@ static void selinux_bprm_committing_creds(struct linux_binprm *bprm) initrlim = init_task.signal->rlim + i; rlim->rlim_cur = min(rlim->rlim_max, initrlim->rlim_cur); } - update_rlimit_cpu(rlim->rlim_cur); + update_rlimit_cpu(current->signal->rlim[RLIMIT_CPU].rlim_cur); } } -- cgit v0.10.2 From 96d07d211739fd2450ac54e81d00fa40fcd4b1bd Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 20 Nov 2009 14:16:33 +0100 Subject: resource: move kernel function inside __KERNEL__ It is an internal function. Move it inside __KERNEL__ ifdef, along with task_struct declaration. Then we get: --- /usr/include/linux/resource.h 2009-09-14 15:09:29.000000000 +0200 +++ usr/include/linux/resource.h 2010-01-04 11:30:54.000000000 +0100 @@ -3,8 +3,6 @@ #include -struct task_struct; - /* * Resource control/accounting header file for linux */ @@ -70,6 +68,5 @@ */ #include -int getrusage(struct task_struct *p, int who, struct rusage *ru); #endif *********** include/linux/Kbuild is untouched, since unifdef is run even on headers-y nowadays. Signed-off-by: Jiri Slaby diff --git a/include/linux/resource.h b/include/linux/resource.h index 40fc7e6..f1e914e 100644 --- a/include/linux/resource.h +++ b/include/linux/resource.h @@ -3,8 +3,6 @@ #include -struct task_struct; - /* * Resource control/accounting header file for linux */ @@ -70,6 +68,12 @@ struct rlimit { */ #include +#ifdef __KERNEL__ + +struct task_struct; + int getrusage(struct task_struct *p, int who, struct rusage __user *ru); +#endif /* __KERNEL__ */ + #endif -- cgit v0.10.2 From 3e10e716abf3c71bdb5d86b8f507f9e72236c9cd Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 19 Nov 2009 17:16:37 +0100 Subject: resource: add helpers for fetching rlimits We want to be sure that compiler fetches the limit variable only once, so add helpers for fetching current and maximal resource limits which do that. Add them to sched.h (instead of resource.h) due to circular dependency sched.h->resource.h->task_struct Alternative would be to create a separate res_access.h or similar. Signed-off-by: Jiri Slaby Cc: James Morris Cc: Heiko Carstens Cc: Andrew Morton Cc: Ingo Molnar diff --git a/include/linux/sched.h b/include/linux/sched.h index f2f842d..8d4991b 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -2601,6 +2601,28 @@ static inline void mm_init_owner(struct mm_struct *mm, struct task_struct *p) } #endif /* CONFIG_MM_OWNER */ +static inline unsigned long task_rlimit(const struct task_struct *tsk, + unsigned int limit) +{ + return ACCESS_ONCE(tsk->signal->rlim[limit].rlim_cur); +} + +static inline unsigned long task_rlimit_max(const struct task_struct *tsk, + unsigned int limit) +{ + return ACCESS_ONCE(tsk->signal->rlim[limit].rlim_max); +} + +static inline unsigned long rlimit(unsigned int limit) +{ + return task_rlimit(current, limit); +} + +static inline unsigned long rlimit_max(unsigned int limit) +{ + return task_rlimit_max(current, limit); +} + #endif /* __KERNEL__ */ #endif -- cgit v0.10.2 From 2243b649aa9e5669bea5413c5b520f333f96be07 Mon Sep 17 00:00:00 2001 From: Alan Carvalho de Assis Date: Fri, 4 Dec 2009 15:44:06 -0200 Subject: mx27: mxt_td60: Remove not used UART pins Signed-off-by: Alan Carvalho de Assis Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-mx2/mxt_td60.c b/arch/arm/mach-mx2/mxt_td60.c index 03dbbdc..8bcc1a5 100644 --- a/arch/arm/mach-mx2/mxt_td60.c +++ b/arch/arm/mach-mx2/mxt_td60.c @@ -58,21 +58,6 @@ static unsigned int mxt_td60_pins[] __initdata = { PE9_PF_UART3_RXD, PE10_PF_UART3_CTS, PE11_PF_UART3_RTS, - /* UART3 */ - PB26_AF_UART4_RTS, - PB28_AF_UART4_TXD, - PB29_AF_UART4_CTS, - PB31_AF_UART4_RXD, - /* UART4 */ - PB18_AF_UART5_TXD, - PB19_AF_UART5_RXD, - PB20_AF_UART5_CTS, - PB21_AF_UART5_RTS, - /* UART5 */ - PB10_AF_UART6_TXD, - PB12_AF_UART6_CTS, - PB11_AF_UART6_RXD, - PB13_AF_UART6_RTS, /* FEC */ PD0_AIN_FEC_TXD0, PD1_AIN_FEC_TXD1, @@ -261,12 +246,6 @@ static struct imxuart_platform_data uart_pdata[] = { .flags = IMXUART_HAVE_RTSCTS, }, { .flags = IMXUART_HAVE_RTSCTS, - }, { - .flags = IMXUART_HAVE_RTSCTS, - }, { - .flags = IMXUART_HAVE_RTSCTS, - }, { - .flags = IMXUART_HAVE_RTSCTS, }, }; @@ -278,9 +257,6 @@ static void __init mxt_td60_board_init(void) mxc_register_device(&mxc_uart_device0, &uart_pdata[0]); mxc_register_device(&mxc_uart_device1, &uart_pdata[1]); mxc_register_device(&mxc_uart_device2, &uart_pdata[2]); - mxc_register_device(&mxc_uart_device3, &uart_pdata[3]); - mxc_register_device(&mxc_uart_device4, &uart_pdata[4]); - mxc_register_device(&mxc_uart_device5, &uart_pdata[5]); mxc_register_device(&mxc_nand_device, &mxt_td60_nand_board_info); i2c_register_board_info(0, mxt_td60_i2c_devices, -- cgit v0.10.2 From 9d00278d481b148fa99222553bb2339bc5f65036 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 11 Dec 2009 14:29:06 +0100 Subject: mx3: add support for the mt9v022 camera sensor to pcm037 platform Signed-off-by: Guennadi Liakhovetski Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-mx3/pcm037.c b/arch/arm/mach-mx3/pcm037.c index 6cbaabe..5be3969 100644 --- a/arch/arm/mach-mx3/pcm037.c +++ b/arch/arm/mach-mx3/pcm037.c @@ -322,16 +322,25 @@ static int pcm037_camera_power(struct device *dev, int on) return 0; } -static struct i2c_board_info pcm037_i2c_2_devices[] = { +static struct i2c_board_info pcm037_i2c_camera[] = { { I2C_BOARD_INFO("mt9t031", 0x5d), + }, { + I2C_BOARD_INFO("mt9v022", 0x48), }, }; -static struct soc_camera_link iclink = { +static struct soc_camera_link iclink_mt9v022 = { + .bus_id = 0, /* Must match with the camera ID */ + .board_info = &pcm037_i2c_camera[1], + .i2c_adapter_id = 2, + .module_name = "mt9v022", +}; + +static struct soc_camera_link iclink_mt9t031 = { .bus_id = 0, /* Must match with the camera ID */ .power = pcm037_camera_power, - .board_info = &pcm037_i2c_2_devices[0], + .board_info = &pcm037_i2c_camera[0], .i2c_adapter_id = 2, .module_name = "mt9t031", }; @@ -345,11 +354,19 @@ static struct i2c_board_info pcm037_i2c_devices[] = { } }; -static struct platform_device pcm037_camera = { +static struct platform_device pcm037_mt9t031 = { .name = "soc-camera-pdrv", .id = 0, .dev = { - .platform_data = &iclink, + .platform_data = &iclink_mt9t031, + }, +}; + +static struct platform_device pcm037_mt9v022 = { + .name = "soc-camera-pdrv", + .id = 1, + .dev = { + .platform_data = &iclink_mt9v022, }, }; @@ -449,7 +466,8 @@ static int __init pcm037_camera_alloc_dma(const size_t buf_size) static struct platform_device *devices[] __initdata = { &pcm037_flash, &pcm037_sram_device, - &pcm037_camera, + &pcm037_mt9t031, + &pcm037_mt9v022, }; static struct ipu_platform_data mx3_ipu_data = { @@ -599,7 +617,7 @@ static void __init mxc_board_init(void) if (!ret) gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_CSI_D5), 1); else - iclink.power = NULL; + iclink_mt9t031.power = NULL; if (!pcm037_camera_alloc_dma(4 * 1024 * 1024)) mxc_register_device(&mx3_camera, &camera_pdata); -- cgit v0.10.2 From 4c21186bd8b1ecf46a7cc20d8ad26476afe14f8c Mon Sep 17 00:00:00 2001 From: Valentin Longchamp Date: Fri, 4 Dec 2009 16:50:29 +0100 Subject: mx31moboard: fix usbh device names Signed-off-by: Valentin Longchamp Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-mx3/mx31moboard-devboard.c b/arch/arm/mach-mx3/mx31moboard-devboard.c index 8fc624f..438428e 100644 --- a/arch/arm/mach-mx3/mx31moboard-devboard.c +++ b/arch/arm/mach-mx3/mx31moboard-devboard.c @@ -179,7 +179,7 @@ static int __init devboard_usbh1_init(void) usbh1_pdata.otg = otg; - return mxc_register_device(&mx31_usbh1, &usbh1_pdata); + return mxc_register_device(&mxc_usbh1, &usbh1_pdata); } /* diff --git a/arch/arm/mach-mx3/mx31moboard-marxbot.c b/arch/arm/mach-mx3/mx31moboard-marxbot.c index 85184a3..1f44b9c 100644 --- a/arch/arm/mach-mx3/mx31moboard-marxbot.c +++ b/arch/arm/mach-mx3/mx31moboard-marxbot.c @@ -294,7 +294,7 @@ static int __init marxbot_usbh1_init(void) usbh1_pdata.otg = otg; - return mxc_register_device(&mx31_usbh1, &usbh1_pdata); + return mxc_register_device(&mxc_usbh1, &usbh1_pdata); } /* diff --git a/arch/arm/mach-mx3/mx31moboard.c b/arch/arm/mach-mx3/mx31moboard.c index b705291..839f09a 100644 --- a/arch/arm/mach-mx3/mx31moboard.c +++ b/arch/arm/mach-mx3/mx31moboard.c @@ -392,7 +392,7 @@ static int __init moboard_usbh2_init(void) usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); - return mxc_register_device(&mx31_usbh2, &usbh2_pdata); + return mxc_register_device(&mxc_usbh2, &usbh2_pdata); } -- cgit v0.10.2 From dda71f1612bd6644714ab5c801d2f6d390b5318f Mon Sep 17 00:00:00 2001 From: Baruch Siach Date: Mon, 14 Dec 2009 12:19:39 +0200 Subject: mx25: s/NO_PAD_CTL/NO_PAD_CTRL/ NO_PAD_CTL is not defined anywhere. Signed-off-by: Baruch Siach Signed-off-by: Sascha Hauer diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx25.h b/arch/arm/plat-mxc/include/mach/iomux-mx25.h index 810c47f..9af494f 100644 --- a/arch/arm/plat-mxc/include/mach/iomux-mx25.h +++ b/arch/arm/plat-mxc/include/mach/iomux-mx25.h @@ -58,19 +58,19 @@ #define MX25_PAD_A18__A18 IOMUX_PAD(0x23c, 0x020, 0x10, 0, 0, NO_PAD_CTRL) #define MX25_PAD_A18__GPIO_2_4 IOMUX_PAD(0x23c, 0x020, 0x15, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_A18__FEC_COL IOMUX_PAD(0x23c, 0x020, 0x17, 0x504, 0, NO_PAD_CTL) +#define MX25_PAD_A18__FEC_COL IOMUX_PAD(0x23c, 0x020, 0x17, 0x504, 0, NO_PAD_CTRL) #define MX25_PAD_A19__A19 IOMUX_PAD(0x240, 0x024, 0x10, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_A19__FEC_RX_ER IOMUX_PAD(0x240, 0x024, 0x17, 0x518, 0, NO_PAD_CTL) +#define MX25_PAD_A19__FEC_RX_ER IOMUX_PAD(0x240, 0x024, 0x17, 0x518, 0, NO_PAD_CTRL) #define MX25_PAD_A19__GPIO_2_5 IOMUX_PAD(0x240, 0x024, 0x15, 0, 0, NO_PAD_CTRL) #define MX25_PAD_A20__A20 IOMUX_PAD(0x244, 0x028, 0x10, 0, 0, NO_PAD_CTRL) #define MX25_PAD_A20__GPIO_2_6 IOMUX_PAD(0x244, 0x028, 0x15, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_A20__FEC_RDATA2 IOMUX_PAD(0x244, 0x028, 0x17, 0x50c, 0, NO_PAD_CTL) +#define MX25_PAD_A20__FEC_RDATA2 IOMUX_PAD(0x244, 0x028, 0x17, 0x50c, 0, NO_PAD_CTRL) #define MX25_PAD_A21__A21 IOMUX_PAD(0x248, 0x02c, 0x10, 0, 0, NO_PAD_CTRL) #define MX25_PAD_A21__GPIO_2_7 IOMUX_PAD(0x248, 0x02c, 0x15, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_A21__FEC_RDATA3 IOMUX_PAD(0x248, 0x02c, 0x17, 0x510, 0, NO_PAD_CTL) +#define MX25_PAD_A21__FEC_RDATA3 IOMUX_PAD(0x248, 0x02c, 0x17, 0x510, 0, NO_PAD_CTRL) #define MX25_PAD_A22__A22 IOMUX_PAD(0x000, 0x030, 0x10, 0, 0, NO_PAD_CTRL) #define MX25_PAD_A22__GPIO_2_8 IOMUX_PAD(0x000, 0x030, 0x15, 0, 0, NO_PAD_CTRL) @@ -80,11 +80,11 @@ #define MX25_PAD_A24__A24 IOMUX_PAD(0x250, 0x038, 0x10, 0, 0, NO_PAD_CTRL) #define MX25_PAD_A24__GPIO_2_10 IOMUX_PAD(0x250, 0x038, 0x15, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_A24__FEC_RX_CLK IOMUX_PAD(0x250, 0x038, 0x17, 0x514, 0, NO_PAD_CTL) +#define MX25_PAD_A24__FEC_RX_CLK IOMUX_PAD(0x250, 0x038, 0x17, 0x514, 0, NO_PAD_CTRL) #define MX25_PAD_A25__A25 IOMUX_PAD(0x254, 0x03c, 0x10, 0, 0, NO_PAD_CTRL) #define MX25_PAD_A25__GPIO_2_11 IOMUX_PAD(0x254, 0x03c, 0x15, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_A25__FEC_CRS IOMUX_PAD(0x254, 0x03c, 0x17, 0x508, 0, NO_PAD_CTL) +#define MX25_PAD_A25__FEC_CRS IOMUX_PAD(0x254, 0x03c, 0x17, 0x508, 0, NO_PAD_CTRL) #define MX25_PAD_EB0__EB0 IOMUX_PAD(0x258, 0x040, 0x10, 0, 0, NO_PAD_CTRL) #define MX25_PAD_EB0__AUD4_TXD IOMUX_PAD(0x258, 0x040, 0x14, 0x464, 0, NO_PAD_CTRL) @@ -112,7 +112,7 @@ #define MX25_PAD_CS5__UART5_RTS IOMUX_PAD(0x268, 0x058, 0x13, 0x574, 0, NO_PAD_CTRL) #define MX25_PAD_CS5__GPIO_3_21 IOMUX_PAD(0x268, 0x058, 0x15, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_NF_CE0__NF_CE0 IOMUX_PAD(0x26c, 0x05c, 0x10, 0, 0, NO_PAD_CTL) +#define MX25_PAD_NF_CE0__NF_CE0 IOMUX_PAD(0x26c, 0x05c, 0x10, 0, 0, NO_PAD_CTRL) #define MX25_PAD_NF_CE0__GPIO_3_22 IOMUX_PAD(0x26c, 0x05c, 0x15, 0, 0, NO_PAD_CTRL) #define MX25_PAD_ECB__ECB IOMUX_PAD(0x270, 0x060, 0x10, 0, 0, NO_PAD_CTRL) @@ -229,28 +229,28 @@ #define MX25_PAD_LD7__GPIO_1_21 IOMUX_PAD(0x2dc, 0x0e4, 0x15, 0, 0, NO_PAD_CTRL) #define MX25_PAD_LD8__LD8 IOMUX_PAD(0x2e0, 0x0e8, 0x10, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_LD8__FEC_TX_ERR IOMUX_PAD(0x2e0, 0x0e8, 0x15, 0, 0, NO_PAD_CTL) +#define MX25_PAD_LD8__FEC_TX_ERR IOMUX_PAD(0x2e0, 0x0e8, 0x15, 0, 0, NO_PAD_CTRL) #define MX25_PAD_LD9__LD9 IOMUX_PAD(0x2e4, 0x0ec, 0x10, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_LD9__FEC_COL IOMUX_PAD(0x2e4, 0x0ec, 0x15, 0x504, 1, NO_PAD_CTL) +#define MX25_PAD_LD9__FEC_COL IOMUX_PAD(0x2e4, 0x0ec, 0x15, 0x504, 1, NO_PAD_CTRL) #define MX25_PAD_LD10__LD10 IOMUX_PAD(0x2e8, 0x0f0, 0x10, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_LD10__FEC_RX_ER IOMUX_PAD(0x2e8, 0x0f0, 0x15, 0x518, 1, NO_PAD_CTL) +#define MX25_PAD_LD10__FEC_RX_ER IOMUX_PAD(0x2e8, 0x0f0, 0x15, 0x518, 1, NO_PAD_CTRL) #define MX25_PAD_LD11__LD11 IOMUX_PAD(0x2ec, 0x0f4, 0x10, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_LD11__FEC_RDATA2 IOMUX_PAD(0x2ec, 0x0f4, 0x15, 0x50c, 1, NO_PAD_CTL) +#define MX25_PAD_LD11__FEC_RDATA2 IOMUX_PAD(0x2ec, 0x0f4, 0x15, 0x50c, 1, NO_PAD_CTRL) #define MX25_PAD_LD12__LD12 IOMUX_PAD(0x2f0, 0x0f8, 0x10, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_LD12__FEC_RDATA3 IOMUX_PAD(0x2f0, 0x0f8, 0x15, 0x510, 1, NO_PAD_CTL) +#define MX25_PAD_LD12__FEC_RDATA3 IOMUX_PAD(0x2f0, 0x0f8, 0x15, 0x510, 1, NO_PAD_CTRL) #define MX25_PAD_LD13__LD13 IOMUX_PAD(0x2f4, 0x0fc, 0x10, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_LD13__FEC_TDATA2 IOMUX_PAD(0x2f4, 0x0fc, 0x15, 0, 0, NO_PAD_CTL) +#define MX25_PAD_LD13__FEC_TDATA2 IOMUX_PAD(0x2f4, 0x0fc, 0x15, 0, 0, NO_PAD_CTRL) #define MX25_PAD_LD14__LD14 IOMUX_PAD(0x2f8, 0x100, 0x10, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_LD14__FEC_TDATA3 IOMUX_PAD(0x2f8, 0x100, 0x15, 0, 0, NO_PAD_CTL) +#define MX25_PAD_LD14__FEC_TDATA3 IOMUX_PAD(0x2f8, 0x100, 0x15, 0, 0, NO_PAD_CTRL) #define MX25_PAD_LD15__LD15 IOMUX_PAD(0x2fc, 0x104, 0x10, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_LD15__FEC_RX_CLK IOMUX_PAD(0x2fc, 0x104, 0x15, 0x514, 1, NO_PAD_CTL) +#define MX25_PAD_LD15__FEC_RX_CLK IOMUX_PAD(0x2fc, 0x104, 0x15, 0x514, 1, NO_PAD_CTRL) #define MX25_PAD_HSYNC__HSYNC IOMUX_PAD(0x300, 0x108, 0x10, 0, 0, NO_PAD_CTRL) #define MX25_PAD_HSYNC__GPIO_1_22 IOMUX_PAD(0x300, 0x108, 0x15, 0, 0, NO_PAD_CTRL) @@ -265,7 +265,7 @@ #define MX25_PAD_OE_ACD__GPIO_1_25 IOMUX_PAD(0x30c, 0x114, 0x15, 0, 0, NO_PAD_CTRL) #define MX25_PAD_CONTRAST__CONTRAST IOMUX_PAD(0x310, 0x118, 0x10, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_CONTRAST__FEC_CRS IOMUX_PAD(0x310, 0x118, 0x15, 0x508, 1, NO_PAD_CTL) +#define MX25_PAD_CONTRAST__FEC_CRS IOMUX_PAD(0x310, 0x118, 0x15, 0x508, 1, NO_PAD_CTRL) #define MX25_PAD_PWM__PWM IOMUX_PAD(0x314, 0x11c, 0x10, 0, 0, NO_PAD_CTRL) #define MX25_PAD_PWM__GPIO_1_26 IOMUX_PAD(0x314, 0x11c, 0x15, 0, 0, NO_PAD_CTRL) @@ -354,19 +354,19 @@ #define MX25_PAD_UART2_TXD__GPIO_4_27 IOMUX_PAD(0x37c, 0x184, 0x15, 0, 0, NO_PAD_CTRL) #define MX25_PAD_UART2_RTS__UART2_RTS IOMUX_PAD(0x380, 0x188, 0x10, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_UART2_RTS__FEC_COL IOMUX_PAD(0x380, 0x188, 0x12, 0x504, 2, NO_PAD_CTL) +#define MX25_PAD_UART2_RTS__FEC_COL IOMUX_PAD(0x380, 0x188, 0x12, 0x504, 2, NO_PAD_CTRL) #define MX25_PAD_UART2_RTS__GPIO_4_28 IOMUX_PAD(0x380, 0x188, 0x15, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_UART2_CTS__FEC_RX_ER IOMUX_PAD(0x384, 0x18c, 0x12, 0x518, 2, NO_PAD_CTL) +#define MX25_PAD_UART2_CTS__FEC_RX_ER IOMUX_PAD(0x384, 0x18c, 0x12, 0x518, 2, NO_PAD_CTRL) #define MX25_PAD_UART2_CTS__UART2_CTS IOMUX_PAD(0x384, 0x18c, 0x10, 0, 0, NO_PAD_CTRL) #define MX25_PAD_UART2_CTS__GPIO_4_29 IOMUX_PAD(0x384, 0x18c, 0x15, 0, 0, NO_PAD_CTRL) #define MX25_PAD_SD1_CMD__SD1_CMD IOMUX_PAD(0x388, 0x190, 0x10, 0, 0, PAD_CTL_PUS_47K_UP) -#define MX25_PAD_SD1_CMD__FEC_RDATA2 IOMUX_PAD(0x388, 0x190, 0x12, 0x50c, 2, NO_PAD_CTL) +#define MX25_PAD_SD1_CMD__FEC_RDATA2 IOMUX_PAD(0x388, 0x190, 0x12, 0x50c, 2, NO_PAD_CTRL) #define MX25_PAD_SD1_CMD__GPIO_2_23 IOMUX_PAD(0x388, 0x190, 0x15, 0, 0, NO_PAD_CTRL) #define MX25_PAD_SD1_CLK__SD1_CLK IOMUX_PAD(0x38c, 0x194, 0x10, 0, 0, PAD_CTL_PUS_47K_UP) -#define MX25_PAD_SD1_CLK__FEC_RDATA3 IOMUX_PAD(0x38c, 0x194, 0x12, 0x510, 2, NO_PAD_CTL) +#define MX25_PAD_SD1_CLK__FEC_RDATA3 IOMUX_PAD(0x38c, 0x194, 0x12, 0x510, 2, NO_PAD_CTRL) #define MX25_PAD_SD1_CLK__GPIO_2_24 IOMUX_PAD(0x38c, 0x194, 0x15, 0, 0, NO_PAD_CTRL) #define MX25_PAD_SD1_DATA0__SD1_DATA0 IOMUX_PAD(0x390, 0x198, 0x10, 0, 0, PAD_CTL_PUS_47K_UP) @@ -377,11 +377,11 @@ #define MX25_PAD_SD1_DATA1__GPIO_2_26 IOMUX_PAD(0x394, 0x19c, 0x15, 0, 0, NO_PAD_CTRL) #define MX25_PAD_SD1_DATA2__SD1_DATA2 IOMUX_PAD(0x398, 0x1a0, 0x10, 0, 0, PAD_CTL_PUS_47K_UP) -#define MX25_PAD_SD1_DATA2__FEC_RX_CLK IOMUX_PAD(0x398, 0x1a0, 0x15, 0x514, 2, NO_PAD_CTL) +#define MX25_PAD_SD1_DATA2__FEC_RX_CLK IOMUX_PAD(0x398, 0x1a0, 0x15, 0x514, 2, NO_PAD_CTRL) #define MX25_PAD_SD1_DATA2__GPIO_2_27 IOMUX_PAD(0x398, 0x1a0, 0x15, 0, 0, NO_PAD_CTRL) #define MX25_PAD_SD1_DATA3__SD1_DATA3 IOMUX_PAD(0x39c, 0x1a4, 0x10, 0, 0, PAD_CTL_PUS_47K_UP) -#define MX25_PAD_SD1_DATA3__FEC_CRS IOMUX_PAD(0x39c, 0x1a4, 0x10, 0x508, 2, NO_PAD_CTL) +#define MX25_PAD_SD1_DATA3__FEC_CRS IOMUX_PAD(0x39c, 0x1a4, 0x10, 0x508, 2, NO_PAD_CTRL) #define MX25_PAD_SD1_DATA3__GPIO_2_28 IOMUX_PAD(0x39c, 0x1a4, 0x15, 0, 0, NO_PAD_CTRL) #define MX25_PAD_KPP_ROW0__KPP_ROW0 IOMUX_PAD(0x3a0, 0x1a8, 0x10, 0, 0, PAD_CTL_PKE) @@ -410,7 +410,7 @@ #define MX25_PAD_KPP_COL3__KPP_COL3 IOMUX_PAD(0x3bc, 0x1c4, 0x10, 0, 0, PAD_CTL_PKE | PAD_CTL_ODE) #define MX25_PAD_KPP_COL3__GPIO_3_4 IOMUX_PAD(0x3bc, 0x1c4, 0x15, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_FEC_MDC__FEC_MDC IOMUX_PAD(0x3c0, 0x1c8, 0x10, 0, 0, NO_PAD_CTL) +#define MX25_PAD_FEC_MDC__FEC_MDC IOMUX_PAD(0x3c0, 0x1c8, 0x10, 0, 0, NO_PAD_CTRL) #define MX25_PAD_FEC_MDC__AUD4_TXD IOMUX_PAD(0x3c0, 0x1c8, 0x12, 0x464, 1, NO_PAD_CTRL) #define MX25_PAD_FEC_MDC__GPIO_3_5 IOMUX_PAD(0x3c0, 0x1c8, 0x15, 0, 0, NO_PAD_CTRL) @@ -418,23 +418,23 @@ #define MX25_PAD_FEC_MDIO__AUD4_RXD IOMUX_PAD(0x3c4, 0x1cc, 0x12, 0x460, 1, NO_PAD_CTRL) #define MX25_PAD_FEC_MDIO__GPIO_3_6 IOMUX_PAD(0x3c4, 0x1cc, 0x15, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_FEC_TDATA0__FEC_TDATA0 IOMUX_PAD(0x3c8, 0x1d0, 0x10, 0, 0, NO_PAD_CTL) +#define MX25_PAD_FEC_TDATA0__FEC_TDATA0 IOMUX_PAD(0x3c8, 0x1d0, 0x10, 0, 0, NO_PAD_CTRL) #define MX25_PAD_FEC_TDATA0__GPIO_3_7 IOMUX_PAD(0x3c8, 0x1d0, 0x15, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_FEC_TDATA1__FEC_TDATA1 IOMUX_PAD(0x3cc, 0x1d4, 0x10, 0, 0, NO_PAD_CTL) +#define MX25_PAD_FEC_TDATA1__FEC_TDATA1 IOMUX_PAD(0x3cc, 0x1d4, 0x10, 0, 0, NO_PAD_CTRL) #define MX25_PAD_FEC_TDATA1__AUD4_TXFS IOMUX_PAD(0x3cc, 0x1d4, 0x12, 0x474, 1, NO_PAD_CTRL) #define MX25_PAD_FEC_TDATA1__GPIO_3_8 IOMUX_PAD(0x3cc, 0x1d4, 0x15, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_FEC_TX_EN__FEC_TX_EN IOMUX_PAD(0x3d0, 0x1d8, 0x10, 0, 0, NO_PAD_CTL) +#define MX25_PAD_FEC_TX_EN__FEC_TX_EN IOMUX_PAD(0x3d0, 0x1d8, 0x10, 0, 0, NO_PAD_CTRL) #define MX25_PAD_FEC_TX_EN__GPIO_3_9 IOMUX_PAD(0x3d0, 0x1d8, 0x15, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_FEC_RDATA0__FEC_RDATA0 IOMUX_PAD(0x3d4, 0x1dc, 0x10, 0, 0, PAD_CTL_PUS_100K_DOWN | NO_PAD_CTL) +#define MX25_PAD_FEC_RDATA0__FEC_RDATA0 IOMUX_PAD(0x3d4, 0x1dc, 0x10, 0, 0, PAD_CTL_PUS_100K_DOWN | NO_PAD_CTRL) #define MX25_PAD_FEC_RDATA0__GPIO_3_10 IOMUX_PAD(0x3d4, 0x1dc, 0x15, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_FEC_RDATA1__FEC_RDATA1 IOMUX_PAD(0x3d8, 0x1e0, 0x10, 0, 0, PAD_CTL_PUS_100K_DOWN | NO_PAD_CTL) +#define MX25_PAD_FEC_RDATA1__FEC_RDATA1 IOMUX_PAD(0x3d8, 0x1e0, 0x10, 0, 0, PAD_CTL_PUS_100K_DOWN | NO_PAD_CTRL) #define MX25_PAD_FEC_RDATA1__GPIO_3_11 IOMUX_PAD(0x3d8, 0x1e0, 0x15, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_FEC_RX_DV__FEC_RX_DV IOMUX_PAD(0x3dc, 0x1e4, 0x10, 0, 0, PAD_CTL_PUS_100K_DOWN | NO_PAD_CTL) +#define MX25_PAD_FEC_RX_DV__FEC_RX_DV IOMUX_PAD(0x3dc, 0x1e4, 0x10, 0, 0, PAD_CTL_PUS_100K_DOWN | NO_PAD_CTRL) #define MX25_PAD_FEC_RX_DV__CAN2_RX IOMUX_PAD(0x3dc, 0x1e4, 0x14, 0x484, 0, PAD_CTL_PUS_22K_UP) #define MX25_PAD_FEC_RX_DV__GPIO_3_12 IOMUX_PAD(0x3dc, 0x1e4, 0x15, 0, 0, NO_PAD_CTRL) -- cgit v0.10.2 From a759544ff95c14dac93759e02a84e233da0dc25a Mon Sep 17 00:00:00 2001 From: Baruch Siach Date: Mon, 21 Dec 2009 13:44:31 +0200 Subject: mx25: add support for FEC on i.MX25 Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-mx25/clock.c b/arch/arm/mach-mx25/clock.c index ef26951..6e838b8 100644 --- a/arch/arm/mach-mx25/clock.c +++ b/arch/arm/mach-mx25/clock.c @@ -173,6 +173,7 @@ DEFINE_CLOCK(pwm4_clk, 0, CCM_CGCR2, 2, get_rate_ipg, NULL); DEFINE_CLOCK(kpp_clk, 0, CCM_CGCR1, 28, get_rate_ipg, NULL); DEFINE_CLOCK(tsc_clk, 0, CCM_CGCR2, 13, get_rate_ipg, NULL); DEFINE_CLOCK(i2c_clk, 0, CCM_CGCR0, 6, get_rate_i2c, NULL); +DEFINE_CLOCK(fec_clk, 0, CCM_CGCR0, 23, get_rate_ipg, NULL); #define _REGISTER_CLOCK(d, n, c) \ { \ @@ -204,6 +205,7 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk) _REGISTER_CLOCK("imx-i2c.1", NULL, i2c_clk) _REGISTER_CLOCK("imx-i2c.2", NULL, i2c_clk) + _REGISTER_CLOCK("fec.0", NULL, fec_clk) }; int __init mx25_clocks_init(unsigned long fref) diff --git a/arch/arm/mach-mx25/devices.c b/arch/arm/mach-mx25/devices.c index 63511de..9fdeea1 100644 --- a/arch/arm/mach-mx25/devices.c +++ b/arch/arm/mach-mx25/devices.c @@ -419,3 +419,22 @@ int __init mxc_register_gpios(void) return mxc_gpio_init(imx_gpio_ports, ARRAY_SIZE(imx_gpio_ports)); } +static struct resource mx25_fec_resources[] = { + { + .start = MX25_FEC_BASE_ADDR, + .end = MX25_FEC_BASE_ADDR + 0xfff, + .flags = IORESOURCE_MEM, + }, + { + .start = MX25_INT_FEC, + .end = MX25_INT_FEC, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device mx25_fec_device = { + .name = "fec", + .id = 0, + .num_resources = ARRAY_SIZE(mx25_fec_resources), + .resource = mx25_fec_resources, +}; diff --git a/arch/arm/mach-mx25/devices.h b/arch/arm/mach-mx25/devices.h index fe6bf88..fe5420f 100644 --- a/arch/arm/mach-mx25/devices.h +++ b/arch/arm/mach-mx25/devices.h @@ -17,3 +17,4 @@ extern struct platform_device mxc_keypad_device; extern struct platform_device mxc_i2c_device0; extern struct platform_device mxc_i2c_device1; extern struct platform_device mxc_i2c_device2; +extern struct platform_device mx25_fec_device; diff --git a/arch/arm/plat-mxc/include/mach/mx25.h b/arch/arm/plat-mxc/include/mach/mx25.h index 91e7381..854e2dc 100644 --- a/arch/arm/plat-mxc/include/mach/mx25.h +++ b/arch/arm/plat-mxc/include/mach/mx25.h @@ -41,4 +41,8 @@ #define UART1_BASE_ADDR 0x43f90000 #define UART2_BASE_ADDR 0x43f94000 +#define MX25_FEC_BASE_ADDR 0x50038000 + +#define MX25_INT_FEC 57 + #endif /* __MACH_MX25_H__ */ -- cgit v0.10.2 From e71fbaf7660cefb49459e66a12bbb928a86958c9 Mon Sep 17 00:00:00 2001 From: Baruch Siach Date: Mon, 21 Dec 2009 13:44:32 +0200 Subject: mx25: pdk: add platform code for FEC support Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-mx25/mx25pdk.c b/arch/arm/mach-mx25/mx25pdk.c index d23ae57..921bc99 100644 --- a/arch/arm/mach-mx25/mx25pdk.c +++ b/arch/arm/mach-mx25/mx25pdk.c @@ -18,10 +18,11 @@ #include #include +#include #include #include #include -#include +#include #include #include @@ -35,16 +36,57 @@ #include #include #include "devices.h" -#include +#include static struct imxuart_platform_data uart_pdata = { .flags = IMXUART_HAVE_RTSCTS, }; +static struct pad_desc mx25pdk_pads[] = { + MX25_PAD_FEC_MDC__FEC_MDC, + MX25_PAD_FEC_MDIO__FEC_MDIO, + MX25_PAD_FEC_TDATA0__FEC_TDATA0, + MX25_PAD_FEC_TDATA1__FEC_TDATA1, + MX25_PAD_FEC_TX_EN__FEC_TX_EN, + MX25_PAD_FEC_RDATA0__FEC_RDATA0, + MX25_PAD_FEC_RDATA1__FEC_RDATA1, + MX25_PAD_FEC_RX_DV__FEC_RX_DV, + MX25_PAD_FEC_TX_CLK__FEC_TX_CLK, + MX25_PAD_A17__GPIO_2_3, /* FEC_EN, GPIO 35 */ + MX25_PAD_D12__GPIO_4_8, /* FEC_RESET_B, GPIO 104 */ +}; + +static struct fec_platform_data mx25_fec_pdata = { + .phy = PHY_INTERFACE_MODE_RMII, +}; + +#define FEC_ENABLE_GPIO 35 +#define FEC_RESET_B_GPIO 104 + +static void __init mx25pdk_fec_reset(void) +{ + gpio_request(FEC_ENABLE_GPIO, "FEC PHY enable"); + gpio_request(FEC_RESET_B_GPIO, "FEC PHY reset"); + + gpio_direction_output(FEC_ENABLE_GPIO, 0); /* drop PHY power */ + gpio_direction_output(FEC_RESET_B_GPIO, 0); /* assert reset */ + udelay(2); + + /* turn on PHY power and lift reset */ + gpio_set_value(FEC_ENABLE_GPIO, 1); + gpio_set_value(FEC_RESET_B_GPIO, 1); +} + static void __init mx25pdk_init(void) { + mxc_iomux_v3_setup_multiple_pads(mx25pdk_pads, + ARRAY_SIZE(mx25pdk_pads)); + mxc_register_device(&mxc_uart_device0, &uart_pdata); mxc_register_device(&mxc_usbh2, NULL); + + mx25pdk_fec_reset(); + mxc_register_device(&mx25_fec_device, &mx25_fec_pdata); } static void __init mx25pdk_timer_init(void) -- cgit v0.10.2 From e94c4c34495e194d778e9ab20044c723280a54e7 Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Tue, 15 Dec 2009 00:27:42 +0100 Subject: ARM: MX3: make CPU revision number detection work on all boards Commit 52939c03 (ARM: MX3: fix CPU revision number detection) started using the CPU's SREV register for revision number detection. This makes it mandatory to have a valid SPBA0 mapping. Add this to the global map_io code instead of adding multiple copies for each board. Signed-off-by: Wolfgang Denk Cc: Daniel Mack Cc: Sascha Hauer Tested on Qong (EVB-Lite) Tested-by: Wolfgang Denk Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-mx3/mm.c b/arch/arm/mach-mx3/mm.c index bedf5b8..6858a4f 100644 --- a/arch/arm/mach-mx3/mm.c +++ b/arch/arm/mach-mx3/mm.c @@ -65,6 +65,11 @@ static struct map_desc mxc_io_desc[] __initdata = { .pfn = __phys_to_pfn(AIPS2_BASE_ADDR), .length = AIPS2_SIZE, .type = MT_DEVICE_NONSHARED + }, { + .virtual = SPBA0_BASE_ADDR_VIRT, + .pfn = __phys_to_pfn(SPBA0_BASE_ADDR), + .length = SPBA0_SIZE, + .type = MT_DEVICE_NONSHARED }, }; diff --git a/arch/arm/mach-mx3/mx31ads.c b/arch/arm/mach-mx3/mx31ads.c index 0497c15..3e7bafa 100644 --- a/arch/arm/mach-mx3/mx31ads.c +++ b/arch/arm/mach-mx3/mx31ads.c @@ -494,11 +494,6 @@ static void mxc_init_i2c(void) */ static struct map_desc mx31ads_io_desc[] __initdata = { { - .virtual = SPBA0_BASE_ADDR_VIRT, - .pfn = __phys_to_pfn(SPBA0_BASE_ADDR), - .length = SPBA0_SIZE, - .type = MT_DEVICE_NONSHARED - }, { .virtual = CS4_BASE_ADDR_VIRT, .pfn = __phys_to_pfn(CS4_BASE_ADDR), .length = CS4_SIZE / 2, diff --git a/arch/arm/mach-mx3/mx31lite.c b/arch/arm/mach-mx3/mx31lite.c index def6b67..4697164 100644 --- a/arch/arm/mach-mx3/mx31lite.c +++ b/arch/arm/mach-mx3/mx31lite.c @@ -212,11 +212,6 @@ static struct platform_device physmap_flash_device = { */ static struct map_desc mx31lite_io_desc[] __initdata = { { - .virtual = SPBA0_BASE_ADDR_VIRT, - .pfn = __phys_to_pfn(SPBA0_BASE_ADDR), - .length = SPBA0_SIZE, - .type = MT_DEVICE_NONSHARED - }, { .virtual = CS4_BASE_ADDR_VIRT, .pfn = __phys_to_pfn(CS4_BASE_ADDR), .length = CS4_SIZE, diff --git a/arch/arm/mach-mx3/mx31pdk.c b/arch/arm/mach-mx3/mx31pdk.c index 0f7a2f0..18715f1 100644 --- a/arch/arm/mach-mx3/mx31pdk.c +++ b/arch/arm/mach-mx3/mx31pdk.c @@ -211,11 +211,6 @@ static int __init mx31pdk_init_expio(void) */ static struct map_desc mx31pdk_io_desc[] __initdata = { { - .virtual = SPBA0_BASE_ADDR_VIRT, - .pfn = __phys_to_pfn(SPBA0_BASE_ADDR), - .length = SPBA0_SIZE, - .type = MT_DEVICE_NONSHARED, - }, { .virtual = CS5_BASE_ADDR_VIRT, .pfn = __phys_to_pfn(CS5_BASE_ADDR), .length = CS5_SIZE, -- cgit v0.10.2 From f9ffaa9ca9889f17ef30b82bc0bf954d141280f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 22 Dec 2009 17:31:05 +0100 Subject: imx/mx3: depend on USB_ULPI for otg_ulpi_create MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit otg_ulpi_create is defined in drivers/usb/otg/ulpi.c which depends on CONFIG_USB_ULPI. So protect its usage by the same symbol. Moreover mxc_ulpi_access_ops needs CONFIG_MXC_ULPI. Signed-off-by: Uwe Kleine-König Cc: Sascha Hauer Cc: Valentin Longchamp Cc: Daniel Mack Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-mx3/Kconfig b/arch/arm/mach-mx3/Kconfig index ea8ed10..2829441 100644 --- a/arch/arm/mach-mx3/Kconfig +++ b/arch/arm/mach-mx3/Kconfig @@ -49,6 +49,7 @@ config MACH_PCM037_EET config MACH_MX31LITE bool "Support MX31 LITEKIT (LogicPD)" select ARCH_MX31 + select MXC_ULPI if USB_ULPI help Include support for MX31 LITEKIT platform. This includes specific configurations for the board and its peripherals. @@ -63,7 +64,7 @@ config MACH_MX31_3DS config MACH_MX31MOBOARD bool "Support mx31moboard platforms (EPFL Mobots group)" select ARCH_MX31 - select MXC_ULPI + select MXC_ULPI if USB_ULPI help Include support for mx31moboard platform. This includes specific configurations for the board and its peripherals. diff --git a/arch/arm/mach-mx3/mx31lite.c b/arch/arm/mach-mx3/mx31lite.c index 4697164..789b20d 100644 --- a/arch/arm/mach-mx3/mx31lite.c +++ b/arch/arm/mach-mx3/mx31lite.c @@ -135,6 +135,7 @@ static struct spi_board_info mc13783_spi_dev __initdata = { * USB */ +#if defined(CONFIG_USB_ULPI) #define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \ PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU) @@ -180,6 +181,7 @@ static struct mxc_usbh_platform_data usbh2_pdata = { .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT, .flags = MXC_EHCI_POWER_PINS_ENABLED, }; +#endif /* * NOR flash @@ -256,11 +258,13 @@ static void __init mxc_board_init(void) mxc_register_device(&mxc_spi_device1, &spi1_pdata); spi_register_board_info(&mc13783_spi_dev, 1); +#if defined(CONFIG_USB_ULPI) /* USB */ usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); mxc_register_device(&mxc_usbh2, &usbh2_pdata); +#endif /* SMSC9117 IRQ pin */ ret = gpio_request(IOMUX_TO_GPIO(MX31_PIN_SFS6), "sms9117-irq"); diff --git a/arch/arm/mach-mx3/mx31moboard.c b/arch/arm/mach-mx3/mx31moboard.c index 839f09a..cfd605d 100644 --- a/arch/arm/mach-mx3/mx31moboard.c +++ b/arch/arm/mach-mx3/mx31moboard.c @@ -346,6 +346,8 @@ static struct fsl_usb2_platform_data usb_pdata = { .phy_mode = FSL_USB2_PHY_ULPI, }; +#if defined(CONFIG_USB_ULPI) + #define USBH2_EN_B IOMUX_TO_GPIO(MX31_PIN_SCK6) static int moboard_usbh2_hw_init(struct platform_device *pdev) @@ -394,6 +396,9 @@ static int __init moboard_usbh2_init(void) return mxc_register_device(&mxc_usbh2, &usbh2_pdata); } +#else +static inline int moboard_usbh2_init(void) { return 0; } +#endif static struct gpio_led mx31moboard_leds[] = { -- cgit v0.10.2 From 04bcef2a83f40c6db24222b27a52892cba39dffb Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Mon, 4 Jan 2010 16:37:12 +0100 Subject: ipvs: Add boundary check on ioctl arguments The ipvs code has a nifty system for doing the size of ioctl command copies; it defines an array with values into which it indexes the cmd to find the right length. Unfortunately, the ipvs code forgot to check if the cmd was in the range that the array provides, allowing for an index outside of the array, which then gives a "garbage" result into the length, which then gets used for copying into a stack buffer. Fix this by adding sanity checks on these as well as the copy size. [ horms@verge.net.au: adjusted limit to IP_VS_SO_GET_MAX ] Signed-off-by: Arjan van de Ven Acked-by: Julian Anastasov Signed-off-by: Simon Horman Signed-off-by: Patrick McHardy diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index 6bde12d..c37ac2d 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c @@ -2077,6 +2077,10 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len) if (!capable(CAP_NET_ADMIN)) return -EPERM; + if (cmd < IP_VS_BASE_CTL || cmd > IP_VS_SO_SET_MAX) + return -EINVAL; + if (len < 0 || len > MAX_ARG_LEN) + return -EINVAL; if (len != set_arglen[SET_CMDID(cmd)]) { pr_err("set_ctl: len %u != %u\n", len, set_arglen[SET_CMDID(cmd)]); @@ -2352,17 +2356,25 @@ do_ip_vs_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) { unsigned char arg[128]; int ret = 0; + unsigned int copylen; if (!capable(CAP_NET_ADMIN)) return -EPERM; + if (cmd < IP_VS_BASE_CTL || cmd > IP_VS_SO_GET_MAX) + return -EINVAL; + if (*len < get_arglen[GET_CMDID(cmd)]) { pr_err("get_ctl: len %u < %u\n", *len, get_arglen[GET_CMDID(cmd)]); return -EINVAL; } - if (copy_from_user(arg, user, get_arglen[GET_CMDID(cmd)]) != 0) + copylen = get_arglen[GET_CMDID(cmd)]; + if (copylen > 128) + return -EINVAL; + + if (copy_from_user(arg, user, copylen) != 0) return -EFAULT; if (mutex_lock_interruptible(&__ip_vs_mutex)) -- cgit v0.10.2 From 40da4186a53e59d801130156ecb89fc5830ff227 Mon Sep 17 00:00:00 2001 From: Hidetoshi Seto Date: Tue, 15 Dec 2009 11:38:04 +0900 Subject: PCI: pcie portdrv: style cleanup No change in logic. Before: drivers/pci/pcie/portdrv_core.c: total: 7 errors, 2 warnings, 508 lines checked drivers/pci/pcie/portdrv_pci.c: total: 4 errors, 2 warnings, 300 lines checked After: drivers/pci/pcie/portdrv_core.c: total: 0 errors, 0 warnings, 506 lines checked drivers/pci/pcie/portdrv_pci.c: total: 0 errors, 0 warnings, 299 lines checked Signed-off-by: Hidetoshi Seto Signed-off-by: Jesse Barnes diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c index 413262e..b174188 100644 --- a/drivers/pci/pcie/portdrv_core.c +++ b/drivers/pci/pcie/portdrv_core.c @@ -27,7 +27,7 @@ */ static void release_pcie_device(struct device *dev) { - kfree(to_pcie_device(dev)); + kfree(to_pcie_device(dev)); } /** @@ -346,12 +346,11 @@ static int suspend_iter(struct device *dev, void *data) { struct pcie_port_service_driver *service_driver; - if ((dev->bus == &pcie_port_bus_type) && - (dev->driver)) { - service_driver = to_service_driver(dev->driver); - if (service_driver->suspend) - service_driver->suspend(to_pcie_device(dev)); - } + if ((dev->bus == &pcie_port_bus_type) && dev->driver) { + service_driver = to_service_driver(dev->driver); + if (service_driver->suspend) + service_driver->suspend(to_pcie_device(dev)); + } return 0; } @@ -494,6 +493,7 @@ int pcie_port_service_register(struct pcie_port_service_driver *new) return driver_register(&new->driver); } +EXPORT_SYMBOL(pcie_port_service_register); /** * pcie_port_service_unregister - unregister PCI Express port service driver @@ -503,6 +503,4 @@ void pcie_port_service_unregister(struct pcie_port_service_driver *drv) { driver_unregister(&drv->driver); } - -EXPORT_SYMBOL(pcie_port_service_register); EXPORT_SYMBOL(pcie_port_service_unregister); diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index 34d6517..13c8972 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c @@ -63,7 +63,7 @@ static const struct dev_pm_ops pcie_portdrv_pm_ops = { * pcie_portdrv_probe - Probe PCI-Express port devices * @dev: PCI-Express port device being probed * - * If detected invokes the pcie_port_device_register() method for + * If detected invokes the pcie_port_device_register() method for * this port device. * */ @@ -78,7 +78,7 @@ static int __devinit pcie_portdrv_probe(struct pci_dev *dev, (dev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM))) return -ENODEV; - if (!dev->irq && dev->pin) { + if (!dev->irq && dev->pin) { dev_warn(&dev->dev, "device [%04x:%04x] has invalid IRQ; " "check vendor BIOS\n", dev->vendor, dev->device); } @@ -91,7 +91,7 @@ static int __devinit pcie_portdrv_probe(struct pci_dev *dev, return 0; } -static void pcie_portdrv_remove (struct pci_dev *dev) +static void pcie_portdrv_remove(struct pci_dev *dev) { pcie_port_device_remove(dev); pci_disable_device(dev); @@ -129,14 +129,13 @@ static int error_detected_iter(struct device *device, void *data) static pci_ers_result_t pcie_portdrv_error_detected(struct pci_dev *dev, enum pci_channel_state error) { - struct aer_broadcast_data result_data = - {error, PCI_ERS_RESULT_CAN_RECOVER}; - int retval; + struct aer_broadcast_data data = {error, PCI_ERS_RESULT_CAN_RECOVER}; + int ret; /* can not fail */ - retval = device_for_each_child(&dev->dev, &result_data, error_detected_iter); + ret = device_for_each_child(&dev->dev, &data, error_detected_iter); - return result_data.result; + return data.result; } static int mmio_enabled_iter(struct device *device, void *data) @@ -290,7 +289,7 @@ static int __init pcie_portdrv_init(void) return retval; } -static void __exit pcie_portdrv_exit(void) +static void __exit pcie_portdrv_exit(void) { pci_unregister_driver(&pcie_portdriver); pcie_port_bus_unregister(); -- cgit v0.10.2 From 46256f83d0d066f99ffde547f27473dfd2a78009 Mon Sep 17 00:00:00 2001 From: "Youquan,Song" Date: Fri, 11 Dec 2009 18:42:35 -0500 Subject: PCI: AER: fix aer inject result in kernel oops If the BIOS does not export _OSC to allow OS take over the PCIe AER, the pcie aer driver will not initialize the aer service. However, the aer_inject driver does not check this scenario, which results in a kernel oops when injecting an aer error into OS. For example: BUG: unable to handle kernel NULL pointer dereference at 0000000000000350 IP: [] _spin_lock_irqsave+0xc/0x23 PGD 155c41067 PUD 157fe0067 PMD 0 Oops: 0002 [#1] SMP Pid: 5119, comm: aer-inject Not tainted 2.6.32-rc8-mce #2 RIP: 0010:[] [] _spin_lock_irqsave+0xc/0x23 RSP: 0018:ffff880157f81e28 EFLAGS: 00010096 RAX: 0000000000000296 RBX: 0000000000000000 RCX: 0000000000000100 RDX: 0000000000010000 RSI: 0000000000000246 RDI: 0000000000000350 RBP: ffff880157f81e28 R08: 0000000000000004 R09: ffff880157f81dac R10: ffff88015a666f60 R11: ffff88015a666f40 R12: ffff88015758cc00 R13: 0000000000000350 R14: 0000000000000000 R15: 0000000000000100 FS: 00007f4d4a66e6f0(0000) GS:ffff8800282e0000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b CR2: 0000000000000350 CR3: 000000015661a000 CR4: 00000000000006e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 Process aer-inject (pid: 5119, threadinfo ffff880157f80000, task ffff8801585f4340) Stack: ffff880157f81e78 ffffffff811b1615 ffff880157f81e78 ffffffff81222823 Call Trace: [] aer_irq+0x38/0x117 [] ? device_for_each_child+0x5f/0x6f [] aer_inject_write+0x409/0x45e [aer_inject] [] vfs_write+0xae/0x16a [] sys_write+0x47/0x6e [] system_call_fastpath+0x16/0x1b RIP [] _spin_lock_irqsave+0xc/0x23 RSP CR2: 0000000000000350 So check the _OSC before assuming that AER is available to the OS. Signed-off-by: Youquan, Song Acked-by: Ying, Huang Signed-off-by: Jesse Barnes diff --git a/drivers/pci/pcie/aer/aer_inject.c b/drivers/pci/pcie/aer/aer_inject.c index 797d478..dd7155a 100644 --- a/drivers/pci/pcie/aer/aer_inject.c +++ b/drivers/pci/pcie/aer/aer_inject.c @@ -413,8 +413,14 @@ static int aer_inject(struct aer_error_inj *einj) if (ret) goto out_put; - if (find_aer_device(rpdev, &edev)) + if (find_aer_device(rpdev, &edev)) { + if (!get_service_data(edev)) { + printk(KERN_WARNING "AER service is not initialized\n"); + ret = -EINVAL; + goto out_put; + } aer_irq(-1, edev); + } else ret = -EINVAL; out_put: -- cgit v0.10.2 From 91e6ecada757a6e2ef7b937634af8a04376772a1 Mon Sep 17 00:00:00 2001 From: Ed Lin Date: Fri, 18 Dec 2009 17:34:51 -0800 Subject: [SCSI] stex: fix scan of nonexistent lun During a manual scan, a user can send command to a nonexistent lun, precisely at the point of max_lun. Normally it's possible (but not required) that the firmware has the knowledge that it is an invalid lun. In the particular case when max_lun is 256, however, the nonexistent lun 256 will be confused with lun 0, because the lun member in a request message is only u8, and 256 will become 0. So we need to fix the problem, at least, at the driver level. Signed-off-by: Ed Lin Signed-off-by: James Bottomley diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c index 3058bb1..fd7b15b 100644 --- a/drivers/scsi/stex.c +++ b/drivers/scsi/stex.c @@ -623,6 +623,11 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) } break; case INQUIRY: + if (lun >= host->max_lun) { + cmd->result = DID_NO_CONNECT << 16; + done(cmd); + return 0; + } if (id != host->max_id - 1) break; if (!lun && !cmd->device->channel && -- cgit v0.10.2 From eeead8115276a76675dc7cfc823a2461745edd27 Mon Sep 17 00:00:00 2001 From: James Smart Date: Mon, 21 Dec 2009 17:01:23 -0500 Subject: [SCSI] lpfc 8.3.7: Fix FC protocol errors Fix FC protocol errors: - Fix multi-frame unsolicited sequences not queued properly - Fix frames for unsolicited sequences not being associated with sequence. - Fix unsolicited frame buffer sizes are not set properly - Fix Sequence count for unsolicited frame headers not byte swapped. - Fix Multi-frame sequence response frames go to wrong DID. Signed-off-by: James Smart Signed-off-by: James Bottomley diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h index 1585148..09c8e36 100644 --- a/drivers/scsi/lpfc/lpfc_hw4.h +++ b/drivers/scsi/lpfc/lpfc_hw4.h @@ -1013,7 +1013,7 @@ struct lpfc_mbx_wq_destroy { }; #define LPFC_HDR_BUF_SIZE 128 -#define LPFC_DATA_BUF_SIZE 4096 +#define LPFC_DATA_BUF_SIZE 2048 struct rq_context { uint32_t word0; #define lpfc_rq_context_rq_size_SHIFT 16 diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 7935667..50f72bf 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -5848,7 +5848,6 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, iocbq->iocb.un.ulpWord[3]); wqe->generic.word3 = 0; bf_set(wqe_rcvoxid, &wqe->generic, iocbq->iocb.ulpContext); - bf_set(wqe_xc, &wqe->generic, 1); /* The entire sequence is transmitted for this IOCB */ xmit_len = total_len; cmnd = CMD_XMIT_SEQUENCE64_CR; @@ -10944,7 +10943,8 @@ lpfc_fc_frame_add(struct lpfc_vport *vport, struct hbq_dmabuf *dmabuf) return dmabuf; } temp_hdr = seq_dmabuf->hbuf.virt; - if (new_hdr->fh_seq_cnt < temp_hdr->fh_seq_cnt) { + if (be16_to_cpu(new_hdr->fh_seq_cnt) < + be16_to_cpu(temp_hdr->fh_seq_cnt)) { list_del_init(&seq_dmabuf->hbuf.list); list_add_tail(&dmabuf->hbuf.list, &vport->rcv_buffer_list); list_add_tail(&dmabuf->dbuf.list, &seq_dmabuf->dbuf.list); @@ -10955,6 +10955,11 @@ lpfc_fc_frame_add(struct lpfc_vport *vport, struct hbq_dmabuf *dmabuf) list_move_tail(&seq_dmabuf->hbuf.list, &vport->rcv_buffer_list); seq_dmabuf->time_stamp = jiffies; lpfc_update_rcv_time_stamp(vport); + if (list_empty(&seq_dmabuf->dbuf.list)) { + temp_hdr = dmabuf->hbuf.virt; + list_add_tail(&dmabuf->dbuf.list, &seq_dmabuf->dbuf.list); + return seq_dmabuf; + } /* find the correct place in the sequence to insert this frame */ list_for_each_entry_reverse(d_buf, &seq_dmabuf->dbuf.list, list) { temp_dmabuf = container_of(d_buf, struct hbq_dmabuf, dbuf); @@ -10963,7 +10968,8 @@ lpfc_fc_frame_add(struct lpfc_vport *vport, struct hbq_dmabuf *dmabuf) * If the frame's sequence count is greater than the frame on * the list then insert the frame right after this frame */ - if (new_hdr->fh_seq_cnt > temp_hdr->fh_seq_cnt) { + if (be16_to_cpu(new_hdr->fh_seq_cnt) > + be16_to_cpu(temp_hdr->fh_seq_cnt)) { list_add(&dmabuf->dbuf.list, &temp_dmabuf->dbuf.list); return seq_dmabuf; } @@ -11210,7 +11216,7 @@ lpfc_seq_complete(struct hbq_dmabuf *dmabuf) seq_dmabuf = container_of(d_buf, struct hbq_dmabuf, dbuf); hdr = (struct fc_frame_header *)seq_dmabuf->hbuf.virt; /* If there is a hole in the sequence count then fail. */ - if (++seq_count != hdr->fh_seq_cnt) + if (++seq_count != be16_to_cpu(hdr->fh_seq_cnt)) return 0; fctl = (hdr->fh_f_ctl[0] << 16 | hdr->fh_f_ctl[1] << 8 | @@ -11242,6 +11248,7 @@ lpfc_prep_seq(struct lpfc_vport *vport, struct hbq_dmabuf *seq_dmabuf) struct lpfc_iocbq *first_iocbq, *iocbq; struct fc_frame_header *fc_hdr; uint32_t sid; + struct ulp_bde64 *pbde; fc_hdr = (struct fc_frame_header *)seq_dmabuf->hbuf.virt; /* remove from receive buffer list */ @@ -11283,8 +11290,9 @@ lpfc_prep_seq(struct lpfc_vport *vport, struct hbq_dmabuf *seq_dmabuf) if (!iocbq->context3) { iocbq->context3 = d_buf; iocbq->iocb.ulpBdeCount++; - iocbq->iocb.unsli3.rcvsli3.bde2.tus.f.bdeSize = - LPFC_DATA_BUF_SIZE; + pbde = (struct ulp_bde64 *) + &iocbq->iocb.unsli3.sli3Words[4]; + pbde->tus.f.bdeSize = LPFC_DATA_BUF_SIZE; first_iocbq->iocb.unsli3.rcvsli3.acc_len += bf_get(lpfc_rcqe_length, &seq_dmabuf->cq_event.cqe.rcqe_cmpl); @@ -11407,7 +11415,6 @@ lpfc_sli4_handle_received_buffer(struct lpfc_hba *phba, * frame to be freed when it is finished. **/ lpfc_sli_hbqbuf_fill_hbqs(phba, LPFC_ELS_HBQ, 1); - dmabuf->tag = -1; return; } /* Send the complete sequence to the upper layer protocol */ -- cgit v0.10.2 From 1987807d4a7f52ca86034865283b207ab9be79c8 Mon Sep 17 00:00:00 2001 From: James Smart Date: Mon, 21 Dec 2009 17:02:00 -0500 Subject: [SCSI] lpfc 8.3.7: Fix NPIV operation errors Fix NPIV operation errors: - Fix vport not logging out of fabric when being deleted - Fix vport fails to discover targets after devloss timeout. Signed-off-by: James Smart Signed-off-by: James Bottomley diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index ce52270..bb2e43a 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -5948,8 +5948,8 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) lpfc_initial_fdisc(vport); break; } - } else { + vport->vpi_state |= LPFC_VPI_REGISTERED; if (vport == phba->pport) if (phba->sli_rev < LPFC_SLI_REV4) lpfc_issue_fabric_reglogin(vport); diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 3b94244..401167d 100755 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -2260,6 +2260,7 @@ lpfc_mbx_cmpl_unreg_vpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) break; } vport->vpi_state &= ~LPFC_VPI_REGISTERED; + vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; vport->unreg_vpi_cmpl = VPORT_OK; mempool_free(pmb, phba->mbox_mem_pool); /* diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c index 7d6dd83..c3a70c4 100644 --- a/drivers/scsi/lpfc/lpfc_vport.c +++ b/drivers/scsi/lpfc/lpfc_vport.c @@ -700,7 +700,7 @@ lpfc_vport_delete(struct fc_vport *fc_vport) } spin_unlock_irq(&phba->ndlp_lock); } - if (vport->vpi_state != LPFC_VPI_REGISTERED) + if (!(vport->vpi_state & LPFC_VPI_REGISTERED)) goto skip_logo; vport->unreg_vpi_cmpl = VPORT_INVAL; timeout = msecs_to_jiffies(phba->fc_ratov * 2000); -- cgit v0.10.2 From def9c7a994f194377a23e687e6fd39b46c3ce631 Mon Sep 17 00:00:00 2001 From: James Smart Date: Mon, 21 Dec 2009 17:02:28 -0500 Subject: [SCSI] lpfc 8.3.7: Fix hardware/SLI relates issues Fix hardware/SLI relates issues: - Fix CNA uses more than one EQ when in INTx interrupt mode. - Fix driver tries to process failed read FCF record mailbox request. - Fix allocating single receive buffer breaks FCoE receive queue. - Support new read FCF record mailbox error case. Signed-off-by: James Smart Signed-off-by: James Bottomley diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 401167d..f40b960 100755 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -1555,10 +1555,16 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) * to book keeping the FCFIs can be used. */ if (shdr_status || shdr_add_status) { - lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "2521 READ_FCF_RECORD mailbox failed " - "with status x%x add_status x%x, mbx\n", - shdr_status, shdr_add_status); + if (shdr_status == STATUS_FCF_TABLE_EMPTY) { + lpfc_printf_log(phba, KERN_ERR, LOG_INIT, + "2726 READ_FCF_RECORD Indicates empty " + "FCF table.\n"); + } else { + lpfc_printf_log(phba, KERN_ERR, LOG_INIT, + "2521 READ_FCF_RECORD mailbox failed " + "with status x%x add_status x%x, mbx\n", + shdr_status, shdr_add_status); + } goto out; } /* Interpreting the returned information of FCF records */ diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h old mode 100644 new mode 100755 index 09c8e36..8a2a1c5 --- a/drivers/scsi/lpfc/lpfc_hw4.h +++ b/drivers/scsi/lpfc/lpfc_hw4.h @@ -1371,6 +1371,7 @@ struct lpfc_mbx_query_fw_cfg { #define STATUS_ERROR_ACITMAIN 0x2a #define STATUS_REBOOT_REQUIRED 0x2c #define STATUS_FCF_IN_USE 0x3a +#define STATUS_FCF_TABLE_EMPTY 0x43 struct lpfc_mbx_sli4_config { struct mbox_header header; diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index d4da6bd..7083ef3 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -7507,6 +7507,9 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid) error = -ENODEV; goto out_free_sysfs_attr; } + /* Default to single FCP EQ for non-MSI-X */ + if (phba->intr_type != MSIX) + phba->cfg_fcp_eq_count = 1; /* Set up SLI-4 HBA */ if (lpfc_sli4_hba_setup(phba)) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 50f72bf..589549b 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -1383,7 +1383,7 @@ lpfc_sli_hbq_to_firmware_s4(struct lpfc_hba *phba, uint32_t hbqno, /* HBQ for ELS and CT traffic. */ static struct lpfc_hbq_init lpfc_els_hbq = { .rn = 1, - .entry_count = 200, + .entry_count = 256, .mask_count = 0, .profile = 0, .ring_mask = (1 << LPFC_ELS_RING), @@ -1482,8 +1482,11 @@ err: int lpfc_sli_hbqbuf_add_hbqs(struct lpfc_hba *phba, uint32_t qno) { - return(lpfc_sli_hbqbuf_fill_hbqs(phba, qno, - lpfc_hbq_defs[qno]->add_count)); + if (phba->sli_rev == LPFC_SLI_REV4) + return 0; + else + return lpfc_sli_hbqbuf_fill_hbqs(phba, qno, + lpfc_hbq_defs[qno]->add_count); } /** @@ -1498,8 +1501,12 @@ lpfc_sli_hbqbuf_add_hbqs(struct lpfc_hba *phba, uint32_t qno) static int lpfc_sli_hbqbuf_init_hbqs(struct lpfc_hba *phba, uint32_t qno) { - return(lpfc_sli_hbqbuf_fill_hbqs(phba, qno, - lpfc_hbq_defs[qno]->init_count)); + if (phba->sli_rev == LPFC_SLI_REV4) + return lpfc_sli_hbqbuf_fill_hbqs(phba, qno, + lpfc_hbq_defs[qno]->entry_count); + else + return lpfc_sli_hbqbuf_fill_hbqs(phba, qno, + lpfc_hbq_defs[qno]->init_count); } /** @@ -4110,6 +4117,7 @@ lpfc_sli4_read_rev(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq, if (rc) { dma_free_coherent(&phba->pcidev->dev, dma_size, dmabuf->virt, dmabuf->phys); + kfree(dmabuf); return -EIO; } @@ -11409,14 +11417,9 @@ lpfc_sli4_handle_received_buffer(struct lpfc_hba *phba, return; } /* If not last frame in sequence continue processing frames. */ - if (!lpfc_seq_complete(seq_dmabuf)) { - /* - * When saving off frames post a new one and mark this - * frame to be freed when it is finished. - **/ - lpfc_sli_hbqbuf_fill_hbqs(phba, LPFC_ELS_HBQ, 1); + if (!lpfc_seq_complete(seq_dmabuf)) return; - } + /* Send the complete sequence to the upper layer protocol */ lpfc_sli4_send_seq_to_ulp(vport, seq_dmabuf); } diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h index 25d66d0..44e5f57 100644 --- a/drivers/scsi/lpfc/lpfc_sli4.h +++ b/drivers/scsi/lpfc/lpfc_sli4.h @@ -28,7 +28,7 @@ /* Multi-queue arrangement for fast-path FCP work queues */ #define LPFC_FN_EQN_MAX 8 #define LPFC_SP_EQN_DEF 1 -#define LPFC_FP_EQN_DEF 1 +#define LPFC_FP_EQN_DEF 4 #define LPFC_FP_EQN_MIN 1 #define LPFC_FP_EQN_MAX (LPFC_FN_EQN_MAX - LPFC_SP_EQN_DEF) -- cgit v0.10.2 From aacc20e35edfb86cf66c5ee8d9f3d06a98362fd1 Mon Sep 17 00:00:00 2001 From: James Smart Date: Mon, 21 Dec 2009 17:02:51 -0500 Subject: [SCSI] lpfc 8.3.7: Fix SCSI protocol related errors. Fix SCSI protocol related errors: - Avoid I/O failures during EEH and HBA/CNA reset by correcting when we block the targets on the adapter. Signed-off-by: James Smart Signed-off-by: James Bottomley diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index f40b960..1c27372 100755 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -747,6 +747,10 @@ lpfc_linkdown(struct lpfc_hba *phba) if (phba->link_state == LPFC_LINK_DOWN) return 0; + + /* Block all SCSI stack I/Os */ + lpfc_scsi_dev_block(phba); + spin_lock_irq(&phba->hbalock); phba->fcf.fcf_flag &= ~(FCF_AVAILABLE | FCF_DISCOVERED); if (phba->link_state > LPFC_LINK_DOWN) { diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 7083ef3..974ea6d 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -7226,8 +7226,6 @@ lpfc_prep_dev_for_perm_failure(struct lpfc_hba *phba) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "2711 PCI channel permanent disable for failure\n"); - /* Block all SCSI devices' I/Os on the host */ - lpfc_scsi_dev_block(phba); /* Clean up all driver's outstanding SCSI I/Os */ lpfc_sli_flush_fcp_rings(phba); } @@ -7256,6 +7254,9 @@ lpfc_io_error_detected_s3(struct pci_dev *pdev, pci_channel_state_t state) struct Scsi_Host *shost = pci_get_drvdata(pdev); struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; + /* Block all SCSI devices' I/Os on the host */ + lpfc_scsi_dev_block(phba); + switch (state) { case pci_channel_io_normal: /* Non-fatal error, prepare for recovery */ -- cgit v0.10.2 From 9795724476860069ce183ead59d0a5958f882037 Mon Sep 17 00:00:00 2001 From: James Smart Date: Mon, 21 Dec 2009 17:03:15 -0500 Subject: [SCSI] lpfc 8.3.7: Fix discovery failures. Fix discovery failures: - Move all accesses to the fc_flag field inside the host lock. - Restore link state after going through linkdown processing for FCF DEAD event. Signed-off-by: James Smart Signed-off-by: James Bottomley diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index bb2e43a..2cc3968 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -4142,8 +4142,8 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, spin_lock_irq(shost->host_lock); if (vport->fc_rscn_flush) { /* Another thread is walking fc_rscn_id_list on this vport */ - spin_unlock_irq(shost->host_lock); vport->fc_flag |= FC_RSCN_DISCOVERY; + spin_unlock_irq(shost->host_lock); /* Send back ACC */ lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL); return 0; diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 1c27372..2445e39 100755 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -1708,7 +1708,9 @@ lpfc_init_vpi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) lpfc_vport_set_state(vport, FC_VPORT_FAILED); return; } + spin_lock_irq(&phba->hbalock); vport->fc_flag &= ~FC_VPORT_NEEDS_INIT_VPI; + spin_unlock_irq(&phba->hbalock); if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) lpfc_initial_fdisc(vport); @@ -2269,8 +2271,10 @@ lpfc_mbx_cmpl_unreg_vpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) mb->mbxStatus); break; } + spin_lock_irq(&phba->hbalock); vport->vpi_state &= ~LPFC_VPI_REGISTERED; vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; + spin_unlock_irq(&phba->hbalock); vport->unreg_vpi_cmpl = VPORT_OK; mempool_free(pmb, phba->mbox_mem_pool); /* @@ -4486,8 +4490,10 @@ lpfc_unregister_unused_fcf(struct lpfc_hba *phba) (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)) for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { lpfc_mbx_unreg_vpi(vports[i]); + spin_lock_irq(&phba->hbalock); vports[i]->fc_flag |= FC_VPORT_NEEDS_INIT_VPI; vports[i]->vpi_state &= ~LPFC_VPI_REGISTERED; + spin_unlock_irq(&phba->hbalock); } lpfc_destroy_vport_work_array(phba, vports); diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 974ea6d..b8eb1b6 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -3006,6 +3006,7 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba, struct lpfc_vport *vport; struct lpfc_nodelist *ndlp; struct Scsi_Host *shost; + uint32_t link_state; phba->fc_eventTag = acqe_fcoe->event_tag; phba->fcoe_eventtag = acqe_fcoe->event_tag; @@ -3052,9 +3053,12 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba, break; /* * Currently, driver support only one FCF - so treat this as - * a link down. + * a link down, but save the link state because we don't want + * it to be changed to Link Down unless it is already down. */ + link_state = phba->link_state; lpfc_linkdown(phba); + phba->link_state = link_state; /* Unregister FCF if no devices connected to it */ lpfc_unregister_unused_fcf(phba); break; diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c index c3a70c4..e3c7fa6 100644 --- a/drivers/scsi/lpfc/lpfc_vport.c +++ b/drivers/scsi/lpfc/lpfc_vport.c @@ -512,8 +512,10 @@ enable_vport(struct fc_vport *fc_vport) return VPORT_OK; } + spin_lock_irq(&phba->hbalock); vport->load_flag |= FC_LOADING; vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; + spin_unlock_irq(&phba->hbalock); /* Use the Physical nodes Fabric NDLP to determine if the link is * up and ready to FDISC. -- cgit v0.10.2 From 500af638b3f378e5d1f04dfe5043a377cdc234de Mon Sep 17 00:00:00 2001 From: James Smart Date: Mon, 21 Dec 2009 17:03:47 -0500 Subject: [SCSI] lpfc 8.3.7: Update Driver version to 8.3.7 Update Driver version to 8.3.7 Signed-off-by: James Smart Signed-off-by: James Bottomley diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h index c7f3aed..792f722 100644 --- a/drivers/scsi/lpfc/lpfc_version.h +++ b/drivers/scsi/lpfc/lpfc_version.h @@ -18,7 +18,7 @@ * included with this package. * *******************************************************************/ -#define LPFC_DRIVER_VERSION "8.3.6" +#define LPFC_DRIVER_VERSION "8.3.7" #define LPFC_DRIVER_NAME "lpfc" #define LPFC_SP_DRIVER_HANDLER_NAME "lpfc:sp" #define LPFC_FP_DRIVER_HANDLER_NAME "lpfc:fp" -- cgit v0.10.2 From ecbec242961ec66e900b5649ded1e40f5d5edc41 Mon Sep 17 00:00:00 2001 From: Manuel Lauss Date: Mon, 4 Jan 2010 16:29:49 +0100 Subject: ASoC: fixup oops in generic AC97 codec glue Initialize the glue by calling snd_soc_new_ac97_codec() as is done in other ASoC AC97 codecs. Fixes an oops caused by dereferencing uninitialized members in snd_soc_new_pcms(). Run-tested on Au1250. Signed-off-by: Manuel Lauss Acked-by: Liam Girdwood Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c index 69bd0ac..a1bbe16 100644 --- a/sound/soc/codecs/ac97.c +++ b/sound/soc/codecs/ac97.c @@ -102,6 +102,12 @@ static int ac97_soc_probe(struct platform_device *pdev) INIT_LIST_HEAD(&codec->dapm_widgets); INIT_LIST_HEAD(&codec->dapm_paths); + ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); + if (ret < 0) { + printk(KERN_ERR "ASoC: failed to init gen ac97 glue\n"); + goto err; + } + /* register pcms */ ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); if (ret < 0) -- cgit v0.10.2 From 6432e734c99ed685e3cad72f7dcae4c65008fcab Mon Sep 17 00:00:00 2001 From: John Kacur Date: Sun, 18 Oct 2009 23:49:49 +0200 Subject: sony_pi: Remove the BKL from open and ioctl The BKL is in this function because of the BKL pushdown (see commit f8f2c79d594463427f7114cedb1555110d547d89) It is not needed here because the mutex_lock sonypi_device.lock provides the necessary locking. sonypi_misc_ioctl can be converted to unlocked ioctls since it relies on its own locking (the mutex sonypi_device.lock) and not the bkl Document that llseek is not needed by explictly setting it to no_llseek LKML-Reference: Signed-off-by: John Kacur Acked-by: Arnd Bergmann Signed-off-by: Linus Torvalds diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index 0798754..bba727c 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c @@ -50,7 +50,6 @@ #include #include #include -#include #include #include @@ -905,14 +904,13 @@ static int sonypi_misc_release(struct inode *inode, struct file *file) static int sonypi_misc_open(struct inode *inode, struct file *file) { - lock_kernel(); mutex_lock(&sonypi_device.lock); /* Flush input queue on first open */ if (!sonypi_device.open_count) kfifo_reset(&sonypi_device.fifo); sonypi_device.open_count++; mutex_unlock(&sonypi_device.lock); - unlock_kernel(); + return 0; } @@ -955,10 +953,10 @@ static unsigned int sonypi_misc_poll(struct file *file, poll_table *wait) return 0; } -static int sonypi_misc_ioctl(struct inode *ip, struct file *fp, +static long sonypi_misc_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) { - int ret = 0; + long ret = 0; void __user *argp = (void __user *)arg; u8 val8; u16 val16; @@ -1074,7 +1072,8 @@ static const struct file_operations sonypi_misc_fops = { .open = sonypi_misc_open, .release = sonypi_misc_release, .fasync = sonypi_misc_fasync, - .ioctl = sonypi_misc_ioctl, + .unlocked_ioctl = sonypi_misc_ioctl, + .llseek = no_llseek, }; static struct miscdevice sonypi_misc_device = { -- cgit v0.10.2 From 5d9d6e44ce15d072d22c10fe670679c77fa2b31d Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 4 Jan 2010 16:18:27 +0000 Subject: i2o: propogate the BKL down into the ioctl method Nobody seems to want to own I2O patches so sending this one directly. Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds diff --git a/drivers/message/i2o/i2o_config.c b/drivers/message/i2o/i2o_config.c index efba702..3d5f40c 100644 --- a/drivers/message/i2o/i2o_config.c +++ b/drivers/message/i2o/i2o_config.c @@ -40,8 +40,7 @@ #define SG_TABLESIZE 30 -static int i2o_cfg_ioctl(struct inode *, struct file *, unsigned int, - unsigned long); +static long i2o_cfg_ioctl(struct file *, unsigned int, unsigned long); static spinlock_t i2o_config_lock; @@ -751,7 +750,7 @@ static long i2o_cfg_compat_ioctl(struct file *file, unsigned cmd, lock_kernel(); switch (cmd) { case I2OGETIOPS: - ret = i2o_cfg_ioctl(NULL, file, cmd, arg); + ret = i2o_cfg_ioctl(file, cmd, arg); break; case I2OPASSTHRU32: ret = i2o_cfg_passthru32(file, cmd, arg); @@ -984,11 +983,11 @@ out: /* * IOCTL Handler */ -static int i2o_cfg_ioctl(struct inode *inode, struct file *fp, unsigned int cmd, - unsigned long arg) +static long i2o_cfg_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) { int ret; + lock_kernel(); switch (cmd) { case I2OGETIOPS: ret = i2o_cfg_getiops(arg); @@ -1044,7 +1043,7 @@ static int i2o_cfg_ioctl(struct inode *inode, struct file *fp, unsigned int cmd, osm_debug("unknown ioctl called!\n"); ret = -EINVAL; } - + unlock_kernel(); return ret; } @@ -1118,7 +1117,7 @@ static int cfg_release(struct inode *inode, struct file *file) static const struct file_operations config_fops = { .owner = THIS_MODULE, .llseek = no_llseek, - .ioctl = i2o_cfg_ioctl, + .unlocked_ioctl = i2o_cfg_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = i2o_cfg_compat_ioctl, #endif -- cgit v0.10.2 From 3e8d95d95eaf4b332f6e1862ffbaa80c24780767 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 4 Jan 2010 16:19:55 +0000 Subject: tosh: Use non bkl ioctl We wrap the smm calls and other bits with the BKL push down as a precaution but they can probably go Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds diff --git a/drivers/char/toshiba.c b/drivers/char/toshiba.c index 663cd15d..f8bc79f 100644 --- a/drivers/char/toshiba.c +++ b/drivers/char/toshiba.c @@ -68,7 +68,7 @@ #include #include #include - +#include #include #define TOSH_MINOR_DEV 181 @@ -88,13 +88,13 @@ static int tosh_date; static int tosh_sci; static int tosh_fan; -static int tosh_ioctl(struct inode *, struct file *, unsigned int, +static long tosh_ioctl(struct file *, unsigned int, unsigned long); static const struct file_operations tosh_fops = { .owner = THIS_MODULE, - .ioctl = tosh_ioctl, + .unlocked_ioctl = tosh_ioctl, }; static struct miscdevice tosh_device = { @@ -252,8 +252,7 @@ int tosh_smm(SMMRegisters *regs) EXPORT_SYMBOL(tosh_smm); -static int tosh_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, - unsigned long arg) +static long tosh_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) { SMMRegisters regs; SMMRegisters __user *argp = (SMMRegisters __user *)arg; @@ -275,13 +274,16 @@ static int tosh_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, return -EINVAL; /* do we need to emulate the fan ? */ + lock_kernel(); if (tosh_fan==1) { if (((ax==0xf300) || (ax==0xf400)) && (bx==0x0004)) { err = tosh_emulate_fan(®s); + unlock_kernel(); break; } } err = tosh_smm(®s); + unlock_kernel(); break; default: return -EINVAL; -- cgit v0.10.2 From 3e27249c84beed1c79d767b350e52ad038db9053 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 4 Jan 2010 19:26:14 +1030 Subject: lguest: fix bug in setting guest GDT entry We kill the guest, but then we blatt random stuff. Reported-by: Dan Carpenter Signed-off-by: Rusty Russell Cc: stable@kernel.org Signed-off-by: Linus Torvalds diff --git a/drivers/lguest/segments.c b/drivers/lguest/segments.c index 951c57b..ede4658 100644 --- a/drivers/lguest/segments.c +++ b/drivers/lguest/segments.c @@ -179,8 +179,10 @@ void load_guest_gdt_entry(struct lg_cpu *cpu, u32 num, u32 lo, u32 hi) * We assume the Guest has the same number of GDT entries as the * Host, otherwise we'd have to dynamically allocate the Guest GDT. */ - if (num >= ARRAY_SIZE(cpu->arch.gdt)) + if (num >= ARRAY_SIZE(cpu->arch.gdt)) { kill_guest(cpu, "too many gdt entries %i", num); + return; + } /* Set it up, then fix it. */ cpu->arch.gdt[num].a = lo; -- cgit v0.10.2 From 846f99749ab68bbc7f75c74fec305de675b1a1bf Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Sat, 2 Jan 2010 13:37:12 -0800 Subject: sysfs: Add lockdep annotations for the sysfs active reference Holding locks over device_del -> kobject_del -> sysfs_deactivate can cause deadlocks if those same locks are grabbed in sysfs show or store methods. The I model s_active count + completion as a sleeping read/write lock. I describe to lockdep sysfs_get_active as a read_trylock, sysfs_put_active as a read_unlock, and sysfs_deactivate as a write_lock and write_unlock pair. This seems to capture the essence for purposes of finding deadlocks, and in my testing gives finds real issues and ignores non-issues. This brings us back to holding locks over kobject_del is a problem that ideally we should find a way of addressing, but at least lockdep can tell us about the problems instead of requiring developers to debug rare strange system deadlocks, that happen when sysfs files are removed while being written to. Signed-off-by: Eric W. Biederman Acked-by: Tejun Heo Signed-off-by: Linus Torvalds diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index f05f230..699f371 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c @@ -106,8 +106,10 @@ static struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd) return NULL; t = atomic_cmpxchg(&sd->s_active, v, v + 1); - if (likely(t == v)) + if (likely(t == v)) { + rwsem_acquire_read(&sd->dep_map, 0, 1, _RET_IP_); return sd; + } if (t < 0) return NULL; @@ -130,6 +132,7 @@ static void sysfs_put_active(struct sysfs_dirent *sd) if (unlikely(!sd)) return; + rwsem_release(&sd->dep_map, 1, _RET_IP_); v = atomic_dec_return(&sd->s_active); if (likely(v != SD_DEACTIVATED_BIAS)) return; @@ -194,15 +197,21 @@ static void sysfs_deactivate(struct sysfs_dirent *sd) BUG_ON(sd->s_sibling || !(sd->s_flags & SYSFS_FLAG_REMOVED)); sd->s_sibling = (void *)&wait; + rwsem_acquire(&sd->dep_map, 0, 0, _RET_IP_); /* atomic_add_return() is a mb(), put_active() will always see * the updated sd->s_sibling. */ v = atomic_add_return(SD_DEACTIVATED_BIAS, &sd->s_active); - if (v != SD_DEACTIVATED_BIAS) + if (v != SD_DEACTIVATED_BIAS) { + lock_contended(&sd->dep_map, _RET_IP_); wait_for_completion(&wait); + } sd->s_sibling = NULL; + + lock_acquired(&sd->dep_map, _RET_IP_); + rwsem_release(&sd->dep_map, 1, _RET_IP_); } static int sysfs_alloc_ino(ino_t *pino) @@ -345,6 +354,7 @@ struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, int type) atomic_set(&sd->s_count, 1); atomic_set(&sd->s_active, 0); + sysfs_dirent_init_lockdep(sd); sd->s_name = name; sd->s_mode = mode; diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h index ca52e7b..cdd9377 100644 --- a/fs/sysfs/sysfs.h +++ b/fs/sysfs/sysfs.h @@ -8,6 +8,7 @@ * This file is released under the GPLv2. */ +#include #include struct sysfs_open_dirent; @@ -50,6 +51,9 @@ struct sysfs_inode_attrs { struct sysfs_dirent { atomic_t s_count; atomic_t s_active; +#ifdef CONFIG_DEBUG_LOCK_ALLOC + struct lockdep_map dep_map; +#endif struct sysfs_dirent *s_parent; struct sysfs_dirent *s_sibling; const char *s_name; @@ -84,6 +88,17 @@ static inline unsigned int sysfs_type(struct sysfs_dirent *sd) return sd->s_flags & SYSFS_TYPE_MASK; } +#ifdef CONFIG_DEBUG_LOCK_ALLOC +#define sysfs_dirent_init_lockdep(sd) \ +do { \ + static struct lock_class_key __key; \ + \ + lockdep_init_map(&sd->dep_map, "s_active", &__key, 0); \ +} while(0) +#else +#define sysfs_dirent_init_lockdep(sd) do {} while(0) +#endif + /* * Context structure to be used while adding/removing nodes. */ -- cgit v0.10.2 From 9dad0fd5a73d4048dff18069733c0b515f68df74 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Tue, 22 Dec 2009 15:40:39 -0800 Subject: x86: Fix size for ex trampoline with 32bit fix for error that is introduced by | x86: Use find_e820() instead of hard coded trampoline address it should end with PAGE_SIZE + PAGE_SIZE Signed-off-by: Yinghai Lu LKML-Reference: <1261525263-13763-2-git-send-email-yinghai@kernel.org> Signed-off-by: H. Peter Anvin diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index 05ed7ab..a1a7876 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c @@ -733,13 +733,13 @@ struct early_res { }; static struct early_res early_res[MAX_EARLY_RES] __initdata = { { 0, PAGE_SIZE, "BIOS data page", 1 }, /* BIOS data page */ -#ifdef CONFIG_X86_32 +#if defined(CONFIG_X86_32) && defined(CONFIG_X86_TRAMPOLINE) /* * But first pinch a few for the stack/trampoline stuff * FIXME: Don't need the extra page at 4K, but need to fix * trampoline before removing it. (see the GDT stuff) */ - { PAGE_SIZE, PAGE_SIZE, "EX TRAMPOLINE", 1 }, + { PAGE_SIZE, PAGE_SIZE + PAGE_SIZE, "EX TRAMPOLINE", 1 }, #endif {} -- cgit v0.10.2 From a557aae29cf5916295c234d4b10ba3f8f29b8a96 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Tue, 22 Dec 2009 15:40:40 -0800 Subject: x86/pci: Intel ioh bus num reg accessing fix It is above 0x100 (PCI-Express extended register space), so if mmconf is not enable, we can't access it. [ hpa: changed the bound from 0x200 to 0x120, which is the tight bound. ] Reported-by: Jens Axboe Signed-off-by: Yinghai Lu LKML-Reference: <1261525263-13763-3-git-send-email-yinghai@kernel.org> Signed-off-by: H. Peter Anvin diff --git a/arch/x86/pci/intel_bus.c b/arch/x86/pci/intel_bus.c index b7a55dc..f81a2fa 100644 --- a/arch/x86/pci/intel_bus.c +++ b/arch/x86/pci/intel_bus.c @@ -49,6 +49,10 @@ static void __devinit pci_root_bus_res(struct pci_dev *dev) u64 mmioh_base, mmioh_end; int bus_base, bus_end; + /* some sys doesn't get mmconf enabled */ + if (dev->cfg_size < 0x120) + return; + if (pci_root_num >= PCI_ROOT_NR) { printk(KERN_DEBUG "intel_bus.c: PCI_ROOT_NR is too small\n"); return; -- cgit v0.10.2 From d3af9dd04f8795dc2761ecfa56632e4d0df0dae2 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 4 Jan 2010 14:36:40 -0800 Subject: cxgb3i: Fix flags test. As noticed by Stephen Rothwell. Signed-off-by: David S. Miller diff --git a/drivers/scsi/cxgb3i/cxgb3i_offload.c b/drivers/scsi/cxgb3i/cxgb3i_offload.c index 4b8a513..7449d46 100644 --- a/drivers/scsi/cxgb3i/cxgb3i_offload.c +++ b/drivers/scsi/cxgb3i/cxgb3i_offload.c @@ -1442,7 +1442,7 @@ static int is_cxgb3_dev(struct net_device *dev) struct cxgb3i_sdev_data *cdata; struct net_device *ndev = dev; - if (dev->priv_flags && IFF_802_1Q_VLAN) + if (dev->priv_flags & IFF_802_1Q_VLAN) ndev = vlan_dev_real_dev(dev); write_lock(&cdata_rwlock); -- cgit v0.10.2 From 6be954d1f91b81ca85c74792b13654069278c577 Mon Sep 17 00:00:00 2001 From: David John Date: Mon, 4 Jan 2010 20:28:57 +0530 Subject: PCI: Check the node argument passed to cpumask_of_node Commit e0cd516 "PCI: derive nearby CPUs from device's instead of bus' NUMA information" causes an null pointer dereference when reading from the sysfs attributes local_cpu* on Intel machines with no ACPI NUMA proximity info, since dev->numa_node gets set to -1 for all PCI devices, which then gets passed to cpumask_of_node. Add a check to prevent this. Signed-off-by: David John Signed-off-by: Jesse Barnes diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index c5df94e..807224e 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -75,7 +75,8 @@ static ssize_t local_cpus_show(struct device *dev, int len; #ifdef CONFIG_NUMA - mask = cpumask_of_node(dev_to_node(dev)); + mask = (dev_to_node(dev) == -1) ? cpu_online_mask : + cpumask_of_node(dev_to_node(dev)); #else mask = cpumask_of_pcibus(to_pci_dev(dev)->bus); #endif @@ -93,7 +94,8 @@ static ssize_t local_cpulist_show(struct device *dev, int len; #ifdef CONFIG_NUMA - mask = cpumask_of_node(dev_to_node(dev)); + mask = (dev_to_node(dev) == -1) ? cpu_online_mask : + cpumask_of_node(dev_to_node(dev)); #else mask = cpumask_of_pcibus(to_pci_dev(dev)->bus); #endif -- cgit v0.10.2 From c7c17c2779075e675cb3c7fe2ecde67e226771fb Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 4 Jan 2010 15:31:10 -0800 Subject: bbc_envctrl: Clean up properly if kthread_run() fails. In bbc_envctrl_init() we have to unlink the fan and temp instances from the lists because our caller is going to free up the 'bp' object if we return an error. We can't rely upon bbc_envctrl_cleanup() to do this work for us in this case. Reported-by: Patrick Finnegan Signed-off-by: David S. Miller diff --git a/drivers/sbus/char/bbc_envctrl.c b/drivers/sbus/char/bbc_envctrl.c index 7c815d3..28d86f9 100644 --- a/drivers/sbus/char/bbc_envctrl.c +++ b/drivers/sbus/char/bbc_envctrl.c @@ -522,6 +522,40 @@ static void attach_one_fan(struct bbc_i2c_bus *bp, struct of_device *op, set_fan_speeds(fp); } +static void destroy_one_temp(struct bbc_cpu_temperature *tp) +{ + bbc_i2c_detach(tp->client); + kfree(tp); +} + +static void destroy_all_temps(struct bbc_i2c_bus *bp) +{ + struct bbc_cpu_temperature *tp, *tpos; + + list_for_each_entry_safe(tp, tpos, &bp->temps, bp_list) { + list_del(&tp->bp_list); + list_del(&tp->glob_list); + destroy_one_temp(tp); + } +} + +static void destroy_one_fan(struct bbc_fan_control *fp) +{ + bbc_i2c_detach(fp->client); + kfree(fp); +} + +static void destroy_all_fans(struct bbc_i2c_bus *bp) +{ + struct bbc_fan_control *fp, *fpos; + + list_for_each_entry_safe(fp, fpos, &bp->fans, bp_list) { + list_del(&fp->bp_list); + list_del(&fp->glob_list); + destroy_one_fan(fp); + } +} + int bbc_envctrl_init(struct bbc_i2c_bus *bp) { struct of_device *op; @@ -541,6 +575,8 @@ int bbc_envctrl_init(struct bbc_i2c_bus *bp) int err = PTR_ERR(kenvctrld_task); kenvctrld_task = NULL; + destroy_all_temps(bp); + destroy_all_fans(bp); return err; } } @@ -548,35 +584,11 @@ int bbc_envctrl_init(struct bbc_i2c_bus *bp) return 0; } -static void destroy_one_temp(struct bbc_cpu_temperature *tp) -{ - bbc_i2c_detach(tp->client); - kfree(tp); -} - -static void destroy_one_fan(struct bbc_fan_control *fp) -{ - bbc_i2c_detach(fp->client); - kfree(fp); -} - void bbc_envctrl_cleanup(struct bbc_i2c_bus *bp) { - struct bbc_cpu_temperature *tp, *tpos; - struct bbc_fan_control *fp, *fpos; - if (kenvctrld_task) kthread_stop(kenvctrld_task); - list_for_each_entry_safe(tp, tpos, &bp->temps, bp_list) { - list_del(&tp->bp_list); - list_del(&tp->glob_list); - destroy_one_temp(tp); - } - - list_for_each_entry_safe(fp, fpos, &bp->fans, bp_list) { - list_del(&fp->bp_list); - list_del(&fp->glob_list); - destroy_one_fan(fp); - } + destroy_all_temps(bp); + destroy_all_fans(bp); } -- cgit v0.10.2 From 8183e2b38480672a1f61d416812ac078ce94b67b Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 4 Jan 2010 15:37:04 -0800 Subject: sparc64: Fix NMI programming when perf events are active. If perf events are active, we should not reset the %pcr to PCR_PIC_PRIV. That perf events code does the management. Signed-off-by: David S. Miller diff --git a/arch/sparc/kernel/nmi.c b/arch/sparc/kernel/nmi.c index f30f4a1..d242a73 100644 --- a/arch/sparc/kernel/nmi.c +++ b/arch/sparc/kernel/nmi.c @@ -96,7 +96,6 @@ notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs) int cpu = smp_processor_id(); clear_softint(1 << irq); - pcr_ops->write(PCR_PIC_PRIV); local_cpu_data().__nmi_count++; @@ -105,6 +104,8 @@ notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs) if (notify_die(DIE_NMI, "nmi", regs, 0, pt_regs_trap_type(regs), SIGINT) == NOTIFY_STOP) touched = 1; + else + pcr_ops->write(PCR_PIC_PRIV); sum = kstat_irqs_cpu(0, cpu); if (__get_cpu_var(nmi_touch)) { -- cgit v0.10.2 From 1ae861e652b5457e7fa98ccbc55abea1e207916e Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 31 Dec 2009 12:15:54 +0100 Subject: PCI/PM: Use per-device D3 delays It turns out that some PCI devices require extra delays when changing power state from D3 to D0 (and the other way around). Although this is against the PCI specification, we can handle it quite easily by allowing drivers to define arbitrary D3 delays for devices known to require extra time for switching power states. Introduce additional field d3_delay in struct pci_dev and use it to store the value of the device's D0->D3 delay, in miliseconds. Make the PCI PM core code use the per-device d3_delay unless pci_pm_d3_delay is greater (in which case the latter is used). [This also allows the driver to specify d3_delay shorter than the 10 ms required by the PCI standard if the device is known to be able to handle that.] Make the sky2 driver set d3_delay to 150 for devices handled by it. Fixes http://bugzilla.kernel.org/show_bug.cgi?id=14730 which is a listed regression from 2.6.30. Signed-off-by: Rafael J. Wysocki Signed-off-by: Jesse Barnes diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 1c01b96..2d28d58 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -4684,6 +4684,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev, INIT_WORK(&hw->restart_work, sky2_restart); pci_set_drvdata(pdev, hw); + pdev->d3_delay = 150; return 0; diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 0906599..315fea4 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -29,7 +29,17 @@ const char *pci_power_names[] = { }; EXPORT_SYMBOL_GPL(pci_power_names); -unsigned int pci_pm_d3_delay = PCI_PM_D3_WAIT; +unsigned int pci_pm_d3_delay; + +static void pci_dev_d3_sleep(struct pci_dev *dev) +{ + unsigned int delay = dev->d3_delay; + + if (delay < pci_pm_d3_delay) + delay = pci_pm_d3_delay; + + msleep(delay); +} #ifdef CONFIG_PCI_DOMAINS int pci_domains_supported = 1; @@ -522,7 +532,7 @@ static int pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state) /* Mandatory power management transition delays */ /* see PCI PM 1.1 5.6.1 table 18 */ if (state == PCI_D3hot || dev->current_state == PCI_D3hot) - msleep(pci_pm_d3_delay); + pci_dev_d3_sleep(dev); else if (state == PCI_D2 || dev->current_state == PCI_D2) udelay(PCI_PM_D2_DELAY); @@ -1409,6 +1419,7 @@ void pci_pm_init(struct pci_dev *dev) } dev->pm_cap = pm; + dev->d3_delay = PCI_PM_D3_WAIT; dev->d1_support = false; dev->d2_support = false; @@ -2247,12 +2258,12 @@ static int pci_pm_reset(struct pci_dev *dev, int probe) csr &= ~PCI_PM_CTRL_STATE_MASK; csr |= PCI_D3hot; pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, csr); - msleep(pci_pm_d3_delay); + pci_dev_d3_sleep(dev); csr &= ~PCI_PM_CTRL_STATE_MASK; csr |= PCI_D0; pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, csr); - msleep(pci_pm_d3_delay); + pci_dev_d3_sleep(dev); return 0; } diff --git a/include/linux/pci.h b/include/linux/pci.h index 5da0690..174e539 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -243,6 +243,7 @@ struct pci_dev { unsigned int d2_support:1; /* Low power state D2 is supported */ unsigned int no_d1d2:1; /* Only allow D0 and D3 */ unsigned int wakeup_prepared:1; + unsigned int d3_delay; /* D3->D0 transition time in ms */ #ifdef CONFIG_PCIEASPM struct pcie_link_state *link_state; /* ASPM link state. */ -- cgit v0.10.2 From b49bfd32901625e4adcfee011d2b32a43b4db67d Mon Sep 17 00:00:00 2001 From: "Youquan,Song" Date: Thu, 17 Dec 2009 08:22:48 -0500 Subject: PCIe AER: prevent AER injection if hardware masks error reporting The Correcteable/Uncorrectable Error Mask Registers are used by PCIe AER driver which will controls the reporting of individual errors to PCIe RC via PCIe error messages. If hardware masks special error reporting to RC, the aer_inject driver should not inject aer error. Acked-by: Andi Kleen Signed-off-by: Youquan, Song Acked-by: Ying, Huang Signed-off-by: Jesse Barnes diff --git a/drivers/pci/pcie/aer/aer_inject.c b/drivers/pci/pcie/aer/aer_inject.c index dd7155a..8c30a95 100644 --- a/drivers/pci/pcie/aer/aer_inject.c +++ b/drivers/pci/pcie/aer/aer_inject.c @@ -321,7 +321,7 @@ static int aer_inject(struct aer_error_inj *einj) unsigned long flags; unsigned int devfn = PCI_DEVFN(einj->dev, einj->fn); int pos_cap_err, rp_pos_cap_err; - u32 sever; + u32 sever, mask; int ret = 0; dev = pci_get_domain_bus_and_slot((int)einj->domain, einj->bus, devfn); @@ -374,6 +374,24 @@ static int aer_inject(struct aer_error_inj *einj) err->header_log2 = einj->header_log2; err->header_log3 = einj->header_log3; + pci_read_config_dword(dev, pos_cap_err + PCI_ERR_COR_MASK, &mask); + if (einj->cor_status && !(einj->cor_status & ~mask)) { + ret = -EINVAL; + printk(KERN_WARNING "The correctable error(s) is masked " + "by device\n"); + spin_unlock_irqrestore(&inject_lock, flags); + goto out_put; + } + + pci_read_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_MASK, &mask); + if (einj->uncor_status && !(einj->uncor_status & ~mask)) { + ret = -EINVAL; + printk(KERN_WARNING "The uncorrectable error(s) is masked " + "by device\n"); + spin_unlock_irqrestore(&inject_lock, flags); + goto out_put; + } + rperr = __find_aer_error_by_dev(rpdev); if (!rperr) { rperr = rperr_alloc; -- cgit v0.10.2 From f4b825bde98938f160315d655597bc9731521cae Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 5 Jan 2010 12:48:49 +1030 Subject: Revert "x86: Side-step lguest problem by only building cmpxchg8b_emu for pre-Pentium" This reverts commit ae1b22f6e46c03cede7cea234d0bf2253b4261cf. As Linus said in 982d007a6ee: "There was something really messy about cmpxchg8b and clone CPU's, so if you enable it on other CPUs later, do it carefully." This breaks lguest for those configs, but we can fix that by emulating if we have to. Fixes: http://bugzilla.kernel.org/show_bug.cgi?id=14884 Signed-off-by: Rusty Russell LKML-Reference: <201001051248.49700.rusty@rustcorp.com.au> Cc: stable@kernel.org Signed-off-by: H. Peter Anvin diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu index 08e442b..f20ddf8 100644 --- a/arch/x86/Kconfig.cpu +++ b/arch/x86/Kconfig.cpu @@ -396,7 +396,7 @@ config X86_TSC config X86_CMPXCHG64 def_bool y - depends on !M386 && !M486 + depends on X86_PAE || X86_64 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MATOM # this should be set for all -march=.. options where the compiler # generates cmov. -- cgit v0.10.2 From 5fe1533fda8ae005541bd418a7a8bc4fa0cda522 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Mon, 4 Jan 2010 22:04:01 +0100 Subject: reiserfs: Fix recursive lock on lchown On chown, reiserfs will call reiserfs_setattr() to change the owner of the given inode, but it may also recursively call reiserfs_setattr() to propagate the owner change to the private xattr files for this inode. Hence, the reiserfs lock may be acquired twice which is not wanted as reiserfs_setattr() calls journal_begin() that is going to try to relax the lock in order to safely acquire the journal mutex. Using reiserfs_write_lock_once() from reiserfs_setattr() solves the problem. This fixes the following warning, that precedes a lockdep report. WARNING: at fs/reiserfs/lock.c:95 reiserfs_lock_check_recursive+0x3f/0x50() Hardware name: MS-7418 Unwanted recursive reiserfs lock! Pid: 4189, comm: fsstress Not tainted 2.6.33-rc2-tip-atom+ #195 Call Trace: [] ? reiserfs_lock_check_recursive+0x3f/0x50 [] ? reiserfs_lock_check_recursive+0x3f/0x50 [] warn_slowpath_common+0x6c/0xc0 [] ? reiserfs_lock_check_recursive+0x3f/0x50 [] warn_slowpath_fmt+0x2b/0x30 [] reiserfs_lock_check_recursive+0x3f/0x50 [] do_journal_begin_r+0x83/0x350 [] journal_begin+0x7d/0x140 [] ? in_group_p+0x2a/0x30 [] ? inode_change_ok+0x91/0x140 [] reiserfs_setattr+0x15d/0x2e0 [] ? dput+0xe3/0x140 [] ? _raw_spin_unlock+0x2c/0x50 [] chown_one_xattr+0xd/0x10 [] reiserfs_for_each_xattr+0x113/0x2c0 [] ? chown_one_xattr+0x0/0x10 [] ? mutex_lock_nested+0x2a9/0x350 [] reiserfs_chown_xattrs+0x1f/0x60 [] ? in_group_p+0x2a/0x30 [] ? inode_change_ok+0x91/0x140 [] reiserfs_setattr+0x126/0x2e0 [] ? reiserfs_getxattr+0x0/0x90 [] ? cap_inode_need_killpriv+0x37/0x50 [] notify_change+0x151/0x330 [] chown_common+0x6f/0x90 [] sys_lchown+0x6d/0x80 [] sysenter_do_call+0x12/0x32 ---[ end trace 7c2b77224c1442fc ]--- Signed-off-by: Frederic Weisbecker Cc: Christian Kujau Cc: Alexander Beregalov Cc: Chris Mason Cc: Ingo Molnar diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index bd615df..47dbfb1 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c @@ -3052,13 +3052,14 @@ static ssize_t reiserfs_direct_IO(int rw, struct kiocb *iocb, int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) { struct inode *inode = dentry->d_inode; - int error; unsigned int ia_valid; + int depth; + int error; /* must be turned off for recursive notify_change calls */ ia_valid = attr->ia_valid &= ~(ATTR_KILL_SUID|ATTR_KILL_SGID); - reiserfs_write_lock(inode->i_sb); + depth = reiserfs_write_lock_once(inode->i_sb); if (attr->ia_valid & ATTR_SIZE) { /* version 2 items will be caught by the s_maxbytes check ** done for us in vmtruncate @@ -3149,7 +3150,8 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) } out: - reiserfs_write_unlock(inode->i_sb); + reiserfs_write_unlock_once(inode->i_sb, depth); + return error; } -- cgit v0.10.2 From 108d3943c021f0b66e860ba98ded40b82b677bd7 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Tue, 5 Jan 2010 00:15:38 +0100 Subject: reiserfs: Relax the lock before truncating pages While truncating a file, reiserfs_setattr() calls inode_setattr() that will truncate the mapping for the given inode, but for that it needs the pages locks. In order to release these, the owners need the reiserfs lock to complete their jobs. But they can't, as we don't release it before calling inode_setattr(). We need to do that to fix the following softlockups: INFO: task flush-8:0:2149 blocked for more than 120 seconds. "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. flush-8:0 D f51af998 0 2149 2 0x00000000 f51af9ac 00000092 00000002 f51af998 c2803304 00000000 c1894ad0 010f3000 f51af9cc c1462604 c189ef80 f51af974 c1710304 f715b450 f715b5ec c2807c40 00000000 0005bb00 c2803320 c102c55b c1710304 c2807c50 c2803304 00000246 Call Trace: [] ? schedule+0x434/0xb20 [] ? resched_task+0x4b/0x70 [] ? mark_held_locks+0x62/0x80 [] ? mutex_lock_nested+0x1fd/0x350 [] mutex_lock_nested+0x169/0x350 [] ? reiserfs_write_lock+0x2e/0x40 [] reiserfs_write_lock+0x2e/0x40 [] do_journal_end+0xc2/0xe70 [] journal_end+0xb2/0x120 [] ? pathrelse+0x33/0xb0 [] reiserfs_end_persistent_transaction+0x64/0x70 [] reiserfs_get_block+0x12ba/0x15f0 [] ? mark_held_locks+0x62/0x80 [] reiserfs_writepage+0xa74/0xe80 [] ? _raw_spin_unlock_irq+0x27/0x50 [] ? radix_tree_gang_lookup_tag_slot+0x95/0xc0 [] ? find_get_pages_tag+0x127/0x1a0 [] ? mark_held_locks+0x62/0x80 [] ? trace_hardirqs_on_caller+0x124/0x170 [] __writepage+0x10/0x40 [] write_cache_pages+0x16b/0x320 [] ? __writepage+0x0/0x40 [] generic_writepages+0x28/0x40 [] do_writepages+0x35/0x40 [] writeback_single_inode+0xc7/0x330 [] writeback_inodes_wb+0x2c2/0x490 [] wb_writeback+0x106/0x1b0 [] wb_do_writeback+0x106/0x1e0 [] ? wb_do_writeback+0x28/0x1e0 [] bdi_writeback_task+0x3a/0xb0 [] bdi_start_fn+0x63/0xc0 [] ? bdi_start_fn+0x0/0xc0 [] kthread+0x74/0x80 [] ? kthread+0x0/0x80 [] kernel_thread_helper+0x6/0x10 3 locks held by flush-8:0/2149: #0: (&type->s_umount_key#30){+++++.}, at: [] writeback_inodes_wb+0x27f/0x490 #1: (&journal->j_mutex){+.+...}, at: [] do_journal_end+0xba/0xe70 #2: (&REISERFS_SB(s)->lock){+.+.+.}, at: [] reiserfs_write_lock+0x2e/0x40 INFO: task fstest:3813 blocked for more than 120 seconds. "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. fstest D 00000002 0 3813 3812 0x00000000 f5103c94 00000082 f5103c40 00000002 f5ad5450 00000007 f5103c28 011f3000 00000006 f5ad5450 c10bb005 00000480 c1710304 f5ad5450 f5ad55ec c2907c40 00000001 f5ad5450 f5103c74 00000046 00000002 f5ad5450 00000007 f5103c6c Call Trace: [] ? free_hot_cold_page+0x1d5/0x280 [] io_schedule+0x74/0xc0 [] sync_page+0x35/0x60 [] __wait_on_bit_lock+0x4a/0x90 [] ? sync_page+0x0/0x60 [] __lock_page+0x85/0x90 [] ? wake_bit_function+0x0/0x60 [] truncate_inode_pages_range+0x1e4/0x2d0 [] truncate_inode_pages+0x1f/0x30 [] truncate_pagecache+0x5f/0xa0 [] vmtruncate+0x5a/0x70 [] inode_setattr+0x5d/0x190 [] reiserfs_setattr+0x1f7/0x2f0 [] ? down_write+0x49/0x70 [] notify_change+0x151/0x330 [] do_truncate+0x6d/0xa0 [] do_filp_open+0x9a2/0xcf0 [] ? _raw_spin_unlock+0x2c/0x50 [] ? alloc_fd+0xe0/0x100 [] do_sys_open+0x6d/0x130 [] ? sysenter_exit+0xf/0x16 [] sys_open+0x2e/0x40 [] sysenter_do_call+0x12/0x32 3 locks held by fstest/3813: #0: (&sb->s_type->i_mutex_key#4){+.+.+.}, at: [] do_truncate+0x63/0xa0 #1: (&sb->s_type->i_alloc_sem_key#3){+.+.+.}, at: [] notify_change+0x257/0x330 #2: (&REISERFS_SB(s)->lock){+.+.+.}, at: [] reiserfs_write_lock_once+0x2e/0x50 Signed-off-by: Frederic Weisbecker Cc: Christian Kujau Cc: Alexander Beregalov Cc: Chris Mason Cc: Ingo Molnar diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 47dbfb1..c876341 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c @@ -3140,8 +3140,17 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) journal_end(&th, inode->i_sb, jbegin_count); } } - if (!error) + if (!error) { + /* + * Relax the lock here, as it might truncate the + * inode pages and wait for inode pages locks. + * To release such page lock, the owner needs the + * reiserfs lock + */ + reiserfs_write_unlock_once(inode->i_sb, depth); error = inode_setattr(inode, attr); + depth = reiserfs_write_lock_once(inode->i_sb); + } } if (!error && reiserfs_posixacl(inode->i_sb)) { -- cgit v0.10.2 From 4f3be1b5a98587b86cae05aa5d129dd0b3fff466 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Tue, 5 Jan 2010 02:14:30 +0100 Subject: reiserfs: Relax lock on xattr removing When we remove an xattr, we call lookup_and_delete_xattr() that takes some private xattr inodes mutexes. But we hold the reiserfs lock at this time, which leads to dependency inversions. We can safely call lookup_and_delete_xattr() without the reiserfs lock, where xattr inodes lookups only need the xattr inodes mutexes. Signed-off-by: Frederic Weisbecker Cc: Christian Kujau Cc: Alexander Beregalov Cc: Chris Mason Cc: Ingo Molnar diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index 75d3706..4899d78 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c @@ -451,7 +451,9 @@ static int lookup_and_delete_xattr(struct inode *inode, const char *name) } if (dentry->d_inode) { + reiserfs_write_lock(inode->i_sb); err = xattr_unlink(xadir->d_inode, dentry); + reiserfs_write_unlock(inode->i_sb); update_ctime(inode); } @@ -485,10 +487,14 @@ reiserfs_xattr_set_handle(struct reiserfs_transaction_handle *th, if (get_inode_sd_version(inode) == STAT_DATA_V1) return -EOPNOTSUPP; - if (!buffer) - return lookup_and_delete_xattr(inode, name); - reiserfs_write_unlock(inode->i_sb); + + if (!buffer) { + err = lookup_and_delete_xattr(inode, name); + reiserfs_write_lock(inode->i_sb); + return err; + } + dentry = xattr_lookup(inode, name, flags); if (IS_ERR(dentry)) { reiserfs_write_lock(inode->i_sb); -- cgit v0.10.2 From 89be503021f550575fc896671b569941140b2c2e Mon Sep 17 00:00:00 2001 From: Boaz Harrosh Date: Mon, 21 Dec 2009 16:36:23 +0200 Subject: exofs: fix pnfs_osd re-definitions in pre-pnfs trees Some on disk exofs constants and types are defined in the pnfs_osd_xdr.h file. Since we needed these types before the pnfs-objects code was accepted to mainline we duplicated the minimal needed definitions into an exofs local header. The definitions where conditionally included depending on !CONFIG_PNFS defined. So if PNFS was present in the tree definitions are taken from there and if not they are defined locally. That was all good but, the CONFIG_PNFS is planed to be included upstream before the pnfs-objects is also included. (The first pnfs batch might be pnfs-files only) So condition exofs local definitions on the absence of pnfs_osd_xdr.h inclusion (__PNFS_OSD_XDR_H__ not defined). User code must make sure that in future pnfs_osd_xdr.h will be included before fs/exofs/pnfs.h, which happens to be so in current code. Once pnfs-objects hits mainline, exofs's local header will be removed. Signed-off-by: Boaz Harrosh diff --git a/fs/exofs/pnfs.h b/fs/exofs/pnfs.h index 423033a..c52e988 100644 --- a/fs/exofs/pnfs.h +++ b/fs/exofs/pnfs.h @@ -15,13 +15,7 @@ #ifndef __EXOFS_PNFS_H__ #define __EXOFS_PNFS_H__ -#if defined(CONFIG_PNFS) - - -/* FIXME: move this file to: linux/exportfs/pnfs_osd_xdr.h */ -#include "../nfs/objlayout/pnfs_osd_xdr.h" - -#else /* defined(CONFIG_PNFS) */ +#if ! defined(__PNFS_OSD_XDR_H__) enum pnfs_iomode { IOMODE_READ = 1, @@ -46,6 +40,6 @@ struct pnfs_osd_data_map { u32 odm_raid_algorithm; }; -#endif /* else defined(CONFIG_PNFS) */ +#endif /* ! defined(__PNFS_OSD_XDR_H__) */ #endif /* __EXOFS_PNFS_H__ */ -- cgit v0.10.2 From efd124b999fb4d426b30675f1684521af0872789 Mon Sep 17 00:00:00 2001 From: Boaz Harrosh Date: Sun, 27 Dec 2009 17:01:42 +0200 Subject: exofs: simple_write_end does not mark_inode_dirty exofs uses simple_write_end() for it's .write_end handler. But it is not enough because simple_write_end() does not call mark_inode_dirty() when it extends i_size. So even if we do call mark_inode_dirty at beginning of write out, with a very long IO and a saturated system we might get the .write_inode() called while still extend-writing to file and miss out on the last i_size updates. So override .write_end, call simple_write_end(), and afterwords if i_size was changed call mark_inode_dirty(). It stands to logic that since simple_write_end() was the one extending i_size it should also call mark_inode_dirty(). But it looks like all users of simple_write_end() are memory-bound pseudo filesystems, who could careless about mark_inode_dirty(). I might submit a warning-comment patch to simple_write_end() in future. CC: Stable Signed-off-by: Boaz Harrosh diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c index 698a863..2afbceb 100644 --- a/fs/exofs/inode.c +++ b/fs/exofs/inode.c @@ -738,13 +738,28 @@ static int exofs_write_begin_export(struct file *file, fsdata); } +static int exofs_write_end(struct file *file, struct address_space *mapping, + loff_t pos, unsigned len, unsigned copied, + struct page *page, void *fsdata) +{ + struct inode *inode = mapping->host; + /* According to comment in simple_write_end i_mutex is held */ + loff_t i_size = inode->i_size; + int ret; + + ret = simple_write_end(file, mapping,pos, len, copied, page, fsdata); + if (i_size != inode->i_size) + mark_inode_dirty(inode); + return ret; +} + const struct address_space_operations exofs_aops = { .readpage = exofs_readpage, .readpages = exofs_readpages, .writepage = exofs_writepage, .writepages = exofs_writepages, .write_begin = exofs_write_begin_export, - .write_end = simple_write_end, + .write_end = exofs_write_end, }; /****************************************************************************** -- cgit v0.10.2 From e04ed38d4e0cd32141f723560efcc8252b0241e2 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 4 Jan 2010 23:16:03 -0800 Subject: sparc64: Fix Niagara2 perf event handling. For chips like Niagara2 that have true overflow indications in the %pcr (which we don't actually need and don't use) the interrupt signal persists until the overflow bits are cleared by an explicit %pcr write. Signed-off-by: David S. Miller diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c index fa5936e..198fb4e 100644 --- a/arch/sparc/kernel/perf_event.c +++ b/arch/sparc/kernel/perf_event.c @@ -986,6 +986,17 @@ static int __kprobes perf_event_nmi_handler(struct notifier_block *self, data.addr = 0; cpuc = &__get_cpu_var(cpu_hw_events); + + /* If the PMU has the TOE IRQ enable bits, we need to do a + * dummy write to the %pcr to clear the overflow bits and thus + * the interrupt. + * + * Do this before we peek at the counters to determine + * overflow so we don't lose any events. + */ + if (sparc_pmu->irq_bit) + pcr_ops->write(cpuc->pcr); + for (idx = 0; idx < MAX_HWEVENTS; idx++) { struct perf_event *event = cpuc->events[idx]; struct hw_perf_event *hwc; -- cgit v0.10.2 From 070f1f178c4377c09f72e414513aeacd8403f6d6 Mon Sep 17 00:00:00 2001 From: Bahadir Balban Date: Fri, 25 Dec 2009 14:25:48 +0100 Subject: ARM: 5858/1: Remove unused vma_vm_flags macro from v7wbi_flush_user_tlb_range Signed-off-by: Bahadir Balban Signed-off-by: Russell King diff --git a/arch/arm/mm/tlb-v7.S b/arch/arm/mm/tlb-v7.S index a26a605..0cb1848 100644 --- a/arch/arm/mm/tlb-v7.S +++ b/arch/arm/mm/tlb-v7.S @@ -40,7 +40,6 @@ ENTRY(v7wbi_flush_user_tlb_range) asid r3, r3 @ mask ASID orr r0, r3, r0, lsl #PAGE_SHIFT @ Create initial MVA mov r1, r1, lsl #PAGE_SHIFT - vma_vm_flags r2, r2 @ get vma->vm_flags 1: #ifdef CONFIG_SMP mcr p15, 0, r0, c8, c3, 1 @ TLB invalidate U MVA (shareable) -- cgit v0.10.2 From 1368c51c501978e5c4148322b7c77d4f49549557 Mon Sep 17 00:00:00 2001 From: Li Jie Date: Thu, 31 Dec 2009 15:57:53 +0100 Subject: ARM: 5863/1: fix bugs of clock source of NUC900 This patch fix following bugs: 1. typo error, CLOCK_EVT_MODE_PERIODIC -> CLOCK_EVT_FEAT_PERIODIC 2. TCSR register of timer1 missed PRESCALE 3. timer1 should be enabled before register it to clock source. Signed-off-by: lijie Acked-by: Wan ZongShun Signed-off-by: Russell King diff --git a/arch/arm/mach-w90x900/time.c b/arch/arm/mach-w90x900/time.c index 4128af8..b80f769 100644 --- a/arch/arm/mach-w90x900/time.c +++ b/arch/arm/mach-w90x900/time.c @@ -42,7 +42,10 @@ #define TICKS_PER_SEC 100 #define PRESCALE 0x63 /* Divider = prescale + 1 */ -unsigned int timer0_load; +#define TDR_SHIFT 24 +#define TDR_MASK ((1 << TDR_SHIFT) - 1) + +static unsigned int timer0_load; static void nuc900_clockevent_setmode(enum clock_event_mode mode, struct clock_event_device *clk) @@ -88,7 +91,7 @@ static int nuc900_clockevent_setnextevent(unsigned long evt, static struct clock_event_device nuc900_clockevent_device = { .name = "nuc900-timer0", .shift = 32, - .features = CLOCK_EVT_MODE_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, + .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, .set_mode = nuc900_clockevent_setmode, .set_next_event = nuc900_clockevent_setnextevent, .rating = 300, @@ -112,8 +115,23 @@ static struct irqaction nuc900_timer0_irq = { .handler = nuc900_timer0_interrupt, }; -static void __init nuc900_clockevents_init(unsigned int rate) +static void __init nuc900_clockevents_init(void) { + unsigned int rate; + struct clk *clk = clk_get(NULL, "timer0"); + + BUG_ON(IS_ERR(clk)); + + __raw_writel(0x00, REG_TCSR0); + + clk_enable(clk); + rate = clk_get_rate(clk) / (PRESCALE + 1); + + timer0_load = (rate / TICKS_PER_SEC); + + __raw_writel(RESETINT, REG_TISR); + setup_irq(IRQ_TIMER0, &nuc900_timer0_irq); + nuc900_clockevent_device.mult = div_sc(rate, NSEC_PER_SEC, nuc900_clockevent_device.shift); nuc900_clockevent_device.max_delta_ns = clockevent_delta2ns(0xffffffff, @@ -127,26 +145,35 @@ static void __init nuc900_clockevents_init(unsigned int rate) static cycle_t nuc900_get_cycles(struct clocksource *cs) { - return ~__raw_readl(REG_TDR1); + return (~__raw_readl(REG_TDR1)) & TDR_MASK; } static struct clocksource clocksource_nuc900 = { .name = "nuc900-timer1", .rating = 200, .read = nuc900_get_cycles, - .mask = CLOCKSOURCE_MASK(32), - .shift = 20, + .mask = CLOCKSOURCE_MASK(TDR_SHIFT), + .shift = 10, .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; -static void __init nuc900_clocksource_init(unsigned int rate) +static void __init nuc900_clocksource_init(void) { unsigned int val; + unsigned int rate; + struct clk *clk = clk_get(NULL, "timer1"); + + BUG_ON(IS_ERR(clk)); + + __raw_writel(0x00, REG_TCSR1); + + clk_enable(clk); + rate = clk_get_rate(clk) / (PRESCALE + 1); __raw_writel(0xffffffff, REG_TICR1); val = __raw_readl(REG_TCSR1); - val |= (COUNTEN | PERIOD); + val |= (COUNTEN | PERIOD | PRESCALE); __raw_writel(val, REG_TCSR1); clocksource_nuc900.mult = @@ -156,25 +183,8 @@ static void __init nuc900_clocksource_init(unsigned int rate) static void __init nuc900_timer_init(void) { - struct clk *ck_ext = clk_get(NULL, "ext"); - unsigned int rate; - - BUG_ON(IS_ERR(ck_ext)); - - rate = clk_get_rate(ck_ext); - clk_put(ck_ext); - rate = rate / (PRESCALE + 0x01); - - /* set a known state */ - __raw_writel(0x00, REG_TCSR0); - __raw_writel(0x00, REG_TCSR1); - __raw_writel(RESETINT, REG_TISR); - timer0_load = (rate / TICKS_PER_SEC); - - setup_irq(IRQ_TIMER0, &nuc900_timer0_irq); - - nuc900_clocksource_init(rate); - nuc900_clockevents_init(rate); + nuc900_clocksource_init(); + nuc900_clockevents_init(); } struct sys_timer nuc900_timer = { -- cgit v0.10.2 From 58b2e0a2dd8e460d3b7d7f8ec5d3042253b9e08a Mon Sep 17 00:00:00 2001 From: Li Jie Date: Thu, 31 Dec 2009 15:50:02 +0100 Subject: ARM: 5864/1: Implement arch_reset() in NUC900 Implement arch_reset(), reboot from shell become possible. Signed-off-by: lijie Acked-by: Wan ZongShun Signed-off-by: Russell King diff --git a/arch/arm/mach-w90x900/include/mach/system.h b/arch/arm/mach-w90x900/include/mach/system.h index 9406400..ce228bd 100644 --- a/arch/arm/mach-w90x900/include/mach/system.h +++ b/arch/arm/mach-w90x900/include/mach/system.h @@ -15,7 +15,15 @@ * */ +#include #include +#include +#include + +#define WTCR (TMR_BA + 0x1C) +#define WTCLK (1 << 10) +#define WTE (1 << 7) +#define WTRE (1 << 1) static void arch_idle(void) { @@ -23,6 +31,11 @@ static void arch_idle(void) static void arch_reset(char mode, const char *cmd) { - cpu_reset(0); + if (mode == 's') { + /* Jump into ROM at address 0 */ + cpu_reset(0); + } else { + __raw_writel(WTE | WTRE | WTCLK, WTCR); + } } -- cgit v0.10.2 From dc2f9c5a13de4f9fd63f49f54add40b2924f66cd Mon Sep 17 00:00:00 2001 From: Li Jie Date: Thu, 31 Dec 2009 16:03:16 +0100 Subject: ARM: 5865/1: nuc900 ethernet driver needs mii nuc900 ethernet driver uses mii_xx_xx serials api, so mii module should be selected. Signed-off-by: lijie Acked-by: Wan ZongShun Signed-off-by: Russell King diff --git a/drivers/net/arm/Kconfig b/drivers/net/arm/Kconfig index c37ee9e..39e1c0d 100644 --- a/drivers/net/arm/Kconfig +++ b/drivers/net/arm/Kconfig @@ -68,6 +68,7 @@ config W90P910_ETH tristate "Nuvoton w90p910 Ethernet support" depends on ARM && ARCH_W90X900 select PHYLIB + select MII help Say Y here if you want to use built-in Ethernet ports on w90p910 processor. -- cgit v0.10.2 From 409d02ef6d74f5e91f5ea4c587b2ee1375f106fc Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 5 Jan 2010 14:19:11 +0100 Subject: x86: copy_from_user() should not return -EFAULT Callers of copy_from_user() expect it to return the number of bytes it could not copy. In no case it is supposed to return -EFAULT. In case of a detected buffer overflow just return the requested length. In addition one could think of a memset that would clear the size of the target object. [ hpa: code is not in .32 so not needed for -stable ] Signed-off-by: Heiko Carstens Acked-by: Arjan van de Ven LKML-Reference: <20100105131911.GC5480@osiris.boeblingen.de.ibm.com> Signed-off-by: H. Peter Anvin diff --git a/arch/x86/include/asm/uaccess_32.h b/arch/x86/include/asm/uaccess_32.h index 0c9825e..088d09f 100644 --- a/arch/x86/include/asm/uaccess_32.h +++ b/arch/x86/include/asm/uaccess_32.h @@ -205,14 +205,13 @@ static inline unsigned long __must_check copy_from_user(void *to, unsigned long n) { int sz = __compiletime_object_size(to); - int ret = -EFAULT; if (likely(sz == -1 || sz >= n)) - ret = _copy_from_user(to, from, n); + n = _copy_from_user(to, from, n); else copy_from_user_overflow(); - return ret; + return n; } long __must_check strncpy_from_user(char *dst, const char __user *src, diff --git a/arch/x86/include/asm/uaccess_64.h b/arch/x86/include/asm/uaccess_64.h index 46324c6..535e4214 100644 --- a/arch/x86/include/asm/uaccess_64.h +++ b/arch/x86/include/asm/uaccess_64.h @@ -30,16 +30,15 @@ static inline unsigned long __must_check copy_from_user(void *to, unsigned long n) { int sz = __compiletime_object_size(to); - int ret = -EFAULT; might_fault(); if (likely(sz == -1 || sz >= n)) - ret = _copy_from_user(to, from, n); + n = _copy_from_user(to, from, n); #ifdef CONFIG_DEBUG_VM else WARN(1, "Buffer overflow detected!\n"); #endif - return ret; + return n; } static __always_inline __must_check -- cgit v0.10.2 From db677ffa5f5a4f15b9dad4d132b3477b80766d82 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 5 Jan 2010 12:48:49 +1030 Subject: Revert "x86: Side-step lguest problem by only building cmpxchg8b_emu for pre-Pentium" This reverts commit ae1b22f6e46c03cede7cea234d0bf2253b4261cf. As Linus said in 982d007a6ee: "There was something really messy about cmpxchg8b and clone CPU's, so if you enable it on other CPUs later, do it carefully." This breaks lguest for those configs, but we can fix that by emulating if we have to. Fixes: http://bugzilla.kernel.org/show_bug.cgi?id=14884 Signed-off-by: Rusty Russell Cc: stable@kernel.org Signed-off-by: Linus Torvalds diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu index 08e442b..f20ddf8 100644 --- a/arch/x86/Kconfig.cpu +++ b/arch/x86/Kconfig.cpu @@ -396,7 +396,7 @@ config X86_TSC config X86_CMPXCHG64 def_bool y - depends on !M386 && !M486 + depends on X86_PAE || X86_64 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MATOM # this should be set for all -march=.. options where the compiler # generates cmov. -- cgit v0.10.2 From 74d2e4f8d79ae0c4b6ec027958d5b18058662eea Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 5 Jan 2010 16:02:46 -0800 Subject: Linux 2.6.33-rc3 diff --git a/Makefile b/Makefile index c628a5c..1231094 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 33 -EXTRAVERSION = -rc2 +EXTRAVERSION = -rc3 NAME = Man-Eating Seals of Antiquity # *DOCUMENTATION* -- cgit v0.10.2 From b9597a1c6fa6cbc938f14ab6a7fe09047b3a346b Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 4 Jan 2010 19:12:02 -0500 Subject: drm/radeon/kms: fallback to default connector table if necessary for combios Some early combios radeon cards don't have a connector table or dac table in the bios, if they do not, fallback to the default tables. Should fix kernel bug 14963. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 91d72b7..1fb2f02 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -329,8 +329,11 @@ static bool radeon_setup_enc_conn(struct drm_device *dev) ret = radeon_get_atom_connector_info_from_object_table(dev); else ret = radeon_get_atom_connector_info_from_supported_devices_table(dev); - } else + } else { ret = radeon_get_legacy_connector_info_from_bios(dev); + if (ret == false) + ret = radeon_get_legacy_connector_info_from_table(dev); + } } else { if (!ASIC_IS_AVIVO(rdev)) ret = radeon_get_legacy_connector_info_from_table(dev); -- cgit v0.10.2 From 246263ccc31e4ba2886cca17000bf09ea683eac5 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 29 Dec 2009 12:09:17 -0500 Subject: drm/radeon/kms: add primary dac adj values table Look up primary dac adj values from the table if there is no bios or bios dac table to reference. The lookup table may need to be adjusted for certain families. Should fix kernel bug 14945. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index fd94dbc..58f3426 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c @@ -595,6 +595,34 @@ bool radeon_combios_get_clock_info(struct drm_device *dev) return false; } +static const uint32_t default_primarydac_adj[CHIP_LAST] = { + 0x00000808, /* r100 */ + 0x00000808, /* rv100 */ + 0x00000808, /* rs100 */ + 0x00000808, /* rv200 */ + 0x00000808, /* rs200 */ + 0x00000808, /* r200 */ + 0x00000808, /* rv250 */ + 0x00000000, /* rs300 */ + 0x00000808, /* rv280 */ + 0x00000808, /* r300 */ + 0x00000808, /* r350 */ + 0x00000808, /* rv350 */ + 0x00000808, /* rv380 */ + 0x00000808, /* r420 */ + 0x00000808, /* r423 */ + 0x00000808, /* rv410 */ + 0x00000000, /* rs400 */ + 0x00000000, /* rs480 */ +}; + +static void radeon_legacy_get_primary_dac_info_from_table(struct radeon_device *rdev, + struct radeon_encoder_primary_dac *p_dac) +{ + p_dac->ps2_pdac_adj = default_primarydac_adj[rdev->family]; + return; +} + struct radeon_encoder_primary_dac *radeon_combios_get_primary_dac_info(struct radeon_encoder *encoder) @@ -604,20 +632,20 @@ struct radeon_encoder_primary_dac *radeon_combios_get_primary_dac_info(struct uint16_t dac_info; uint8_t rev, bg, dac; struct radeon_encoder_primary_dac *p_dac = NULL; + int found = 0; - if (rdev->bios == NULL) + p_dac = kzalloc(sizeof(struct radeon_encoder_primary_dac), + GFP_KERNEL); + + if (!p_dac) return NULL; + if (rdev->bios == NULL) + goto out; + /* check CRT table */ dac_info = combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE); if (dac_info) { - p_dac = - kzalloc(sizeof(struct radeon_encoder_primary_dac), - GFP_KERNEL); - - if (!p_dac) - return NULL; - rev = RBIOS8(dac_info) & 0x3; if (rev < 2) { bg = RBIOS8(dac_info + 0x2) & 0xf; @@ -628,9 +656,13 @@ struct radeon_encoder_primary_dac *radeon_combios_get_primary_dac_info(struct dac = RBIOS8(dac_info + 0x3) & 0xf; p_dac->ps2_pdac_adj = (bg << 8) | (dac); } - + found = 1; } +out: + if (!found) /* fallback to defaults */ + radeon_legacy_get_primary_dac_info_from_table(rdev, p_dac); + return p_dac; } -- cgit v0.10.2 From 1d3d51b6d2d6fb51c6c30a8c7ed0fd939f6100bf Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 28 Dec 2009 13:45:23 -0500 Subject: drm/radeon/kms: add missing breaks in i2c and ss lookups Should fix fdo bug 25741 Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 321044b..41dd8eb 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -114,6 +114,7 @@ static inline struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_dev i2c.i2c_id = gpio->sucI2cId.ucAccess; i2c.valid = true; + break; } } @@ -1026,6 +1027,7 @@ static struct radeon_atom_ss *radeon_atombios_get_ss_info(struct ss->delay = ss_info->asSS_Info[i].ucSS_Delay; ss->range = ss_info->asSS_Info[i].ucSS_Range; ss->refdiv = ss_info->asSS_Info[i].ucRecommendedRef_Div; + break; } } } -- cgit v0.10.2 From 10b465aaf9536ee5a16652fa0700740183d48ec9 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sat, 19 Dec 2009 14:43:01 +0000 Subject: modules: Skip empty sections when exporting section notes Commit 35dead4 "modules: don't export section names of empty sections via sysfs" changed the set of sections that have attributes, but did not change the iteration over these attributes in add_notes_attrs(). This can lead to add_notes_attrs() creating attributes with the wrong names or with null name pointers. Introduce a sect_empty() function and use it in both add_sect_attrs() and add_notes_attrs(). Reported-by: Martin Michlmayr Signed-off-by: Ben Hutchings Tested-by: Martin Michlmayr Cc: stable@kernel.org Signed-off-by: Rusty Russell Signed-off-by: Linus Torvalds diff --git a/kernel/module.c b/kernel/module.c index e96b8ed..f82386b 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -1010,6 +1010,12 @@ static const struct kernel_symbol *resolve_symbol(Elf_Shdr *sechdrs, * J. Corbet */ #if defined(CONFIG_KALLSYMS) && defined(CONFIG_SYSFS) + +static inline bool sect_empty(const Elf_Shdr *sect) +{ + return !(sect->sh_flags & SHF_ALLOC) || sect->sh_size == 0; +} + struct module_sect_attr { struct module_attribute mattr; @@ -1051,8 +1057,7 @@ static void add_sect_attrs(struct module *mod, unsigned int nsect, /* Count loaded sections and allocate structures */ for (i = 0; i < nsect; i++) - if (sechdrs[i].sh_flags & SHF_ALLOC - && sechdrs[i].sh_size) + if (!sect_empty(&sechdrs[i])) nloaded++; size[0] = ALIGN(sizeof(*sect_attrs) + nloaded * sizeof(sect_attrs->attrs[0]), @@ -1070,9 +1075,7 @@ static void add_sect_attrs(struct module *mod, unsigned int nsect, sattr = §_attrs->attrs[0]; gattr = §_attrs->grp.attrs[0]; for (i = 0; i < nsect; i++) { - if (! (sechdrs[i].sh_flags & SHF_ALLOC)) - continue; - if (!sechdrs[i].sh_size) + if (sect_empty(&sechdrs[i])) continue; sattr->address = sechdrs[i].sh_addr; sattr->name = kstrdup(secstrings + sechdrs[i].sh_name, @@ -1156,7 +1159,7 @@ static void add_notes_attrs(struct module *mod, unsigned int nsect, /* Count notes sections and allocate structures. */ notes = 0; for (i = 0; i < nsect; i++) - if ((sechdrs[i].sh_flags & SHF_ALLOC) && + if (!sect_empty(&sechdrs[i]) && (sechdrs[i].sh_type == SHT_NOTE)) ++notes; @@ -1172,7 +1175,7 @@ static void add_notes_attrs(struct module *mod, unsigned int nsect, notes_attrs->notes = notes; nattr = ¬es_attrs->attrs[0]; for (loaded = i = 0; i < nsect; ++i) { - if (!(sechdrs[i].sh_flags & SHF_ALLOC)) + if (sect_empty(&sechdrs[i])) continue; if (sechdrs[i].sh_type == SHT_NOTE) { nattr->attr.name = mod->sect_attrs->attrs[loaded].name; -- cgit v0.10.2 From 077639f443294a25b16e4040ca06a1611700a4ae Mon Sep 17 00:00:00 2001 From: Vaibhav Hiremath Date: Tue, 13 Oct 2009 15:08:54 +0000 Subject: Davinci VPFE Capture: Take i2c adapter id through platform data The I2C adapter ID is actually depends on Board and may vary, Davinci uses id=1, but in case of AM3517 id=3. So modified respective davinci board files. Signed-off-by: Vaibhav Hiremath Signed-off-by: Kevin Hilman diff --git a/arch/arm/mach-davinci/board-dm355-evm.c b/arch/arm/mach-davinci/board-dm355-evm.c index a9b650d..077ecf4 100644 --- a/arch/arm/mach-davinci/board-dm355-evm.c +++ b/arch/arm/mach-davinci/board-dm355-evm.c @@ -236,6 +236,7 @@ static struct vpfe_subdev_info vpfe_sub_devs[] = { static struct vpfe_config vpfe_cfg = { .num_subdevs = ARRAY_SIZE(vpfe_sub_devs), + .i2c_adapter_id = 1, .sub_devs = vpfe_sub_devs, .card_name = "DM355 EVM", .ccdc = "DM355 CCDC", diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c index fd0398b..e9612cf 100644 --- a/arch/arm/mach-davinci/board-dm644x-evm.c +++ b/arch/arm/mach-davinci/board-dm644x-evm.c @@ -247,6 +247,7 @@ static struct vpfe_subdev_info vpfe_sub_devs[] = { static struct vpfe_config vpfe_cfg = { .num_subdevs = ARRAY_SIZE(vpfe_sub_devs), + .i2c_adapter_id = 1, .sub_devs = vpfe_sub_devs, .card_name = "DM6446 EVM", .ccdc = "DM6446 CCDC", -- cgit v0.10.2 From 2d3f595016f982294c1669ee87aa91179d88502b Mon Sep 17 00:00:00 2001 From: Sekhar Nori Date: Mon, 16 Nov 2009 17:21:30 +0530 Subject: davinci: cp_intc: provide set_wake function There is nothing special to be done for interrupts which can wakeup the device from sleep on CP-INTC, but not having a set_wake implemented prevents use of common drivers which expect this function to be implemented for all wakeup interrupt sources. This patch fixes the issue encountered when using the omap-rtc driver on DA850. On DA850 the RTC alarm interrupt is used to wake up the SoC from deep sleep mode. Without this patch, the disable_irq_wake throws an unbalanced wake disable warning while resuming because the previous enable call fails for lack of set_wake implementation. Signed-off-by: Sekhar Nori Signed-off-by: Kevin Hilman diff --git a/arch/arm/mach-davinci/cp_intc.c b/arch/arm/mach-davinci/cp_intc.c index 52b287c..37311d1 100644 --- a/arch/arm/mach-davinci/cp_intc.c +++ b/arch/arm/mach-davinci/cp_intc.c @@ -81,12 +81,23 @@ static int cp_intc_set_irq_type(unsigned int irq, unsigned int flow_type) return 0; } +/* + * Faking this allows us to to work with suspend functions of + * generic drivers which call {enable|disable}_irq_wake for + * wake up interrupt sources (eg RTC on DA850). + */ +static int cp_intc_set_wake(unsigned int irq, unsigned int on) +{ + return 0; +} + static struct irq_chip cp_intc_irq_chip = { .name = "cp_intc", .ack = cp_intc_ack_irq, .mask = cp_intc_mask_irq, .unmask = cp_intc_unmask_irq, .set_type = cp_intc_set_irq_type, + .set_wake = cp_intc_set_wake, }; void __init cp_intc_init(void __iomem *base, unsigned short num_irq, -- cgit v0.10.2 From 75c99bb0006ee065b4e2995078d779418b0fab54 Mon Sep 17 00:00:00 2001 From: Sekhar Nori Date: Mon, 16 Nov 2009 17:21:31 +0530 Subject: davinci: da8xx/omap-l1: mark RTC as a wakeup source On da850, RTC alarm is a wakeup source from deep sleep. Mark it as a wakeup source after the rtc platform device is registered. Without this patch, the rtc-omap driver suspends the RTC during the suspend sequence and hence it cannot wakeup the SoC. Signed-off-by: Sekhar Nori Signed-off-by: Kevin Hilman diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c index dd2d32c..a5105f0 100644 --- a/arch/arm/mach-davinci/devices-da8xx.c +++ b/arch/arm/mach-davinci/devices-da8xx.c @@ -481,11 +481,18 @@ static struct platform_device da8xx_rtc_device = { int da8xx_register_rtc(void) { + int ret; + /* Unlock the rtc's registers */ __raw_writel(0x83e70b13, IO_ADDRESS(DA8XX_RTC_BASE + 0x6c)); __raw_writel(0x95a4f1e0, IO_ADDRESS(DA8XX_RTC_BASE + 0x70)); - return platform_device_register(&da8xx_rtc_device); + ret = platform_device_register(&da8xx_rtc_device); + if (!ret) + /* Atleast on DA850, RTC is a wakeup source */ + device_init_wakeup(&da8xx_rtc_device.dev, true); + + return ret; } static struct resource da8xx_cpuidle_resources[] = { -- cgit v0.10.2 From ae88e05a5adb5f6da2d1e1a852bea8c88cb2c9cb Mon Sep 17 00:00:00 2001 From: Sekhar Nori Date: Thu, 19 Nov 2009 15:34:01 +0530 Subject: davinci: enable ARCH_HAS_HOLES_MEMORYMODEL for DaVinci All DaVinci platforms include a DSP or co-processor for audio/video acceleration. While creating memory for the DSP/co-processor, system integrator can end up creating a hole in the memory map of the sort: This sort of configuration needs ARCH_HAS_HOLES_MEMORYMODEL enabled. See further details see this discussion on ARM linux mailing list: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg15262.html The patch is boot tested on OMAP-L138, DM6446 and DM355 EVMs Signed-off-by: Sekhar Nori CC: Sriramakrishnan CC: Khasim Syed Mohammed Signed-off-by: Kevin Hilman diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 233a222..4f8760d 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -688,6 +688,7 @@ config ARCH_DAVINCI select HAVE_IDE select COMMON_CLKDEV select GENERIC_ALLOCATOR + select ARCH_HAS_HOLES_MEMORYMODEL help Support for TI's DaVinci platform. -- cgit v0.10.2 From c92b29ec4a7a197199b8b937b909d80dc79d8e5b Mon Sep 17 00:00:00 2001 From: Miguel Aguilar Date: Fri, 13 Nov 2009 13:44:23 -0600 Subject: DaVinci: DM365: Add the device_enable for the DaVinci Keyscan Adds the device_enable function to the DaVinci Keyscan platform data to setup the PINMUX configuration. It also removes #ifdef from the DM365 EVM board in order to load it properly as a module. Signed-off-by: Miguel Aguilar Signed-off-by: Kevin Hilman diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c index 289fe1b..b476395 100644 --- a/arch/arm/mach-davinci/board-dm365-evm.c +++ b/arch/arm/mach-davinci/board-dm365-evm.c @@ -192,7 +192,11 @@ static struct davinci_i2c_platform_data i2c_pdata = { .bus_delay = 0 /* usec */, }; -#ifdef CONFIG_KEYBOARD_DAVINCI +static int dm365evm_keyscan_enable(struct device *dev) +{ + return davinci_cfg_reg(DM365_KEYSCAN); +} + static unsigned short dm365evm_keymap[] = { KEY_KP2, KEY_LEFT, @@ -214,6 +218,7 @@ static unsigned short dm365evm_keymap[] = { }; static struct davinci_ks_platform_data dm365evm_ks_data = { + .device_enable = dm365evm_keyscan_enable, .keymap = dm365evm_keymap, .keymapsize = ARRAY_SIZE(dm365evm_keymap), .rep = 1, @@ -222,7 +227,6 @@ static struct davinci_ks_platform_data dm365evm_ks_data = { .interval = 0x2, .matrix_type = DAVINCI_KEYSCAN_MATRIX_4X4, }; -#endif static int cpld_mmc_get_cd(int module) { @@ -511,10 +515,7 @@ static __init void dm365_evm_init(void) dm365_init_asp(&dm365_evm_snd_data); dm365_init_rtc(); - -#ifdef CONFIG_KEYBOARD_DAVINCI dm365_init_ks(&dm365evm_ks_data); -#endif } static __init void dm365_evm_irq_init(void) diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c index 2ec619e..f53735c 100644 --- a/arch/arm/mach-davinci/dm365.c +++ b/arch/arm/mach-davinci/dm365.c @@ -993,7 +993,6 @@ void __init dm365_init_asp(struct snd_platform_data *pdata) void __init dm365_init_ks(struct davinci_ks_platform_data *pdata) { - davinci_cfg_reg(DM365_KEYSCAN); dm365_ks_device.dev.platform_data = pdata; platform_device_register(&dm365_ks_device); } -- cgit v0.10.2 From 76446cac68568fc7f5168a27deaf803ed22a4360 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Thu, 17 Dec 2009 22:05:42 -0500 Subject: drm/i915: execbuf2 support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds a new execbuf ioctl, execbuf2, for use by clients that want to control fence register allocation more finely. The buffer passed in to the new ioctl includes a new relocation type to indicate whether a given object needs a fence register assigned for the command buffer in question. Compatibility with the existing execbuf ioctl is implemented in terms of the new code, preserving the assumption that fence registers are required for pre-965 rendering commands. Signed-off-by: Jesse Barnes [ickle: Remove pre-emptive clear_fence_reg()] Signed-off-by: Chris Wilson Signed-off-by: Kristian Høgsberg [anholt: Removed dmesg spam] Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index e3e5d50..d67be65 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -813,9 +813,13 @@ static int i915_getparam(struct drm_device *dev, void *data, case I915_PARAM_HAS_PAGEFLIPPING: value = 1; break; + case I915_PARAM_HAS_EXECBUF2: + /* depends on GEM */ + value = dev_priv->has_gem; + break; default: DRM_DEBUG_DRIVER("Unknown parameter %d\n", - param->param); + param->param); return -EINVAL; } @@ -1646,6 +1650,7 @@ struct drm_ioctl_desc i915_ioctls[] = { DRM_IOCTL_DEF(DRM_I915_HWS_ADDR, i915_set_status_page, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF(DRM_I915_GEM_INIT, i915_gem_init_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER, i915_gem_execbuffer, DRM_AUTH), + DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER2, i915_gem_execbuffer2, DRM_AUTH), DRM_IOCTL_DEF(DRM_I915_GEM_PIN, i915_gem_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY), DRM_IOCTL_DEF(DRM_I915_GEM_UNPIN, i915_gem_unpin_ioctl, DRM_AUTH|DRM_ROOT_ONLY), DRM_IOCTL_DEF(DRM_I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_AUTH), diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 9a05f1a..7eb4ad5 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -815,6 +815,8 @@ int i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); int i915_gem_execbuffer(struct drm_device *dev, void *data, struct drm_file *file_priv); +int i915_gem_execbuffer2(struct drm_device *dev, void *data, + struct drm_file *file_priv); int i915_gem_pin_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); int i915_gem_unpin_ioctl(struct drm_device *dev, void *data, @@ -881,6 +883,9 @@ void i915_gem_shrinker_exit(void); void i915_gem_detect_bit_6_swizzle(struct drm_device *dev); void i915_gem_object_do_bit_17_swizzle(struct drm_gem_object *obj); void i915_gem_object_save_bit_17_swizzle(struct drm_gem_object *obj); +bool i915_tiling_ok(struct drm_device *dev, int stride, int size, + int tiling_mode); +bool i915_obj_fenceable(struct drm_device *dev, struct drm_gem_object *obj); /* i915_gem_debug.c */ void i915_gem_dump_object(struct drm_gem_object *obj, int len, diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 9e81a0d..0330c3a 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3199,7 +3199,7 @@ i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj, static int i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, struct drm_file *file_priv, - struct drm_i915_gem_exec_object *entry, + struct drm_i915_gem_exec_object2 *entry, struct drm_i915_gem_relocation_entry *relocs) { struct drm_device *dev = obj->dev; @@ -3207,12 +3207,35 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, struct drm_i915_gem_object *obj_priv = obj->driver_private; int i, ret; void __iomem *reloc_page; + bool need_fence; + + need_fence = entry->flags & EXEC_OBJECT_NEEDS_FENCE && + obj_priv->tiling_mode != I915_TILING_NONE; + + /* Check fence reg constraints and rebind if necessary */ + if (need_fence && !i915_obj_fenceable(dev, obj)) + i915_gem_object_unbind(obj); /* Choose the GTT offset for our buffer and put it there. */ ret = i915_gem_object_pin(obj, (uint32_t) entry->alignment); if (ret) return ret; + /* + * Pre-965 chips need a fence register set up in order to + * properly handle blits to/from tiled surfaces. + */ + if (need_fence) { + ret = i915_gem_object_get_fence_reg(obj); + if (ret != 0) { + if (ret != -EBUSY && ret != -ERESTARTSYS) + DRM_ERROR("Failure to install fence: %d\n", + ret); + i915_gem_object_unpin(obj); + return ret; + } + } + entry->offset = obj_priv->gtt_offset; /* Apply the relocations, using the GTT aperture to avoid cache @@ -3374,7 +3397,7 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, */ static int i915_dispatch_gem_execbuffer(struct drm_device *dev, - struct drm_i915_gem_execbuffer *exec, + struct drm_i915_gem_execbuffer2 *exec, struct drm_clip_rect *cliprects, uint64_t exec_offset) { @@ -3464,7 +3487,7 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file_priv) } static int -i915_gem_get_relocs_from_user(struct drm_i915_gem_exec_object *exec_list, +i915_gem_get_relocs_from_user(struct drm_i915_gem_exec_object2 *exec_list, uint32_t buffer_count, struct drm_i915_gem_relocation_entry **relocs) { @@ -3479,8 +3502,10 @@ i915_gem_get_relocs_from_user(struct drm_i915_gem_exec_object *exec_list, } *relocs = drm_calloc_large(reloc_count, sizeof(**relocs)); - if (*relocs == NULL) + if (*relocs == NULL) { + DRM_ERROR("failed to alloc relocs, count %d\n", reloc_count); return -ENOMEM; + } for (i = 0; i < buffer_count; i++) { struct drm_i915_gem_relocation_entry __user *user_relocs; @@ -3504,7 +3529,7 @@ i915_gem_get_relocs_from_user(struct drm_i915_gem_exec_object *exec_list, } static int -i915_gem_put_relocs_to_user(struct drm_i915_gem_exec_object *exec_list, +i915_gem_put_relocs_to_user(struct drm_i915_gem_exec_object2 *exec_list, uint32_t buffer_count, struct drm_i915_gem_relocation_entry *relocs) { @@ -3537,7 +3562,7 @@ err: } static int -i915_gem_check_execbuffer (struct drm_i915_gem_execbuffer *exec, +i915_gem_check_execbuffer (struct drm_i915_gem_execbuffer2 *exec, uint64_t exec_offset) { uint32_t exec_start, exec_len; @@ -3590,18 +3615,18 @@ i915_gem_wait_for_pending_flip(struct drm_device *dev, } int -i915_gem_execbuffer(struct drm_device *dev, void *data, - struct drm_file *file_priv) +i915_gem_do_execbuffer(struct drm_device *dev, void *data, + struct drm_file *file_priv, + struct drm_i915_gem_execbuffer2 *args, + struct drm_i915_gem_exec_object2 *exec_list) { drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_execbuffer *args = data; - struct drm_i915_gem_exec_object *exec_list = NULL; struct drm_gem_object **object_list = NULL; struct drm_gem_object *batch_obj; struct drm_i915_gem_object *obj_priv; struct drm_clip_rect *cliprects = NULL; struct drm_i915_gem_relocation_entry *relocs; - int ret, ret2, i, pinned = 0; + int ret = 0, ret2, i, pinned = 0; uint64_t exec_offset; uint32_t seqno, flush_domains, reloc_index; int pin_tries, flips; @@ -3615,25 +3640,13 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, DRM_ERROR("execbuf with %d buffers\n", args->buffer_count); return -EINVAL; } - /* Copy in the exec list from userland */ - exec_list = drm_malloc_ab(sizeof(*exec_list), args->buffer_count); object_list = drm_malloc_ab(sizeof(*object_list), args->buffer_count); - if (exec_list == NULL || object_list == NULL) { - DRM_ERROR("Failed to allocate exec or object list " - "for %d buffers\n", + if (object_list == NULL) { + DRM_ERROR("Failed to allocate object list for %d buffers\n", args->buffer_count); ret = -ENOMEM; goto pre_mutex_err; } - ret = copy_from_user(exec_list, - (struct drm_i915_relocation_entry __user *) - (uintptr_t) args->buffers_ptr, - sizeof(*exec_list) * args->buffer_count); - if (ret != 0) { - DRM_ERROR("copy %d exec entries failed %d\n", - args->buffer_count, ret); - goto pre_mutex_err; - } if (args->num_cliprects != 0) { cliprects = kcalloc(args->num_cliprects, sizeof(*cliprects), @@ -3885,20 +3898,6 @@ err: mutex_unlock(&dev->struct_mutex); - if (!ret) { - /* Copy the new buffer offsets back to the user's exec list. */ - ret = copy_to_user((struct drm_i915_relocation_entry __user *) - (uintptr_t) args->buffers_ptr, - exec_list, - sizeof(*exec_list) * args->buffer_count); - if (ret) { - ret = -EFAULT; - DRM_ERROR("failed to copy %d exec entries " - "back to user (%d)\n", - args->buffer_count, ret); - } - } - /* Copy the updated relocations out regardless of current error * state. Failure to update the relocs would mean that the next * time userland calls execbuf, it would do so with presumed offset @@ -3915,12 +3914,158 @@ err: pre_mutex_err: drm_free_large(object_list); - drm_free_large(exec_list); kfree(cliprects); return ret; } +/* + * Legacy execbuffer just creates an exec2 list from the original exec object + * list array and passes it to the real function. + */ +int +i915_gem_execbuffer(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_i915_gem_execbuffer *args = data; + struct drm_i915_gem_execbuffer2 exec2; + struct drm_i915_gem_exec_object *exec_list = NULL; + struct drm_i915_gem_exec_object2 *exec2_list = NULL; + int ret, i; + +#if WATCH_EXEC + DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n", + (int) args->buffers_ptr, args->buffer_count, args->batch_len); +#endif + + if (args->buffer_count < 1) { + DRM_ERROR("execbuf with %d buffers\n", args->buffer_count); + return -EINVAL; + } + + /* Copy in the exec list from userland */ + exec_list = drm_malloc_ab(sizeof(*exec_list), args->buffer_count); + exec2_list = drm_malloc_ab(sizeof(*exec2_list), args->buffer_count); + if (exec_list == NULL || exec2_list == NULL) { + DRM_ERROR("Failed to allocate exec list for %d buffers\n", + args->buffer_count); + drm_free_large(exec_list); + drm_free_large(exec2_list); + return -ENOMEM; + } + ret = copy_from_user(exec_list, + (struct drm_i915_relocation_entry __user *) + (uintptr_t) args->buffers_ptr, + sizeof(*exec_list) * args->buffer_count); + if (ret != 0) { + DRM_ERROR("copy %d exec entries failed %d\n", + args->buffer_count, ret); + drm_free_large(exec_list); + drm_free_large(exec2_list); + return -EFAULT; + } + + for (i = 0; i < args->buffer_count; i++) { + exec2_list[i].handle = exec_list[i].handle; + exec2_list[i].relocation_count = exec_list[i].relocation_count; + exec2_list[i].relocs_ptr = exec_list[i].relocs_ptr; + exec2_list[i].alignment = exec_list[i].alignment; + exec2_list[i].offset = exec_list[i].offset; + if (!IS_I965G(dev)) + exec2_list[i].flags = EXEC_OBJECT_NEEDS_FENCE; + else + exec2_list[i].flags = 0; + } + + exec2.buffers_ptr = args->buffers_ptr; + exec2.buffer_count = args->buffer_count; + exec2.batch_start_offset = args->batch_start_offset; + exec2.batch_len = args->batch_len; + exec2.DR1 = args->DR1; + exec2.DR4 = args->DR4; + exec2.num_cliprects = args->num_cliprects; + exec2.cliprects_ptr = args->cliprects_ptr; + exec2.flags = 0; + + ret = i915_gem_do_execbuffer(dev, data, file_priv, &exec2, exec2_list); + if (!ret) { + /* Copy the new buffer offsets back to the user's exec list. */ + for (i = 0; i < args->buffer_count; i++) + exec_list[i].offset = exec2_list[i].offset; + /* ... and back out to userspace */ + ret = copy_to_user((struct drm_i915_relocation_entry __user *) + (uintptr_t) args->buffers_ptr, + exec_list, + sizeof(*exec_list) * args->buffer_count); + if (ret) { + ret = -EFAULT; + DRM_ERROR("failed to copy %d exec entries " + "back to user (%d)\n", + args->buffer_count, ret); + } + } else { + DRM_ERROR("i915_gem_do_execbuffer returns %d\n", ret); + } + + drm_free_large(exec_list); + drm_free_large(exec2_list); + return ret; +} + +int +i915_gem_execbuffer2(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_i915_gem_execbuffer2 *args = data; + struct drm_i915_gem_exec_object2 *exec2_list = NULL; + int ret; + +#if WATCH_EXEC + DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n", + (int) args->buffers_ptr, args->buffer_count, args->batch_len); +#endif + + if (args->buffer_count < 1) { + DRM_ERROR("execbuf2 with %d buffers\n", args->buffer_count); + return -EINVAL; + } + + exec2_list = drm_malloc_ab(sizeof(*exec2_list), args->buffer_count); + if (exec2_list == NULL) { + DRM_ERROR("Failed to allocate exec list for %d buffers\n", + args->buffer_count); + return -ENOMEM; + } + ret = copy_from_user(exec2_list, + (struct drm_i915_relocation_entry __user *) + (uintptr_t) args->buffers_ptr, + sizeof(*exec2_list) * args->buffer_count); + if (ret != 0) { + DRM_ERROR("copy %d exec entries failed %d\n", + args->buffer_count, ret); + drm_free_large(exec2_list); + return -EFAULT; + } + + ret = i915_gem_do_execbuffer(dev, data, file_priv, args, exec2_list); + if (!ret) { + /* Copy the new buffer offsets back to the user's exec list. */ + ret = copy_to_user((struct drm_i915_relocation_entry __user *) + (uintptr_t) args->buffers_ptr, + exec2_list, + sizeof(*exec2_list) * args->buffer_count); + if (ret) { + ret = -EFAULT; + DRM_ERROR("failed to copy %d exec entries " + "back to user (%d)\n", + args->buffer_count, ret); + } + } + + drm_free_large(exec2_list); + return ret; +} + int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment) { @@ -3934,19 +4079,7 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment) if (ret) return ret; } - /* - * Pre-965 chips need a fence register set up in order to - * properly handle tiled surfaces. - */ - if (!IS_I965G(dev) && obj_priv->tiling_mode != I915_TILING_NONE) { - ret = i915_gem_object_get_fence_reg(obj); - if (ret != 0) { - if (ret != -EBUSY && ret != -ERESTARTSYS) - DRM_ERROR("Failure to install fence: %d\n", - ret); - return ret; - } - } + obj_priv->pin_count++; /* If the object is not active and not pending a flush, diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index 30d6af6c..df278b2 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c @@ -304,35 +304,39 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev) /** - * Returns the size of the fence for a tiled object of the given size. + * Returns whether an object is currently fenceable. If not, it may need + * to be unbound and have its pitch adjusted. */ -static int -i915_get_fence_size(struct drm_device *dev, int size) +bool +i915_obj_fenceable(struct drm_device *dev, struct drm_gem_object *obj) { - int i; - int start; + struct drm_i915_gem_object *obj_priv = obj->driver_private; if (IS_I965G(dev)) { /* The 965 can have fences at any page boundary. */ - return ALIGN(size, 4096); + if (obj->size & 4095) + return false; + return true; + } else if (IS_I9XX(dev)) { + if (obj_priv->gtt_offset & ~I915_FENCE_START_MASK) + return false; } else { - /* Align the size to a power of two greater than the smallest - * fence size. - */ - if (IS_I9XX(dev)) - start = 1024 * 1024; - else - start = 512 * 1024; + if (obj_priv->gtt_offset & ~I830_FENCE_START_MASK) + return false; + } - for (i = start; i < size; i <<= 1) - ; + /* Power of two sized... */ + if (obj->size & (obj->size - 1)) + return false; - return i; - } + /* Objects must be size aligned as well */ + if (obj_priv->gtt_offset & (obj->size - 1)) + return false; + return true; } /* Check pitch constriants for all chips & tiling formats */ -static bool +bool i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode) { int tile_width; @@ -384,12 +388,6 @@ i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode) if (stride & (stride - 1)) return false; - /* We don't 0handle the aperture area covered by the fence being bigger - * than the object size. - */ - if (i915_get_fence_size(dev, size) != size) - return false; - return true; } diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h index ec3f5e80..b64a8d7 100644 --- a/include/drm/i915_drm.h +++ b/include/drm/i915_drm.h @@ -188,6 +188,7 @@ typedef struct _drm_i915_sarea { #define DRM_I915_GEM_MADVISE 0x26 #define DRM_I915_OVERLAY_PUT_IMAGE 0x27 #define DRM_I915_OVERLAY_ATTRS 0x28 +#define DRM_I915_GEM_EXECBUFFER2 0x29 #define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t) #define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH) @@ -207,6 +208,7 @@ typedef struct _drm_i915_sarea { #define DRM_IOCTL_I915_VBLANK_SWAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_VBLANK_SWAP, drm_i915_vblank_swap_t) #define DRM_IOCTL_I915_GEM_INIT DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_INIT, struct drm_i915_gem_init) #define DRM_IOCTL_I915_GEM_EXECBUFFER DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER, struct drm_i915_gem_execbuffer) +#define DRM_IOCTL_I915_GEM_EXECBUFFER2 DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER2, struct drm_i915_gem_execbuffer2) #define DRM_IOCTL_I915_GEM_PIN DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_PIN, struct drm_i915_gem_pin) #define DRM_IOCTL_I915_GEM_UNPIN DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_UNPIN, struct drm_i915_gem_unpin) #define DRM_IOCTL_I915_GEM_BUSY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_BUSY, struct drm_i915_gem_busy) @@ -272,6 +274,7 @@ typedef struct drm_i915_irq_wait { #define I915_PARAM_NUM_FENCES_AVAIL 6 #define I915_PARAM_HAS_OVERLAY 7 #define I915_PARAM_HAS_PAGEFLIPPING 8 +#define I915_PARAM_HAS_EXECBUF2 9 typedef struct drm_i915_getparam { int param; @@ -567,6 +570,57 @@ struct drm_i915_gem_execbuffer { __u64 cliprects_ptr; }; +struct drm_i915_gem_exec_object2 { + /** + * User's handle for a buffer to be bound into the GTT for this + * operation. + */ + __u32 handle; + + /** Number of relocations to be performed on this buffer */ + __u32 relocation_count; + /** + * Pointer to array of struct drm_i915_gem_relocation_entry containing + * the relocations to be performed in this buffer. + */ + __u64 relocs_ptr; + + /** Required alignment in graphics aperture */ + __u64 alignment; + + /** + * Returned value of the updated offset of the object, for future + * presumed_offset writes. + */ + __u64 offset; + +#define EXEC_OBJECT_NEEDS_FENCE (1<<0) + __u64 flags; + __u64 rsvd1; + __u64 rsvd2; +}; + +struct drm_i915_gem_execbuffer2 { + /** + * List of gem_exec_object2 structs + */ + __u64 buffers_ptr; + __u32 buffer_count; + + /** Offset in the batchbuffer to start execution from. */ + __u32 batch_start_offset; + /** Bytes used in batchbuffer from batch_start_offset */ + __u32 batch_len; + __u32 DR1; + __u32 DR4; + __u32 num_cliprects; + /** This is a struct drm_clip_rect *cliprects */ + __u64 cliprects_ptr; + __u64 flags; /* currently unused */ + __u64 rsvd1; + __u64 rsvd2; +}; + struct drm_i915_gem_pin { /** Handle of the buffer to be pinned. */ __u32 handle; -- cgit v0.10.2 From 1d3c36ad4122651018599d4e3c9be0cccfbfb939 Mon Sep 17 00:00:00 2001 From: Andrew Lutomirski Date: Mon, 21 Dec 2009 10:10:22 -0500 Subject: drm/i915: Fix RC6 suspend/resume We restored RC6 twice on resume, even with modesetting off. Instead, only restore it once and skip RC6 initialization entirely in non-KMS mode. Signed-off-by: Andy Lutomirski Tested-by: Jeff Chua Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 7eb4ad5..29dd676 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -307,8 +307,6 @@ typedef struct drm_i915_private { u32 saveDSPACNTR; u32 saveDSPBCNTR; u32 saveDSPARB; - u32 saveRENDERSTANDBY; - u32 savePWRCTXA; u32 saveHWS; u32 savePIPEACONF; u32 savePIPEBCONF; diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index d5ebb00..a3b90c9 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c @@ -732,12 +732,6 @@ int i915_save_state(struct drm_device *dev) pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB); - /* Render Standby */ - if (I915_HAS_RC6(dev)) { - dev_priv->saveRENDERSTANDBY = I915_READ(MCHBAR_RENDER_STANDBY); - dev_priv->savePWRCTXA = I915_READ(PWRCTXA); - } - /* Hardware status page */ dev_priv->saveHWS = I915_READ(HWS_PGA); @@ -793,12 +787,6 @@ int i915_restore_state(struct drm_device *dev) pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB); - /* Render Standby */ - if (I915_HAS_RC6(dev)) { - I915_WRITE(MCHBAR_RENDER_STANDBY, dev_priv->saveRENDERSTANDBY); - I915_WRITE(PWRCTXA, dev_priv->savePWRCTXA); - } - /* Hardware status page */ I915_WRITE(HWS_PGA, dev_priv->saveHWS); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index c21dede..089b1df 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4593,7 +4593,7 @@ void intel_init_clock_gating(struct drm_device *dev) * GPU can automatically power down the render unit if given a page * to save state. */ - if (I915_HAS_RC6(dev)) { + if (I915_HAS_RC6(dev) && drm_core_check_feature(dev, DRIVER_MODESET)) { struct drm_gem_object *pwrctx; struct drm_i915_gem_object *obj_priv; int ret; -- cgit v0.10.2 From cda9d05c499093c67b4a376a15009923acc2127a Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Thu, 17 Dec 2009 11:11:13 -0800 Subject: drm/i915: remove render reclock support This code generally fails to adjust the render clock, and when it does, it conflicts with some other register settings and can cause problems. So remove this code altogether. I'm reworking it now to do the right thing, but the only bit it will share is the VBT check for whether reclocking is supported, so I'm leaving that bit. Reverts most of 652c393a3368af84359da37c45afc35a91144960 ("add dynamic clock frequency control"), though for many the regressions showed up in the later 181a5336d6cc836f05507410d66988c483ad0154 ("Fix render reclock availability detection"). Signed-off-by: Jesse Barnes Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 089b1df..9187a17 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3779,125 +3779,6 @@ static void intel_gpu_idle_timer(unsigned long arg) queue_work(dev_priv->wq, &dev_priv->idle_work); } -void intel_increase_renderclock(struct drm_device *dev, bool schedule) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - - if (IS_IRONLAKE(dev)) - return; - - if (!dev_priv->render_reclock_avail) { - DRM_DEBUG_DRIVER("not reclocking render clock\n"); - return; - } - - /* Restore render clock frequency to original value */ - if (IS_G4X(dev) || IS_I9XX(dev)) - pci_write_config_word(dev->pdev, GCFGC, dev_priv->orig_clock); - else if (IS_I85X(dev)) - pci_write_config_word(dev->pdev, HPLLCC, dev_priv->orig_clock); - DRM_DEBUG_DRIVER("increasing render clock frequency\n"); - - /* Schedule downclock */ - if (schedule) - mod_timer(&dev_priv->idle_timer, jiffies + - msecs_to_jiffies(GPU_IDLE_TIMEOUT)); -} - -void intel_decrease_renderclock(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - - if (IS_IRONLAKE(dev)) - return; - - if (!dev_priv->render_reclock_avail) { - DRM_DEBUG_DRIVER("not reclocking render clock\n"); - return; - } - - if (IS_G4X(dev)) { - u16 gcfgc; - - /* Adjust render clock... */ - pci_read_config_word(dev->pdev, GCFGC, &gcfgc); - - /* Down to minimum... */ - gcfgc &= ~GM45_GC_RENDER_CLOCK_MASK; - gcfgc |= GM45_GC_RENDER_CLOCK_266_MHZ; - - pci_write_config_word(dev->pdev, GCFGC, gcfgc); - } else if (IS_I965G(dev)) { - u16 gcfgc; - - /* Adjust render clock... */ - pci_read_config_word(dev->pdev, GCFGC, &gcfgc); - - /* Down to minimum... */ - gcfgc &= ~I965_GC_RENDER_CLOCK_MASK; - gcfgc |= I965_GC_RENDER_CLOCK_267_MHZ; - - pci_write_config_word(dev->pdev, GCFGC, gcfgc); - } else if (IS_I945G(dev) || IS_I945GM(dev)) { - u16 gcfgc; - - /* Adjust render clock... */ - pci_read_config_word(dev->pdev, GCFGC, &gcfgc); - - /* Down to minimum... */ - gcfgc &= ~I945_GC_RENDER_CLOCK_MASK; - gcfgc |= I945_GC_RENDER_CLOCK_166_MHZ; - - pci_write_config_word(dev->pdev, GCFGC, gcfgc); - } else if (IS_I915G(dev)) { - u16 gcfgc; - - /* Adjust render clock... */ - pci_read_config_word(dev->pdev, GCFGC, &gcfgc); - - /* Down to minimum... */ - gcfgc &= ~I915_GC_RENDER_CLOCK_MASK; - gcfgc |= I915_GC_RENDER_CLOCK_166_MHZ; - - pci_write_config_word(dev->pdev, GCFGC, gcfgc); - } else if (IS_I85X(dev)) { - u16 hpllcc; - - /* Adjust render clock... */ - pci_read_config_word(dev->pdev, HPLLCC, &hpllcc); - - /* Up to maximum... */ - hpllcc &= ~GC_CLOCK_CONTROL_MASK; - hpllcc |= GC_CLOCK_133_200; - - pci_write_config_word(dev->pdev, HPLLCC, hpllcc); - } - DRM_DEBUG_DRIVER("decreasing render clock frequency\n"); -} - -/* Note that no increase function is needed for this - increase_renderclock() - * will also rewrite these bits - */ -void intel_decrease_displayclock(struct drm_device *dev) -{ - if (IS_IRONLAKE(dev)) - return; - - if (IS_I945G(dev) || IS_I945GM(dev) || IS_I915G(dev) || - IS_I915GM(dev)) { - u16 gcfgc; - - /* Adjust render clock... */ - pci_read_config_word(dev->pdev, GCFGC, &gcfgc); - - /* Down to minimum... */ - gcfgc &= ~0xf0; - gcfgc |= 0x80; - - pci_write_config_word(dev->pdev, GCFGC, gcfgc); - } -} - #define CRTC_IDLE_TIMEOUT 1000 /* ms */ static void intel_crtc_idle_timer(unsigned long arg) @@ -4011,12 +3892,6 @@ static void intel_idle_update(struct work_struct *work) mutex_lock(&dev->struct_mutex); - /* GPU isn't processing, downclock it. */ - if (!dev_priv->busy) { - intel_decrease_renderclock(dev); - intel_decrease_displayclock(dev); - } - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { /* Skip inactive CRTCs */ if (!crtc->fb) @@ -4050,13 +3925,11 @@ void intel_mark_busy(struct drm_device *dev, struct drm_gem_object *obj) if (!drm_core_check_feature(dev, DRIVER_MODESET)) return; - if (!dev_priv->busy) { + if (!dev_priv->busy) dev_priv->busy = true; - intel_increase_renderclock(dev, true); - } else { + else mod_timer(&dev_priv->idle_timer, jiffies + msecs_to_jiffies(GPU_IDLE_TIMEOUT)); - } list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { if (!crtc->fb) @@ -4784,7 +4657,6 @@ void intel_modeset_cleanup(struct drm_device *dev) del_timer_sync(&intel_crtc->idle_timer); } - intel_increase_renderclock(dev, false); del_timer_sync(&dev_priv->idle_timer); if (dev_priv->display.disable_fbc) -- cgit v0.10.2 From 69e302a998ddfc3bd99033052f6d6152a46e7d6e Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Wed, 23 Dec 2009 14:14:34 +0100 Subject: drm/i915: Storage class should be before const qualifier The C99 specification states in section 6.11.5: The placement of a storage-class specifier other than at the beginning of the declaration specifiers in a declaration is an obsolescent feature. Signed-off-by: Tobias Klauser Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 9187a17..af61dd9 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2448,7 +2448,7 @@ static void pineview_enable_cxsr(struct drm_device *dev, unsigned long clock, * A value of 5us seems to be a good balance; safe for very low end * platforms but not overly aggressive on lower latency configs. */ -const static int latency_ns = 5000; +static const int latency_ns = 5000; static int i9xx_get_fifo_size(struct drm_device *dev, int plane) { @@ -2559,7 +2559,7 @@ static void g4x_update_wm(struct drm_device *dev, int planea_clock, /* Calc sr entries for one plane configs */ if (sr_hdisplay && (!planea_clock || !planeb_clock)) { /* self-refresh has much higher latency */ - const static int sr_latency_ns = 12000; + static const int sr_latency_ns = 12000; sr_clock = planea_clock ? planea_clock : planeb_clock; line_time_us = ((sr_hdisplay * 1000) / sr_clock); @@ -2598,7 +2598,7 @@ static void i965_update_wm(struct drm_device *dev, int planea_clock, /* Calc sr entries for one plane configs */ if (sr_hdisplay && (!planea_clock || !planeb_clock)) { /* self-refresh has much higher latency */ - const static int sr_latency_ns = 12000; + static const int sr_latency_ns = 12000; sr_clock = planea_clock ? planea_clock : planeb_clock; line_time_us = ((sr_hdisplay * 1000) / sr_clock); @@ -2667,7 +2667,7 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock, if (HAS_FW_BLC(dev) && sr_hdisplay && (!planea_clock || !planeb_clock)) { /* self-refresh has much higher latency */ - const static int sr_latency_ns = 6000; + static const int sr_latency_ns = 6000; sr_clock = planea_clock ? planea_clock : planeb_clock; line_time_us = ((sr_hdisplay * 1000) / sr_clock); -- cgit v0.10.2 From 29bd0ae25f8cb96b63560c2cbccec77b425e1603 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 17 Nov 2009 14:08:52 -0800 Subject: drm/i915: fix unused var drivers/gpu/drm/i915/i915_dma.c: In function 'i915_driver_load': drivers/gpu/drm/i915/i915_dma.c:1114: warning: 'll_base' may be used uninitialized in this function Partly this is because gcc isn't smart enough. But `ll_base' does get used uninitialised in the DRM_DEBUG() call. Cc: Jesse Barnes Cc: Eric Anholt Cc: Dave Airlie Signed-off-by: Andrew Morton Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index d67be65..c2b1108 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1121,7 +1121,8 @@ static void i915_setup_compression(struct drm_device *dev, int size) { struct drm_i915_private *dev_priv = dev->dev_private; struct drm_mm_node *compressed_fb, *compressed_llb; - unsigned long cfb_base, ll_base; + unsigned long cfb_base; + unsigned long ll_base = 0; /* Leave 1M for line length buffer & misc. */ compressed_fb = drm_mm_search_free(&dev_priv->vram, size, 4096, 0); -- cgit v0.10.2 From 9ea8d05932c082a7ccbd9dc2e10687c88a70bd13 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 4 Jan 2010 18:57:56 +0000 Subject: drm/i915: Hold struct mutex whilst pinning power context bo. Hugh found an error path where we were attempting to unref a bo without holding the struct mutex: [drm:intel_init_clock_gating] *ERROR* failed to pin power context: -16 ------------[ cut here ]------------ WARNING: at drivers/gpu/drm/drm_gem.c:438 drm_gem_object_free+0x20/0x5e() Hardware name: ESPRIMO Mobile V5505 Modules linked in: snd_pcm_oss snd_mixer_oss snd_seq snd_seq_device Pid: 3793, comm: s2ram Not tainted 2.6.33-rc2 #4 Call Trace: [<7815298e>] warn_slowpath_common+0x59/0x6b [<781529b3>] warn_slowpath_null+0x13/0x18 [<78317c1a>] ? drm_gem_object_free+0x20/0x5e [<78317c1a>] drm_gem_object_free+0x20/0x5e [<78317bfa>] ? drm_gem_object_free+0x0/0x5e [<7829df11>] kref_put+0x38/0x45 [<7833a5f0>] intel_init_clock_gating+0x232/0x271 [<78317bfa>] ? drm_gem_object_free+0x0/0x5e [<7832c307>] i915_restore_state+0x21a/0x2b3 [<7832379d>] i915_resume+0x3c/0xbb [<78174fe5>] ? trace_hardirqs_on_caller+0xfc/0x123 [<7831c756>] ? drm_class_resume+0x0/0x3e [<7831c78d>] drm_class_resume+0x37/0x3e [<78351e0a>] legacy_resume+0x1e/0x51 [<78351ece>] device_resume+0x91/0xab [<7831c756>] ? drm_class_resume+0x0/0x3e [<78352226>] dpm_resume+0x58/0x10f [<783522fb>] dpm_resume_end+0x1e/0x2c [<78180f80>] suspend_devices_and_enter+0x61/0x84 [<78180ff8>] enter_state+0x55/0x83 [<7818091c>] state_store+0x94/0xaa [<7829d09e>] kobj_attr_store+0x1e/0x23 [<782098e0>] sysfs_write_file+0x66/0x99 [<781cd2f0>] vfs_write+0x8a/0x108 [<781cd408>] sys_write+0x3c/0x63 [<78125c10>] sysenter_do_call+0x12/0x36 ---[ end trace a343537f29950fda ]--- It is in fact slightly more insiduous that first appears since we are attempting to not just free the object without the lock, but are trying to do the whole bo manipulation without holding the lock. Reported-by: Hugh Dickins Signed-off-by: Chris Wilson Cc: stable@kernel.org Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index af61dd9..84705b7 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4414,6 +4414,42 @@ static const struct drm_mode_config_funcs intel_mode_funcs = { .fb_changed = intelfb_probe, }; +static struct drm_gem_object * +intel_alloc_power_context(struct drm_device *dev) +{ + struct drm_gem_object *pwrctx; + int ret; + + pwrctx = drm_gem_object_alloc(dev, 4096); + if (!pwrctx) { + DRM_DEBUG("failed to alloc power context, RC6 disabled\n"); + return NULL; + } + + mutex_lock(&dev->struct_mutex); + ret = i915_gem_object_pin(pwrctx, 4096); + if (ret) { + DRM_ERROR("failed to pin power context: %d\n", ret); + goto err_unref; + } + + ret = i915_gem_object_set_to_gtt_domain(pwrctx, 1); + if (ret) { + DRM_ERROR("failed to set-domain on power context: %d\n", ret); + goto err_unpin; + } + mutex_unlock(&dev->struct_mutex); + + return pwrctx; + +err_unpin: + i915_gem_object_unpin(pwrctx); +err_unref: + drm_gem_object_unreference(pwrctx); + mutex_unlock(&dev->struct_mutex); + return NULL; +} + void intel_init_clock_gating(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -4467,41 +4503,26 @@ void intel_init_clock_gating(struct drm_device *dev) * to save state. */ if (I915_HAS_RC6(dev) && drm_core_check_feature(dev, DRIVER_MODESET)) { - struct drm_gem_object *pwrctx; - struct drm_i915_gem_object *obj_priv; - int ret; + struct drm_i915_gem_object *obj_priv = NULL; if (dev_priv->pwrctx) { obj_priv = dev_priv->pwrctx->driver_private; } else { - pwrctx = drm_gem_object_alloc(dev, 4096); - if (!pwrctx) { - DRM_DEBUG("failed to alloc power context, " - "RC6 disabled\n"); - goto out; - } + struct drm_gem_object *pwrctx; - ret = i915_gem_object_pin(pwrctx, 4096); - if (ret) { - DRM_ERROR("failed to pin power context: %d\n", - ret); - drm_gem_object_unreference(pwrctx); - goto out; + pwrctx = intel_alloc_power_context(dev); + if (pwrctx) { + dev_priv->pwrctx = pwrctx; + obj_priv = pwrctx->driver_private; } - - i915_gem_object_set_to_gtt_domain(pwrctx, 1); - - dev_priv->pwrctx = pwrctx; - obj_priv = pwrctx->driver_private; } - I915_WRITE(PWRCTXA, obj_priv->gtt_offset | PWRCTX_EN); - I915_WRITE(MCHBAR_RENDER_STANDBY, - I915_READ(MCHBAR_RENDER_STANDBY) & ~RCX_SW_EXIT); + if (obj_priv) { + I915_WRITE(PWRCTXA, obj_priv->gtt_offset | PWRCTX_EN); + I915_WRITE(MCHBAR_RENDER_STANDBY, + I915_READ(MCHBAR_RENDER_STANDBY) & ~RCX_SW_EXIT); + } } - -out: - return; } /* Set up chip specific display functions */ -- cgit v0.10.2 From e3d8affb0d2d95f2da61e30ce86b33177feb91e8 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 4 Jan 2010 18:57:57 +0000 Subject: drm/i915: Permit pinning whilst the device is 'suspended' As pinning (allocating and binding GTT memory) does not actually invoke GPU commands, it is safe, and indeed is attempted, during resumption from suspension: [drm:intel_init_clock_gating] *ERROR* failed to pin power context: -16 Signed-off-by: Chris Wilson Reported-by: Hugh Dickins Cc: stable@kernel.org Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 0330c3a..21950ef 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2582,9 +2582,6 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) bool retry_alloc = false; int ret; - if (dev_priv->mm.suspended) - return -EBUSY; - if (obj_priv->madv != I915_MADV_WILLNEED) { DRM_ERROR("Attempting to bind a purgeable object\n"); return -EINVAL; -- cgit v0.10.2 From 898822ce9561ab9b58a7eb60580a162a83dadecd Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Mon, 4 Jan 2010 16:29:30 +0800 Subject: drm/i915: Enable/disable the dithering for LVDS based on VBT setting Enable/disable the dithering for LVDS based on VBT setting. On the 965/g4x platform the dithering flag is defined in LVDS register. And on the ironlake the dithering flag is defined in pipeconf register. Signed-off-by: Zhao Yakui Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index f79b133..149d360 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -975,6 +975,8 @@ #define LVDS_PORT_EN (1 << 31) /* Selects pipe B for LVDS data. Must be set on pre-965. */ #define LVDS_PIPEB_SELECT (1 << 30) +/* LVDS dithering flag on 965/g4x platform */ +#define LVDS_ENABLE_DITHER (1 << 25) /* Enable border for unscaled (or aspect-scaled) display */ #define LVDS_BORDER_ENABLE (1 << 15) /* @@ -1744,6 +1746,8 @@ /* Display & cursor control */ +/* dithering flag on Ironlake */ +#define PIPE_ENABLE_DITHER (1 << 4) /* Pipe A */ #define PIPEADSL 0x70000 #define PIPEACONF 0x70008 diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 84705b7..0c9b79f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3195,7 +3195,20 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, * appropriately here, but we need to look more thoroughly into how * panels behave in the two modes. */ - + /* set the dithering flag */ + if (IS_I965G(dev)) { + if (dev_priv->lvds_dither) { + if (IS_IRONLAKE(dev)) + pipeconf |= PIPE_ENABLE_DITHER; + else + lvds |= LVDS_ENABLE_DITHER; + } else { + if (IS_IRONLAKE(dev)) + pipeconf &= ~PIPE_ENABLE_DITHER; + else + lvds &= ~LVDS_ENABLE_DITHER; + } + } I915_WRITE(lvds_reg, lvds); I915_READ(lvds_reg); } -- cgit v0.10.2 From 8faf3b317471179c02db339aa80955a2e88c036d Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Mon, 4 Jan 2010 16:29:31 +0800 Subject: drm/i915: Make the BPC in FDI rx/transcoder be consistent with that in pipeconf on Ironlake Make the BPC in FDI rx/transcoder be consistent with that in pipeconf on Ironlake. Signed-off-by: Zhao Yakui Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 0c9b79f..63e8e9f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1493,6 +1493,10 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) int trans_vsync_reg = (pipe == 0) ? TRANS_VSYNC_A : TRANS_VSYNC_B; u32 temp; int tries = 5, j, n; + u32 pipe_bpc; + + temp = I915_READ(pipeconf_reg); + pipe_bpc = temp & PIPE_BPC_MASK; /* XXX: When our outputs are all unaware of DPMS modes other than off * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC. @@ -1524,6 +1528,12 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) /* enable PCH FDI RX PLL, wait warmup plus DMI latency */ temp = I915_READ(fdi_rx_reg); + /* + * make the BPC in FDI Rx be consistent with that in + * pipeconf reg. + */ + temp &= ~(0x7 << 16); + temp |= (pipe_bpc << 11); I915_WRITE(fdi_rx_reg, temp | FDI_RX_PLL_ENABLE | FDI_SEL_PCDCLK | FDI_DP_PORT_WIDTH_X4); /* default 4 lanes */ @@ -1666,6 +1676,12 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) /* enable PCH transcoder */ temp = I915_READ(transconf_reg); + /* + * make the BPC in transcoder be consistent with + * that in pipeconf reg. + */ + temp &= ~PIPE_BPC_MASK; + temp |= pipe_bpc; I915_WRITE(transconf_reg, temp | TRANS_ENABLE); I915_READ(transconf_reg); @@ -1745,6 +1761,9 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) I915_READ(fdi_tx_reg); temp = I915_READ(fdi_rx_reg); + /* BPC in FDI rx is consistent with that in pipeconf */ + temp &= ~(0x07 << 16); + temp |= (pipe_bpc << 11); I915_WRITE(fdi_rx_reg, temp & ~FDI_RX_ENABLE); I915_READ(fdi_rx_reg); @@ -1789,7 +1808,12 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) } } } - + temp = I915_READ(transconf_reg); + /* BPC in transcoder is consistent with that in pipeconf */ + temp &= ~PIPE_BPC_MASK; + temp |= pipe_bpc; + I915_WRITE(transconf_reg, temp); + I915_READ(transconf_reg); udelay(100); /* disable PCH DPLL */ -- cgit v0.10.2 From e5a95eb778690bc864eb330202d2c1b974caaeb4 Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Mon, 4 Jan 2010 16:29:32 +0800 Subject: drm/i915: Select the correct BPC for LVDS on Ironlake Select the correct BPC for LVDS on Ironlake. If it is 18-bit LVDS panel, the BPC will be 6. When it is 24-bit LVDS panel, the BPC will 8. At the same time the BPC will be 8 when the output device is CRT/HDMI/DP. Signed-off-by: Zhao Yakui Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 63e8e9f..5e2159b 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2993,6 +2993,18 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, /* determine panel color depth */ temp = I915_READ(pipeconf_reg); + temp &= ~PIPE_BPC_MASK; + if (is_lvds) { + int lvds_reg = I915_READ(PCH_LVDS); + /* the BPC will be 6 if it is 18-bit LVDS panel */ + if ((lvds_reg & LVDS_A3_POWER_MASK) == LVDS_A3_POWER_UP) + temp |= PIPE_8BPC; + else + temp |= PIPE_6BPC; + } else + temp |= PIPE_8BPC; + I915_WRITE(pipeconf_reg, temp); + I915_READ(pipeconf_reg); switch (temp & PIPE_BPC_MASK) { case PIPE_8BPC: -- cgit v0.10.2 From 4547668a050e7de3cd73a4c6736dfc2adebff67d Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Thu, 31 Dec 2009 16:06:04 +0800 Subject: drm/i915: Add DP dpll limit on ironlake and use existing DPLL search function For some clocks, the old Ironlake DPLL calculator wold give m/n/p combinations that didn't match the spreadsheet of what HW validation tests. Instead, use the G4X DPLL calculator, which does a better job at it. So we use the intel_g4x_find_best_pll to calculate the DPLL for CRT/HDMI/LVDS on ironlake. At the same time to consider the dpll setting for display port, we add the display port DPLL limit on ironlake, which will directly use the function of intel_find_pll_ironlake_dp to get the corresponding dpll setting. Signed-off-by: Zhao Yakui Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 5e2159b..002612f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -262,6 +262,14 @@ struct intel_limit { #define IRONLAKE_P2_LVDS_FAST 7 /* double channel */ #define IRONLAKE_P2_DOT_LIMIT 225000 /* 225Mhz */ +#define IRONLAKE_P_DISPLAY_PORT_MIN 10 +#define IRONLAKE_P_DISPLAY_PORT_MAX 20 +#define IRONLAKE_P2_DISPLAY_PORT_FAST 10 +#define IRONLAKE_P2_DISPLAY_PORT_SLOW 10 +#define IRONLAKE_P2_DISPLAY_PORT_LIMIT 0 +#define IRONLAKE_P1_DISPLAY_PORT_MIN 1 +#define IRONLAKE_P1_DISPLAY_PORT_MAX 2 + static bool intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, int target, int refclk, intel_clock_t *best_clock); @@ -271,9 +279,6 @@ intel_find_best_reduced_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, static bool intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, int target, int refclk, intel_clock_t *best_clock); -static bool -intel_ironlake_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, - int target, int refclk, intel_clock_t *best_clock); static bool intel_find_pll_g4x_dp(const intel_limit_t *, struct drm_crtc *crtc, @@ -496,7 +501,7 @@ static const intel_limit_t intel_limits_ironlake_sdvo = { .p2 = { .dot_limit = IRONLAKE_P2_DOT_LIMIT, .p2_slow = IRONLAKE_P2_SDVO_DAC_SLOW, .p2_fast = IRONLAKE_P2_SDVO_DAC_FAST }, - .find_pll = intel_ironlake_find_best_PLL, + .find_pll = intel_g4x_find_best_PLL, }; static const intel_limit_t intel_limits_ironlake_lvds = { @@ -511,7 +516,30 @@ static const intel_limit_t intel_limits_ironlake_lvds = { .p2 = { .dot_limit = IRONLAKE_P2_DOT_LIMIT, .p2_slow = IRONLAKE_P2_LVDS_SLOW, .p2_fast = IRONLAKE_P2_LVDS_FAST }, - .find_pll = intel_ironlake_find_best_PLL, + .find_pll = intel_g4x_find_best_PLL, +}; + +static const intel_limit_t intel_limits_ironlake_display_port = { + .dot = { .min = IRONLAKE_DOT_MIN, + .max = IRONLAKE_DOT_MAX }, + .vco = { .min = IRONLAKE_VCO_MIN, + .max = IRONLAKE_VCO_MAX}, + .n = { .min = IRONLAKE_N_MIN, + .max = IRONLAKE_N_MAX }, + .m = { .min = IRONLAKE_M_MIN, + .max = IRONLAKE_M_MAX }, + .m1 = { .min = IRONLAKE_M1_MIN, + .max = IRONLAKE_M1_MAX }, + .m2 = { .min = IRONLAKE_M2_MIN, + .max = IRONLAKE_M2_MAX }, + .p = { .min = IRONLAKE_P_DISPLAY_PORT_MIN, + .max = IRONLAKE_P_DISPLAY_PORT_MAX }, + .p1 = { .min = IRONLAKE_P1_DISPLAY_PORT_MIN, + .max = IRONLAKE_P1_DISPLAY_PORT_MAX}, + .p2 = { .dot_limit = IRONLAKE_P2_DISPLAY_PORT_LIMIT, + .p2_slow = IRONLAKE_P2_DISPLAY_PORT_SLOW, + .p2_fast = IRONLAKE_P2_DISPLAY_PORT_FAST }, + .find_pll = intel_find_pll_ironlake_dp, }; static const intel_limit_t *intel_ironlake_limit(struct drm_crtc *crtc) @@ -519,6 +547,9 @@ static const intel_limit_t *intel_ironlake_limit(struct drm_crtc *crtc) const intel_limit_t *limit; if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) limit = &intel_limits_ironlake_lvds; + else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT) || + HAS_eDP) + limit = &intel_limits_ironlake_display_port; else limit = &intel_limits_ironlake_sdvo; @@ -791,7 +822,13 @@ intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, found = false; if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { - if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) == + int lvds_reg; + + if (IS_IRONLAKE(dev)) + lvds_reg = PCH_LVDS; + else + lvds_reg = LVDS; + if ((I915_READ(lvds_reg) & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP) clock.p2 = limit->p2.p2_fast; else @@ -839,6 +876,11 @@ intel_find_pll_ironlake_dp(const intel_limit_t *limit, struct drm_crtc *crtc, { struct drm_device *dev = crtc->dev; intel_clock_t clock; + + /* return directly when it is eDP */ + if (HAS_eDP) + return true; + if (target < 200000) { clock.n = 1; clock.p1 = 2; @@ -857,68 +899,6 @@ intel_find_pll_ironlake_dp(const intel_limit_t *limit, struct drm_crtc *crtc, return true; } -static bool -intel_ironlake_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, - int target, int refclk, intel_clock_t *best_clock) -{ - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - intel_clock_t clock; - int err_most = 47; - int err_min = 10000; - - /* eDP has only 2 clock choice, no n/m/p setting */ - if (HAS_eDP) - return true; - - if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) - return intel_find_pll_ironlake_dp(limit, crtc, target, - refclk, best_clock); - - if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { - if ((I915_READ(PCH_LVDS) & LVDS_CLKB_POWER_MASK) == - LVDS_CLKB_POWER_UP) - clock.p2 = limit->p2.p2_fast; - else - clock.p2 = limit->p2.p2_slow; - } else { - if (target < limit->p2.dot_limit) - clock.p2 = limit->p2.p2_slow; - else - clock.p2 = limit->p2.p2_fast; - } - - memset(best_clock, 0, sizeof(*best_clock)); - for (clock.p1 = limit->p1.max; clock.p1 >= limit->p1.min; clock.p1--) { - /* based on hardware requriment prefer smaller n to precision */ - for (clock.n = limit->n.min; clock.n <= limit->n.max; clock.n++) { - /* based on hardware requirment prefere larger m1,m2 */ - for (clock.m1 = limit->m1.max; - clock.m1 >= limit->m1.min; clock.m1--) { - for (clock.m2 = limit->m2.max; - clock.m2 >= limit->m2.min; clock.m2--) { - int this_err; - - intel_clock(dev, refclk, &clock); - if (!intel_PLL_is_valid(crtc, &clock)) - continue; - this_err = abs((10000 - (target*10000/clock.dot))); - if (this_err < err_most) { - *best_clock = clock; - /* found on first matching */ - goto out; - } else if (this_err < err_min) { - *best_clock = clock; - err_min = this_err; - } - } - } - } - } -out: - return true; -} - /* DisplayPort has only two frequencies, 162MHz and 270MHz */ static bool intel_find_pll_g4x_dp(const intel_limit_t *limit, struct drm_crtc *crtc, -- cgit v0.10.2 From 823f68fd646da6a39a9c0d3eb4c60d69dab5aa13 Mon Sep 17 00:00:00 2001 From: Zhenyu Wang Date: Mon, 28 Dec 2009 13:23:36 +0800 Subject: drm/i915: remove full registers dump debug This one reverts 9e3a6d155ed0a7636b926a798dd7221ea107b274. As reported by http://bugzilla.kernel.org/show_bug.cgi?id=14485, this dump will cause hang problem on some machine. If something really needs this kind of full registers dump, that could be done within intel-gpu-tools. Cc: Ben Gamari Signed-off-by: Zhenyu Wang Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 463e8d0..9c9998c 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -386,34 +386,6 @@ out: return 0; } -static int i915_registers_info(struct seq_file *m, void *data) { - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - uint32_t reg; - -#define DUMP_RANGE(start, end) \ - for (reg=start; reg < end; reg += 4) \ - seq_printf(m, "%08x\t%08x\n", reg, I915_READ(reg)); - - DUMP_RANGE(0x00000, 0x00fff); /* VGA registers */ - DUMP_RANGE(0x02000, 0x02fff); /* instruction, memory, interrupt control registers */ - DUMP_RANGE(0x03000, 0x031ff); /* FENCE and PPGTT control registers */ - DUMP_RANGE(0x03200, 0x03fff); /* frame buffer compression registers */ - DUMP_RANGE(0x05000, 0x05fff); /* I/O control registers */ - DUMP_RANGE(0x06000, 0x06fff); /* clock control registers */ - DUMP_RANGE(0x07000, 0x07fff); /* 3D internal debug registers */ - DUMP_RANGE(0x07400, 0x088ff); /* GPE debug registers */ - DUMP_RANGE(0x0a000, 0x0afff); /* display palette registers */ - DUMP_RANGE(0x10000, 0x13fff); /* MMIO MCHBAR */ - DUMP_RANGE(0x30000, 0x3ffff); /* overlay registers */ - DUMP_RANGE(0x60000, 0x6ffff); /* display engine pipeline registers */ - DUMP_RANGE(0x70000, 0x72fff); /* display and cursor registers */ - DUMP_RANGE(0x73000, 0x73fff); /* performance counters */ - - return 0; -} - static int i915_wedged_open(struct inode *inode, struct file *filp) @@ -519,7 +491,6 @@ static int i915_wedged_create(struct dentry *root, struct drm_minor *minor) } static struct drm_info_list i915_debugfs_list[] = { - {"i915_regs", i915_registers_info, 0}, {"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST}, {"i915_gem_flushing", i915_gem_object_list_info, 0, (void *) FLUSHING_LIST}, {"i915_gem_inactive", i915_gem_object_list_info, 0, (void *) INACTIVE_LIST}, -- cgit v0.10.2 From 7f41c2e1523f628cc248e34192162aec5728bed7 Mon Sep 17 00:00:00 2001 From: Suresh Siddha Date: Wed, 6 Jan 2010 10:56:31 -0800 Subject: x86, irq: Check move_in_progress before freeing the vector mapping With the recent irq migration fixes (post 2.6.32), Gary Hade has noticed "No IRQ handler for vector" messages during the 2.6.33-rc1 kernel boot on IBM AMD platforms and root caused the issue to this commit: > commit 23359a88e7eca3c4f402562b102f23014db3c2aa > Author: Suresh Siddha > Date: Mon Oct 26 14:24:33 2009 -0800 > > x86: Remove move_cleanup_count from irq_cfg As part of this patch, we have removed the move_cleanup_count check in smp_irq_move_cleanup_interrupt(). With this change, we can run into a situation where an irq cleanup interrupt on a cpu can cleanup the vector mappings associated with multiple irqs, of which one of the irq's migration might be still in progress. As such when that irq hits the old cpu, we get the "No IRQ handler" messages. Fix this by checking for the irq_cfg's move_in_progress and if the move is still in progress delay the vector cleanup to another irq cleanup interrupt request (which will happen when the irq starts arriving at the new cpu destination). Reported-and-tested-by: Gary Hade Signed-off-by: Suresh Siddha LKML-Reference: <1262804191.2732.7.camel@sbs-t61.sc.intel.com> Cc: Eric W. Biederman Signed-off-by: H. Peter Anvin diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index de00c46..53243ca 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -2434,6 +2434,13 @@ asmlinkage void smp_irq_move_cleanup_interrupt(void) cfg = irq_cfg(irq); raw_spin_lock(&desc->lock); + /* + * Check if the irq migration is in progress. If so, we + * haven't received the cleanup request yet for this irq. + */ + if (cfg->move_in_progress) + goto unlock; + if (vector == cfg->vector && cpumask_test_cpu(me, cfg->domain)) goto unlock; -- cgit v0.10.2 From 4c425588e0d72c9c55024752b0f6e709c96787ff Mon Sep 17 00:00:00 2001 From: Jack Morgenstein Date: Wed, 6 Jan 2010 12:48:55 -0800 Subject: IB/mlx4: Initialize SRQ scatter entries when creating an SRQ As for memfree mthca hardware, ConnectX also requires SRQ WQE scatter entries to be initialized with the invalid L_Key at SRQ creation time. Signed-off-by: Jack Morgenstein Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/mlx4/srq.c b/drivers/infiniband/hw/mlx4/srq.c index d425652..cf8085b 100644 --- a/drivers/infiniband/hw/mlx4/srq.c +++ b/drivers/infiniband/hw/mlx4/srq.c @@ -74,6 +74,7 @@ struct ib_srq *mlx4_ib_create_srq(struct ib_pd *pd, struct mlx4_ib_dev *dev = to_mdev(pd->device); struct mlx4_ib_srq *srq; struct mlx4_wqe_srq_next_seg *next; + struct mlx4_wqe_data_seg *scatter; int desc_size; int buf_size; int err; @@ -149,6 +150,11 @@ struct ib_srq *mlx4_ib_create_srq(struct ib_pd *pd, next = get_wqe(srq, i); next->next_wqe_index = cpu_to_be16((i + 1) & (srq->msrq.max - 1)); + + for (scatter = (void *) (next + 1); + (void *) scatter < (void *) next + desc_size; + ++scatter) + scatter->lkey = cpu_to_be32(MLX4_INVALID_LKEY); } err = mlx4_mtt_init(dev->dev, srq->buf.npages, srq->buf.page_shift, -- cgit v0.10.2 From 2b946077423270f065013c45d78522a5fb9542ca Mon Sep 17 00:00:00 2001 From: Or Gerlitz Date: Wed, 6 Jan 2010 12:51:30 -0800 Subject: IB/mlx4: Fix queue overflow check in post_recv In mlx4_ib_post_recv(), we should check the queue for overflow using recv_cq instead of send_cq (current code looks like a copy-and-paste mistake). Signed-off-by: Or Gerlitz Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index 989555c..2a97c96 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c @@ -1752,7 +1752,7 @@ int mlx4_ib_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *wr, ind = qp->rq.head & (qp->rq.wqe_cnt - 1); for (nreq = 0; wr; ++nreq, wr = wr->next) { - if (mlx4_wq_overflow(&qp->rq, nreq, qp->ibqp.send_cq)) { + if (mlx4_wq_overflow(&qp->rq, nreq, qp->ibqp.recv_cq)) { err = -ENOMEM; *bad_wr = wr; goto out; -- cgit v0.10.2 From b4f77264cd1a858ee09da8dba5a2711a649adbf3 Mon Sep 17 00:00:00 2001 From: Eli Cohen Date: Wed, 6 Jan 2010 12:54:39 -0800 Subject: mlx4_core: Fix cleanup in __mlx4_init_one() error path If mlx4_init_port_info() fails, cleanup the initialized ports only. Signed-off-by: Eli Cohen Signed-off-by: Roland Dreier diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c index 291a505..3cf56d9 100644 --- a/drivers/net/mlx4/main.c +++ b/drivers/net/mlx4/main.c @@ -1174,7 +1174,7 @@ static int __mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id) return 0; err_port: - for (port = 1; port <= dev->caps.num_ports; port++) + for (--port; port >= 1; --port) mlx4_cleanup_port_info(&priv->port[port]); mlx4_cleanup_mcg_table(dev); -- cgit v0.10.2 From fd4582a3999e03fa9eae315bf14c88fd32d44035 Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Wed, 6 Jan 2010 13:16:30 -0800 Subject: IB/addr: Correct CONFIG_IPv6 to CONFIG_IPV6 Correct misspelled "CONFIG_IPv6" that was introduced in commit d14714df ("IB/addr: Fix IPv6 routing lookup"). The config variable should be all uppercase. Signed-off-by: Robert P. J. Day [ This was my fault when I munged the original patch. - Roland ] Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index fbdd731..cc9b594 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c @@ -2083,7 +2083,7 @@ static int cma_get_port(struct rdma_id_private *id_priv) static int cma_check_linklocal(struct rdma_dev_addr *dev_addr, struct sockaddr *addr) { -#if defined(CONFIG_IPv6) || defined(CONFIG_IPV6_MODULE) +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) struct sockaddr_in6 *sin6; if (addr->sa_family != AF_INET6) -- cgit v0.10.2 From 6c8530993e1fdf1d6af0403e796fe14d80b4b097 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 6 Jan 2010 17:26:27 -0500 Subject: sunrpc: fix build-time warning Fix auth_gss printk format warning: net/sunrpc/auth_gss/auth_gss.c:660: warning: format '%ld' expects type 'long int', but argument 3 has type 'ssize_t' Signed-off-by: Randy Dunlap Acked-by: Jeff Layton Signed-off-by: Trond Myklebust diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 66cb89c..f7a7f83 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c @@ -657,7 +657,7 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) break; default: printk(KERN_CRIT "%s: bad return from " - "gss_fill_context: %ld\n", __func__, err); + "gss_fill_context: %zd\n", __func__, err); BUG(); } goto err_release_msg; -- cgit v0.10.2 From 7211a4e859ad070b28545c06e0a6cb60b3b8aa31 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 25 Dec 2009 17:44:45 +0100 Subject: nfsd: make sure data is on disk before calling ->fsync nfsd is not using vfs_fsync, so I missed it when changing the calling convention during the 2.6.32 window. This patch fixes it to not only start the data writeout, but also wait for it to complete before calling into ->fsync. Signed-off-by: Christoph Hellwig Cc: stable@kernel.org Signed-off-by: J. Bruce Fields diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index e3ef3ec..d5fe17c 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -782,12 +782,9 @@ static inline int nfsd_dosync(struct file *filp, struct dentry *dp, int (*fsync) (struct file *, struct dentry *, int); int err; - err = filemap_fdatawrite(inode->i_mapping); + err = filemap_write_and_wait(inode->i_mapping); if (err == 0 && fop && (fsync = fop->fsync)) err = fsync(filp, dp, 0); - if (err == 0) - err = filemap_fdatawait(inode->i_mapping); - return err; } -- cgit v0.10.2 From b292cf9ce70d221c3f04ff62db5ab13d9a249ca8 Mon Sep 17 00:00:00 2001 From: Xiaotian Feng Date: Thu, 31 Dec 2009 10:52:36 +0800 Subject: sunrpc: fix peername failed on closed listener There're some warnings of "nfsd: peername failed (err 107)!" socket error -107 means Transport endpoint is not connected. This warning message was outputed by svc_tcp_accept() [net/sunrpc/svcsock.c], when kernel_getpeername returns -107. This means socket might be CLOSED. And svc_tcp_accept was called by svc_recv() [net/sunrpc/svc_xprt.c] if (test_bit(XPT_LISTENER, &xprt->xpt_flags)) { newxpt = xprt->xpt_ops->xpo_accept(xprt); So this might happen when xprt->xpt_flags has both XPT_LISTENER and XPT_CLOSE. Let's take a look at commit b0401d72, this commit has moved the close processing after do recvfrom method, but this commit also introduces this warnings, if the xpt_flags has both XPT_LISTENER and XPT_CLOSED, we should close it, not accpet then close. Signed-off-by: Xiaotian Feng Cc: J. Bruce Fields Cc: Neil Brown Cc: Trond Myklebust Cc: David S. Miller Cc: stable@kernel.org Signed-off-by: J. Bruce Fields diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index 2c58b75..810ffe8 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c @@ -699,7 +699,8 @@ int svc_recv(struct svc_rqst *rqstp, long timeout) spin_unlock_bh(&pool->sp_lock); len = 0; - if (test_bit(XPT_LISTENER, &xprt->xpt_flags)) { + if (test_bit(XPT_LISTENER, &xprt->xpt_flags) && + !test_bit(XPT_CLOSE, &xprt->xpt_flags)) { struct svc_xprt *newxpt; newxpt = xprt->xpt_ops->xpo_accept(xprt); if (newxpt) { -- cgit v0.10.2 From 1d1e9f04216b379000128392b11edd7f5d0ebed1 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Wed, 6 Jan 2010 15:55:12 +1100 Subject: [IA64] cpumask_of_node() should handle -1 as a node pcibus_to_node can return -1 if we cannot determine which node a pci bus is on. If passed -1, cpumask_of_node will negatively index the lookup array and pull in random data: # cat /sys/devices/pci0000:00/0000:00:01.0/local_cpus 00000000,00000003,00000000,00000000 # cat /sys/devices/pci0000:00/0000:00:01.0/local_cpulist 64-65 Change cpumask_of_node to check for -1 and return cpu_all_mask in this case: # cat /sys/devices/pci0000:00/0000:00:01.0/local_cpus ffffffff,ffffffff,ffffffff,ffffffff # cat /sys/devices/pci0000:00/0000:00:01.0/local_cpulist 0-127 Signed-off-by: Anton Blanchard Signed-off-by: Tony Luck diff --git a/arch/ia64/include/asm/topology.h b/arch/ia64/include/asm/topology.h index 3ddb4e7..d323071 100644 --- a/arch/ia64/include/asm/topology.h +++ b/arch/ia64/include/asm/topology.h @@ -33,7 +33,9 @@ /* * Returns a bitmask of CPUs on Node 'node'. */ -#define cpumask_of_node(node) (&node_to_cpu_mask[node]) +#define cpumask_of_node(node) ((node) == -1 ? \ + cpu_all_mask : \ + &node_to_cpu_mask[node]) /* * Returns the number of the node containing Node 'nid'. -- cgit v0.10.2 From 56335936de1a41c8978fde62b2158af77ddc7258 Mon Sep 17 00:00:00 2001 From: OGAWA Hirofumi Date: Wed, 6 Jan 2010 18:48:26 -0500 Subject: nfs: fix oops in nfs_rename() Recent change is missing to update "rehash". With that change, it will become the cause of adding dentry to hash twice. This explains the reason of Oops (dereference the freed dentry in __d_lookup()) on my machine. Signed-off-by: OGAWA Hirofumi Reported-by: Marvin Cc: Trond Myklebust Signed-off-by: Andrew Morton Signed-off-by: Trond Myklebust diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 2c5ace4..3c7f03b 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -1615,6 +1615,7 @@ static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry, goto out; new_dentry = dentry; + rehash = NULL; new_inode = NULL; } } -- cgit v0.10.2 From 02b763b8ccc88d030117851f2b76a119932f109e Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 6 Jan 2010 16:24:30 +0100 Subject: [IA64] use helpers for rlimits Make sure compiler won't do weird things with limits. E.g. fetching them twice may return 2 different values after writable limits are implemented. I.e. either use rlimit helpers added in 3e10e716abf3c71bdb5d86b8f507f9e72236c9cd or ACCESS_ONCE if not applicable. Signed-off-by: Jiri Slaby Cc: Fenghua Yu Signed-off-by: Tony Luck diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index 5246285..6bcbe21 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c @@ -2293,7 +2293,7 @@ pfm_smpl_buffer_alloc(struct task_struct *task, struct file *filp, pfm_context_t * if ((mm->total_vm << PAGE_SHIFT) + len> task->rlim[RLIMIT_AS].rlim_cur) * return -ENOMEM; */ - if (size > task->signal->rlim[RLIMIT_MEMLOCK].rlim_cur) + if (size > task_rlimit(task, RLIMIT_MEMLOCK)) return -ENOMEM; /* diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c index b9609c6..7c0d481 100644 --- a/arch/ia64/mm/init.c +++ b/arch/ia64/mm/init.c @@ -91,7 +91,7 @@ dma_mark_clean(void *addr, size_t size) inline void ia64_set_rbs_bot (void) { - unsigned long stack_size = current->signal->rlim[RLIMIT_STACK].rlim_max & -16; + unsigned long stack_size = rlimit_max(RLIMIT_STACK) & -16; if (stack_size > MAX_USER_STACK_SIZE) stack_size = MAX_USER_STACK_SIZE; -- cgit v0.10.2 From 410dc0aac63d1500faeabcbaecce4f4266380ed1 Mon Sep 17 00:00:00 2001 From: Tony Luck Date: Wed, 6 Jan 2010 15:52:35 -0800 Subject: [IA64] sanity in #include files. Move fnptr to types.h Signed-off-by: Tony Luck diff --git a/arch/ia64/include/asm/ftrace.h b/arch/ia64/include/asm/ftrace.h index d20db3c..fbd1a24 100644 --- a/arch/ia64/include/asm/ftrace.h +++ b/arch/ia64/include/asm/ftrace.h @@ -8,7 +8,6 @@ extern void _mcount(unsigned long pfs, unsigned long r1, unsigned long b0, unsigned long r0); #define mcount _mcount -#include /* In IA64, MCOUNT_ADDR is set in link time, so it's not a constant at compile time */ #define MCOUNT_ADDR (((struct fnptr *)mcount)->ip) #define FTRACE_ADDR (((struct fnptr *)ftrace_caller)->ip) diff --git a/arch/ia64/include/asm/kprobes.h b/arch/ia64/include/asm/kprobes.h index dbf83fb..d5505d6 100644 --- a/arch/ia64/include/asm/kprobes.h +++ b/arch/ia64/include/asm/kprobes.h @@ -103,11 +103,6 @@ typedef struct kprobe_opcode { bundle_t bundle; } kprobe_opcode_t; -struct fnptr { - unsigned long ip; - unsigned long gp; -}; - /* Architecture specific copy of original instruction*/ struct arch_specific_insn { /* copy of the instruction to be emulated */ diff --git a/arch/ia64/include/asm/types.h b/arch/ia64/include/asm/types.h index bcd260e..b8e5d97 100644 --- a/arch/ia64/include/asm/types.h +++ b/arch/ia64/include/asm/types.h @@ -30,6 +30,11 @@ typedef unsigned int umode_t; +struct fnptr { + unsigned long ip; + unsigned long gp; +}; + /* * These aren't exported outside the kernel to avoid name space clashes */ -- cgit v0.10.2 From 04e4f2b18c8de1389d1e00fef0f42a8099910daf Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 6 Jan 2010 17:23:17 +0000 Subject: FDPIC: Respect PT_GNU_STACK exec protection markings when creating NOMMU stack The current code will load the stack size and protection markings, but then only use the markings in the MMU code path. The NOMMU code path always passes PROT_EXEC to the mmap() call. While this doesn't matter to most people whilst the code is running, it will cause a pointless icache flush when starting every FDPIC application. Typically this icache flush will be of a region on the order of 128KB in size, or may be the entire icache, depending on the facilities available on the CPU. In the case where the arch default behaviour seems to be desired (EXSTACK_DEFAULT), we probe VM_STACK_FLAGS for VM_EXEC to determine whether we should be setting PROT_EXEC or not. For arches that support an MPU (Memory Protection Unit - an MMU without the virtual mapping capability), setting PROT_EXEC or not will make an important difference. It should be noted that this change also affects the executability of the brk region, since ELF-FDPIC has that share with the stack. However, this is probably irrelevant as NOMMU programs aren't likely to use the brk region, preferring instead allocation via mmap(). Signed-off-by: Mike Frysinger Signed-off-by: David Howells Signed-off-by: Linus Torvalds diff --git a/arch/blackfin/include/asm/page.h b/arch/blackfin/include/asm/page.h index 944a07c..1d04e40 100644 --- a/arch/blackfin/include/asm/page.h +++ b/arch/blackfin/include/asm/page.h @@ -10,4 +10,9 @@ #include #define MAP_NR(addr) (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT) +#define VM_DATA_DEFAULT_FLAGS \ + (VM_READ | VM_WRITE | \ + ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \ + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) + #endif diff --git a/arch/frv/include/asm/page.h b/arch/frv/include/asm/page.h index 25c6a50..8c97068 100644 --- a/arch/frv/include/asm/page.h +++ b/arch/frv/include/asm/page.h @@ -63,12 +63,10 @@ extern unsigned long max_pfn; #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) -#ifdef CONFIG_MMU #define VM_DATA_DEFAULT_FLAGS \ (VM_READ | VM_WRITE | \ ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) -#endif #endif /* __ASSEMBLY__ */ diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index 7dc8599..c57d9ce 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c @@ -171,6 +171,9 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm, #ifdef ELF_FDPIC_PLAT_INIT unsigned long dynaddr; #endif +#ifndef CONFIG_MMU + unsigned long stack_prot; +#endif struct file *interpreter = NULL; /* to shut gcc up */ char *interpreter_name = NULL; int executable_stack; @@ -316,6 +319,8 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm, * defunct, deceased, etc. after this point we have to exit via * error_kill */ set_personality(PER_LINUX_FDPIC); + if (elf_read_implies_exec(&exec_params.hdr, executable_stack)) + current->personality |= READ_IMPLIES_EXEC; set_binfmt(&elf_fdpic_format); current->mm->start_code = 0; @@ -377,9 +382,13 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm, if (stack_size < PAGE_SIZE * 2) stack_size = PAGE_SIZE * 2; + stack_prot = PROT_READ | PROT_WRITE; + if (executable_stack == EXSTACK_ENABLE_X || + (executable_stack == EXSTACK_DEFAULT && VM_STACK_FLAGS & VM_EXEC)) + stack_prot |= PROT_EXEC; + down_write(¤t->mm->mmap_sem); - current->mm->start_brk = do_mmap(NULL, 0, stack_size, - PROT_READ | PROT_WRITE | PROT_EXEC, + current->mm->start_brk = do_mmap(NULL, 0, stack_size, stack_prot, MAP_PRIVATE | MAP_ANONYMOUS | MAP_UNINITIALIZED | MAP_GROWSDOWN, 0); -- cgit v0.10.2 From cfe79c00a2f4f687eed8b7534d1d3d3d35540c29 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 6 Jan 2010 17:23:23 +0000 Subject: NOMMU: Avoiding duplicate icache flushes of shared maps When working with FDPIC, there are many shared mappings of read-only code regions between applications (the C library, applet packages like busybox, etc.), but the current do_mmap_pgoff() function will issue an icache flush whenever a VMA is added to an MM instead of only doing it when the map is initially created. The flush can instead be done when a region is first mmapped PROT_EXEC. Note that we may not rely on the first mapping of a region being executable - it's possible for it to be PROT_READ only, so we have to remember whether we've flushed the region or not, and then flush the entire region when a bit of it is made executable. However, this also affects the brk area. That will no longer be executable. We can mprotect() it to PROT_EXEC on MPU-mode kernels, but for NOMMU mode kernels, when it increases the brk allocation, making sys_brk() flush the extra from the icache should suffice. The brk area probably isn't used by NOMMU programs since the brk area can only use up the leavings from the stack allocation, where the stack allocation is larger than requested. Signed-off-by: David Howells Signed-off-by: Mike Frysinger Signed-off-by: Linus Torvalds diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 84a524a..84d020b 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -123,6 +123,8 @@ struct vm_region { struct file *vm_file; /* the backing file or NULL */ atomic_t vm_usage; /* region usage count */ + bool vm_icache_flushed : 1; /* true if the icache has been flushed for + * this region */ }; /* diff --git a/mm/nommu.c b/mm/nommu.c index 6f9248f..a8d1752 100644 --- a/mm/nommu.c +++ b/mm/nommu.c @@ -432,6 +432,7 @@ SYSCALL_DEFINE1(brk, unsigned long, brk) /* * Ok, looks good - let it rip. */ + flush_icache_range(mm->brk, brk); return mm->brk = brk; } @@ -1353,10 +1354,14 @@ unsigned long do_mmap_pgoff(struct file *file, share: add_vma_to_mm(current->mm, vma); - up_write(&nommu_region_sem); + /* we flush the region from the icache only when the first executable + * mapping of it is made */ + if (vma->vm_flags & VM_EXEC && !region->vm_icache_flushed) { + flush_icache_range(region->vm_start, region->vm_end); + region->vm_icache_flushed = true; + } - if (prot & PROT_EXEC) - flush_icache_range(result, result + len); + up_write(&nommu_region_sem); kleave(" = %lx", result); return result; -- cgit v0.10.2 From 7959722b951cffcd61a0a35229d007deeed8c2dd Mon Sep 17 00:00:00 2001 From: Jie Zhang Date: Wed, 6 Jan 2010 17:23:28 +0000 Subject: NOMMU: Use copy_*_user_page() in access_process_vm() The MMU code uses the copy_*_user_page() variants in access_process_vm() rather than copy_*_user() as the former includes an icache flush. This is important when doing things like setting software breakpoints with gdb. So switch the NOMMU code over to do the same. This patch makes the reasonable assumption that copy_from_user_page() won't fail - which is probably fine, as we've checked the VMA from which we're copying is usable, and the copy is not allowed to cross VMAs. The one case where it might go wrong is if the VMA is a device rather than RAM, and that device returns an error which - in which case rubbish will be returned rather than EIO. Signed-off-by: Jie Zhang Signed-off-by: Mike Frysinger Signed-off-by: David Howells Acked-by: David McCullough Acked-by: Paul Mundt Acked-by: Greg Ungerer Signed-off-by: Linus Torvalds diff --git a/mm/nommu.c b/mm/nommu.c index a8d1752..1777386 100644 --- a/mm/nommu.c +++ b/mm/nommu.c @@ -1921,9 +1921,11 @@ int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, in /* only read or write mappings where it is permitted */ if (write && vma->vm_flags & VM_MAYWRITE) - len -= copy_to_user((void *) addr, buf, len); + copy_to_user_page(vma, NULL, addr, + (void *) addr, buf, len); else if (!write && vma->vm_flags & VM_MAYREAD) - len -= copy_from_user(buf, (void *) addr, len); + copy_from_user_page(vma, NULL, addr, + buf, (void *) addr, len); else len = 0; } else { -- cgit v0.10.2 From 87d26d2d119953d07fdaa6435f324e8cb2e6f475 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Thu, 7 Jan 2010 11:05:55 +0900 Subject: ARM: S3C64XX: Fix possible clock look in EPLL and MPLL clock chains There is a possibility of a loop happening in the PLL output clock chain on the S3C64XX series. clk_mpll's parent was set to be clk_mout_mpll, but this is fed from clk_fout_epll (which is also clk_mpll). clk_mpll is meant to be the output from the MPLL, and clk_mout_mpll is a seperate clock derived from the mux of clk_mpll and clk_fin_mpll and thus should be considered a seperate clock. Anything using clk_mpll directly really should not be relying on this being the clock that is eventually routed to a peripheral, so remove the loop and ensure that the clocks accurately represent the clock chain in the device. The clk_mpll is not being used outside of the s3c6400-clock.c code, so this change should not break anything else. Do the same for the EPLL. Signed-off-by: Ben Dooks diff --git a/arch/arm/plat-s3c64xx/s3c6400-clock.c b/arch/arm/plat-s3c64xx/s3c6400-clock.c index 6ffa21e..ffd56de 100644 --- a/arch/arm/plat-s3c64xx/s3c6400-clock.c +++ b/arch/arm/plat-s3c64xx/s3c6400-clock.c @@ -46,6 +46,7 @@ static struct clk clk_ext_xtal_mux = { #define clk_fin_epll clk_ext_xtal_mux #define clk_fout_mpll clk_mpll +#define clk_fout_epll clk_epll struct clk_sources { unsigned int nr_sources; @@ -88,11 +89,6 @@ static struct clksrc_clk clk_mout_apll = { .sources = &clk_src_apll, }; -static struct clk clk_fout_epll = { - .name = "fout_epll", - .id = -1, -}; - static struct clk *clk_src_epll_list[] = { [0] = &clk_fin_epll, [1] = &clk_fout_epll, @@ -715,7 +711,6 @@ static struct clk *clks[] __initdata = { &clk_iis_cd1, &clk_pcm_cd, &clk_mout_epll.clk, - &clk_fout_epll, &clk_mout_mpll.clk, &clk_dout_mpll, &clk_mmc0.clk, @@ -760,7 +755,4 @@ void __init s3c6400_register_clocks(unsigned armclk_divlimit) clkp->name, ret); } } - - clk_mpll.parent = &clk_mout_mpll.clk; - clk_epll.parent = &clk_mout_epll.clk; } -- cgit v0.10.2 From e6be8d9d17bd44061116f601fe2609b3ace7aa69 Mon Sep 17 00:00:00 2001 From: Zhenyu Wang Date: Tue, 5 Jan 2010 11:25:05 +0800 Subject: drm: remove address mask param for drm_pci_alloc() drm_pci_alloc() has input of address mask for setting pci dma mask on the device, which should be properly setup by drm driver. And leave it as a param for drm_pci_alloc() would cause confusion or mistake would corrupt the correct dma mask setting, as seen on intel hw which set wrong dma mask for hw status page. So remove it from drm_pci_alloc() function. Signed-off-by: Zhenyu Wang Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/ati_pcigart.c b/drivers/gpu/drm/ati_pcigart.c index 628eae3..a1fce68 100644 --- a/drivers/gpu/drm/ati_pcigart.c +++ b/drivers/gpu/drm/ati_pcigart.c @@ -39,8 +39,7 @@ static int drm_ati_alloc_pcigart_table(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info) { gart_info->table_handle = drm_pci_alloc(dev, gart_info->table_size, - PAGE_SIZE, - gart_info->table_mask); + PAGE_SIZE); if (gart_info->table_handle == NULL) return -ENOMEM; @@ -112,6 +111,13 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) { DRM_DEBUG("PCI: no table in VRAM: using normal RAM\n"); + if (pci_set_dma_mask(dev->pdev, gart_info->table_mask)) { + DRM_ERROR("fail to set dma mask to 0x%Lx\n", + gart_info->table_mask); + ret = 1; + goto done; + } + ret = drm_ati_alloc_pcigart_table(dev, gart_info); if (ret) { DRM_ERROR("cannot allocate PCI GART page!\n"); diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c index 3d09e30..8417cc4 100644 --- a/drivers/gpu/drm/drm_bufs.c +++ b/drivers/gpu/drm/drm_bufs.c @@ -326,7 +326,7 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset, * As we're limiting the address to 2^32-1 (or less), * casting it down to 32 bits is no problem, but we * need to point to a 64bit variable first. */ - dmah = drm_pci_alloc(dev, map->size, map->size, 0xffffffffUL); + dmah = drm_pci_alloc(dev, map->size, map->size); if (!dmah) { kfree(map); return -ENOMEM; @@ -885,7 +885,7 @@ int drm_addbufs_pci(struct drm_device * dev, struct drm_buf_desc * request) while (entry->buf_count < count) { - dmah = drm_pci_alloc(dev, PAGE_SIZE << page_order, 0x1000, 0xfffffffful); + dmah = drm_pci_alloc(dev, PAGE_SIZE << page_order, 0x1000); if (!dmah) { /* Set count correctly so we free the proper amount. */ diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c index 577094f..e68ebf9 100644 --- a/drivers/gpu/drm/drm_pci.c +++ b/drivers/gpu/drm/drm_pci.c @@ -47,8 +47,7 @@ /** * \brief Allocate a PCI consistent memory block, for DMA. */ -drm_dma_handle_t *drm_pci_alloc(struct drm_device * dev, size_t size, size_t align, - dma_addr_t maxaddr) +drm_dma_handle_t *drm_pci_alloc(struct drm_device * dev, size_t size, size_t align) { drm_dma_handle_t *dmah; #if 1 @@ -63,11 +62,6 @@ drm_dma_handle_t *drm_pci_alloc(struct drm_device * dev, size_t size, size_t ali if (align > size) return NULL; - if (pci_set_dma_mask(dev->pdev, maxaddr) != 0) { - DRM_ERROR("Setting pci dma mask failed\n"); - return NULL; - } - dmah = kmalloc(sizeof(drm_dma_handle_t), GFP_KERNEL); if (!dmah) return NULL; diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 701bfea..02607ed 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -123,7 +123,7 @@ static int i915_init_phys_hws(struct drm_device *dev) drm_i915_private_t *dev_priv = dev->dev_private; /* Program Hardware Status Page */ dev_priv->status_page_dmah = - drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff); + drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE); if (!dev_priv->status_page_dmah) { DRM_ERROR("Can not allocate hardware status page\n"); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 917b837..c7f0cbe 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4708,7 +4708,7 @@ int i915_gem_init_phys_object(struct drm_device *dev, phys_obj->id = id; - phys_obj->handle = drm_pci_alloc(dev, size, 0, 0xffffffff); + phys_obj->handle = drm_pci_alloc(dev, size, 0); if (!phys_obj->handle) { ret = -ENOMEM; goto kfree_obj; diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 71dafb6..ffac157 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -1408,7 +1408,7 @@ extern int drm_ati_pcigart_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info * gart_info); extern drm_dma_handle_t *drm_pci_alloc(struct drm_device *dev, size_t size, - size_t align, dma_addr_t maxaddr); + size_t align); extern void __drm_pci_free(struct drm_device *dev, drm_dma_handle_t * dmah); extern void drm_pci_free(struct drm_device *dev, drm_dma_handle_t * dmah); -- cgit v0.10.2 From 69da301589b579f9619475e30cc449df9193410c Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Mon, 4 Jan 2010 17:53:06 -0500 Subject: drm/edid: Skip empty CVT codepoints Signed-off-by: Adam Jackson Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 5c9f798..7d6ac22 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -911,11 +911,15 @@ static int drm_cvt_modes(struct drm_connector *connector, struct drm_device *dev = connector->dev; struct cvt_timing *cvt; const int rates[] = { 60, 85, 75, 60, 50 }; + const u8 empty[3] = { 0, 0, 0 }; for (i = 0; i < 4; i++) { int uninitialized_var(width), height; cvt = &(timing->data.other_data.data.cvt[i]); + if (!memcmp(cvt->code, empty, 3)) + continue; + height = (cvt->code[0] + ((cvt->code[1] & 0xf0) << 8) + 1) * 2; switch (cvt->code[1] & 0xc0) { case 0x00: -- cgit v0.10.2 From 8e10ee9a0da12c586d3397150e34a946507c23f3 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Mon, 4 Jan 2010 17:53:07 -0500 Subject: drm/edid: Fix CVT width/height decode Signed-off-by: Adam Jackson Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 7d6ac22..defcaf1 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -920,18 +920,18 @@ static int drm_cvt_modes(struct drm_connector *connector, if (!memcmp(cvt->code, empty, 3)) continue; - height = (cvt->code[0] + ((cvt->code[1] & 0xf0) << 8) + 1) * 2; - switch (cvt->code[1] & 0xc0) { + height = (cvt->code[0] + ((cvt->code[1] & 0xf0) << 4) + 1) * 2; + switch (cvt->code[1] & 0x0c) { case 0x00: width = height * 4 / 3; break; - case 0x40: + case 0x04: width = height * 16 / 9; break; - case 0x80: + case 0x08: width = height * 16 / 10; break; - case 0xc0: + case 0x0c: width = height * 15 / 9; break; } -- cgit v0.10.2 From e89a8c901ca94a47c0e0b2fb335623d810e37545 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Thu, 31 Dec 2009 13:06:29 +0100 Subject: drm/kms: Fix &&/|| confusion in drm_fb_helper_connector_parse_command_line() This always evaluates to true. Signed-off-by: Roel Kluin Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 1b49fa0..100ee48 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -156,7 +156,7 @@ static bool drm_fb_helper_connector_parse_command_line(struct drm_connector *con force = DRM_FORCE_ON; break; case 'D': - if ((connector->connector_type != DRM_MODE_CONNECTOR_DVII) || + if ((connector->connector_type != DRM_MODE_CONNECTOR_DVII) && (connector->connector_type != DRM_MODE_CONNECTOR_HDMIB)) force = DRM_FORCE_ON; else -- cgit v0.10.2 From 5eb226132f53d5ec36ce4e7ff9d6b49cceb50f3d Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 6 Jan 2010 17:39:31 +0100 Subject: drm/radeon/kms: fix memory leak Stanse found a memory leak in radeon_master_create. master_priv is not freed/assigned on all paths. Fix that. Signed-off-by: Jiri Slaby Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c index 0b2f9c2..06123ba 100644 --- a/drivers/gpu/drm/radeon/radeon_cp.c +++ b/drivers/gpu/drm/radeon/radeon_cp.c @@ -2145,6 +2145,7 @@ int radeon_master_create(struct drm_device *dev, struct drm_master *master) &master_priv->sarea); if (ret) { DRM_ERROR("SAREA setup failed\n"); + kfree(master_priv); return ret; } master_priv->sarea_priv = master_priv->sarea->handle + sizeof(struct drm_sarea); -- cgit v0.10.2 From d8a7f79246a447722bd90c2c4ba3ca068b2aa4c0 Mon Sep 17 00:00:00 2001 From: Darren Jenkins Date: Wed, 30 Dec 2009 12:22:55 +1100 Subject: drm/radeon/radeon_connectors.c: add a NULL test before dereference The encoder variable can be NULL in this function so I believe it should be checked before dereference. Coverity CID: 13253 [airlied: extremely unlikely to happen] Signed-off-by: Darren Jenkins Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 2016156..b82ae61 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -615,7 +615,7 @@ static enum drm_connector_status radeon_vga_detect(struct drm_connector *connect ret = connector_status_connected; } } else { - if (radeon_connector->dac_load_detect) { + if (radeon_connector->dac_load_detect && encoder) { encoder_funcs = encoder->helper_private; ret = encoder_funcs->detect(encoder, connector); } -- cgit v0.10.2 From 3655d54af8dd85788c3e5088387469703a0f8f12 Mon Sep 17 00:00:00 2001 From: Darren Jenkins Date: Wed, 30 Dec 2009 12:20:05 +1100 Subject: drm/radeon/radeon_fence.c: move a dereference below the NULL test If a NULL value is possible, the dereference should only occur after the NULL test. Coverity CID: 13334 Signed-off-by: Darren Jenkins Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index 4cdd8b4..8495d4e 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c @@ -140,16 +140,15 @@ int radeon_fence_create(struct radeon_device *rdev, struct radeon_fence **fence) bool radeon_fence_signaled(struct radeon_fence *fence) { - struct radeon_device *rdev = fence->rdev; unsigned long irq_flags; bool signaled = false; - if (rdev->gpu_lockup) { + if (!fence) return true; - } - if (fence == NULL) { + + if (fence->rdev->gpu_lockup) return true; - } + write_lock_irqsave(&fence->rdev->fence_drv.lock, irq_flags); signaled = fence->signaled; /* if we are shuting down report all fence as signaled */ -- cgit v0.10.2 From 875c186620e017e62b773c93e46af21bb704fe6b Mon Sep 17 00:00:00 2001 From: Darren Jenkins Date: Wed, 30 Dec 2009 12:18:30 +1100 Subject: drm/radeon/radeon_device.c: move a dereference below a NULL test If a NULL value is possible, the dereference should only occur after the NULL test. Coverity CID: 13335 Signed-off-by: Darren Jenkins Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 7c68480..0c51f8e 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -733,16 +733,18 @@ void radeon_device_fini(struct radeon_device *rdev) */ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state) { - struct radeon_device *rdev = dev->dev_private; + struct radeon_device *rdev; struct drm_crtc *crtc; int r; - if (dev == NULL || rdev == NULL) { + if (dev == NULL || dev->dev_private == NULL) { return -ENODEV; } if (state.event == PM_EVENT_PRETHAW) { return 0; } + rdev = dev->dev_private; + /* unpin the front buffers */ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { struct radeon_framebuffer *rfb = to_radeon_framebuffer(crtc->fb); -- cgit v0.10.2 From 65aa2f4e8d85b6145ef4834f440a63ab68bd7443 Mon Sep 17 00:00:00 2001 From: Darren Jenkins Date: Wed, 30 Dec 2009 12:16:35 +1100 Subject: gpu/drm/radeon/radeon_irq.c: move a dereference below a NULL test If a NULL value is possible, the dereference should only occur after the NULL test. Coverity CID: 13338 Signed-off-by: Darren Jenkins Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/radeon_irq.c b/drivers/gpu/drm/radeon/radeon_irq.c index b79ecc4..2f349a3 100644 --- a/drivers/gpu/drm/radeon/radeon_irq.c +++ b/drivers/gpu/drm/radeon/radeon_irq.c @@ -289,16 +289,16 @@ int radeon_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_pr drm_radeon_irq_emit_t *emit = data; int result; - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - return -EINVAL; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - if (!dev_priv) { DRM_ERROR("called with no initialization\n"); return -EINVAL; } + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + return -EINVAL; + + LOCK_TEST_WITH_RETURN(dev, file_priv); + result = radeon_emit_irq(dev); if (DRM_COPY_TO_USER(emit->irq_seq, &result, sizeof(int))) { -- cgit v0.10.2 From 43b19f161c7a9941e3aa7db0e3ee19b93980e3d7 Mon Sep 17 00:00:00 2001 From: Luca Tettamanti Date: Mon, 28 Dec 2009 22:53:05 +0100 Subject: drm/radeon/kms: rs600: use correct mask for SW interrupt The mask happens to be the same, but the IH is reading the status, not the not the control register. Signed-off-by: Luca Tettamanti Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 4f8ea42..4245218 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c @@ -396,7 +396,7 @@ int rs600_irq_process(struct radeon_device *rdev) } while (status || r500_disp_int) { /* SW interrupt */ - if (G_000040_SW_INT_EN(status)) + if (G_000044_SW_INT(status)) radeon_fence_process(rdev); /* Vertical blank interrupts */ if (G_007EDC_LB_D1_VBLANK_INTERRUPT(r500_disp_int)) -- cgit v0.10.2 From 58933c643f86651decc4818cf680f9ec3b0460d2 Mon Sep 17 00:00:00 2001 From: Dave Liu Date: Wed, 6 Jan 2010 20:32:38 -0800 Subject: ucc_geth: Fix the wrong the Rx/Tx FIFO size current the Rx/Tx FIFO size settings cause problem when four UEC ethernets work simultaneously. eg: GETH1, UEM-J15, GETH2, UEC-J5 on 8569MDS board $ ifconfig eth0 10.193.20.166 $ ifconfig eth1 10.193.20.167 $ ifconfig eth2 10.193.20.168 then $ ifconfig eth3 10.193.20.169 The fourth ethernet will cause all of interface broken, you cann't ping successfully any more. The patch fix this issue for MPC8569 Rev1.0 and Rev2.0 Signed-off-by: Dave Liu Acked-by: Anton Vorontsov Signed-off-by: David S. Miller diff --git a/drivers/net/ucc_geth.h b/drivers/net/ucc_geth.h index a007e2a..ef1fbeb 100644 --- a/drivers/net/ucc_geth.h +++ b/drivers/net/ucc_geth.h @@ -838,13 +838,13 @@ struct ucc_geth_hardware_statistics { using the maximum is easier */ #define UCC_GETH_SEND_QUEUE_QUEUE_DESCRIPTOR_ALIGNMENT 32 -#define UCC_GETH_SCHEDULER_ALIGNMENT 4 /* This is a guess */ +#define UCC_GETH_SCHEDULER_ALIGNMENT 8 /* This is a guess */ #define UCC_GETH_TX_STATISTICS_ALIGNMENT 4 /* This is a guess */ #define UCC_GETH_RX_STATISTICS_ALIGNMENT 4 /* This is a guess */ #define UCC_GETH_RX_INTERRUPT_COALESCING_ALIGNMENT 64 #define UCC_GETH_RX_BD_QUEUES_ALIGNMENT 8 /* This is a guess */ #define UCC_GETH_RX_PREFETCHED_BDS_ALIGNMENT 128 /* This is a guess */ -#define UCC_GETH_RX_EXTENDED_FILTERING_GLOBAL_PARAMETERS_ALIGNMENT 4 /* This +#define UCC_GETH_RX_EXTENDED_FILTERING_GLOBAL_PARAMETERS_ALIGNMENT 8 /* This is a guess */ @@ -899,16 +899,17 @@ struct ucc_geth_hardware_statistics { #define UCC_GETH_UTFS_INIT 512 /* Tx virtual FIFO size */ #define UCC_GETH_UTFET_INIT 256 /* 1/2 utfs */ -#define UCC_GETH_UTFTT_INIT 128 +#define UCC_GETH_UTFTT_INIT 512 /* Gigabit Ethernet (1000 Mbps) */ #define UCC_GETH_URFS_GIGA_INIT 4096/*2048*/ /* Rx virtual FIFO size */ #define UCC_GETH_URFET_GIGA_INIT 2048/*1024*/ /* 1/2 urfs */ #define UCC_GETH_URFSET_GIGA_INIT 3072/*1536*/ /* 3/4 urfs */ -#define UCC_GETH_UTFS_GIGA_INIT 8192/*2048*/ /* Tx virtual +#define UCC_GETH_UTFS_GIGA_INIT 4096/*2048*/ /* Tx virtual + FIFO size */ +#define UCC_GETH_UTFET_GIGA_INIT 2048/*1024*/ /* 1/2 utfs */ +#define UCC_GETH_UTFTT_GIGA_INIT 4096/*0x40*/ /* Tx virtual FIFO size */ -#define UCC_GETH_UTFET_GIGA_INIT 4096/*1024*/ /* 1/2 utfs */ -#define UCC_GETH_UTFTT_GIGA_INIT 0x400/*0x40*/ /* */ #define UCC_GETH_REMODER_INIT 0 /* bits that must be set */ -- cgit v0.10.2 From 7ad6848c7e81a603605fad3f3575841aab004eea Mon Sep 17 00:00:00 2001 From: Octavian Purdila Date: Wed, 6 Jan 2010 20:37:01 -0800 Subject: ip: fix mc_loop checks for tunnels with multicast outer addresses When we have L3 tunnels with different inner/outer families (i.e. IPV4/IPV6) which use a multicast address as the outer tunnel destination address, multicast packets will be loopbacked back to the sending socket even if IP*_MULTICAST_LOOP is set to disabled. The mc_loop flag is present in the family specific part of the socket (e.g. the IPv4 or IPv4 specific part). setsockopt sets the inner family mc_loop flag. When the packet is pushed through the L3 tunnel it will eventually be processed by the outer family which if different will check the flag in a different part of the socket then it was set. Signed-off-by: Octavian Purdila Signed-off-by: David S. Miller diff --git a/include/net/ip.h b/include/net/ip.h index 85108cf..d9a0e74 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -326,6 +326,22 @@ static __inline__ void inet_reset_saddr(struct sock *sk) #endif +static inline int sk_mc_loop(struct sock *sk) +{ + if (!sk) + return 1; + switch (sk->sk_family) { + case AF_INET: + return inet_sk(sk)->mc_loop; +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + case AF_INET6: + return inet6_sk(sk)->mc_loop; +#endif + } + __WARN(); + return 1; +} + extern int ip_call_ra_chain(struct sk_buff *skb); /* diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index e34013a..3451799 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -254,7 +254,7 @@ int ip_mc_output(struct sk_buff *skb) */ if (rt->rt_flags&RTCF_MULTICAST) { - if ((!sk || inet_sk(sk)->mc_loop) + if (sk_mc_loop(sk) #ifdef CONFIG_IP_MROUTE /* Small optimization: do not loopback not local frames, which returned after forwarding; they will be dropped diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index cd48801a..eb6d097 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -121,10 +121,9 @@ static int ip6_output2(struct sk_buff *skb) skb->dev = dev; if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr)) { - struct ipv6_pinfo* np = skb->sk ? inet6_sk(skb->sk) : NULL; struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb)); - if (!(dev->flags & IFF_LOOPBACK) && (!np || np->mc_loop) && + if (!(dev->flags & IFF_LOOPBACK) && sk_mc_loop(skb->sk) && ((mroute6_socket(dev_net(dev)) && !(IP6CB(skb)->flags & IP6SKB_FORWARDED)) || ipv6_chk_mcast_addr(dev, &ipv6_hdr(skb)->daddr, -- cgit v0.10.2 From abe8806901086b6cb29b4d4d4c616bbff3f0e7e1 Mon Sep 17 00:00:00 2001 From: Ken Kawasaki Date: Wed, 6 Jan 2010 20:37:58 -0800 Subject: pcnet_cs: add cis of KTI PE520 pcmcia network card pcnet_cs,serial_cs: add cis of KTI PE520 pcmcia network card, and serial card(Sierra Wireless AC860). Signed-off-by: Ken Kawasaki Signed-off-by: David S. Miller diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index 2d26b6c..c2651ae 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c @@ -1741,7 +1741,7 @@ static struct pcmcia_device_id pcnet_ids[] = { PCMCIA_MFC_DEVICE_CIS_PROD_ID4(0, "NSC MF LAN/Modem", 0x58fc6056, "cis/DP83903.cis"), PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0175, 0x0000, "cis/DP83903.cis"), PCMCIA_DEVICE_CIS_MANF_CARD(0xc00f, 0x0002, "cis/LA-PCM.cis"), - PCMCIA_DEVICE_CIS_PROD_ID12("KTI", "PE520 PLUS", 0xad180345, 0x9d58d392, "PE520.cis"), + PCMCIA_DEVICE_CIS_PROD_ID12("KTI", "PE520 PLUS", 0xad180345, 0x9d58d392, "cis/PE520.cis"), PCMCIA_DEVICE_CIS_PROD_ID12("NDC", "Ethernet", 0x01c43ae1, 0x00b2e941, "cis/NE2K.cis"), PCMCIA_DEVICE_CIS_PROD_ID12("PMX ", "PE-200", 0x34f3f1c8, 0x10b59f8c, "cis/PE-200.cis"), PCMCIA_DEVICE_CIS_PROD_ID12("TAMARACK", "Ethernet", 0xcf434fba, 0x00b2e941, "cis/tamarack.cis"), @@ -1754,7 +1754,7 @@ MODULE_DEVICE_TABLE(pcmcia, pcnet_ids); MODULE_FIRMWARE("cis/PCMLM28.cis"); MODULE_FIRMWARE("cis/DP83903.cis"); MODULE_FIRMWARE("cis/LA-PCM.cis"); -MODULE_FIRMWARE("PE520.cis"); +MODULE_FIRMWARE("cis/PE520.cis"); MODULE_FIRMWARE("cis/NE2K.cis"); MODULE_FIRMWARE("cis/PE-200.cis"); MODULE_FIRMWARE("cis/tamarack.cis"); diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c index fc413f0..0ee7239 100644 --- a/drivers/serial/serial_cs.c +++ b/drivers/serial/serial_cs.c @@ -819,6 +819,7 @@ static struct pcmcia_device_id serial_ids[] = { PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0035, "cis/3CXEM556.cis"), PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x003d, "cis/3CXEM556.cis"), PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC850", 0xd85f6206, 0x42a2c018, "cis/SW_8xx_SER.cis"), /* Sierra Wireless AC850 3G Network Adapter R1 */ + PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC860", 0xd85f6206, 0x698f93db, "cis/SW_8xx_SER.cis"), /* Sierra Wireless AC860 3G Network Adapter R1 */ PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC710/AC750", 0xd85f6206, 0x761b11e0, "cis/SW_7xx_SER.cis"), /* Sierra Wireless AC710/AC750 GPRS Network Adapter R1 */ PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0xa555, "cis/SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- pre update */ PCMCIA_DEVICE_CIS_MANF_CARD(0x013f, 0xa555, "cis/SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- post update */ @@ -827,7 +828,7 @@ static struct pcmcia_device_id serial_ids[] = { PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-4", 0x96913a85, 0xcec8f102, "cis/COMpad4.cis"), PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH", "COMpad-32/85", "1.0", 0x96913a85, 0x8fbe92ae, 0x0877b627, "cis/COMpad2.cis"), PCMCIA_DEVICE_CIS_PROD_ID2("RS-COM 2P", 0xad20b156, "cis/RS-COM-2P.cis"), - PCMCIA_DEVICE_CIS_MANF_CARD(0x0013, 0x0000, "GLOBETROTTER.cis"), + PCMCIA_DEVICE_CIS_MANF_CARD(0x0013, 0x0000, "cis/GLOBETROTTER.cis"), PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL100 1.00.",0x19ca78af,0xf964f42b), PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL100",0x19ca78af,0x71d98e83), PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL232 1.00.",0x19ca78af,0x69fb7490), @@ -861,6 +862,18 @@ static struct pcmcia_device_id serial_ids[] = { }; MODULE_DEVICE_TABLE(pcmcia, serial_ids); +MODULE_FIRMWARE("cis/PCMLM28.cis"); +MODULE_FIRMWARE("cis/DP83903.cis"); +MODULE_FIRMWARE("cis/3CCFEM556.cis"); +MODULE_FIRMWARE("cis/3CXEM556.cis"); +MODULE_FIRMWARE("cis/SW_8xx_SER.cis"); +MODULE_FIRMWARE("cis/SW_7xx_SER.cis"); +MODULE_FIRMWARE("cis/SW_555_SER.cis"); +MODULE_FIRMWARE("cis/MT5634ZLX.cis"); +MODULE_FIRMWARE("cis/COMpad2.cis"); +MODULE_FIRMWARE("cis/COMpad4.cis"); +MODULE_FIRMWARE("cis/RS-COM-2P.cis"); + static struct pcmcia_driver serial_cs_driver = { .owner = THIS_MODULE, .drv = { diff --git a/firmware/Makefile b/firmware/Makefile index 6d5c3ab..1c00d05 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -69,7 +69,8 @@ fw-shipped-$(CONFIG_E100) += e100/d101m_ucode.bin e100/d101s_ucode.bin \ fw-shipped-$(CONFIG_MYRI_SBUS) += myricom/lanai.bin fw-shipped-$(CONFIG_PCMCIA_PCNET) += cis/LA-PCM.cis cis/PCMLM28.cis \ cis/DP83903.cis cis/NE2K.cis \ - cis/tamarack.cis cis/PE-200.cis + cis/tamarack.cis cis/PE-200.cis \ + cis/PE520.cis fw-shipped-$(CONFIG_PCMCIA_3C589) += cis/3CXEM556.cis fw-shipped-$(CONFIG_PCMCIA_3C574) += cis/3CCFEM556.cis fw-shipped-$(CONFIG_SERIAL_8250_CS) += cis/MT5634ZLX.cis cis/RS-COM-2P.cis \ diff --git a/firmware/WHENCE b/firmware/WHENCE index 34b5d0a..ac174fe 100644 --- a/firmware/WHENCE +++ b/firmware/WHENCE @@ -601,6 +601,7 @@ File: cis/LA-PCM.cis cis/NE2K.cis cis/tamarack.cis cis/PE-200.cis + cis/PE520.cis Licence: GPL diff --git a/firmware/cis/PE520.cis.ihex b/firmware/cis/PE520.cis.ihex new file mode 100644 index 0000000..97a745b --- /dev/null +++ b/firmware/cis/PE520.cis.ihex @@ -0,0 +1,9 @@ +:1000000001030000FF152304014B544900504535FE +:10001000323020504C55530050434D434941204508 +:10002000746865726E65740000FF20046101100041 +:10003000210206001A050101D00F0B1B09C101198D +:0A00400001556530FFFF1400FF00BA +:00000001FF +# +# Replacement CIS for PE520 ethernet card +# -- cgit v0.10.2 From d950d1775228e71ca557c86278ae54bd2bcd7c1a Mon Sep 17 00:00:00 2001 From: Ursula Braun Date: Mon, 4 Jan 2010 03:14:45 +0000 Subject: claw: use "claw" as root device name Claw module cannot be loaded together with qeth, because "qeth" has been errorneously used as root device name. It is changed into "claw". Signed-off-by: Ursula Braun Signed-off-by: David S. Miller diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c index 3c77bfe..147bb1a 100644 --- a/drivers/s390/net/claw.c +++ b/drivers/s390/net/claw.c @@ -3398,7 +3398,7 @@ claw_init(void) goto out_err; } CLAW_DBF_TEXT(2, setup, "init_mod"); - claw_root_dev = root_device_register("qeth"); + claw_root_dev = root_device_register("claw"); ret = IS_ERR(claw_root_dev) ? PTR_ERR(claw_root_dev) : 0; if (ret) goto register_err; -- cgit v0.10.2 From ec157937d9799cf30c9a19bd18be33721242c64f Mon Sep 17 00:00:00 2001 From: Jan Dumon Date: Tue, 5 Jan 2010 04:50:31 +0000 Subject: hso: Add Vendor/Product ID's for new devices Add product ID's for new devices. Signed-off-by: Jan Dumon Signed-off-by: David S. Miller diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index f78f090..eb930b2 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -461,10 +461,17 @@ static const struct usb_device_id hso_ids[] = { {USB_DEVICE(0x0af0, 0x7501)}, /* GTM 382 */ {USB_DEVICE(0x0af0, 0x7601)}, /* GE40x */ {USB_DEVICE(0x0af0, 0x7701)}, + {USB_DEVICE(0x0af0, 0x7706)}, {USB_DEVICE(0x0af0, 0x7801)}, {USB_DEVICE(0x0af0, 0x7901)}, + {USB_DEVICE(0x0af0, 0x7A01)}, + {USB_DEVICE(0x0af0, 0x7A05)}, {USB_DEVICE(0x0af0, 0x8200)}, {USB_DEVICE(0x0af0, 0x8201)}, + {USB_DEVICE(0x0af0, 0x8300)}, + {USB_DEVICE(0x0af0, 0x8302)}, + {USB_DEVICE(0x0af0, 0x8304)}, + {USB_DEVICE(0x0af0, 0x8400)}, {USB_DEVICE(0x0af0, 0xd035)}, {USB_DEVICE(0x0af0, 0xd055)}, {USB_DEVICE(0x0af0, 0xd155)}, @@ -473,6 +480,8 @@ static const struct usb_device_id hso_ids[] = { {USB_DEVICE(0x0af0, 0xd157)}, {USB_DEVICE(0x0af0, 0xd257)}, {USB_DEVICE(0x0af0, 0xd357)}, + {USB_DEVICE(0x0af0, 0xd058)}, + {USB_DEVICE(0x0af0, 0xc100)}, {} }; MODULE_DEVICE_TABLE(usb, hso_ids); -- cgit v0.10.2 From d9ced80d1084758772d350ac66b1ad0eeefc7f95 Mon Sep 17 00:00:00 2001 From: Jan Dumon Date: Tue, 5 Jan 2010 04:51:02 +0000 Subject: hso: Fix for endian issues on big endian machines Some fields are always little endian and have to be converted on big endian machines. Signed-off-by: Jan Dumon Signed-off-by: David S. Miller diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index eb930b2..aba90e7 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -1028,7 +1028,8 @@ static void read_bulk_callback(struct urb *urb) if (odev->parent->port_spec & HSO_INFO_CRC_BUG) { u32 rest; u8 crc_check[4] = { 0xDE, 0xAD, 0xBE, 0xEF }; - rest = urb->actual_length % odev->in_endp->wMaxPacketSize; + rest = urb->actual_length % + le16_to_cpu(odev->in_endp->wMaxPacketSize); if (((rest == 5) || (rest == 6)) && !memcmp(((u8 *) urb->transfer_buffer) + urb->actual_length - 4, crc_check, 4)) { @@ -1234,7 +1235,7 @@ static void hso_std_serial_read_bulk_callback(struct urb *urb) u8 crc_check[4] = { 0xDE, 0xAD, 0xBE, 0xEF }; rest = urb->actual_length % - serial->in_endp->wMaxPacketSize; + le16_to_cpu(serial->in_endp->wMaxPacketSize); if (((rest == 5) || (rest == 6)) && !memcmp(((u8 *) urb->transfer_buffer) + urb->actual_length - 4, crc_check, 4)) { @@ -2843,8 +2844,9 @@ struct hso_shared_int *hso_create_shared_int(struct usb_interface *interface) dev_err(&interface->dev, "Could not allocate intr urb?"); goto exit; } - mux->shared_intr_buf = kzalloc(mux->intr_endp->wMaxPacketSize, - GFP_KERNEL); + mux->shared_intr_buf = + kzalloc(le16_to_cpu(mux->intr_endp->wMaxPacketSize), + GFP_KERNEL); if (!mux->shared_intr_buf) { dev_err(&interface->dev, "Could not allocate intr buf?"); goto exit; @@ -3241,7 +3243,7 @@ static int hso_mux_submit_intr_urb(struct hso_shared_int *shared_int, usb_rcvintpipe(usb, shared_int->intr_endp->bEndpointAddress & 0x7F), shared_int->shared_intr_buf, - shared_int->intr_endp->wMaxPacketSize, + 1, intr_callback, shared_int, shared_int->intr_endp->bInterval); -- cgit v0.10.2 From f4763e96c08ea0790750603999e5b3158c3b50d4 Mon Sep 17 00:00:00 2001 From: Jan Dumon Date: Tue, 5 Jan 2010 04:51:28 +0000 Subject: hso: don't change the state of a closed port Don't change the state of a port if it's not open. This fixes an issue where a port sometimes has to be opened twice before data can be received. Signed-off-by: Jan Dumon Signed-off-by: David S. Miller diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index aba90e7..fb1c5ac 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -1915,18 +1915,18 @@ static void intr_callback(struct urb *urb) if (serial != NULL) { D1("Pending read interrupt on port %d\n", i); spin_lock(&serial->serial_lock); - if (serial->rx_state == RX_IDLE) { + if (serial->rx_state == RX_IDLE && + serial->open_count > 0) { /* Setup and send a ctrl req read on * port i */ - if (!serial->rx_urb_filled[0]) { + if (!serial->rx_urb_filled[0]) { serial->rx_state = RX_SENT; hso_mux_serial_read(serial); } else serial->rx_state = RX_PENDING; - } else { - D1("Already pending a read on " - "port %d\n", i); + D1("Already a read pending on " + "port %d or port not open\n", i); } spin_unlock(&serial->serial_lock); } -- cgit v0.10.2 From 68a351c501ad22077a969df157cd13367cb43a40 Mon Sep 17 00:00:00 2001 From: Jan Dumon Date: Tue, 5 Jan 2010 04:52:13 +0000 Subject: hso: Attempt to recover from usb bus errors Attempt to reset the usb device when we receive usb bus errors. Signed-off-by: Jan Dumon Signed-off-by: David S. Miller diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index fb1c5ac..7482d0d 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -286,6 +286,7 @@ struct hso_device { u8 usb_gone; struct work_struct async_get_intf; struct work_struct async_put_intf; + struct work_struct reset_device; struct usb_device *usb; struct usb_interface *interface; @@ -332,7 +333,8 @@ static void hso_kick_transmit(struct hso_serial *serial); /* Helper functions */ static int hso_mux_submit_intr_urb(struct hso_shared_int *mux_int, struct usb_device *usb, gfp_t gfp); -static void log_usb_status(int status, const char *function); +static void handle_usb_error(int status, const char *function, + struct hso_device *hso_dev); static struct usb_endpoint_descriptor *hso_get_ep(struct usb_interface *intf, int type, int dir); static int hso_get_mux_ports(struct usb_interface *intf, unsigned char *ports); @@ -350,6 +352,7 @@ static void async_put_intf(struct work_struct *data); static int hso_put_activity(struct hso_device *hso_dev); static int hso_get_activity(struct hso_device *hso_dev); static void tiocmget_intr_callback(struct urb *urb); +static void reset_device(struct work_struct *data); /*****************************************************************************/ /* Helping functions */ /*****************************************************************************/ @@ -664,8 +667,8 @@ static void set_serial_by_index(unsigned index, struct hso_serial *serial) spin_unlock_irqrestore(&serial_table_lock, flags); } -/* log a meaningful explanation of an USB status */ -static void log_usb_status(int status, const char *function) +static void handle_usb_error(int status, const char *function, + struct hso_device *hso_dev) { char *explanation; @@ -694,10 +697,20 @@ static void log_usb_status(int status, const char *function) case -EMSGSIZE: explanation = "internal error"; break; + case -EILSEQ: + case -EPROTO: + case -ETIME: + case -ETIMEDOUT: + explanation = "protocol error"; + if (hso_dev) + schedule_work(&hso_dev->reset_device); + break; default: explanation = "unknown status"; break; } + + /* log a meaningful explanation of an USB status */ D1("%s: received USB status - %s (%d)", function, explanation, status); } @@ -771,7 +784,7 @@ static void write_bulk_callback(struct urb *urb) /* log status, but don't act on it, we don't need to resubmit anything * anyhow */ if (status) - log_usb_status(status, __func__); + handle_usb_error(status, __func__, odev->parent); hso_put_activity(odev->parent); @@ -1007,7 +1020,7 @@ static void read_bulk_callback(struct urb *urb) /* is al ok? (Filip: Who's Al ?) */ if (status) { - log_usb_status(status, __func__); + handle_usb_error(status, __func__, odev->parent); return; } @@ -1217,7 +1230,7 @@ static void hso_std_serial_read_bulk_callback(struct urb *urb) D1("serial == NULL"); return; } else if (status) { - log_usb_status(status, __func__); + handle_usb_error(status, __func__, serial->parent); return; } @@ -1523,7 +1536,7 @@ static void tiocmget_intr_callback(struct urb *urb) if (!serial) return; if (status) { - log_usb_status(status, __func__); + handle_usb_error(status, __func__, serial->parent); return; } tiocmget = serial->tiocmget; @@ -1898,7 +1911,7 @@ static void intr_callback(struct urb *urb) /* status check */ if (status) { - log_usb_status(status, __func__); + handle_usb_error(status, __func__, NULL); return; } D4("\n--- Got intr callback 0x%02X ---", status); @@ -1968,7 +1981,7 @@ static void hso_std_serial_write_bulk_callback(struct urb *urb) tty = tty_kref_get(serial->tty); spin_unlock(&serial->serial_lock); if (status) { - log_usb_status(status, __func__); + handle_usb_error(status, __func__, serial->parent); tty_kref_put(tty); return; } @@ -2024,7 +2037,7 @@ static void ctrl_callback(struct urb *urb) tty = tty_kref_get(serial->tty); spin_unlock(&serial->serial_lock); if (status) { - log_usb_status(status, __func__); + handle_usb_error(status, __func__, serial->parent); tty_kref_put(tty); return; } @@ -2401,6 +2414,7 @@ static struct hso_device *hso_create_device(struct usb_interface *intf, INIT_WORK(&hso_dev->async_get_intf, async_get_intf); INIT_WORK(&hso_dev->async_put_intf, async_put_intf); + INIT_WORK(&hso_dev->reset_device, reset_device); return hso_dev; } @@ -3143,6 +3157,26 @@ out: return result; } +static void reset_device(struct work_struct *data) +{ + struct hso_device *hso_dev = + container_of(data, struct hso_device, reset_device); + struct usb_device *usb = hso_dev->usb; + int result; + + if (hso_dev->usb_gone) { + D1("No reset during disconnect\n"); + } else { + result = usb_lock_device_for_reset(usb, hso_dev->interface); + if (result < 0) + D1("unable to lock device for reset: %d\n", result); + else { + usb_reset_device(usb); + usb_unlock_device(usb); + } + } +} + static void hso_serial_ref_free(struct kref *ref) { struct hso_device *hso_dev = container_of(ref, struct hso_device, ref); -- cgit v0.10.2 From 0e0367e980b55629917f3dd5f5f0ccbf3d0dab62 Mon Sep 17 00:00:00 2001 From: Jan Dumon Date: Tue, 5 Jan 2010 04:52:42 +0000 Subject: hso: Fix for 5 sec timeouts with v2.x firmware Don't send flow control settings to any port other than the modem port. Older firmware ignored this request but did sent a reply. Newer firmware just ignores it without reply and causes a 5 second timeout every time a port (except for the modem port) is opened or if tiocm settings are changed. Signed-off-by: Jan Dumon Signed-off-by: David S. Miller diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 7482d0d..67eb839 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -1723,6 +1723,10 @@ static int hso_serial_tiocmset(struct tty_struct *tty, struct file *file, D1("no tty structures"); return -EINVAL; } + + if ((serial->parent->port_spec & HSO_PORT_MASK) != HSO_PORT_MODEM) + return -EINVAL; + if_num = serial->parent->interface->altsetting->desc.bInterfaceNumber; spin_lock_irqsave(&serial->serial_lock, flags); -- cgit v0.10.2 From 8a5c9c4932ad1fbe9daa501e89a7357a2804e3fa Mon Sep 17 00:00:00 2001 From: Jan Dumon Date: Tue, 5 Jan 2010 04:53:00 +0000 Subject: hso: fixed missing newlines Fixed missing newlines in calls to dev_warn & dev_err. Signed-off-by: Jan Dumon Signed-off-by: David S. Miller diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 67eb839..6895f15 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -828,7 +828,7 @@ static netdev_tx_t hso_net_start_xmit(struct sk_buff *skb, result = usb_submit_urb(odev->mux_bulk_tx_urb, GFP_ATOMIC); if (result) { dev_warn(&odev->parent->interface->dev, - "failed mux_bulk_tx_urb %d", result); + "failed mux_bulk_tx_urb %d\n", result); net->stats.tx_errors++; netif_start_queue(net); } else { @@ -1076,7 +1076,7 @@ static void read_bulk_callback(struct urb *urb) result = usb_submit_urb(urb, GFP_ATOMIC); if (result) dev_warn(&odev->parent->interface->dev, - "%s failed submit mux_bulk_rx_urb %d", __func__, + "%s failed submit mux_bulk_rx_urb %d\n", __func__, result); } @@ -1865,7 +1865,7 @@ static int mux_device_request(struct hso_serial *serial, u8 type, u16 port, result = usb_submit_urb(ctrl_urb, GFP_ATOMIC); if (result) { dev_err(&ctrl_urb->dev->dev, - "%s failed submit ctrl_urb %d type %d", __func__, + "%s failed submit ctrl_urb %d type %d\n", __func__, result, type); return result; } @@ -2385,12 +2385,12 @@ static int hso_serial_common_create(struct hso_serial *serial, int num_urbs, serial->tx_data_length = tx_size; serial->tx_data = kzalloc(serial->tx_data_length, GFP_KERNEL); if (!serial->tx_data) { - dev_err(dev, "%s - Out of memory", __func__); + dev_err(dev, "%s - Out of memory\n", __func__); goto exit; } serial->tx_buffer = kzalloc(serial->tx_data_length, GFP_KERNEL); if (!serial->tx_buffer) { - dev_err(dev, "%s - Out of memory", __func__); + dev_err(dev, "%s - Out of memory\n", __func__); goto exit; } @@ -2859,14 +2859,14 @@ struct hso_shared_int *hso_create_shared_int(struct usb_interface *interface) mux->shared_intr_urb = usb_alloc_urb(0, GFP_KERNEL); if (!mux->shared_intr_urb) { - dev_err(&interface->dev, "Could not allocate intr urb?"); + dev_err(&interface->dev, "Could not allocate intr urb?\n"); goto exit; } mux->shared_intr_buf = kzalloc(le16_to_cpu(mux->intr_endp->wMaxPacketSize), GFP_KERNEL); if (!mux->shared_intr_buf) { - dev_err(&interface->dev, "Could not allocate intr buf?"); + dev_err(&interface->dev, "Could not allocate intr buf?\n"); goto exit; } @@ -3287,7 +3287,7 @@ static int hso_mux_submit_intr_urb(struct hso_shared_int *shared_int, result = usb_submit_urb(shared_int->shared_intr_urb, gfp); if (result) - dev_warn(&usb->dev, "%s failed mux_intr_urb %d", __func__, + dev_warn(&usb->dev, "%s failed mux_intr_urb %d\n", __func__, result); return result; -- cgit v0.10.2 From 569b7892fe09dd6502bdadb7cf5e7acce907c1a1 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 7 Jan 2010 00:53:05 -0800 Subject: cs89x0: Always report failure to request interrupt A failure on request_irq() is always fatal but unlike other fatal errors it's only reported to the user if net_debug is set. Make the diagnostic unconditional and raise the priority so that errors are more obvious to the user. Signed-off-by: Mark Brown Signed-off-by: David S. Miller diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c index af93216..0e79cef 100644 --- a/drivers/net/cs89x0.c +++ b/drivers/net/cs89x0.c @@ -1325,8 +1325,7 @@ net_open(struct net_device *dev) write_irq(dev, lp->chip_type, dev->irq); ret = request_irq(dev->irq, net_interrupt, 0, dev->name, dev); if (ret) { - if (net_debug) - printk(KERN_DEBUG "cs89x0: request_irq(%d) failed\n", dev->irq); + printk(KERN_ERR "cs89x0: request_irq(%d) failed\n", dev->irq); goto bad_out; } } -- cgit v0.10.2 From c91aa55e7e65be11d68dffb66be5f7a44506fb54 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Wed, 6 Jan 2010 13:05:46 +0000 Subject: pcmcia: ncmlan_cs: remove odd bracket Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c index 8a5ae3b..12e3233 100644 --- a/drivers/net/pcmcia/nmclan_cs.c +++ b/drivers/net/pcmcia/nmclan_cs.c @@ -1402,7 +1402,6 @@ static void BuildLAF(int *ladrf, int *adr) for (i = 0; i < 8; i++) printk(KERN_CONT " %02X", ladrf[i]); printk(KERN_CONT "\n"); - } #endif } /* BuildLAF */ -- cgit v0.10.2 From 2467ab9590092ffdf837e9283e84dedd04c93ab3 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 6 Jan 2010 06:54:16 +0000 Subject: NET: atlx, fix memory leak Stanse found a memory leak in atl2_get_eeprom. eeprom_buff is not freed/assigned on all paths. Fix that. Signed-off-by: Jiri Slaby Cc: Jay Cliburn Cc: Chris Snook Cc: Jie Yang Cc: atl1-devel@lists.sourceforge.net Cc: "David S. Miller" Cc: netdev@vger.kernel.org Signed-off-by: David S. Miller diff --git a/drivers/net/atlx/atl2.c b/drivers/net/atlx/atl2.c index c0451d7..ec52529 100644 --- a/drivers/net/atlx/atl2.c +++ b/drivers/net/atlx/atl2.c @@ -1959,12 +1959,15 @@ static int atl2_get_eeprom(struct net_device *netdev, return -ENOMEM; for (i = first_dword; i < last_dword; i++) { - if (!atl2_read_eeprom(hw, i*4, &(eeprom_buff[i-first_dword]))) - return -EIO; + if (!atl2_read_eeprom(hw, i*4, &(eeprom_buff[i-first_dword]))) { + ret_val = -EIO; + goto free; + } } memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 3), eeprom->len); +free: kfree(eeprom_buff); return ret_val; -- cgit v0.10.2 From 530e557ab268de154609f3cce2f2390e7b195af3 Mon Sep 17 00:00:00 2001 From: Saeed Bishara Date: Tue, 5 Jan 2010 09:15:32 +0000 Subject: mv643xx_eth: don't include cache padding in rx desc buffer size If NET_SKB_PAD is not a multiple of the cache line size, mv643xx_eth allocates a couple of extra bytes at the start of each receive buffer to make the data payload end up on a cache line boundary. These extra bytes are skb_reserve()'d before DMA mapping, so they should not be included in the DMA map byte count (as the mapping is done starting at skb->data), nor should they be included in the receive descriptor buffer size field, or the hardware can end up DMAing beyond the end of the buffer, which can happen if someone sends us a larger-than-MTU sized packet. This problem was introduced in commit 7fd96ce47ff ("mv643xx_eth: rework receive skb cache alignment", May 6 2009), but hasn't appeared to be problematic so far, probably as the main users of mv643xx_eth all have NET_SKB_PAD == L1_CACHE_BYTES. Signed-off-by: Saeed Bishara Signed-off-by: Lennert Buytenhek Signed-off-by: David S. Miller diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index 1405a17..af67af5 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c @@ -656,6 +656,7 @@ static int rxq_refill(struct rx_queue *rxq, int budget) struct sk_buff *skb; int rx; struct rx_desc *rx_desc; + int size; skb = __skb_dequeue(&mp->rx_recycle); if (skb == NULL) @@ -678,10 +679,11 @@ static int rxq_refill(struct rx_queue *rxq, int budget) rx_desc = rxq->rx_desc_area + rx; + size = skb->end - skb->data; rx_desc->buf_ptr = dma_map_single(mp->dev->dev.parent, - skb->data, mp->skb_size, + skb->data, size, DMA_FROM_DEVICE); - rx_desc->buf_size = mp->skb_size; + rx_desc->buf_size = size; rxq->rx_skb[rx] = skb; wmb(); rx_desc->cmd_sts = BUFFER_OWNED_BY_DMA | RX_ENABLE_INTERRUPT; -- cgit v0.10.2 From 6c28705418de012216161b14a2ff1dda3da3d786 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Thu, 7 Jan 2010 12:57:47 +0100 Subject: reiserfs: Don't call reiserfs_get_acl() with the reiserfs lock reiserfs_get_acl is usually not called under the reiserfs lock, as it doesn't need it. But it happens when it is called by reiserfs_acl_chmod(), which creates a dependency inversion against the private xattr inodes mutexes for the given inode. We need to call it without the reiserfs lock, especially since it's unnecessary. Signed-off-by: Frederic Weisbecker Cc: Christian Kujau Cc: Alexander Beregalov Cc: Chris Mason Cc: Ingo Molnar diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c index 35d6e67..f559c9e 100644 --- a/fs/reiserfs/xattr_acl.c +++ b/fs/reiserfs/xattr_acl.c @@ -452,7 +452,9 @@ int reiserfs_acl_chmod(struct inode *inode) return 0; } + reiserfs_write_unlock(inode->i_sb); acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS); + reiserfs_write_lock(inode->i_sb); if (!acl) return 0; if (IS_ERR(acl)) -- cgit v0.10.2 From e0baec1b63632f25ea8101b76edaca0accc061ec Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 6 Jan 2010 23:09:50 +0100 Subject: reiserfs: Fix unreachable statement Stanse found an unreachable statement in reiserfs_ioctl. There is a if followed by error assignment and `break' with no braces. Add the braces so that we don't break every time, but only in error case, so that REISERFS_IOC_SETVERSION actually works when it returns no error. Signed-off-by: Jiri Slaby Cc: Reiserfs Cc: Andrew Morton Signed-off-by: Frederic Weisbecker diff --git a/fs/reiserfs/ioctl.c b/fs/reiserfs/ioctl.c index ace7745..f53505d 100644 --- a/fs/reiserfs/ioctl.c +++ b/fs/reiserfs/ioctl.c @@ -104,9 +104,10 @@ setflags_out: err = put_user(inode->i_generation, (int __user *)arg); break; case REISERFS_IOC_SETVERSION: - if (!is_owner_or_cap(inode)) + if (!is_owner_or_cap(inode)) { err = -EPERM; break; + } err = mnt_want_write(filp->f_path.mnt); if (err) break; -- cgit v0.10.2 From 31370f62baa1460b785cee9944bdcaf63d19e567 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Thu, 7 Jan 2010 15:55:31 +0100 Subject: reiserfs: Relax reiserfs_xattr_set_handle() while acquiring xattr locks Fix remaining xattr locks acquired in reiserfs_xattr_set_handle() while we are holding the reiserfs lock to avoid lock inversions. Signed-off-by: Frederic Weisbecker Cc: Christian Kujau Cc: Alexander Beregalov Cc: Chris Mason Cc: Ingo Molnar diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index 4899d78..7fee995 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c @@ -559,8 +559,12 @@ reiserfs_xattr_set_handle(struct reiserfs_transaction_handle *th, .ia_size = buffer_size, .ia_valid = ATTR_SIZE | ATTR_CTIME, }; + + reiserfs_write_unlock(inode->i_sb); mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_XATTR); down_write(&dentry->d_inode->i_alloc_sem); + reiserfs_write_lock(inode->i_sb); + err = reiserfs_setattr(dentry, &newattrs); up_write(&dentry->d_inode->i_alloc_sem); mutex_unlock(&dentry->d_inode->i_mutex); -- cgit v0.10.2 From aaff23a95aea5f000895f50d90e91f1e2f727002 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Thu, 7 Jan 2010 18:33:18 +0100 Subject: netfilter: nf_ct_ftp: fix out of bounds read in update_nl_seq() As noticed by Dan Carpenter , update_nl_seq() currently contains an out of bounds read of the seq_aft_nl array when looking for the oldest sequence number position. Fix it to only compare valid positions. Cc: stable@kernel.org Signed-off-by: Patrick McHardy diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c index 38ea7ef..f0732aa 100644 --- a/net/netfilter/nf_conntrack_ftp.c +++ b/net/netfilter/nf_conntrack_ftp.c @@ -323,24 +323,24 @@ static void update_nl_seq(struct nf_conn *ct, u32 nl_seq, struct nf_ct_ftp_master *info, int dir, struct sk_buff *skb) { - unsigned int i, oldest = NUM_SEQ_TO_REMEMBER; + unsigned int i, oldest; /* Look for oldest: if we find exact match, we're done. */ for (i = 0; i < info->seq_aft_nl_num[dir]; i++) { if (info->seq_aft_nl[dir][i] == nl_seq) return; - - if (oldest == info->seq_aft_nl_num[dir] || - before(info->seq_aft_nl[dir][i], - info->seq_aft_nl[dir][oldest])) - oldest = i; } if (info->seq_aft_nl_num[dir] < NUM_SEQ_TO_REMEMBER) { info->seq_aft_nl[dir][info->seq_aft_nl_num[dir]++] = nl_seq; - } else if (oldest != NUM_SEQ_TO_REMEMBER && - after(nl_seq, info->seq_aft_nl[dir][oldest])) { - info->seq_aft_nl[dir][oldest] = nl_seq; + } else { + if (before(info->seq_aft_nl[dir][0], info->seq_aft_nl[dir][1])) + oldest = 0; + else + oldest = 1; + + if (after(nl_seq, info->seq_aft_nl[dir][oldest])) + info->seq_aft_nl[dir][oldest] = nl_seq; } } -- cgit v0.10.2 From 8784895ede9a39cfecf76fe26b090a602877f70f Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 7 Jan 2010 17:52:26 +0000 Subject: ARM: add missing recvmmsg syscall number Signed-off-by: Russell King diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h index 4e506d0..cf9cdaa 100644 --- a/arch/arm/include/asm/unistd.h +++ b/arch/arm/include/asm/unistd.h @@ -391,6 +391,7 @@ #define __NR_pwritev (__NR_SYSCALL_BASE+362) #define __NR_rt_tgsigqueueinfo (__NR_SYSCALL_BASE+363) #define __NR_perf_event_open (__NR_SYSCALL_BASE+364) +#define __NR_recvmmsg (__NR_SYSCALL_BASE+365) /* * The following SWIs are ARM private. -- cgit v0.10.2 From 6144a85a0e018c19bc4b24f7eb6c1f3f7431813d Mon Sep 17 00:00:00 2001 From: Jason Wessel Date: Thu, 7 Jan 2010 11:58:36 -0600 Subject: maccess,probe_kernel: Allow arch specific override probe_kernel_(read|write) Some archs such as blackfin, would like to have an arch specific probe_kernel_read() and probe_kernel_write() implementation which can fall back to the generic implementation if no special operations are needed. CC: Thomas Gleixner CC: Ingo Molnar Signed-off-by: Jason Wessel Signed-off-by: Mike Frysinger diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h index 6b58367..d512d98 100644 --- a/include/linux/uaccess.h +++ b/include/linux/uaccess.h @@ -94,6 +94,7 @@ static inline unsigned long __copy_from_user_nocache(void *to, * happens, handle that and return -EFAULT. */ extern long probe_kernel_read(void *dst, void *src, size_t size); +extern long __probe_kernel_read(void *dst, void *src, size_t size); /* * probe_kernel_write(): safely attempt to write to a location @@ -104,6 +105,7 @@ extern long probe_kernel_read(void *dst, void *src, size_t size); * Safely write to address @dst from the buffer at @src. If a kernel fault * happens, handle that and return -EFAULT. */ -extern long probe_kernel_write(void *dst, void *src, size_t size); +extern long notrace probe_kernel_write(void *dst, void *src, size_t size); +extern long notrace __probe_kernel_write(void *dst, void *src, size_t size); #endif /* __LINUX_UACCESS_H__ */ diff --git a/mm/maccess.c b/mm/maccess.c index 9073695..4e348db 100644 --- a/mm/maccess.c +++ b/mm/maccess.c @@ -14,7 +14,11 @@ * Safely read from address @src to the buffer at @dst. If a kernel fault * happens, handle that and return -EFAULT. */ -long probe_kernel_read(void *dst, void *src, size_t size) + +long __weak probe_kernel_read(void *dst, void *src, size_t size) + __attribute__((alias("__probe_kernel_read"))); + +long __probe_kernel_read(void *dst, void *src, size_t size) { long ret; mm_segment_t old_fs = get_fs(); @@ -39,7 +43,10 @@ EXPORT_SYMBOL_GPL(probe_kernel_read); * Safely write to address @dst from the buffer at @src. If a kernel fault * happens, handle that and return -EFAULT. */ -long notrace __weak probe_kernel_write(void *dst, void *src, size_t size) +long __weak probe_kernel_write(void *dst, void *src, size_t size) + __attribute__((alias("__probe_kernel_write"))); + +long __probe_kernel_write(void *dst, void *src, size_t size) { long ret; mm_segment_t old_fs = get_fs(); -- cgit v0.10.2 From 0fde663708c981189e4e62f3be51e02b1ad4eead Mon Sep 17 00:00:00 2001 From: Jason Wessel Date: Thu, 7 Jan 2010 11:58:36 -0600 Subject: blackfin,kgdb,probe_kernel: Cleanup probe_kernel_read/write Blackfin needs it own arch specific probe_kernel_read() and probe_kernel_write(). This was moved out of the kgdb code and into the arch/blackfin/maccess.c, because it is a generic kernel api. The arch specific kgdb.c for blackfin was cleaned of all functions which exist in the kgdb core that do the same thing after resolving the probe_kernel_read() and probe_kernel_write(). This also eliminated the need for most of the #include's. CC: Sonic Zhang Signed-off-by: Jason Wessel Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/kernel/kgdb.c b/arch/blackfin/kernel/kgdb.c index f1036b6..da03848 100644 --- a/arch/blackfin/kernel/kgdb.c +++ b/arch/blackfin/kernel/kgdb.c @@ -6,23 +6,9 @@ * Licensed under the GPL-2 or later. */ -#include -#include -#include -#include -#include -#include #include /* for linux pt_regs struct */ #include -#include -#include -#include -#include #include -#include -#include -#include -#include void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs) { @@ -424,182 +410,6 @@ struct kgdb_arch arch_kgdb_ops = { .correct_hw_break = bfin_correct_hw_break, }; -static int hex(char ch) -{ - if ((ch >= 'a') && (ch <= 'f')) - return ch - 'a' + 10; - if ((ch >= '0') && (ch <= '9')) - return ch - '0'; - if ((ch >= 'A') && (ch <= 'F')) - return ch - 'A' + 10; - return -1; -} - -static int validate_memory_access_address(unsigned long addr, int size) -{ - if (size < 0 || addr == 0) - return -EFAULT; - return bfin_mem_access_type(addr, size); -} - -static int bfin_probe_kernel_read(char *dst, char *src, int size) -{ - unsigned long lsrc = (unsigned long)src; - int mem_type; - - mem_type = validate_memory_access_address(lsrc, size); - if (mem_type < 0) - return mem_type; - - if (lsrc >= SYSMMR_BASE) { - if (size == 2 && lsrc % 2 == 0) { - u16 mmr = bfin_read16(src); - memcpy(dst, &mmr, sizeof(mmr)); - return 0; - } else if (size == 4 && lsrc % 4 == 0) { - u32 mmr = bfin_read32(src); - memcpy(dst, &mmr, sizeof(mmr)); - return 0; - } - } else { - switch (mem_type) { - case BFIN_MEM_ACCESS_CORE: - case BFIN_MEM_ACCESS_CORE_ONLY: - return probe_kernel_read(dst, src, size); - /* XXX: should support IDMA here with SMP */ - case BFIN_MEM_ACCESS_DMA: - if (dma_memcpy(dst, src, size)) - return 0; - break; - case BFIN_MEM_ACCESS_ITEST: - if (isram_memcpy(dst, src, size)) - return 0; - break; - } - } - - return -EFAULT; -} - -static int bfin_probe_kernel_write(char *dst, char *src, int size) -{ - unsigned long ldst = (unsigned long)dst; - int mem_type; - - mem_type = validate_memory_access_address(ldst, size); - if (mem_type < 0) - return mem_type; - - if (ldst >= SYSMMR_BASE) { - if (size == 2 && ldst % 2 == 0) { - u16 mmr; - memcpy(&mmr, src, sizeof(mmr)); - bfin_write16(dst, mmr); - return 0; - } else if (size == 4 && ldst % 4 == 0) { - u32 mmr; - memcpy(&mmr, src, sizeof(mmr)); - bfin_write32(dst, mmr); - return 0; - } - } else { - switch (mem_type) { - case BFIN_MEM_ACCESS_CORE: - case BFIN_MEM_ACCESS_CORE_ONLY: - return probe_kernel_write(dst, src, size); - /* XXX: should support IDMA here with SMP */ - case BFIN_MEM_ACCESS_DMA: - if (dma_memcpy(dst, src, size)) - return 0; - break; - case BFIN_MEM_ACCESS_ITEST: - if (isram_memcpy(dst, src, size)) - return 0; - break; - } - } - - return -EFAULT; -} - -/* - * Convert the memory pointed to by mem into hex, placing result in buf. - * Return a pointer to the last char put in buf (null). May return an error. - */ -int kgdb_mem2hex(char *mem, char *buf, int count) -{ - char *tmp; - int err; - - /* - * We use the upper half of buf as an intermediate buffer for the - * raw memory copy. Hex conversion will work against this one. - */ - tmp = buf + count; - - err = bfin_probe_kernel_read(tmp, mem, count); - if (!err) { - while (count > 0) { - buf = pack_hex_byte(buf, *tmp); - tmp++; - count--; - } - - *buf = 0; - } - - return err; -} - -/* - * Copy the binary array pointed to by buf into mem. Fix $, #, and - * 0x7d escaped with 0x7d. Return a pointer to the character after - * the last byte written. - */ -int kgdb_ebin2mem(char *buf, char *mem, int count) -{ - char *tmp_old, *tmp_new; - int size; - - tmp_old = tmp_new = buf; - - for (size = 0; size < count; ++size) { - if (*tmp_old == 0x7d) - *tmp_new = *(++tmp_old) ^ 0x20; - else - *tmp_new = *tmp_old; - tmp_new++; - tmp_old++; - } - - return bfin_probe_kernel_write(mem, buf, count); -} - -/* - * Convert the hex array pointed to by buf into binary to be placed in mem. - * Return a pointer to the character AFTER the last byte written. - * May return an error. - */ -int kgdb_hex2mem(char *buf, char *mem, int count) -{ - char *tmp_raw, *tmp_hex; - - /* - * We use the upper half of buf as an intermediate buffer for the - * raw memory that is converted from hex. - */ - tmp_raw = buf + count * 2; - - tmp_hex = tmp_raw - 1; - while (tmp_hex >= buf) { - tmp_raw--; - *tmp_raw = hex(*tmp_hex--); - *tmp_raw |= hex(*tmp_hex--) << 4; - } - - return bfin_probe_kernel_write(mem, tmp_raw, count); -} - #define IN_MEM(addr, size, l1_addr, l1_size) \ ({ \ unsigned long __addr = (unsigned long)(addr); \ @@ -629,21 +439,6 @@ int kgdb_validate_break_address(unsigned long addr) return -EFAULT; } -int kgdb_arch_set_breakpoint(unsigned long addr, char *saved_instr) -{ - int err = bfin_probe_kernel_read(saved_instr, (char *)addr, - BREAK_INSTR_SIZE); - if (err) - return err; - return bfin_probe_kernel_write((char *)addr, arch_kgdb_ops.gdb_bpt_instr, - BREAK_INSTR_SIZE); -} - -int kgdb_arch_remove_breakpoint(unsigned long addr, char *bundle) -{ - return bfin_probe_kernel_write((char *)addr, bundle, BREAK_INSTR_SIZE); -} - int kgdb_arch_init(void) { kgdb_single_step = 0; diff --git a/arch/blackfin/mm/Makefile b/arch/blackfin/mm/Makefile index d489f89..4c011b1f6 100644 --- a/arch/blackfin/mm/Makefile +++ b/arch/blackfin/mm/Makefile @@ -2,4 +2,4 @@ # arch/blackfin/mm/Makefile # -obj-y := sram-alloc.o isram-driver.o init.o +obj-y := sram-alloc.o isram-driver.o init.o maccess.o diff --git a/arch/blackfin/mm/maccess.c b/arch/blackfin/mm/maccess.c new file mode 100644 index 0000000..b71cebc --- /dev/null +++ b/arch/blackfin/mm/maccess.c @@ -0,0 +1,97 @@ +/* + * safe read and write memory routines callable while atomic + * + * Copyright 2005-2008 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include + +static int validate_memory_access_address(unsigned long addr, int size) +{ + if (size < 0 || addr == 0) + return -EFAULT; + return bfin_mem_access_type(addr, size); +} + +long probe_kernel_read(void *dst, void *src, size_t size) +{ + unsigned long lsrc = (unsigned long)src; + int mem_type; + + mem_type = validate_memory_access_address(lsrc, size); + if (mem_type < 0) + return mem_type; + + if (lsrc >= SYSMMR_BASE) { + if (size == 2 && lsrc % 2 == 0) { + u16 mmr = bfin_read16(src); + memcpy(dst, &mmr, sizeof(mmr)); + return 0; + } else if (size == 4 && lsrc % 4 == 0) { + u32 mmr = bfin_read32(src); + memcpy(dst, &mmr, sizeof(mmr)); + return 0; + } + } else { + switch (mem_type) { + case BFIN_MEM_ACCESS_CORE: + case BFIN_MEM_ACCESS_CORE_ONLY: + return __probe_kernel_read(dst, src, size); + /* XXX: should support IDMA here with SMP */ + case BFIN_MEM_ACCESS_DMA: + if (dma_memcpy(dst, src, size)) + return 0; + break; + case BFIN_MEM_ACCESS_ITEST: + if (isram_memcpy(dst, src, size)) + return 0; + break; + } + } + + return -EFAULT; +} + +long probe_kernel_write(void *dst, void *src, size_t size) +{ + unsigned long ldst = (unsigned long)dst; + int mem_type; + + mem_type = validate_memory_access_address(ldst, size); + if (mem_type < 0) + return mem_type; + + if (ldst >= SYSMMR_BASE) { + if (size == 2 && ldst % 2 == 0) { + u16 mmr; + memcpy(&mmr, src, sizeof(mmr)); + bfin_write16(dst, mmr); + return 0; + } else if (size == 4 && ldst % 4 == 0) { + u32 mmr; + memcpy(&mmr, src, sizeof(mmr)); + bfin_write32(dst, mmr); + return 0; + } + } else { + switch (mem_type) { + case BFIN_MEM_ACCESS_CORE: + case BFIN_MEM_ACCESS_CORE_ONLY: + return __probe_kernel_write(dst, src, size); + /* XXX: should support IDMA here with SMP */ + case BFIN_MEM_ACCESS_DMA: + if (dma_memcpy(dst, src, size)) + return 0; + break; + case BFIN_MEM_ACCESS_ITEST: + if (isram_memcpy(dst, src, size)) + return 0; + break; + } + } + + return -EFAULT; +} -- cgit v0.10.2 From 7fe1a91281de095e4cc43868cc14ca4937154a0c Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Thu, 7 Jan 2010 11:58:37 -0600 Subject: blackfin,kgdb: Do not put PC in gdb_regs into retx. In blackfin, kgdb is running in delayed exception IRQ5 other than in exception IRQ3 directly. Register reti other than retx in pt_regs is the kgdb return address. So, don't put PC in gdb_regs into retx. CC: Mike Frysinger Signed-off-by: Sonic Zhang Signed-off-by: Jason Wessel diff --git a/arch/blackfin/kernel/kgdb.c b/arch/blackfin/kernel/kgdb.c index da03848..34c7c3e 100644 --- a/arch/blackfin/kernel/kgdb.c +++ b/arch/blackfin/kernel/kgdb.c @@ -133,7 +133,7 @@ void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs) regs->lb1 = gdb_regs[BFIN_LB1]; regs->usp = gdb_regs[BFIN_USP]; regs->syscfg = gdb_regs[BFIN_SYSCFG]; - regs->retx = gdb_regs[BFIN_PC]; + regs->retx = gdb_regs[BFIN_RETX]; regs->retn = gdb_regs[BFIN_RETN]; regs->rete = gdb_regs[BFIN_RETE]; regs->pc = gdb_regs[BFIN_PC]; -- cgit v0.10.2 From b11e1eca7ed9c0b5dab21a62c11acc711d9bdda0 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 7 Jan 2010 11:58:37 -0600 Subject: kgdb: Fix kernel-doc format error in kgdb.h linux-next-20081022//include/linux/kgdb.h:308): duplicate section name 'Description' and fix typos in that file's kernel-doc comments. Signed-off-by: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Jason Wessel diff --git a/include/linux/kgdb.h b/include/linux/kgdb.h index 6adcc29..19ec41a 100644 --- a/include/linux/kgdb.h +++ b/include/linux/kgdb.h @@ -29,8 +29,7 @@ struct pt_regs; * * On some architectures it is required to skip a breakpoint * exception when it occurs after a breakpoint has been removed. - * This can be implemented in the architecture specific portion of - * for kgdb. + * This can be implemented in the architecture specific portion of kgdb. */ extern int kgdb_skipexception(int exception, struct pt_regs *regs); @@ -65,7 +64,7 @@ struct uart_port; /** * kgdb_breakpoint - compiled in breakpoint * - * This will be impelmented a static inline per architecture. This + * This will be implemented as a static inline per architecture. This * function is called by the kgdb core to execute an architecture * specific trap to cause kgdb to enter the exception processing. * @@ -190,7 +189,7 @@ kgdb_arch_handle_exception(int vector, int signo, int err_code, * @flags: Current IRQ state * * On SMP systems, we need to get the attention of the other CPUs - * and get them be in a known state. This should do what is needed + * and get them into a known state. This should do what is needed * to get the other CPUs to call kgdb_wait(). Note that on some arches, * the NMI approach is not used for rounding up all the CPUs. For example, * in case of MIPS, smp_call_function() is used to roundup CPUs. In -- cgit v0.10.2 From 6c57a332901f851bd092aba7a2b4d8ef4e643829 Mon Sep 17 00:00:00 2001 From: Tony Luck Date: Thu, 7 Jan 2010 16:10:57 -0800 Subject: [IA64] __per_cpu_idtrs[] is a memory hog __per_cpu_idtrs is statically allocated ... on CONFIG_NR_CPUS=4096 systems it hogs 16MB of memory. This is way too much for a quite probably unused facility (only KVM uses dynamic TR registers). Change to an array of pointers, and allocate entries as needed on a per cpu basis. Change the name too as the __per_cpu_ prefix is confusing (this isn't a classic type object). Signed-off-by: Tony Luck diff --git a/arch/ia64/include/asm/tlb.h b/arch/ia64/include/asm/tlb.h index 85d965c..23cce99 100644 --- a/arch/ia64/include/asm/tlb.h +++ b/arch/ia64/include/asm/tlb.h @@ -74,7 +74,7 @@ struct ia64_tr_entry { extern int ia64_itr_entry(u64 target_mask, u64 va, u64 pte, u64 log_size); extern void ia64_ptr_entry(u64 target_mask, int slot); -extern struct ia64_tr_entry __per_cpu_idtrs[NR_CPUS][2][IA64_TR_ALLOC_MAX]; +extern struct ia64_tr_entry *ia64_idtrs[NR_CPUS]; /* region register macros diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c index 32f2639..378b483 100644 --- a/arch/ia64/kernel/mca.c +++ b/arch/ia64/kernel/mca.c @@ -1225,9 +1225,12 @@ static void mca_insert_tr(u64 iord) unsigned long psr; int cpu = smp_processor_id(); + if (!ia64_idtrs[cpu]) + return; + psr = ia64_clear_ic(); for (i = IA64_TR_ALLOC_BASE; i < IA64_TR_ALLOC_MAX; i++) { - p = &__per_cpu_idtrs[cpu][iord-1][i]; + p = ia64_idtrs[cpu] + (iord - 1) * IA64_TR_ALLOC_MAX; if (p->pte & 0x1) { old_rr = ia64_get_rr(p->ifa); if (old_rr != p->rr) { diff --git a/arch/ia64/mm/tlb.c b/arch/ia64/mm/tlb.c index ee09d26..f3de9d7 100644 --- a/arch/ia64/mm/tlb.c +++ b/arch/ia64/mm/tlb.c @@ -48,7 +48,7 @@ DEFINE_PER_CPU(u8, ia64_need_tlb_flush); DEFINE_PER_CPU(u8, ia64_tr_num); /*Number of TR slots in current processor*/ DEFINE_PER_CPU(u8, ia64_tr_used); /*Max Slot number used by kernel*/ -struct ia64_tr_entry __per_cpu_idtrs[NR_CPUS][2][IA64_TR_ALLOC_MAX]; +struct ia64_tr_entry *ia64_idtrs[NR_CPUS]; /* * Initializes the ia64_ctx.bitmap array based on max_ctx+1. @@ -429,10 +429,16 @@ int ia64_itr_entry(u64 target_mask, u64 va, u64 pte, u64 log_size) struct ia64_tr_entry *p; int cpu = smp_processor_id(); + if (!ia64_idtrs[cpu]) { + ia64_idtrs[cpu] = kmalloc(2 * IA64_TR_ALLOC_MAX * + sizeof (struct ia64_tr_entry), GFP_KERNEL); + if (!ia64_idtrs[cpu]) + return -ENOMEM; + } r = -EINVAL; /*Check overlap with existing TR entries*/ if (target_mask & 0x1) { - p = &__per_cpu_idtrs[cpu][0][0]; + p = ia64_idtrs[cpu]; for (i = IA64_TR_ALLOC_BASE; i <= per_cpu(ia64_tr_used, cpu); i++, p++) { if (p->pte & 0x1) @@ -444,7 +450,7 @@ int ia64_itr_entry(u64 target_mask, u64 va, u64 pte, u64 log_size) } } if (target_mask & 0x2) { - p = &__per_cpu_idtrs[cpu][1][0]; + p = ia64_idtrs[cpu] + IA64_TR_ALLOC_MAX; for (i = IA64_TR_ALLOC_BASE; i <= per_cpu(ia64_tr_used, cpu); i++, p++) { if (p->pte & 0x1) @@ -459,16 +465,16 @@ int ia64_itr_entry(u64 target_mask, u64 va, u64 pte, u64 log_size) for (i = IA64_TR_ALLOC_BASE; i < per_cpu(ia64_tr_num, cpu); i++) { switch (target_mask & 0x3) { case 1: - if (!(__per_cpu_idtrs[cpu][0][i].pte & 0x1)) + if (!((ia64_idtrs[cpu] + i)->pte & 0x1)) goto found; continue; case 2: - if (!(__per_cpu_idtrs[cpu][1][i].pte & 0x1)) + if (!((ia64_idtrs[cpu] + IA64_TR_ALLOC_MAX + i)->pte & 0x1)) goto found; continue; case 3: - if (!(__per_cpu_idtrs[cpu][0][i].pte & 0x1) && - !(__per_cpu_idtrs[cpu][1][i].pte & 0x1)) + if (!((ia64_idtrs[cpu] + i)->pte & 0x1) && + !((ia64_idtrs[cpu] + IA64_TR_ALLOC_MAX + i)->pte & 0x1)) goto found; continue; default: @@ -488,7 +494,7 @@ found: if (target_mask & 0x1) { ia64_itr(0x1, i, va, pte, log_size); ia64_srlz_i(); - p = &__per_cpu_idtrs[cpu][0][i]; + p = ia64_idtrs[cpu] + i; p->ifa = va; p->pte = pte; p->itir = log_size << 2; @@ -497,7 +503,7 @@ found: if (target_mask & 0x2) { ia64_itr(0x2, i, va, pte, log_size); ia64_srlz_i(); - p = &__per_cpu_idtrs[cpu][1][i]; + p = ia64_idtrs[cpu] + IA64_TR_ALLOC_MAX + i; p->ifa = va; p->pte = pte; p->itir = log_size << 2; @@ -528,7 +534,7 @@ void ia64_ptr_entry(u64 target_mask, int slot) return; if (target_mask & 0x1) { - p = &__per_cpu_idtrs[cpu][0][slot]; + p = ia64_idtrs[cpu] + slot; if ((p->pte&0x1) && is_tr_overlap(p, p->ifa, p->itir>>2)) { p->pte = 0; ia64_ptr(0x1, p->ifa, p->itir>>2); @@ -537,7 +543,7 @@ void ia64_ptr_entry(u64 target_mask, int slot) } if (target_mask & 0x2) { - p = &__per_cpu_idtrs[cpu][1][slot]; + p = ia64_idtrs[cpu] + IA64_TR_ALLOC_MAX + slot; if ((p->pte & 0x1) && is_tr_overlap(p, p->ifa, p->itir>>2)) { p->pte = 0; ia64_ptr(0x2, p->ifa, p->itir>>2); @@ -546,8 +552,8 @@ void ia64_ptr_entry(u64 target_mask, int slot) } for (i = per_cpu(ia64_tr_used, cpu); i >= IA64_TR_ALLOC_BASE; i--) { - if ((__per_cpu_idtrs[cpu][0][i].pte & 0x1) || - (__per_cpu_idtrs[cpu][1][i].pte & 0x1)) + if (((ia64_idtrs[cpu] + i)->pte & 0x1) || + ((ia64_idtrs[cpu] + IA64_TR_ALLOC_MAX + i)->pte & 0x1)) break; } per_cpu(ia64_tr_used, cpu) = i; -- cgit v0.10.2 From 6837e895cbfd5ce8a717f112e927d2815f341e54 Mon Sep 17 00:00:00 2001 From: PJ Waskiewicz Date: Wed, 6 Jan 2010 17:50:29 +0000 Subject: ixgbe: Fix compiler warning about variable being used uninitialized tc is still throwing a warning that is could be used uninitialized. This fixes it, and properly formats the device ID checks for the use of this variable. Signed-off-by: Peter P Waskiewicz Jr Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 1a2ea62..2ad754c 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -262,10 +262,12 @@ static inline bool ixgbe_tx_is_paused(struct ixgbe_adapter *adapter, int reg_idx = tx_ring->reg_idx; int dcb_i = adapter->ring_feature[RING_F_DCB].indices; - if (adapter->hw.mac.type == ixgbe_mac_82598EB) { + switch (adapter->hw.mac.type) { + case ixgbe_mac_82598EB: tc = reg_idx >> 2; txoff = IXGBE_TFCS_TXOFF0; - } else if (adapter->hw.mac.type == ixgbe_mac_82599EB) { + break; + case ixgbe_mac_82599EB: tc = 0; txoff = IXGBE_TFCS_TXOFF; if (dcb_i == 8) { @@ -284,6 +286,9 @@ static inline bool ixgbe_tx_is_paused(struct ixgbe_adapter *adapter, tc += (reg_idx - 96) >> 4; } } + break; + default: + tc = 0; } txoff <<= tc; } -- cgit v0.10.2 From 4d907069bc1b745f4abd4745c332d33098e733b8 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 7 Jan 2010 02:41:51 +0000 Subject: dmfe/tulip: Let dmfe handle DM910x except for SPARC on-board chips The Davicom DM9100 and DM9102 chips are used on the motherboards of some SPARC systems (supported by the tulip driver) and also in PCI expansion cards (supported by the dmfe driver). There is no difference in the PCI device ids for the two different configurations, so these drivers both claim the device ids. However, it is possible to distinguish the two configurations by the presence of Open Firmware properties for them, so we do that. Signed-off-by: Ben Hutchings Signed-off-by: Grant Grundler Signed-off-by: David S. Miller diff --git a/drivers/net/tulip/Kconfig b/drivers/net/tulip/Kconfig index 1cc8cf4..516713f 100644 --- a/drivers/net/tulip/Kconfig +++ b/drivers/net/tulip/Kconfig @@ -101,6 +101,10 @@ config TULIP_NAPI_HW_MITIGATION If in doubt, say Y. +config TULIP_DM910X + def_bool y + depends on TULIP && SPARC + config DE4X5 tristate "Generic DECchip & DIGITAL EtherWORKS PCI/EISA" depends on PCI || EISA diff --git a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c index ad63621..6f44ebf 100644 --- a/drivers/net/tulip/dmfe.c +++ b/drivers/net/tulip/dmfe.c @@ -92,6 +92,10 @@ #include #include +#ifdef CONFIG_TULIP_DM910X +#include +#endif + /* Board/System/Debug information/definition ---------------- */ #define PCI_DM9132_ID 0x91321282 /* Davicom DM9132 ID */ @@ -377,6 +381,23 @@ static int __devinit dmfe_init_one (struct pci_dev *pdev, if (!printed_version++) printk(version); + /* + * SPARC on-board DM910x chips should be handled by the main + * tulip driver, except for early DM9100s. + */ +#ifdef CONFIG_TULIP_DM910X + if ((ent->driver_data == PCI_DM9100_ID && pdev->revision >= 0x30) || + ent->driver_data == PCI_DM9102_ID) { + struct device_node *dp = pci_device_to_OF_node(pdev); + + if (dp && of_get_property(dp, "local-mac-address", NULL)) { + printk(KERN_INFO DRV_NAME + ": skipping on-board DM910x (use tulip)\n"); + return -ENODEV; + } + } +#endif + /* Init network device */ dev = alloc_etherdev(sizeof(*db)); if (dev == NULL) diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index 0fa3140..595777d 100644 --- a/drivers/net/tulip/tulip_core.c +++ b/drivers/net/tulip/tulip_core.c @@ -196,9 +196,13 @@ struct tulip_chip_table tulip_tbl[] = { | HAS_NWAY | HAS_PCI_MWI, tulip_timer, tulip_media_task }, /* DM910X */ +#ifdef CONFIG_TULIP_DM910X { "Davicom DM9102/DM9102A", 128, 0x0001ebef, HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | HAS_ACPI, tulip_timer, tulip_media_task }, +#else + { NULL }, +#endif /* RS7112 */ { "Conexant LANfinity", 256, 0x0001ebef, @@ -228,8 +232,10 @@ static struct pci_device_id tulip_pci_tbl[] = { { 0x1259, 0xa120, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, { 0x11F6, 0x9881, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMPEX9881 }, { 0x8086, 0x0039, PCI_ANY_ID, PCI_ANY_ID, 0, 0, I21145 }, +#ifdef CONFIG_TULIP_DM910X { 0x1282, 0x9100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DM910X }, { 0x1282, 0x9102, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DM910X }, +#endif { 0x1113, 0x1216, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, { 0x1113, 0x1217, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MX98715 }, { 0x1113, 0x9511, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, @@ -1299,18 +1305,30 @@ static int __devinit tulip_init_one (struct pci_dev *pdev, } /* - * Early DM9100's need software CRC and the DMFE driver + * DM910x chips should be handled by the dmfe driver, except + * on-board chips on SPARC systems. Also, early DM9100s need + * software CRC which only the dmfe driver supports. */ - if (pdev->vendor == 0x1282 && pdev->device == 0x9100) - { - /* Read Chip revision */ - if (pdev->revision < 0x30) - { - printk(KERN_ERR PFX "skipping early DM9100 with Crc bug (use dmfe)\n"); +#ifdef CONFIG_TULIP_DM910X + if (chip_idx == DM910X) { + struct device_node *dp; + + if (pdev->vendor == 0x1282 && pdev->device == 0x9100 && + pdev->revision < 0x30) { + printk(KERN_INFO PFX + "skipping early DM9100 with Crc bug (use dmfe)\n"); + return -ENODEV; + } + + dp = pci_device_to_OF_node(pdev); + if (!(dp && of_get_property(dp, "local-mac-address", NULL))) { + printk(KERN_INFO PFX + "skipping DM910x expansion card (use dmfe)\n"); return -ENODEV; } } +#endif /* * Looks for early PCI chipsets where people report hangs -- cgit v0.10.2 From 1ca518b64b4b5865b677f292322e893fa89997d4 Mon Sep 17 00:00:00 2001 From: Sriram Date: Thu, 7 Jan 2010 00:22:37 +0000 Subject: TI DaVinci EMAC: Handle emac module clock correctly. In the driver probe function the emac module clock needs to be enabled before calling register_netdev(). As soon as the device is registered the driver get_stats function can be invoked by the core - the module clock must be switched on to be able to read from stats registers. Also explicitly call matching clk_disable for failure conditions in probe function. Signed-off-by: Sriramakrishnan Signed-off-by: David S. Miller diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c index 34e0310..33c4fe2 100644 --- a/drivers/net/davinci_emac.c +++ b/drivers/net/davinci_emac.c @@ -2711,6 +2711,8 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev) SET_ETHTOOL_OPS(ndev, ðtool_ops); netif_napi_add(ndev, &priv->napi, emac_poll, EMAC_POLL_WEIGHT); + clk_enable(emac_clk); + /* register the network device */ SET_NETDEV_DEV(ndev, &pdev->dev); rc = register_netdev(ndev); @@ -2720,7 +2722,6 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev) goto netdev_reg_err; } - clk_enable(emac_clk); /* MII/Phy intialisation, mdio bus registration */ emac_mii = mdiobus_alloc(); @@ -2760,6 +2761,7 @@ mdiobus_quit: netdev_reg_err: mdio_alloc_err: + clk_disable(emac_clk); no_irq_res: res = platform_get_resource(pdev, IORESOURCE_MEM, 0); release_mem_region(res->start, res->end - res->start + 1); -- cgit v0.10.2 From d13fecd0293d55a4bcb8a31078216504192d8ce0 Mon Sep 17 00:00:00 2001 From: Cyril Hrubis Date: Thu, 7 Jan 2010 21:31:04 +0100 Subject: [ARM] pxa: fix strange characters in zaurus gpio .desc Somehow, strange characters made their way zaurus gpio .desc fields. Fix it. Signed-off-by: Pavel Machek Acked-by: Stanislav Brabec Signed-off-by: Eric Miao diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c index 4b50f14..28352c0 100644 --- a/arch/arm/mach-pxa/spitz.c +++ b/arch/arm/mach-pxa/spitz.c @@ -389,13 +389,13 @@ static struct gpio_keys_button spitz_gpio_keys[] = { .type = EV_SW, .code = 0, .gpio = SPITZ_GPIO_SWA, - .desc = "Display Down", + .desc = "Display Down", }, { .type = EV_SW, .code = 1, .gpio = SPITZ_GPIO_SWB, - .desc = "Lid Closed", + .desc = "Lid Closed", }, }; -- cgit v0.10.2 From a5899fcc189e9357873ddf26d5e6e7e6ff84c2f4 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 7 Jan 2010 14:19:47 -0500 Subject: drm/radeon/kms: fix typo in atom connector type handling Also remove the problematic enums that were unused remnants from the ddx. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index ccba95f..844c513 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c @@ -604,13 +604,13 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) else return ATOM_ENCODER_MODE_DVI; break; - case CONNECTOR_DVI_A: - case CONNECTOR_VGA: + case DRM_MODE_CONNECTOR_DVIA: + case DRM_MODE_CONNECTOR_VGA: return ATOM_ENCODER_MODE_CRT; break; - case CONNECTOR_STV: - case CONNECTOR_CTV: - case CONNECTOR_DIN: + case DRM_MODE_CONNECTOR_Composite: + case DRM_MODE_CONNECTOR_SVIDEO: + case DRM_MODE_CONNECTOR_9PinDIN: /* fix me */ return ATOM_ENCODER_MODE_TV; /*return ATOM_ENCODER_MODE_CV;*/ diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 402369d..91cb041 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -46,32 +46,6 @@ struct radeon_device; #define to_radeon_encoder(x) container_of(x, struct radeon_encoder, base) #define to_radeon_framebuffer(x) container_of(x, struct radeon_framebuffer, base) -enum radeon_connector_type { - CONNECTOR_NONE, - CONNECTOR_VGA, - CONNECTOR_DVI_I, - CONNECTOR_DVI_D, - CONNECTOR_DVI_A, - CONNECTOR_STV, - CONNECTOR_CTV, - CONNECTOR_LVDS, - CONNECTOR_DIGITAL, - CONNECTOR_SCART, - CONNECTOR_HDMI_TYPE_A, - CONNECTOR_HDMI_TYPE_B, - CONNECTOR_0XC, - CONNECTOR_0XD, - CONNECTOR_DIN, - CONNECTOR_DISPLAY_PORT, - CONNECTOR_UNSUPPORTED -}; - -enum radeon_dvi_type { - DVI_AUTO, - DVI_DIGITAL, - DVI_ANALOG -}; - enum radeon_rmx_type { RMX_OFF, RMX_FULL, -- cgit v0.10.2 From a7bc115fffb69a55cf2c332567ea6908d9026f22 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 7 Jan 2010 11:35:48 -0500 Subject: drm/radeon/kms: whitespace changes to ObjectID.h Makes it easier to keep in sync with ddx and the upstream AMD versions. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/ObjectID.h b/drivers/gpu/drm/radeon/ObjectID.h index 6d0183c..f1f18a4 100644 --- a/drivers/gpu/drm/radeon/ObjectID.h +++ b/drivers/gpu/drm/radeon/ObjectID.h @@ -1,5 +1,5 @@ /* -* Copyright 2006-2007 Advanced Micro Devices, Inc. +* Copyright 2006-2007 Advanced Micro Devices, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -41,14 +41,14 @@ /****************************************************/ /* Encoder Object ID Definition */ /****************************************************/ -#define ENCODER_OBJECT_ID_NONE 0x00 +#define ENCODER_OBJECT_ID_NONE 0x00 /* Radeon Class Display Hardware */ #define ENCODER_OBJECT_ID_INTERNAL_LVDS 0x01 #define ENCODER_OBJECT_ID_INTERNAL_TMDS1 0x02 #define ENCODER_OBJECT_ID_INTERNAL_TMDS2 0x03 #define ENCODER_OBJECT_ID_INTERNAL_DAC1 0x04 -#define ENCODER_OBJECT_ID_INTERNAL_DAC2 0x05 /* TV/CV DAC */ +#define ENCODER_OBJECT_ID_INTERNAL_DAC2 0x05 /* TV/CV DAC */ #define ENCODER_OBJECT_ID_INTERNAL_SDVOA 0x06 #define ENCODER_OBJECT_ID_INTERNAL_SDVOB 0x07 @@ -56,11 +56,11 @@ #define ENCODER_OBJECT_ID_SI170B 0x08 #define ENCODER_OBJECT_ID_CH7303 0x09 #define ENCODER_OBJECT_ID_CH7301 0x0A -#define ENCODER_OBJECT_ID_INTERNAL_DVO1 0x0B /* This belongs to Radeon Class Display Hardware */ +#define ENCODER_OBJECT_ID_INTERNAL_DVO1 0x0B /* This belongs to Radeon Class Display Hardware */ #define ENCODER_OBJECT_ID_EXTERNAL_SDVOA 0x0C #define ENCODER_OBJECT_ID_EXTERNAL_SDVOB 0x0D #define ENCODER_OBJECT_ID_TITFP513 0x0E -#define ENCODER_OBJECT_ID_INTERNAL_LVTM1 0x0F /* not used for Radeon */ +#define ENCODER_OBJECT_ID_INTERNAL_LVTM1 0x0F /* not used for Radeon */ #define ENCODER_OBJECT_ID_VT1623 0x10 #define ENCODER_OBJECT_ID_HDMI_SI1930 0x11 #define ENCODER_OBJECT_ID_HDMI_INTERNAL 0x12 @@ -68,9 +68,9 @@ #define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1 0x13 #define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1 0x14 #define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1 0x15 -#define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2 0x16 /* Shared with CV/TV and CRT */ -#define ENCODER_OBJECT_ID_SI178 0X17 /* External TMDS (dual link, no HDCP.) */ -#define ENCODER_OBJECT_ID_MVPU_FPGA 0x18 /* MVPU FPGA chip */ +#define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2 0x16 /* Shared with CV/TV and CRT */ +#define ENCODER_OBJECT_ID_SI178 0X17 /* External TMDS (dual link, no HDCP.) */ +#define ENCODER_OBJECT_ID_MVPU_FPGA 0x18 /* MVPU FPGA chip */ #define ENCODER_OBJECT_ID_INTERNAL_DDI 0x19 #define ENCODER_OBJECT_ID_VT1625 0x1A #define ENCODER_OBJECT_ID_HDMI_SI1932 0x1B @@ -86,7 +86,7 @@ /****************************************************/ /* Connector Object ID Definition */ /****************************************************/ -#define CONNECTOR_OBJECT_ID_NONE 0x00 +#define CONNECTOR_OBJECT_ID_NONE 0x00 #define CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I 0x01 #define CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I 0x02 #define CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D 0x03 @@ -96,7 +96,7 @@ #define CONNECTOR_OBJECT_ID_SVIDEO 0x07 #define CONNECTOR_OBJECT_ID_YPbPr 0x08 #define CONNECTOR_OBJECT_ID_D_CONNECTOR 0x09 -#define CONNECTOR_OBJECT_ID_9PIN_DIN 0x0A /* Supports both CV & TV */ +#define CONNECTOR_OBJECT_ID_9PIN_DIN 0x0A /* Supports both CV & TV */ #define CONNECTOR_OBJECT_ID_SCART 0x0B #define CONNECTOR_OBJECT_ID_HDMI_TYPE_A 0x0C #define CONNECTOR_OBJECT_ID_HDMI_TYPE_B 0x0D @@ -116,7 +116,7 @@ #define ROUTER_OBJECT_ID_I2C_EXTENDER_CNTL 0x01 /****************************************************/ -/* Graphics Object ENUM ID Definition */ +// Graphics Object ENUM ID Definition */ /****************************************************/ #define GRAPH_OBJECT_ENUM_ID1 0x01 #define GRAPH_OBJECT_ENUM_ID2 0x02 @@ -133,35 +133,35 @@ #define RESERVED1_ID_MASK 0x0800 #define OBJECT_TYPE_MASK 0x7000 #define RESERVED2_ID_MASK 0x8000 - + #define OBJECT_ID_SHIFT 0x00 #define ENUM_ID_SHIFT 0x08 #define OBJECT_TYPE_SHIFT 0x0C + /****************************************************/ /* Graphics Object family definition */ /****************************************************/ -#define CONSTRUCTOBJECTFAMILYID(GRAPHICS_OBJECT_TYPE, GRAPHICS_OBJECT_ID) \ - (GRAPHICS_OBJECT_TYPE << OBJECT_TYPE_SHIFT | \ - GRAPHICS_OBJECT_ID << OBJECT_ID_SHIFT) +#define CONSTRUCTOBJECTFAMILYID(GRAPHICS_OBJECT_TYPE, GRAPHICS_OBJECT_ID) (GRAPHICS_OBJECT_TYPE << OBJECT_TYPE_SHIFT | \ + GRAPHICS_OBJECT_ID << OBJECT_ID_SHIFT) /****************************************************/ /* GPU Object ID definition - Shared with BIOS */ /****************************************************/ -#define GPU_ENUM_ID1 (GRAPH_OBJECT_TYPE_GPU << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT) +#define GPU_ENUM_ID1 ( GRAPH_OBJECT_TYPE_GPU << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT) /****************************************************/ /* Encoder Object ID definition - Shared with BIOS */ /****************************************************/ /* -#define ENCODER_INTERNAL_LVDS_ENUM_ID1 0x2101 +#define ENCODER_INTERNAL_LVDS_ENUM_ID1 0x2101 #define ENCODER_INTERNAL_TMDS1_ENUM_ID1 0x2102 #define ENCODER_INTERNAL_TMDS2_ENUM_ID1 0x2103 #define ENCODER_INTERNAL_DAC1_ENUM_ID1 0x2104 #define ENCODER_INTERNAL_DAC2_ENUM_ID1 0x2105 #define ENCODER_INTERNAL_SDVOA_ENUM_ID1 0x2106 #define ENCODER_INTERNAL_SDVOB_ENUM_ID1 0x2107 -#define ENCODER_SIL170B_ENUM_ID1 0x2108 +#define ENCODER_SIL170B_ENUM_ID1 0x2108 #define ENCODER_CH7303_ENUM_ID1 0x2109 #define ENCODER_CH7301_ENUM_ID1 0x210A #define ENCODER_INTERNAL_DVO1_ENUM_ID1 0x210B @@ -175,8 +175,8 @@ #define ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID1 0x2113 #define ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1 0x2114 #define ENCODER_INTERNAL_KLDSCP_DAC1_ENUM_ID1 0x2115 -#define ENCODER_INTERNAL_KLDSCP_DAC2_ENUM_ID1 0x2116 -#define ENCODER_SI178_ENUM_ID1 0x2117 +#define ENCODER_INTERNAL_KLDSCP_DAC2_ENUM_ID1 0x2116 +#define ENCODER_SI178_ENUM_ID1 0x2117 #define ENCODER_MVPU_FPGA_ENUM_ID1 0x2118 #define ENCODER_INTERNAL_DDI_ENUM_ID1 0x2119 #define ENCODER_VT1625_ENUM_ID1 0x211A @@ -185,205 +185,169 @@ #define ENCODER_DP_DP501_ENUM_ID1 0x211D #define ENCODER_INTERNAL_UNIPHY_ENUM_ID1 0x211E */ -#define ENCODER_INTERNAL_LVDS_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_INTERNAL_LVDS << OBJECT_ID_SHIFT) - -#define ENCODER_INTERNAL_TMDS1_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_INTERNAL_TMDS1 << OBJECT_ID_SHIFT) - -#define ENCODER_INTERNAL_TMDS2_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_INTERNAL_TMDS2 << OBJECT_ID_SHIFT) - -#define ENCODER_INTERNAL_DAC1_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_INTERNAL_DAC1 << OBJECT_ID_SHIFT) - -#define ENCODER_INTERNAL_DAC2_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_INTERNAL_DAC2 << OBJECT_ID_SHIFT) - -#define ENCODER_INTERNAL_SDVOA_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_INTERNAL_SDVOA << OBJECT_ID_SHIFT) - -#define ENCODER_INTERNAL_SDVOA_ENUM_ID2 \ - (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_INTERNAL_SDVOA << OBJECT_ID_SHIFT) - -#define ENCODER_INTERNAL_SDVOB_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_INTERNAL_SDVOB << OBJECT_ID_SHIFT) - -#define ENCODER_SIL170B_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_SI170B << OBJECT_ID_SHIFT) - -#define ENCODER_CH7303_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_CH7303 << OBJECT_ID_SHIFT) - -#define ENCODER_CH7301_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_CH7301 << OBJECT_ID_SHIFT) - -#define ENCODER_INTERNAL_DVO1_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_INTERNAL_DVO1 << OBJECT_ID_SHIFT) - -#define ENCODER_EXTERNAL_SDVOA_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_EXTERNAL_SDVOA << OBJECT_ID_SHIFT) - -#define ENCODER_EXTERNAL_SDVOA_ENUM_ID2 \ - (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_EXTERNAL_SDVOA << OBJECT_ID_SHIFT) - -#define ENCODER_EXTERNAL_SDVOB_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_EXTERNAL_SDVOB << OBJECT_ID_SHIFT) - -#define ENCODER_TITFP513_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_TITFP513 << OBJECT_ID_SHIFT) - -#define ENCODER_INTERNAL_LVTM1_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_INTERNAL_LVTM1 << OBJECT_ID_SHIFT) - -#define ENCODER_VT1623_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_VT1623 << OBJECT_ID_SHIFT) - -#define ENCODER_HDMI_SI1930_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_HDMI_SI1930 << OBJECT_ID_SHIFT) - -#define ENCODER_HDMI_INTERNAL_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_HDMI_INTERNAL << OBJECT_ID_SHIFT) - -#define ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1 << OBJECT_ID_SHIFT) - -#define ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID2 \ - (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1 << OBJECT_ID_SHIFT) - -#define ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1 << OBJECT_ID_SHIFT) - -#define ENCODER_INTERNAL_KLDSCP_DAC1_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1 << OBJECT_ID_SHIFT) - -#define ENCODER_INTERNAL_KLDSCP_DAC2_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2 << OBJECT_ID_SHIFT) /* Shared with CV/TV and CRT */ - -#define ENCODER_SI178_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_SI178 << OBJECT_ID_SHIFT) - -#define ENCODER_MVPU_FPGA_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_MVPU_FPGA << OBJECT_ID_SHIFT) - -#define ENCODER_INTERNAL_DDI_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_INTERNAL_DDI << OBJECT_ID_SHIFT) - -#define ENCODER_VT1625_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_VT1625 << OBJECT_ID_SHIFT) - -#define ENCODER_HDMI_SI1932_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_HDMI_SI1932 << OBJECT_ID_SHIFT) - -#define ENCODER_DP_DP501_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_DP_DP501 << OBJECT_ID_SHIFT) - -#define ENCODER_DP_AN9801_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_DP_AN9801 << OBJECT_ID_SHIFT) - -#define ENCODER_INTERNAL_UNIPHY_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_INTERNAL_UNIPHY << OBJECT_ID_SHIFT) - -#define ENCODER_INTERNAL_UNIPHY_ENUM_ID2 \ - (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_INTERNAL_UNIPHY << OBJECT_ID_SHIFT) - -#define ENCODER_INTERNAL_KLDSCP_LVTMA_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA << OBJECT_ID_SHIFT) - -#define ENCODER_INTERNAL_UNIPHY1_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_INTERNAL_UNIPHY1 << OBJECT_ID_SHIFT) - -#define ENCODER_INTERNAL_UNIPHY1_ENUM_ID2 \ - (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_INTERNAL_UNIPHY1 << OBJECT_ID_SHIFT) - -#define ENCODER_INTERNAL_UNIPHY2_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_INTERNAL_UNIPHY2 << OBJECT_ID_SHIFT) - -#define ENCODER_INTERNAL_UNIPHY2_ENUM_ID2 \ - (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_INTERNAL_UNIPHY2 << OBJECT_ID_SHIFT) - -#define ENCODER_GENERAL_EXTERNAL_DVO_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_GENERAL_EXTERNAL_DVO << OBJECT_ID_SHIFT) +#define ENCODER_INTERNAL_LVDS_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + ENCODER_OBJECT_ID_INTERNAL_LVDS << OBJECT_ID_SHIFT) + +#define ENCODER_INTERNAL_TMDS1_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + ENCODER_OBJECT_ID_INTERNAL_TMDS1 << OBJECT_ID_SHIFT) + +#define ENCODER_INTERNAL_TMDS2_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + ENCODER_OBJECT_ID_INTERNAL_TMDS2 << OBJECT_ID_SHIFT) + +#define ENCODER_INTERNAL_DAC1_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + ENCODER_OBJECT_ID_INTERNAL_DAC1 << OBJECT_ID_SHIFT) + +#define ENCODER_INTERNAL_DAC2_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + ENCODER_OBJECT_ID_INTERNAL_DAC2 << OBJECT_ID_SHIFT) + +#define ENCODER_INTERNAL_SDVOA_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + ENCODER_OBJECT_ID_INTERNAL_SDVOA << OBJECT_ID_SHIFT) + +#define ENCODER_INTERNAL_SDVOA_ENUM_ID2 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ + ENCODER_OBJECT_ID_INTERNAL_SDVOA << OBJECT_ID_SHIFT) + +#define ENCODER_INTERNAL_SDVOB_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + ENCODER_OBJECT_ID_INTERNAL_SDVOB << OBJECT_ID_SHIFT) + +#define ENCODER_SIL170B_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + ENCODER_OBJECT_ID_SI170B << OBJECT_ID_SHIFT) + +#define ENCODER_CH7303_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + ENCODER_OBJECT_ID_CH7303 << OBJECT_ID_SHIFT) + +#define ENCODER_CH7301_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + ENCODER_OBJECT_ID_CH7301 << OBJECT_ID_SHIFT) + +#define ENCODER_INTERNAL_DVO1_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + ENCODER_OBJECT_ID_INTERNAL_DVO1 << OBJECT_ID_SHIFT) + +#define ENCODER_EXTERNAL_SDVOA_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + ENCODER_OBJECT_ID_EXTERNAL_SDVOA << OBJECT_ID_SHIFT) + +#define ENCODER_EXTERNAL_SDVOA_ENUM_ID2 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ + ENCODER_OBJECT_ID_EXTERNAL_SDVOA << OBJECT_ID_SHIFT) + + +#define ENCODER_EXTERNAL_SDVOB_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + ENCODER_OBJECT_ID_EXTERNAL_SDVOB << OBJECT_ID_SHIFT) + + +#define ENCODER_TITFP513_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + ENCODER_OBJECT_ID_TITFP513 << OBJECT_ID_SHIFT) + +#define ENCODER_INTERNAL_LVTM1_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + ENCODER_OBJECT_ID_INTERNAL_LVTM1 << OBJECT_ID_SHIFT) + +#define ENCODER_VT1623_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + ENCODER_OBJECT_ID_VT1623 << OBJECT_ID_SHIFT) + +#define ENCODER_HDMI_SI1930_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + ENCODER_OBJECT_ID_HDMI_SI1930 << OBJECT_ID_SHIFT) + +#define ENCODER_HDMI_INTERNAL_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + ENCODER_OBJECT_ID_HDMI_INTERNAL << OBJECT_ID_SHIFT) + +#define ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1 << OBJECT_ID_SHIFT) + + +#define ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID2 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ + ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1 << OBJECT_ID_SHIFT) + + +#define ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1 << OBJECT_ID_SHIFT) + +#define ENCODER_INTERNAL_KLDSCP_DAC1_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1 << OBJECT_ID_SHIFT) + +#define ENCODER_INTERNAL_KLDSCP_DAC2_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2 << OBJECT_ID_SHIFT) // Shared with CV/TV and CRT + +#define ENCODER_SI178_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + ENCODER_OBJECT_ID_SI178 << OBJECT_ID_SHIFT) + +#define ENCODER_MVPU_FPGA_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + ENCODER_OBJECT_ID_MVPU_FPGA << OBJECT_ID_SHIFT) + +#define ENCODER_INTERNAL_DDI_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + ENCODER_OBJECT_ID_INTERNAL_DDI << OBJECT_ID_SHIFT) + +#define ENCODER_VT1625_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + ENCODER_OBJECT_ID_VT1625 << OBJECT_ID_SHIFT) + +#define ENCODER_HDMI_SI1932_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + ENCODER_OBJECT_ID_HDMI_SI1932 << OBJECT_ID_SHIFT) + +#define ENCODER_DP_DP501_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + ENCODER_OBJECT_ID_DP_DP501 << OBJECT_ID_SHIFT) + +#define ENCODER_DP_AN9801_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + ENCODER_OBJECT_ID_DP_AN9801 << OBJECT_ID_SHIFT) + +#define ENCODER_INTERNAL_UNIPHY_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + ENCODER_OBJECT_ID_INTERNAL_UNIPHY << OBJECT_ID_SHIFT) + +#define ENCODER_INTERNAL_UNIPHY_ENUM_ID2 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ + ENCODER_OBJECT_ID_INTERNAL_UNIPHY << OBJECT_ID_SHIFT) + +#define ENCODER_INTERNAL_KLDSCP_LVTMA_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA << OBJECT_ID_SHIFT) + +#define ENCODER_INTERNAL_UNIPHY1_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + ENCODER_OBJECT_ID_INTERNAL_UNIPHY1 << OBJECT_ID_SHIFT) + +#define ENCODER_INTERNAL_UNIPHY1_ENUM_ID2 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ + ENCODER_OBJECT_ID_INTERNAL_UNIPHY1 << OBJECT_ID_SHIFT) + +#define ENCODER_INTERNAL_UNIPHY2_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + ENCODER_OBJECT_ID_INTERNAL_UNIPHY2 << OBJECT_ID_SHIFT) + +#define ENCODER_INTERNAL_UNIPHY2_ENUM_ID2 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ + ENCODER_OBJECT_ID_INTERNAL_UNIPHY2 << OBJECT_ID_SHIFT) + +#define ENCODER_GENERAL_EXTERNAL_DVO_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + ENCODER_OBJECT_ID_GENERAL_EXTERNAL_DVO << OBJECT_ID_SHIFT) /****************************************************/ /* Connector Object ID definition - Shared with BIOS */ @@ -406,158 +370,129 @@ #define CONNECTOR_7PIN_DIN_ENUM_ID1 0x310F #define CONNECTOR_PCIE_CONNECTOR_ENUM_ID1 0x3110 */ -#define CONNECTOR_LVDS_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_LVDS << OBJECT_ID_SHIFT) - -#define CONNECTOR_SINGLE_LINK_DVI_I_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I << OBJECT_ID_SHIFT) - -#define CONNECTOR_SINGLE_LINK_DVI_I_ENUM_ID2 \ - (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I << OBJECT_ID_SHIFT) - -#define CONNECTOR_DUAL_LINK_DVI_I_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I << OBJECT_ID_SHIFT) - -#define CONNECTOR_DUAL_LINK_DVI_I_ENUM_ID2 \ - (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I << OBJECT_ID_SHIFT) - -#define CONNECTOR_SINGLE_LINK_DVI_D_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D << OBJECT_ID_SHIFT) - -#define CONNECTOR_SINGLE_LINK_DVI_D_ENUM_ID2 \ - (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D << OBJECT_ID_SHIFT) - -#define CONNECTOR_DUAL_LINK_DVI_D_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D << OBJECT_ID_SHIFT) - -#define CONNECTOR_VGA_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_VGA << OBJECT_ID_SHIFT) - -#define CONNECTOR_VGA_ENUM_ID2 \ - (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_VGA << OBJECT_ID_SHIFT) - -#define CONNECTOR_COMPOSITE_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_COMPOSITE << OBJECT_ID_SHIFT) - -#define CONNECTOR_SVIDEO_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_SVIDEO << OBJECT_ID_SHIFT) - -#define CONNECTOR_YPbPr_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_YPbPr << OBJECT_ID_SHIFT) - -#define CONNECTOR_D_CONNECTOR_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_D_CONNECTOR << OBJECT_ID_SHIFT) - -#define CONNECTOR_9PIN_DIN_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_9PIN_DIN << OBJECT_ID_SHIFT) - -#define CONNECTOR_SCART_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_SCART << OBJECT_ID_SHIFT) - -#define CONNECTOR_HDMI_TYPE_A_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_HDMI_TYPE_A << OBJECT_ID_SHIFT) - -#define CONNECTOR_HDMI_TYPE_B_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_HDMI_TYPE_B << OBJECT_ID_SHIFT) - -#define CONNECTOR_7PIN_DIN_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_7PIN_DIN << OBJECT_ID_SHIFT) - -#define CONNECTOR_PCIE_CONNECTOR_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_PCIE_CONNECTOR << OBJECT_ID_SHIFT) - -#define CONNECTOR_PCIE_CONNECTOR_ENUM_ID2 \ - (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_PCIE_CONNECTOR << OBJECT_ID_SHIFT) - -#define CONNECTOR_CROSSFIRE_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_CROSSFIRE << OBJECT_ID_SHIFT) - -#define CONNECTOR_CROSSFIRE_ENUM_ID2 \ - (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_CROSSFIRE << OBJECT_ID_SHIFT) - -#define CONNECTOR_HARDCODE_DVI_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_HARDCODE_DVI << OBJECT_ID_SHIFT) - -#define CONNECTOR_HARDCODE_DVI_ENUM_ID2 \ - (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_HARDCODE_DVI << OBJECT_ID_SHIFT) - -#define CONNECTOR_DISPLAYPORT_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT) - -#define CONNECTOR_DISPLAYPORT_ENUM_ID2 \ - (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT) - -#define CONNECTOR_DISPLAYPORT_ENUM_ID3 \ - (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID3 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT) - -#define CONNECTOR_DISPLAYPORT_ENUM_ID4 \ - (GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID4 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT) +#define CONNECTOR_LVDS_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_LVDS << OBJECT_ID_SHIFT) + +#define CONNECTOR_SINGLE_LINK_DVI_I_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I << OBJECT_ID_SHIFT) + +#define CONNECTOR_SINGLE_LINK_DVI_I_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I << OBJECT_ID_SHIFT) + +#define CONNECTOR_DUAL_LINK_DVI_I_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I << OBJECT_ID_SHIFT) + +#define CONNECTOR_DUAL_LINK_DVI_I_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I << OBJECT_ID_SHIFT) + +#define CONNECTOR_SINGLE_LINK_DVI_D_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D << OBJECT_ID_SHIFT) + +#define CONNECTOR_SINGLE_LINK_DVI_D_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D << OBJECT_ID_SHIFT) + +#define CONNECTOR_DUAL_LINK_DVI_D_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D << OBJECT_ID_SHIFT) + +#define CONNECTOR_VGA_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_VGA << OBJECT_ID_SHIFT) + +#define CONNECTOR_VGA_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_VGA << OBJECT_ID_SHIFT) + +#define CONNECTOR_COMPOSITE_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_COMPOSITE << OBJECT_ID_SHIFT) + +#define CONNECTOR_SVIDEO_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_SVIDEO << OBJECT_ID_SHIFT) + +#define CONNECTOR_YPbPr_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_YPbPr << OBJECT_ID_SHIFT) + +#define CONNECTOR_D_CONNECTOR_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_D_CONNECTOR << OBJECT_ID_SHIFT) + +#define CONNECTOR_9PIN_DIN_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_9PIN_DIN << OBJECT_ID_SHIFT) + +#define CONNECTOR_SCART_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_SCART << OBJECT_ID_SHIFT) + +#define CONNECTOR_HDMI_TYPE_A_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_HDMI_TYPE_A << OBJECT_ID_SHIFT) + +#define CONNECTOR_HDMI_TYPE_B_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_HDMI_TYPE_B << OBJECT_ID_SHIFT) + +#define CONNECTOR_7PIN_DIN_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_7PIN_DIN << OBJECT_ID_SHIFT) + +#define CONNECTOR_PCIE_CONNECTOR_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_PCIE_CONNECTOR << OBJECT_ID_SHIFT) + +#define CONNECTOR_PCIE_CONNECTOR_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_PCIE_CONNECTOR << OBJECT_ID_SHIFT) + +#define CONNECTOR_CROSSFIRE_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_CROSSFIRE << OBJECT_ID_SHIFT) + +#define CONNECTOR_CROSSFIRE_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_CROSSFIRE << OBJECT_ID_SHIFT) + + +#define CONNECTOR_HARDCODE_DVI_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_HARDCODE_DVI << OBJECT_ID_SHIFT) + +#define CONNECTOR_HARDCODE_DVI_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_HARDCODE_DVI << OBJECT_ID_SHIFT) + +#define CONNECTOR_DISPLAYPORT_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT) + +#define CONNECTOR_DISPLAYPORT_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT) + +#define CONNECTOR_DISPLAYPORT_ENUM_ID3 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID3 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT) + +#define CONNECTOR_DISPLAYPORT_ENUM_ID4 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID4 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT) /****************************************************/ /* Router Object ID definition - Shared with BIOS */ /****************************************************/ -#define ROUTER_I2C_EXTENDER_CNTL_ENUM_ID1 \ - (GRAPH_OBJECT_TYPE_ROUTER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ROUTER_OBJECT_ID_I2C_EXTENDER_CNTL << OBJECT_ID_SHIFT) +#define ROUTER_I2C_EXTENDER_CNTL_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ROUTER << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + ROUTER_OBJECT_ID_I2C_EXTENDER_CNTL << OBJECT_ID_SHIFT) /* deleted */ @@ -567,6 +502,7 @@ #define GRAPHICS_OBJECT_CAP_I2C 0x00000001L #define GRAPHICS_OBJECT_CAP_TABLE_ID 0x00000002L + #define GRAPHICS_OBJECT_I2CCOMMAND_TABLE_ID 0x01 #define GRAPHICS_OBJECT_HOTPLUGDETECTIONINTERUPT_TABLE_ID 0x02 #define GRAPHICS_OBJECT_ENCODER_OUTPUT_PROTECTION_TABLE_ID 0x03 @@ -575,4 +511,8 @@ #pragma pack() #endif -#endif /*GRAPHICTYPE */ +#endif /*GRAPHICTYPE */ + + + + -- cgit v0.10.2 From f0f480adcb6c44e76186c6d3036e06ed7e7e0202 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 7 Jan 2010 11:39:07 -0500 Subject: drm/radeon/kms: pull in the latest upstream ObjectID.h changes Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/ObjectID.h b/drivers/gpu/drm/radeon/ObjectID.h index f1f18a4..c714179 100644 --- a/drivers/gpu/drm/radeon/ObjectID.h +++ b/drivers/gpu/drm/radeon/ObjectID.h @@ -106,6 +106,8 @@ #define CONNECTOR_OBJECT_ID_CROSSFIRE 0x11 #define CONNECTOR_OBJECT_ID_HARDCODE_DVI 0x12 #define CONNECTOR_OBJECT_ID_DISPLAYPORT 0x13 +#define CONNECTOR_OBJECT_ID_eDP 0x14 +#define CONNECTOR_OBJECT_ID_MXM 0x15 /* deleted */ @@ -116,7 +118,15 @@ #define ROUTER_OBJECT_ID_I2C_EXTENDER_CNTL 0x01 /****************************************************/ -// Graphics Object ENUM ID Definition */ +/* Generic Object ID Definition */ +/****************************************************/ +#define GENERIC_OBJECT_ID_NONE 0x00 +#define GENERIC_OBJECT_ID_GLSYNC 0x01 +#define GENERIC_OBJECT_ID_PX2_NON_DRIVABLE 0x02 +#define GENERIC_OBJECT_ID_MXM_OPM 0x03 + +/****************************************************/ +/* Graphics Object ENUM ID Definition */ /****************************************************/ #define GRAPH_OBJECT_ENUM_ID1 0x01 #define GRAPH_OBJECT_ENUM_ID2 0x02 @@ -124,6 +134,7 @@ #define GRAPH_OBJECT_ENUM_ID4 0x04 #define GRAPH_OBJECT_ENUM_ID5 0x05 #define GRAPH_OBJECT_ENUM_ID6 0x06 +#define GRAPH_OBJECT_ENUM_ID7 0x07 /****************************************************/ /* Graphics Object ID Bit definition */ @@ -374,6 +385,18 @@ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ CONNECTOR_OBJECT_ID_LVDS << OBJECT_ID_SHIFT) +#define CONNECTOR_LVDS_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_LVDS << OBJECT_ID_SHIFT) + +#define CONNECTOR_eDP_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_eDP << OBJECT_ID_SHIFT) + +#define CONNECTOR_eDP_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_eDP << OBJECT_ID_SHIFT) + #define CONNECTOR_SINGLE_LINK_DVI_I_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I << OBJECT_ID_SHIFT) @@ -402,6 +425,14 @@ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D << OBJECT_ID_SHIFT) +#define CONNECTOR_DUAL_LINK_DVI_D_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D << OBJECT_ID_SHIFT) + +#define CONNECTOR_DUAL_LINK_DVI_D_ENUM_ID3 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID3 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D << OBJECT_ID_SHIFT) + #define CONNECTOR_VGA_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ CONNECTOR_OBJECT_ID_VGA << OBJECT_ID_SHIFT) @@ -414,37 +445,76 @@ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ CONNECTOR_OBJECT_ID_COMPOSITE << OBJECT_ID_SHIFT) +#define CONNECTOR_COMPOSITE_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_COMPOSITE << OBJECT_ID_SHIFT) + #define CONNECTOR_SVIDEO_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ CONNECTOR_OBJECT_ID_SVIDEO << OBJECT_ID_SHIFT) +#define CONNECTOR_SVIDEO_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_SVIDEO << OBJECT_ID_SHIFT) + #define CONNECTOR_YPbPr_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ CONNECTOR_OBJECT_ID_YPbPr << OBJECT_ID_SHIFT) +#define CONNECTOR_YPbPr_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_YPbPr << OBJECT_ID_SHIFT) + #define CONNECTOR_D_CONNECTOR_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ CONNECTOR_OBJECT_ID_D_CONNECTOR << OBJECT_ID_SHIFT) +#define CONNECTOR_D_CONNECTOR_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_D_CONNECTOR << OBJECT_ID_SHIFT) + #define CONNECTOR_9PIN_DIN_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ CONNECTOR_OBJECT_ID_9PIN_DIN << OBJECT_ID_SHIFT) +#define CONNECTOR_9PIN_DIN_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_9PIN_DIN << OBJECT_ID_SHIFT) + #define CONNECTOR_SCART_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ CONNECTOR_OBJECT_ID_SCART << OBJECT_ID_SHIFT) +#define CONNECTOR_SCART_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_SCART << OBJECT_ID_SHIFT) + #define CONNECTOR_HDMI_TYPE_A_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ CONNECTOR_OBJECT_ID_HDMI_TYPE_A << OBJECT_ID_SHIFT) +#define CONNECTOR_HDMI_TYPE_A_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_HDMI_TYPE_A << OBJECT_ID_SHIFT) + +#define CONNECTOR_HDMI_TYPE_A_ENUM_ID3 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID3 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_HDMI_TYPE_A << OBJECT_ID_SHIFT) + #define CONNECTOR_HDMI_TYPE_B_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ CONNECTOR_OBJECT_ID_HDMI_TYPE_B << OBJECT_ID_SHIFT) +#define CONNECTOR_HDMI_TYPE_B_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_HDMI_TYPE_B << OBJECT_ID_SHIFT) + #define CONNECTOR_7PIN_DIN_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ CONNECTOR_OBJECT_ID_7PIN_DIN << OBJECT_ID_SHIFT) +#define CONNECTOR_7PIN_DIN_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_7PIN_DIN << OBJECT_ID_SHIFT) #define CONNECTOR_PCIE_CONNECTOR_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ @@ -487,6 +557,42 @@ GRAPH_OBJECT_ENUM_ID4 << ENUM_ID_SHIFT |\ CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT) +#define CONNECTOR_DISPLAYPORT_ENUM_ID5 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID5 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT) + +#define CONNECTOR_DISPLAYPORT_ENUM_ID6 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID6 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT) + +#define CONNECTOR_MXM_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_MXM << OBJECT_ID_SHIFT) //Mapping to MXM_DP_A + +#define CONNECTOR_MXM_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_MXM << OBJECT_ID_SHIFT) //Mapping to MXM_DP_B + +#define CONNECTOR_MXM_ENUM_ID3 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID3 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_MXM << OBJECT_ID_SHIFT) //Mapping to MXM_DP_C + +#define CONNECTOR_MXM_ENUM_ID4 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID4 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_MXM << OBJECT_ID_SHIFT) //Mapping to MXM_DP_D + +#define CONNECTOR_MXM_ENUM_ID5 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID5 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_MXM << OBJECT_ID_SHIFT) //Mapping to MXM_LVDS_TXxx + +#define CONNECTOR_MXM_ENUM_ID6 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID6 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_MXM << OBJECT_ID_SHIFT) //Mapping to MXM_LVDS_UXxx + +#define CONNECTOR_MXM_ENUM_ID7 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID7 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_MXM << OBJECT_ID_SHIFT) //Mapping to MXM_DAC + /****************************************************/ /* Router Object ID definition - Shared with BIOS */ /****************************************************/ @@ -497,6 +603,25 @@ /* deleted */ /****************************************************/ +/* Generic Object ID definition - Shared with BIOS */ +/****************************************************/ +#define GENERICOBJECT_GLSYNC_ENUM_ID1 (GRAPH_OBJECT_TYPE_GENERIC << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + GENERIC_OBJECT_ID_GLSYNC << OBJECT_ID_SHIFT) + +#define GENERICOBJECT_PX2_NON_DRIVABLE_ID1 (GRAPH_OBJECT_TYPE_GENERIC << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + GENERIC_OBJECT_ID_PX2_NON_DRIVABLE<< OBJECT_ID_SHIFT) + +#define GENERICOBJECT_PX2_NON_DRIVABLE_ID2 (GRAPH_OBJECT_TYPE_GENERIC << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ + GENERIC_OBJECT_ID_PX2_NON_DRIVABLE<< OBJECT_ID_SHIFT) + +#define GENERICOBJECT_MXM_OPM_ENUM_ID1 (GRAPH_OBJECT_TYPE_GENERIC << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + GENERIC_OBJECT_ID_MXM_OPM << OBJECT_ID_SHIFT) + +/****************************************************/ /* Object Cap definition - Shared with BIOS */ /****************************************************/ #define GRAPHICS_OBJECT_CAP_I2C 0x00000001L -- cgit v0.10.2 From 7970e677accb676f15e11468c60cb93ae477a513 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 7 Jan 2010 13:47:47 -0500 Subject: drm: Add eDP connector type Add a new connector type for eDP (embedded displayport) eDP is more or less the same as DP but there are some cases when you might want to handle it separately. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 4a7bbdb..fa19c2b9 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -158,6 +158,7 @@ static struct drm_conn_prop_enum_list drm_connector_enum_list[] = { DRM_MODE_CONNECTOR_HDMIA, "HDMI Type A", 0 }, { DRM_MODE_CONNECTOR_HDMIB, "HDMI Type B", 0 }, { DRM_MODE_CONNECTOR_TV, "TV", 0 }, + { DRM_MODE_CONNECTOR_eDP, "Embedded DisplayPort", 0 }, }; static struct drm_prop_enum_list drm_encoder_enum_list[] = diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h index 43009bc..bc4fdf2 100644 --- a/include/drm/drm_mode.h +++ b/include/drm/drm_mode.h @@ -160,6 +160,7 @@ struct drm_mode_get_encoder { #define DRM_MODE_CONNECTOR_HDMIA 11 #define DRM_MODE_CONNECTOR_HDMIB 12 #define DRM_MODE_CONNECTOR_TV 13 +#define DRM_MODE_CONNECTOR_eDP 14 struct drm_mode_get_connector { -- cgit v0.10.2 From 196c58d21fc47fbabab6a98e23e5a6335f717e44 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 7 Jan 2010 14:22:32 -0500 Subject: drm/radeon/kms: add support for eDP (embedded DisplayPort) This is displayport used for internal connections such as laptop panels and systems with integrated monitors. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index 0d63c44..3eb0ca5 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c @@ -468,7 +468,8 @@ void radeon_dp_set_link_config(struct drm_connector *connector, struct radeon_connector *radeon_connector; struct radeon_connector_atom_dig *dig_connector; - if (connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort) + if ((connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort) || + (connector->connector_type != DRM_MODE_CONNECTOR_eDP)) return; radeon_connector = to_radeon_connector(connector); @@ -582,7 +583,8 @@ void dp_link_train(struct drm_encoder *encoder, u8 train_set[4]; int i; - if (connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort) + if ((connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort) || + (connector->connector_type != DRM_MODE_CONNECTOR_eDP)) return; if (!radeon_encoder->enc_priv) diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 41dd8eb..1834035 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -346,7 +346,9 @@ const int object_connector_convert[] = { DRM_MODE_CONNECTOR_Unknown, DRM_MODE_CONNECTOR_Unknown, DRM_MODE_CONNECTOR_Unknown, - DRM_MODE_CONNECTOR_DisplayPort + DRM_MODE_CONNECTOR_DisplayPort, + DRM_MODE_CONNECTOR_eDP, + DRM_MODE_CONNECTOR_Unknown }; bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index b82ae61..9da10dd 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -49,8 +49,10 @@ void radeon_connector_hotplug(struct drm_connector *connector) if (radeon_connector->hpd.hpd != RADEON_HPD_NONE) radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); - if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) { - if (radeon_dp_getsinktype(radeon_connector) == CONNECTOR_OBJECT_ID_DISPLAYPORT) { + if ((connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) || + (connector->connector_type == DRM_MODE_CONNECTOR_eDP)) { + if ((radeon_dp_getsinktype(radeon_connector) == CONNECTOR_OBJECT_ID_DISPLAYPORT) || + (radeon_dp_getsinktype(radeon_connector) == CONNECTOR_OBJECT_ID_eDP)) { if (radeon_dp_needs_link_train(radeon_connector)) { if (connector->encoder) dp_link_train(connector->encoder, connector); @@ -967,7 +969,8 @@ static enum drm_connector_status radeon_dp_detect(struct drm_connector *connecto } sink_type = radeon_dp_getsinktype(radeon_connector); - if (sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) { + if ((sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || + (sink_type == CONNECTOR_OBJECT_ID_eDP)) { if (radeon_dp_getdpcd(radeon_connector)) { radeon_dig_connector->dp_sink_type = sink_type; ret = connector_status_connected; @@ -992,7 +995,8 @@ static int radeon_dp_mode_valid(struct drm_connector *connector, /* XXX check mode bandwidth */ - if (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) + if ((radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || + (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) return radeon_dp_mode_valid_helper(radeon_connector, mode); else return MODE_OK; @@ -1145,6 +1149,7 @@ radeon_add_atom_connector(struct drm_device *dev, subpixel_order = SubPixelHorizontalRGB; break; case DRM_MODE_CONNECTOR_DisplayPort: + case DRM_MODE_CONNECTOR_eDP: radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); if (!radeon_dig_connector) goto failed; @@ -1157,10 +1162,16 @@ radeon_add_atom_connector(struct drm_device *dev, goto failed; if (i2c_bus->valid) { /* add DP i2c bus */ - radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "DP-auxch"); + if (connector_type == DRM_MODE_CONNECTOR_eDP) + radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "eDP-auxch"); + else + radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "DP-auxch"); if (!radeon_dig_connector->dp_i2c_bus) goto failed; - radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DP"); + if (connector_type == DRM_MODE_CONNECTOR_eDP) + radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "eDP"); + else + radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DP"); if (!radeon_connector->ddc_bus) goto failed; } diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 1fb2f02..0ec491e 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -234,7 +234,7 @@ static const char *encoder_names[34] = { "INTERNAL_UNIPHY2", }; -static const char *connector_names[13] = { +static const char *connector_names[15] = { "Unknown", "VGA", "DVI-I", @@ -248,6 +248,8 @@ static const char *connector_names[13] = { "DisplayPort", "HDMI-A", "HDMI-B", + "TV", + "eDP", }; static const char *hpd_names[7] = { @@ -352,7 +354,8 @@ int radeon_ddc_get_modes(struct radeon_connector *radeon_connector) { int ret = 0; - if (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort) { + if ((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort) || + (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP)) { struct radeon_connector_atom_dig *dig = radeon_connector->con_priv; if (dig->dp_i2c_bus) radeon_connector->edid = drm_get_edid(&radeon_connector->base, &dig->dp_i2c_bus->adapter); diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index 844c513..82eb551 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c @@ -596,8 +596,10 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) return ATOM_ENCODER_MODE_LVDS; break; case DRM_MODE_CONNECTOR_DisplayPort: + case DRM_MODE_CONNECTOR_eDP: radeon_dig_connector = radeon_connector->con_priv; - if (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) + if ((radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || + (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) return ATOM_ENCODER_MODE_DP; else if (drm_detect_hdmi_monitor(radeon_connector->edid)) return ATOM_ENCODER_MODE_HDMI; -- cgit v0.10.2 From fc9a89f97e532152ae614d5ce717b81c8f8b0e91 Mon Sep 17 00:00:00 2001 From: Darren Jenkins Date: Thu, 7 Jan 2010 01:35:21 -0500 Subject: drm/radeon: fix a couple of array index errors There are a couple of array overruns, and some associated confusion in the code. This is just a wild guess at what the code should actually look like. Coverity CID: 13305 13306 agd5f: fix up the original intent of the timing code Signed-off-by: Darren Jenkins Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/radeon_legacy_tv.c b/drivers/gpu/drm/radeon/radeon_legacy_tv.c index 3a12bb0..417684d 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_tv.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_tv.c @@ -77,7 +77,7 @@ struct radeon_tv_mode_constants { unsigned pix_to_tv; }; -static const uint16_t hor_timing_NTSC[] = { +static const uint16_t hor_timing_NTSC[MAX_H_CODE_TIMING_LEN] = { 0x0007, 0x003f, 0x0263, @@ -98,7 +98,7 @@ static const uint16_t hor_timing_NTSC[] = { 0 }; -static const uint16_t vert_timing_NTSC[] = { +static const uint16_t vert_timing_NTSC[MAX_V_CODE_TIMING_LEN] = { 0x2001, 0x200d, 0x1006, @@ -115,7 +115,7 @@ static const uint16_t vert_timing_NTSC[] = { 0 }; -static const uint16_t hor_timing_PAL[] = { +static const uint16_t hor_timing_PAL[MAX_H_CODE_TIMING_LEN] = { 0x0007, 0x0058, 0x027c, @@ -136,7 +136,7 @@ static const uint16_t hor_timing_PAL[] = { 0 }; -static const uint16_t vert_timing_PAL[] = { +static const uint16_t vert_timing_PAL[MAX_V_CODE_TIMING_LEN] = { 0x2001, 0x200c, 0x1005, @@ -623,9 +623,9 @@ void radeon_legacy_tv_mode_set(struct drm_encoder *encoder, } flicker_removal = (tmp + 500) / 1000; - if (flicker_removal < 3) - flicker_removal = 3; - for (i = 0; i < 6; ++i) { + if (flicker_removal < 2) + flicker_removal = 2; + for (i = 0; i < ARRAY_SIZE(SLOPE_limit); ++i) { if (flicker_removal == SLOPE_limit[i]) break; } -- cgit v0.10.2 From 06b6476d6b291473d0928ed242158a001d50c0f0 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 5 Jan 2010 11:27:29 -0500 Subject: drm/radeon/kms: detect sideport memory on IGP chips This detects if the sideport memory is enabled and if it is VRAM is evicted on suspend/resume. This should fix s/r issues on some IGPs. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 5c6058c..921926f 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -726,6 +726,10 @@ int r600_mc_init(struct radeon_device *rdev) a.full = rfixed_const(100); rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk); rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a); + + if (rdev->flags & RADEON_IS_IGP) + rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); + return 0; } diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 53b5560..a7e349d 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -319,10 +319,12 @@ struct radeon_mc { u64 real_vram_size; int vram_mtrr; bool vram_is_ddr; + bool igp_sideport_enabled; }; int radeon_mc_setup(struct radeon_device *rdev); - +bool radeon_combios_sideport_present(struct radeon_device *rdev); +bool radeon_atombios_sideport_present(struct radeon_device *rdev); /* * GPU scratch registers structures, functions & helpers diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 1834035..fa82ca7 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -938,6 +938,43 @@ bool radeon_atom_get_clock_info(struct drm_device *dev) return false; } +union igp_info { + struct _ATOM_INTEGRATED_SYSTEM_INFO info; + struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_2; +}; + +bool radeon_atombios_sideport_present(struct radeon_device *rdev) +{ + struct radeon_mode_info *mode_info = &rdev->mode_info; + int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo); + union igp_info *igp_info; + u8 frev, crev; + u16 data_offset; + + atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, + &crev, &data_offset); + + igp_info = (union igp_info *)(mode_info->atom_context->bios + + data_offset); + + if (igp_info) { + switch (crev) { + case 1: + if (igp_info->info.ucMemoryType & 0xf0) + return true; + break; + case 2: + if (igp_info->info_2.ucMemoryType & 0x0f) + return true; + break; + default: + DRM_ERROR("Unsupported IGP table: %d %d\n", frev, crev); + break; + } + } + return false; +} + bool radeon_atombios_get_tmds_info(struct radeon_encoder *encoder, struct radeon_encoder_int_tmds *tmds) { diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 58f3426..7914455 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c @@ -595,6 +595,20 @@ bool radeon_combios_get_clock_info(struct drm_device *dev) return false; } +bool radeon_combios_sideport_present(struct radeon_device *rdev) +{ + struct drm_device *dev = rdev->ddev; + u16 igp_info; + + igp_info = combios_get_table_offset(dev, COMBIOS_INTEGRATED_SYSTEM_INFO_TABLE); + + if (igp_info) { + if (RBIOS16(igp_info + 0x4)) + return true; + } + return false; +} + static const uint32_t default_primarydac_adj[CHIP_LAST] = { 0x00000808, /* r100 */ 0x00000808, /* rv100 */ diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index d9ffe1f..4e636de 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c @@ -221,8 +221,9 @@ int radeon_bo_unpin(struct radeon_bo *bo) int radeon_bo_evict_vram(struct radeon_device *rdev) { if (rdev->flags & RADEON_IS_IGP) { - /* Useless to evict on IGP chips */ - return 0; + if (rdev->mc.igp_sideport_enabled == false) + /* Useless to evict on IGP chips */ + return 0; } return ttm_bo_evict_mm(&rdev->mman.bdev, TTM_PL_VRAM); } diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c index 368415d..bf7b3cf 100644 --- a/drivers/gpu/drm/radeon/rs400.c +++ b/drivers/gpu/drm/radeon/rs400.c @@ -356,6 +356,7 @@ static int rs400_mc_init(struct radeon_device *rdev) rdev->mc.vram_location = G_00015C_MC_FB_START(tmp) << 16; rdev->mc.gtt_location = 0xFFFFFFFFUL; r = radeon_mc_setup(rdev); + rdev->mc.igp_sideport_enabled = radeon_combios_sideport_present(rdev); if (r) return r; return 0; diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 4245218..1925894 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c @@ -56,6 +56,7 @@ int rs600_mc_init(struct radeon_device *rdev) rdev->mc.vram_location = G_000004_MC_FB_START(tmp) << 16; rdev->mc.gtt_location = 0xffffffffUL; r = radeon_mc_setup(rdev); + rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); if (r) return r; return 0; diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index 1e22f52..42f2720 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c @@ -172,6 +172,7 @@ static int rs690_mc_init(struct radeon_device *rdev) rdev->mc.vram_location = G_000100_MC_FB_START(tmp) << 16; rdev->mc.gtt_location = 0xFFFFFFFFUL; r = radeon_mc_setup(rdev); + rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); if (r) return r; return 0; -- cgit v0.10.2 From 62cdc0c20663ef840a94850892517b2b7f584904 Mon Sep 17 00:00:00 2001 From: Corbin Simpson Date: Wed, 6 Jan 2010 19:28:48 +0100 Subject: drm/radeon/kms: Workaround RV410/R420 CP errata (V3) Long story short, this fixes sporadic hardlocks with my rv410 during times of intense 2D acceleration (Flash on Fx3). V2: Fix indentation and move errata_fini to suspend function so we don't leak scratch register over suspend/resume cycle. V3: Move scratch_reg to asic specific structure (aim is to slowly move stuff to asic specific structure and avoid poluting radeon_device struct with asic specific variables) Signed-off-by: Corbin Simpson Signed-off-by: Jerome Glisse Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c index c05a727..f46502a 100644 --- a/drivers/gpu/drm/radeon/r420.c +++ b/drivers/gpu/drm/radeon/r420.c @@ -30,6 +30,7 @@ #include "radeon_reg.h" #include "radeon.h" #include "atom.h" +#include "r100d.h" #include "r420d.h" int r420_mc_init(struct radeon_device *rdev) @@ -165,6 +166,34 @@ static void r420_clock_resume(struct radeon_device *rdev) WREG32_PLL(R_00000D_SCLK_CNTL, sclk_cntl); } +static void r420_cp_errata_init(struct radeon_device *rdev) +{ + /* RV410 and R420 can lock up if CP DMA to host memory happens + * while the 2D engine is busy. + * + * The proper workaround is to queue a RESYNC at the beginning + * of the CP init, apparently. + */ + radeon_scratch_get(rdev, &rdev->config.r300.resync_scratch); + radeon_ring_lock(rdev, 8); + radeon_ring_write(rdev, PACKET0(R300_CP_RESYNC_ADDR, 1)); + radeon_ring_write(rdev, rdev->config.r300.resync_scratch); + radeon_ring_write(rdev, 0xDEADBEEF); + radeon_ring_unlock_commit(rdev); +} + +static void r420_cp_errata_fini(struct radeon_device *rdev) +{ + /* Catch the RESYNC we dispatched all the way back, + * at the very beginning of the CP init. + */ + radeon_ring_lock(rdev, 8); + radeon_ring_write(rdev, PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); + radeon_ring_write(rdev, R300_RB3D_DC_FINISH); + radeon_ring_unlock_commit(rdev); + radeon_scratch_free(rdev, rdev->config.r300.resync_scratch); +} + static int r420_startup(struct radeon_device *rdev) { int r; @@ -196,6 +225,7 @@ static int r420_startup(struct radeon_device *rdev) dev_err(rdev->dev, "failled initializing CP (%d).\n", r); return r; } + r420_cp_errata_init(rdev); r = r100_wb_init(rdev); if (r) { dev_err(rdev->dev, "failled initializing WB (%d).\n", r); @@ -238,6 +268,7 @@ int r420_resume(struct radeon_device *rdev) int r420_suspend(struct radeon_device *rdev) { + r420_cp_errata_fini(rdev); r100_cp_disable(rdev); r100_wb_disable(rdev); r100_irq_disable(rdev); diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index a7e349d..cee8bdc 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -674,6 +674,7 @@ struct r100_asic { struct r300_asic { const unsigned *reg_safe_bm; unsigned reg_safe_bm_size; + u32 resync_scratch; }; struct r600_asic { -- cgit v0.10.2 From cafe6609d6dc0a6a278f9fdbb59ce4d761a35ddd Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Thu, 7 Jan 2010 12:39:21 +0100 Subject: drm/radeon/kms: Schedule host path read cache flush through the ring V2 R300 family will hard lockup if host path read cache flush is done through MMIO to HOST_PATH_CNTL. But scheduling same flush through ring seems harmless. This patch remove the hdp_flush callback and add a flush after each fence emission which means a flush after each IB schedule. Thus we should have same behavior without the hard lockup. Tested on R100,R200,R300,R400,R500,R600,R700 family. V2: Adjust fence counts in r600_blit_prepare_copy() Signed-off-by: Jerome Glisse Reviewed-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 7172746..1a056b7 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -356,6 +356,11 @@ void r100_fence_ring_emit(struct radeon_device *rdev, /* Wait until IDLE & CLEAN */ radeon_ring_write(rdev, PACKET0(0x1720, 0)); radeon_ring_write(rdev, (1 << 16) | (1 << 17)); + radeon_ring_write(rdev, PACKET0(RADEON_HOST_PATH_CNTL, 0)); + radeon_ring_write(rdev, rdev->config.r100.hdp_cntl | + RADEON_HDP_READ_BUFFER_INVALIDATE); + radeon_ring_write(rdev, PACKET0(RADEON_HOST_PATH_CNTL, 0)); + radeon_ring_write(rdev, rdev->config.r100.hdp_cntl); /* Emit fence sequence & fire IRQ */ radeon_ring_write(rdev, PACKET0(rdev->fence_drv.scratch_reg, 0)); radeon_ring_write(rdev, fence->seq); @@ -1713,14 +1718,6 @@ void r100_gpu_init(struct radeon_device *rdev) r100_hdp_reset(rdev); } -void r100_hdp_flush(struct radeon_device *rdev) -{ - u32 tmp; - tmp = RREG32(RADEON_HOST_PATH_CNTL); - tmp |= RADEON_HDP_READ_BUFFER_INVALIDATE; - WREG32(RADEON_HOST_PATH_CNTL, tmp); -} - void r100_hdp_reset(struct radeon_device *rdev) { uint32_t tmp; @@ -3313,6 +3310,7 @@ static int r100_startup(struct radeon_device *rdev) } /* Enable IRQ */ r100_irq_set(rdev); + rdev->config.r100.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); /* 1M ring buffer */ r = r100_cp_init(rdev, 1024 * 1024); if (r) { diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 3f2cc9e..b8623b7 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c @@ -36,7 +36,15 @@ #include "rv350d.h" #include "r300_reg_safe.h" -/* This files gather functions specifics to: r300,r350,rv350,rv370,rv380 */ +/* This files gather functions specifics to: r300,r350,rv350,rv370,rv380 + * + * GPU Errata: + * - HOST_PATH_CNTL: r300 family seems to dislike write to HOST_PATH_CNTL + * using MMIO to flush host path read cache, this lead to HARDLOCKUP. + * However, scheduling such write to the ring seems harmless, i suspect + * the CP read collide with the flush somehow, or maybe the MC, hard to + * tell. (Jerome Glisse) + */ /* * rv370,rv380 PCIE GART @@ -178,6 +186,11 @@ void r300_fence_ring_emit(struct radeon_device *rdev, /* Wait until IDLE & CLEAN */ radeon_ring_write(rdev, PACKET0(0x1720, 0)); radeon_ring_write(rdev, (1 << 17) | (1 << 16) | (1 << 9)); + radeon_ring_write(rdev, PACKET0(RADEON_HOST_PATH_CNTL, 0)); + radeon_ring_write(rdev, rdev->config.r300.hdp_cntl | + RADEON_HDP_READ_BUFFER_INVALIDATE); + radeon_ring_write(rdev, PACKET0(RADEON_HOST_PATH_CNTL, 0)); + radeon_ring_write(rdev, rdev->config.r300.hdp_cntl); /* Emit fence sequence & fire IRQ */ radeon_ring_write(rdev, PACKET0(rdev->fence_drv.scratch_reg, 0)); radeon_ring_write(rdev, fence->seq); @@ -1258,6 +1271,7 @@ static int r300_startup(struct radeon_device *rdev) } /* Enable IRQ */ r100_irq_set(rdev); + rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); /* 1M ring buffer */ r = r100_cp_init(rdev, 1024 * 1024); if (r) { diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c index f46502a..1d4d16e 100644 --- a/drivers/gpu/drm/radeon/r420.c +++ b/drivers/gpu/drm/radeon/r420.c @@ -219,6 +219,7 @@ static int r420_startup(struct radeon_device *rdev) r420_pipes_init(rdev); /* Enable IRQ */ r100_irq_set(rdev); + rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); /* 1M ring buffer */ r = r100_cp_init(rdev, 1024 * 1024); if (r) { diff --git a/drivers/gpu/drm/radeon/r520.c b/drivers/gpu/drm/radeon/r520.c index 0f3843b..9a18907 100644 --- a/drivers/gpu/drm/radeon/r520.c +++ b/drivers/gpu/drm/radeon/r520.c @@ -186,6 +186,7 @@ static int r520_startup(struct radeon_device *rdev) } /* Enable IRQ */ rs600_irq_set(rdev); + rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); /* 1M ring buffer */ r = r100_cp_init(rdev, 1024 * 1024); if (r) { diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 921926f..e2f43c1 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -1388,11 +1388,6 @@ void r600_pciep_wreg(struct radeon_device *rdev, u32 reg, u32 v) (void)RREG32(PCIE_PORT_DATA); } -void r600_hdp_flush(struct radeon_device *rdev) -{ - WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); -} - /* * CP & Ring */ @@ -1789,6 +1784,8 @@ void r600_fence_ring_emit(struct radeon_device *rdev, radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); radeon_ring_write(rdev, ((rdev->fence_drv.scratch_reg - PACKET3_SET_CONFIG_REG_OFFSET) >> 2)); radeon_ring_write(rdev, fence->seq); + radeon_ring_write(rdev, PACKET0(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0)); + radeon_ring_write(rdev, 1); /* CP_INTERRUPT packet 3 no longer exists, use packet 0 */ radeon_ring_write(rdev, PACKET0(CP_INT_STATUS, 0)); radeon_ring_write(rdev, RB_INT_STAT); diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c index 9aecafb..8787ea8 100644 --- a/drivers/gpu/drm/radeon/r600_blit_kms.c +++ b/drivers/gpu/drm/radeon/r600_blit_kms.c @@ -577,9 +577,9 @@ int r600_blit_prepare_copy(struct radeon_device *rdev, int size_bytes) ring_size = num_loops * dwords_per_loop; /* set default + shaders */ ring_size += 40; /* shaders + def state */ - ring_size += 5; /* fence emit for VB IB */ + ring_size += 7; /* fence emit for VB IB */ ring_size += 5; /* done copy */ - ring_size += 5; /* fence emit for done copy */ + ring_size += 7; /* fence emit for done copy */ r = radeon_ring_lock(rdev, ring_size); WARN_ON(r); diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index cee8bdc..eb5f99b 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -656,7 +656,6 @@ struct radeon_asic { uint32_t offset, uint32_t obj_size); int (*clear_surface_reg)(struct radeon_device *rdev, int reg); void (*bandwidth_update)(struct radeon_device *rdev); - void (*hdp_flush)(struct radeon_device *rdev); void (*hpd_init)(struct radeon_device *rdev); void (*hpd_fini)(struct radeon_device *rdev); bool (*hpd_sense)(struct radeon_device *rdev, enum radeon_hpd_id hpd); @@ -669,12 +668,14 @@ struct radeon_asic { struct r100_asic { const unsigned *reg_safe_bm; unsigned reg_safe_bm_size; + u32 hdp_cntl; }; struct r300_asic { const unsigned *reg_safe_bm; unsigned reg_safe_bm_size; u32 resync_scratch; + u32 hdp_cntl; }; struct r600_asic { @@ -1010,7 +1011,6 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v) #define radeon_set_surface_reg(rdev, r, f, p, o, s) ((rdev)->asic->set_surface_reg((rdev), (r), (f), (p), (o), (s))) #define radeon_clear_surface_reg(rdev, r) ((rdev)->asic->clear_surface_reg((rdev), (r))) #define radeon_bandwidth_update(rdev) (rdev)->asic->bandwidth_update((rdev)) -#define radeon_hdp_flush(rdev) (rdev)->asic->hdp_flush((rdev)) #define radeon_hpd_init(rdev) (rdev)->asic->hpd_init((rdev)) #define radeon_hpd_fini(rdev) (rdev)->asic->hpd_fini((rdev)) #define radeon_hpd_sense(rdev, hpd) (rdev)->asic->hpd_sense((rdev), (hpd)) diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index eb29217..f2fbd2e 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h @@ -77,7 +77,6 @@ int r100_clear_surface_reg(struct radeon_device *rdev, int reg); void r100_bandwidth_update(struct radeon_device *rdev); void r100_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); int r100_ring_test(struct radeon_device *rdev); -void r100_hdp_flush(struct radeon_device *rdev); void r100_hpd_init(struct radeon_device *rdev); void r100_hpd_fini(struct radeon_device *rdev); bool r100_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); @@ -114,7 +113,6 @@ static struct radeon_asic r100_asic = { .set_surface_reg = r100_set_surface_reg, .clear_surface_reg = r100_clear_surface_reg, .bandwidth_update = &r100_bandwidth_update, - .hdp_flush = &r100_hdp_flush, .hpd_init = &r100_hpd_init, .hpd_fini = &r100_hpd_fini, .hpd_sense = &r100_hpd_sense, @@ -174,7 +172,6 @@ static struct radeon_asic r300_asic = { .set_surface_reg = r100_set_surface_reg, .clear_surface_reg = r100_clear_surface_reg, .bandwidth_update = &r100_bandwidth_update, - .hdp_flush = &r100_hdp_flush, .hpd_init = &r100_hpd_init, .hpd_fini = &r100_hpd_fini, .hpd_sense = &r100_hpd_sense, @@ -218,7 +215,6 @@ static struct radeon_asic r420_asic = { .set_surface_reg = r100_set_surface_reg, .clear_surface_reg = r100_clear_surface_reg, .bandwidth_update = &r100_bandwidth_update, - .hdp_flush = &r100_hdp_flush, .hpd_init = &r100_hpd_init, .hpd_fini = &r100_hpd_fini, .hpd_sense = &r100_hpd_sense, @@ -267,7 +263,6 @@ static struct radeon_asic rs400_asic = { .set_surface_reg = r100_set_surface_reg, .clear_surface_reg = r100_clear_surface_reg, .bandwidth_update = &r100_bandwidth_update, - .hdp_flush = &r100_hdp_flush, .hpd_init = &r100_hpd_init, .hpd_fini = &r100_hpd_fini, .hpd_sense = &r100_hpd_sense, @@ -324,7 +319,6 @@ static struct radeon_asic rs600_asic = { .set_pcie_lanes = NULL, .set_clock_gating = &radeon_atom_set_clock_gating, .bandwidth_update = &rs600_bandwidth_update, - .hdp_flush = &r100_hdp_flush, .hpd_init = &rs600_hpd_init, .hpd_fini = &rs600_hpd_fini, .hpd_sense = &rs600_hpd_sense, @@ -372,7 +366,6 @@ static struct radeon_asic rs690_asic = { .set_surface_reg = r100_set_surface_reg, .clear_surface_reg = r100_clear_surface_reg, .bandwidth_update = &rs690_bandwidth_update, - .hdp_flush = &r100_hdp_flush, .hpd_init = &rs600_hpd_init, .hpd_fini = &rs600_hpd_fini, .hpd_sense = &rs600_hpd_sense, @@ -424,7 +417,6 @@ static struct radeon_asic rv515_asic = { .set_surface_reg = r100_set_surface_reg, .clear_surface_reg = r100_clear_surface_reg, .bandwidth_update = &rv515_bandwidth_update, - .hdp_flush = &r100_hdp_flush, .hpd_init = &rs600_hpd_init, .hpd_fini = &rs600_hpd_fini, .hpd_sense = &rs600_hpd_sense, @@ -467,7 +459,6 @@ static struct radeon_asic r520_asic = { .set_surface_reg = r100_set_surface_reg, .clear_surface_reg = r100_clear_surface_reg, .bandwidth_update = &rv515_bandwidth_update, - .hdp_flush = &r100_hdp_flush, .hpd_init = &rs600_hpd_init, .hpd_fini = &rs600_hpd_fini, .hpd_sense = &rs600_hpd_sense, @@ -508,7 +499,6 @@ int r600_ring_test(struct radeon_device *rdev); int r600_copy_blit(struct radeon_device *rdev, uint64_t src_offset, uint64_t dst_offset, unsigned num_pages, struct radeon_fence *fence); -void r600_hdp_flush(struct radeon_device *rdev); void r600_hpd_init(struct radeon_device *rdev); void r600_hpd_fini(struct radeon_device *rdev); bool r600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); @@ -544,7 +534,6 @@ static struct radeon_asic r600_asic = { .set_surface_reg = r600_set_surface_reg, .clear_surface_reg = r600_clear_surface_reg, .bandwidth_update = &rv515_bandwidth_update, - .hdp_flush = &r600_hdp_flush, .hpd_init = &r600_hpd_init, .hpd_fini = &r600_hpd_fini, .hpd_sense = &r600_hpd_sense, @@ -589,7 +578,6 @@ static struct radeon_asic rv770_asic = { .set_surface_reg = r600_set_surface_reg, .clear_surface_reg = r600_clear_surface_reg, .bandwidth_update = &rv515_bandwidth_update, - .hdp_flush = &r600_hdp_flush, .hpd_init = &r600_hpd_init, .hpd_fini = &r600_hpd_fini, .hpd_sense = &r600_hpd_sense, diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index 60df2d7..0e1325e 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c @@ -131,7 +131,6 @@ int radeon_gem_set_domain(struct drm_gem_object *gobj, printk(KERN_ERR "Failed to wait for object !\n"); return r; } - radeon_hdp_flush(robj->rdev); } return 0; } @@ -312,7 +311,6 @@ int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data, mutex_lock(&dev->struct_mutex); drm_gem_object_unreference(gobj); mutex_unlock(&dev->struct_mutex); - radeon_hdp_flush(robj->rdev); return r; } diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c index bf7b3cf..9f54189 100644 --- a/drivers/gpu/drm/radeon/rs400.c +++ b/drivers/gpu/drm/radeon/rs400.c @@ -396,6 +396,7 @@ static int rs400_startup(struct radeon_device *rdev) return r; /* Enable IRQ */ r100_irq_set(rdev); + rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); /* 1M ring buffer */ r = r100_cp_init(rdev, 1024 * 1024); if (r) { diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 1925894..a0378c5 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c @@ -554,6 +554,7 @@ static int rs600_startup(struct radeon_device *rdev) return r; /* Enable IRQ */ rs600_irq_set(rdev); + rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); /* 1M ring buffer */ r = r100_cp_init(rdev, 1024 * 1024); if (r) { diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index 42f2720..cd31da9 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c @@ -626,6 +626,7 @@ static int rs690_startup(struct radeon_device *rdev) return r; /* Enable IRQ */ rs600_irq_set(rdev); + rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); /* 1M ring buffer */ r = r100_cp_init(rdev, 1024 * 1024); if (r) { diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index 59632a5..6275671 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c @@ -479,6 +479,7 @@ static int rv515_startup(struct radeon_device *rdev) } /* Enable IRQ */ rs600_irq_set(rdev); + rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); /* 1M ring buffer */ r = r100_cp_init(rdev, 1024 * 1024); if (r) { -- cgit v0.10.2 From d0269ed8580b492df75dafb011dc51a1390bf200 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Thu, 7 Jan 2010 16:08:32 +0100 Subject: drm/radeon/kms: Make sure we release AGP device if we acquired it In some case we weren't releasing the AGP device at module unloading. This leaded to unfunctional AGP at next module load. This patch make sure we release the AGP bus if we acquire it. Signed-off-by: Jerome Glisse Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 1a056b7..d2b789e 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -3369,6 +3369,7 @@ void r100_fini(struct radeon_device *rdev) radeon_gem_fini(rdev); if (rdev->flags & RADEON_IS_PCI) r100_pci_gart_fini(rdev); + radeon_agp_fini(rdev); radeon_irq_kms_fini(rdev); radeon_fence_driver_fini(rdev); radeon_bo_fini(rdev); diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index b8623b7..0051d11 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c @@ -1336,6 +1336,7 @@ void r300_fini(struct radeon_device *rdev) rv370_pcie_gart_fini(rdev); if (rdev->flags & RADEON_IS_PCI) r100_pci_gart_fini(rdev); + radeon_agp_fini(rdev); radeon_irq_kms_fini(rdev); radeon_fence_driver_fini(rdev); radeon_bo_fini(rdev); diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index e2f43c1..0c065f4 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -2090,8 +2090,7 @@ void r600_fini(struct radeon_device *rdev) radeon_gem_fini(rdev); radeon_fence_driver_fini(rdev); radeon_clocks_fini(rdev); - if (rdev->flags & RADEON_IS_AGP) - radeon_agp_fini(rdev); + radeon_agp_fini(rdev); radeon_bo_fini(rdev); radeon_atombios_fini(rdev); kfree(rdev->bios); diff --git a/drivers/gpu/drm/radeon/radeon_agp.c b/drivers/gpu/drm/radeon/radeon_agp.c index 54bf49a..220f454 100644 --- a/drivers/gpu/drm/radeon/radeon_agp.c +++ b/drivers/gpu/drm/radeon/radeon_agp.c @@ -252,10 +252,8 @@ void radeon_agp_resume(struct radeon_device *rdev) void radeon_agp_fini(struct radeon_device *rdev) { #if __OS_HAS_AGP - if (rdev->flags & RADEON_IS_AGP) { - if (rdev->ddev->agp && rdev->ddev->agp->acquired) { - drm_agp_release(rdev->ddev); - } + if (rdev->ddev->agp && rdev->ddev->agp->acquired) { + drm_agp_release(rdev->ddev); } #endif } diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index f58dc67..16f7317 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -1096,8 +1096,7 @@ void rv770_fini(struct radeon_device *rdev) radeon_gem_fini(rdev); radeon_fence_driver_fini(rdev); radeon_clocks_fini(rdev); - if (rdev->flags & RADEON_IS_AGP) - radeon_agp_fini(rdev); + radeon_agp_fini(rdev); radeon_bo_fini(rdev); radeon_atombios_fini(rdev); kfree(rdev->bios); -- cgit v0.10.2 From 059d233f9c1183ed2f59d631e4daf486060e880d Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Thu, 7 Jan 2010 02:59:31 +0300 Subject: drm/radeon: mkregtable.c: close a file before exit Signed-off-by: Alexander Beregalov Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/mkregtable.c b/drivers/gpu/drm/radeon/mkregtable.c index 0d79577..607241c 100644 --- a/drivers/gpu/drm/radeon/mkregtable.c +++ b/drivers/gpu/drm/radeon/mkregtable.c @@ -661,8 +661,10 @@ static int parser_auth(struct table *t, const char *filename) fseek(file, 0, SEEK_SET); /* get header */ - if (fgets(buf, 1024, file) == NULL) + if (fgets(buf, 1024, file) == NULL) { + fclose(file); return -1; + } /* first line will contain the last register * and gpu name */ -- cgit v0.10.2 From e77cef9c2d87db835ad9d70cde4a9b00b0ca2262 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Thu, 7 Jan 2010 15:39:13 +0100 Subject: drm: Avoid calling vblank function is vblank wasn't initialized In some case vblank might not be initialized and we shouldn't try to use associated function. This patch make sure this is the case. It also export drm_vblank_cleanup so driver can cleanup vblank if for any reason IRQ/MSI is not working. Signed-off-by: Jerome Glisse Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 7998ee6..b98384d 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -115,6 +115,7 @@ void drm_vblank_cleanup(struct drm_device *dev) dev->num_crtcs = 0; } +EXPORT_SYMBOL(drm_vblank_cleanup); int drm_vblank_init(struct drm_device *dev, int num_crtcs) { @@ -163,7 +164,6 @@ int drm_vblank_init(struct drm_device *dev, int num_crtcs) } dev->vblank_disable_allowed = 0; - return 0; err: @@ -493,6 +493,9 @@ EXPORT_SYMBOL(drm_vblank_off); */ void drm_vblank_pre_modeset(struct drm_device *dev, int crtc) { + /* vblank is not initialized (IRQ not installed ?) */ + if (!dev->num_crtcs) + return; /* * To avoid all the problems that might happen if interrupts * were enabled/disabled around or between these calls, we just -- cgit v0.10.2 From 003e69f9862bcda89a75c27750efdbc17ac02945 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Thu, 7 Jan 2010 15:39:14 +0100 Subject: drm/radeon/kms: Don't try to enable IRQ if we have no handler installed If for any reason we haven't installed handler we shouldn't try to enable IRQ/MSI on the hw so we don't get unhandled IRQ/MSI which makes the kernel sad. Signed-off-by: Jerome Glisse Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index d2b789e..8760d66 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -131,7 +131,8 @@ void r100_hpd_init(struct radeon_device *rdev) break; } } - r100_irq_set(rdev); + if (rdev->irq.installed) + r100_irq_set(rdev); } void r100_hpd_fini(struct radeon_device *rdev) @@ -243,6 +244,11 @@ int r100_irq_set(struct radeon_device *rdev) { uint32_t tmp = 0; + if (!rdev->irq.installed) { + WARN(1, "Can't enable IRQ/MSI because no handler is installed.\n"); + WREG32(R_000040_GEN_INT_CNTL, 0); + return -EINVAL; + } if (rdev->irq.sw_int) { tmp |= RADEON_SW_INT_ENABLE; } diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 0c065f4..1f4f83d 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -285,7 +285,8 @@ void r600_hpd_init(struct radeon_device *rdev) } } } - r600_irq_set(rdev); + if (rdev->irq.installed) + r600_irq_set(rdev); } void r600_hpd_fini(struct radeon_device *rdev) @@ -2461,6 +2462,10 @@ int r600_irq_set(struct radeon_device *rdev) u32 mode_int = 0; u32 hpd1, hpd2, hpd3, hpd4 = 0, hpd5 = 0, hpd6 = 0; + if (!rdev->irq.installed) { + WARN(1, "Can't enable IRQ/MSI because no handler is installed.\n"); + return -EINVAL; + } /* don't enable anything if the ih is disabled */ if (!rdev->ih.enabled) return 0; diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c index 9223296..3cfd60f 100644 --- a/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c @@ -97,6 +97,7 @@ void radeon_driver_irq_uninstall_kms(struct drm_device *dev) rdev->irq.sw_int = false; for (i = 0; i < 2; i++) { rdev->irq.crtc_vblank_int[i] = false; + rdev->irq.hpd[i] = false; } radeon_irq_set(rdev); } @@ -128,17 +129,22 @@ int radeon_irq_kms_init(struct radeon_device *rdev) DRM_INFO("radeon: using MSI.\n"); } } - drm_irq_install(rdev->ddev); rdev->irq.installed = true; + r = drm_irq_install(rdev->ddev); + if (r) { + rdev->irq.installed = false; + return r; + } DRM_INFO("radeon: irq initialized.\n"); return 0; } void radeon_irq_kms_fini(struct radeon_device *rdev) { + drm_vblank_cleanup(rdev->ddev); if (rdev->irq.installed) { - rdev->irq.installed = false; drm_irq_uninstall(rdev->ddev); + rdev->irq.installed = false; if (rdev->msi_enabled) pci_disable_msi(rdev->pdev); } diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index a0378c5..d525575 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c @@ -135,7 +135,8 @@ void rs600_hpd_init(struct radeon_device *rdev) break; } } - rs600_irq_set(rdev); + if (rdev->irq.installed) + rs600_irq_set(rdev); } void rs600_hpd_fini(struct radeon_device *rdev) @@ -316,6 +317,11 @@ int rs600_irq_set(struct radeon_device *rdev) u32 hpd2 = RREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL) & ~S_007D18_DC_HOT_PLUG_DETECT2_INT_EN(1); + if (!rdev->irq.installed) { + WARN(1, "Can't enable IRQ/MSI because no handler is installed.\n"); + WREG32(R_000040_GEN_INT_CNTL, 0); + return -EINVAL; + } if (rdev->irq.sw_int) { tmp |= S_000040_SW_INT_EN(1); } -- cgit v0.10.2 From 704da560c0a0120d8869187f511491a00951a1d3 Mon Sep 17 00:00:00 2001 From: Octavian Purdila Date: Fri, 8 Jan 2010 00:00:09 -0800 Subject: tcp: update the netstamp_needed counter when cloning sockets This fixes a netstamp_needed accounting issue when the listen socket has SO_TIMESTAMP set: s = socket(AF_INET, SOCK_STREAM, 0); setsockopt(s, SOL_SOCKET, SO_TIMESTAMP, 1); -> netstamp_needed = 1 bind(s, ...); listen(s, ...); s2 = accept(s, ...); -> netstamp_needed = 1 close(s2); -> netstamp_needed = 0 close(s); -> netstamp_needed = -1 Signed-off-by: Octavian Purdila Signed-off-by: David S. Miller diff --git a/net/core/sock.c b/net/core/sock.c index 76ff58d..e1f6f22 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -1205,6 +1205,10 @@ struct sock *sk_clone(const struct sock *sk, const gfp_t priority) if (newsk->sk_prot->sockets_allocated) percpu_counter_inc(newsk->sk_prot->sockets_allocated); + + if (sock_flag(newsk, SOCK_TIMESTAMP) || + sock_flag(newsk, SOCK_TIMESTAMPING_RX_SOFTWARE)) + net_enable_timestamp(); } out: return newsk; -- cgit v0.10.2 From 444c1953d496d272208902ff7010dc70d1f887f0 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sun, 3 Jan 2010 12:39:27 +0100 Subject: sound: oss: off by one bug The problem is that in the original code sound_nblocks could go up to 1024 which would be an array overflow. This was found with a static checker and has been compile tested only. Signed-off-by: Dan Carpenter Signed-off-by: Jaroslav Kysela diff --git a/sound/oss/dev_table.c b/sound/oss/dev_table.c index 08274c9..727bdb9 100644 --- a/sound/oss/dev_table.c +++ b/sound/oss/dev_table.c @@ -67,14 +67,15 @@ int sound_install_audiodrv(int vers, char *name, struct audio_driver *driver, return -(EBUSY); } d = (struct audio_driver *) (sound_mem_blocks[sound_nblocks] = vmalloc(sizeof(struct audio_driver))); - - if (sound_nblocks < 1024) - sound_nblocks++; + sound_nblocks++; + if (sound_nblocks >= MAX_MEM_BLOCKS) + sound_nblocks = MAX_MEM_BLOCKS - 1; op = (struct audio_operations *) (sound_mem_blocks[sound_nblocks] = vmalloc(sizeof(struct audio_operations))); + sound_nblocks++; + if (sound_nblocks >= MAX_MEM_BLOCKS) + sound_nblocks = MAX_MEM_BLOCKS - 1; - if (sound_nblocks < 1024) - sound_nblocks++; if (d == NULL || op == NULL) { printk(KERN_ERR "Sound: Can't allocate driver for (%s)\n", name); sound_unload_audiodev(num); @@ -128,9 +129,10 @@ int sound_install_mixer(int vers, char *name, struct mixer_operations *driver, until you unload sound! */ op = (struct mixer_operations *) (sound_mem_blocks[sound_nblocks] = vmalloc(sizeof(struct mixer_operations))); + sound_nblocks++; + if (sound_nblocks >= MAX_MEM_BLOCKS) + sound_nblocks = MAX_MEM_BLOCKS - 1; - if (sound_nblocks < 1024) - sound_nblocks++; if (op == NULL) { printk(KERN_ERR "Sound: Can't allocate mixer driver for (%s)\n", name); return -ENOMEM; diff --git a/sound/oss/sound_config.h b/sound/oss/sound_config.h index 55271fb..9d35c4c 100644 --- a/sound/oss/sound_config.h +++ b/sound/oss/sound_config.h @@ -142,4 +142,6 @@ static inline int translate_mode(struct file *file) #define TIMER_ARMED 121234 #define TIMER_NOT_ARMED 1 +#define MAX_MEM_BLOCKS 1024 + #endif diff --git a/sound/oss/soundcard.c b/sound/oss/soundcard.c index 61aaeda..c625309 100644 --- a/sound/oss/soundcard.c +++ b/sound/oss/soundcard.c @@ -56,7 +56,7 @@ /* * Table for permanently allocated memory (used when unloading the module) */ -void * sound_mem_blocks[1024]; +void * sound_mem_blocks[MAX_MEM_BLOCKS]; int sound_nblocks = 0; /* Persistent DMA buffers */ @@ -574,7 +574,7 @@ static int __init oss_init(void) NULL, "%s%d", dev_list[i].name, j); } - if (sound_nblocks >= 1024) + if (sound_nblocks >= MAX_MEM_BLOCKS - 1) printk(KERN_ERR "Sound warning: Deallocation table was too small.\n"); return 0; -- cgit v0.10.2 From edf12b4af6e1d2b7c42c75ff00e55a9c52c06d70 Mon Sep 17 00:00:00 2001 From: Krzysztof Helt Date: Mon, 4 Jan 2010 22:23:34 +0100 Subject: sbawe: fix memory detection part 2 The patch "sbawe: fix memory detection" fixed detection for memoryless SB32 cards but broke detection of memory above 512KB. This patch fixes the regression. The patch has been tested on the SB32 card (CT3670) with 0MB, 2MB and 8MB memory installed. Signed-off-by: Krzysztof Helt Signed-off-by: Jaroslav Kysela diff --git a/sound/isa/sb/emu8000.c b/sound/isa/sb/emu8000.c index 751762f..0c40951 100644 --- a/sound/isa/sb/emu8000.c +++ b/sound/isa/sb/emu8000.c @@ -377,12 +377,13 @@ init_arrays(struct snd_emu8000 *emu) static void __devinit size_dram(struct snd_emu8000 *emu) { - int i, size; + int i, size, detected_size; if (emu->dram_checked) return; size = 0; + detected_size = 0; /* write out a magic number */ snd_emu8000_dma_chan(emu, 0, EMU8000_RAM_WRITE); @@ -393,6 +394,8 @@ size_dram(struct snd_emu8000 *emu) while (size < EMU8000_MAX_DRAM) { + size += 512 * 1024; /* increment 512kbytes */ + /* Write a unique data on the test address. * if the address is out of range, the data is written on * 0x200000(=EMU8000_DRAM_OFFSET). Then the id word is @@ -414,7 +417,7 @@ size_dram(struct snd_emu8000 *emu) if (EMU8000_SMLD_READ(emu) != UNIQUE_ID2) break; /* no memory at this address */ - size += 512 * 1024; /* increment 512kbytes */ + detected_size = size; snd_emu8000_read_wait(emu); @@ -442,9 +445,9 @@ size_dram(struct snd_emu8000 *emu) snd_emu8000_dma_chan(emu, 1, EMU8000_RAM_CLOSE); snd_printdd("EMU8000 [0x%lx]: %d Kb on-board memory detected\n", - emu->port1, size/1024); + emu->port1, detected_size/1024); - emu->mem_size = size; + emu->mem_size = detected_size; emu->dram_checked = 1; } -- cgit v0.10.2 From 011f4ea09768fdf6f95e3781cba2ed681a2ac710 Mon Sep 17 00:00:00 2001 From: Amit Kumar Salecha Date: Thu, 7 Jan 2010 22:10:14 +0000 Subject: netxen: fix tx ring memory leak o While unloading driver or resetting the context, tx ring was not getting free. Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 02f8d4b..925b699 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -184,6 +184,8 @@ skip_rds: tx_ring = adapter->tx_ring; vfree(tx_ring->cmd_buf_arr); + kfree(tx_ring); + adapter->tx_ring = NULL; } int netxen_alloc_sw_resources(struct netxen_adapter *adapter) -- cgit v0.10.2 From 581e8ae49ea3a70b438991e388ded2dcbdbd2162 Mon Sep 17 00:00:00 2001 From: Amit Kumar Salecha Date: Thu, 7 Jan 2010 22:10:15 +0000 Subject: netxen: fix smatch warning o Fix pointless assignments Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 2e364fe..398dfd4 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -345,8 +345,7 @@ netxen_pcie_sem_lock(struct netxen_adapter *adapter, int sem, u32 id_reg) void netxen_pcie_sem_unlock(struct netxen_adapter *adapter, int sem) { - int val; - val = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM_UNLOCK(sem))); + NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM_UNLOCK(sem))); } int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port) diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 925b699..64cff68 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -784,7 +784,7 @@ netxen_need_fw_reset(struct netxen_adapter *adapter) if (NXRD32(adapter, CRB_CMDPEG_STATE) == PHAN_INITIALIZE_FAILED) return 1; - old_count = count = NXRD32(adapter, NETXEN_PEG_ALIVE_COUNTER); + old_count = NXRD32(adapter, NETXEN_PEG_ALIVE_COUNTER); for (i = 0; i < 10; i++) { diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 880fcd06..9f9d608 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -340,7 +340,7 @@ netxen_check_hw_init(struct netxen_adapter *adapter, int first_boot) if (!(first_boot & 0x4)) { first_boot |= 0x4; NXWR32(adapter, NETXEN_PCIE_REG(0x4), first_boot); - first_boot = NXRD32(adapter, NETXEN_PCIE_REG(0x4)); + NXRD32(adapter, NETXEN_PCIE_REG(0x4)); } /* This is the first boot after power up */ -- cgit v0.10.2 From d49c9640975355c79f346869831bf9780d185de0 Mon Sep 17 00:00:00 2001 From: Amit Kumar Salecha Date: Thu, 7 Jan 2010 22:10:16 +0000 Subject: netxen: fix set mac addr o If tx and rx resources are not available, during set mac request. Then this request wont be passed to firmware and it will be added to driver mac list and will never make it to firmware. So if resources are not available, don't add it to driver mac list. Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 398dfd4..85e28e6 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -690,6 +690,9 @@ void netxen_p3_nic_set_multi(struct net_device *netdev) struct list_head *head; nx_mac_list_t *cur; + if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC) + return; + list_splice_tail_init(&adapter->mac_list, &del_list); nx_p3_nic_add_mac(adapter, adapter->mac_addr, &del_list); -- cgit v0.10.2 From c651a8c160647b2eb6e61fb485f307e3781415e8 Mon Sep 17 00:00:00 2001 From: Amit Kumar Salecha Date: Thu, 7 Jan 2010 22:10:17 +0000 Subject: netxen: update version to 4.0.72 Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 76cd1f3..9bc5bd1d 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -53,8 +53,8 @@ #define _NETXEN_NIC_LINUX_MAJOR 4 #define _NETXEN_NIC_LINUX_MINOR 0 -#define _NETXEN_NIC_LINUX_SUBVERSION 65 -#define NETXEN_NIC_LINUX_VERSIONID "4.0.65" +#define _NETXEN_NIC_LINUX_SUBVERSION 72 +#define NETXEN_NIC_LINUX_VERSIONID "4.0.72" #define NETXEN_VERSION_CODE(a, b, c) (((a) << 24) + ((b) << 16) + (c)) #define _major(v) (((v) >> 24) & 0xff) -- cgit v0.10.2 From 28b8f04a5256ca5ec0781b06ee9353c37c650980 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Thu, 7 Jan 2010 16:30:56 +0000 Subject: e1000e: call pci_save_state() after pci_restore_state() Due to a change in pci_restore_state()[1] which clears the saved_state flag, the driver should call pci_save_state() to set the flag once again to avoid issues with EEH (same fix that recently was submitted for ixgbe). [1] commmit 4b77b0a2ba27d64f58f16d8d4d48d8319dda36ff Signed-off-by: Bruce Allan Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 762b697..10aa0ec 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -4674,6 +4674,7 @@ static int e1000_resume(struct pci_dev *pdev) pci_set_power_state(pdev, PCI_D0); pci_restore_state(pdev); + pci_save_state(pdev); e1000e_disable_l1aspm(pdev); err = pci_enable_device_mem(pdev); @@ -4825,6 +4826,7 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev) } else { pci_set_master(pdev); pci_restore_state(pdev); + pci_save_state(pdev); pci_enable_wake(pdev, PCI_D3hot, 0); pci_enable_wake(pdev, PCI_D3cold, 0); -- cgit v0.10.2 From 29477e249f5a28444c556bbb816f3af2b6f84412 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Thu, 7 Jan 2010 16:31:16 +0000 Subject: e1000e: don't accumulate PHY statistics on PHY read failure Signed-off-by: Bruce Allan Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 10aa0ec..c45965a 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -3315,24 +3315,24 @@ void e1000e_update_stats(struct e1000_adapter *adapter) if ((hw->phy.type == e1000_phy_82578) || (hw->phy.type == e1000_phy_82577)) { e1e_rphy(hw, HV_SCC_UPPER, &phy_data); - e1e_rphy(hw, HV_SCC_LOWER, &phy_data); - adapter->stats.scc += phy_data; + if (!e1e_rphy(hw, HV_SCC_LOWER, &phy_data)) + adapter->stats.scc += phy_data; e1e_rphy(hw, HV_ECOL_UPPER, &phy_data); - e1e_rphy(hw, HV_ECOL_LOWER, &phy_data); - adapter->stats.ecol += phy_data; + if (!e1e_rphy(hw, HV_ECOL_LOWER, &phy_data)) + adapter->stats.ecol += phy_data; e1e_rphy(hw, HV_MCC_UPPER, &phy_data); - e1e_rphy(hw, HV_MCC_LOWER, &phy_data); - adapter->stats.mcc += phy_data; + if (!e1e_rphy(hw, HV_MCC_LOWER, &phy_data)) + adapter->stats.mcc += phy_data; e1e_rphy(hw, HV_LATECOL_UPPER, &phy_data); - e1e_rphy(hw, HV_LATECOL_LOWER, &phy_data); - adapter->stats.latecol += phy_data; + if (!e1e_rphy(hw, HV_LATECOL_LOWER, &phy_data)) + adapter->stats.latecol += phy_data; e1e_rphy(hw, HV_DC_UPPER, &phy_data); - e1e_rphy(hw, HV_DC_LOWER, &phy_data); - adapter->stats.dc += phy_data; + if (!e1e_rphy(hw, HV_DC_LOWER, &phy_data)) + adapter->stats.dc += phy_data; } else { adapter->stats.scc += er32(SCC); adapter->stats.ecol += er32(ECOL); @@ -3360,8 +3360,8 @@ void e1000e_update_stats(struct e1000_adapter *adapter) if ((hw->phy.type == e1000_phy_82578) || (hw->phy.type == e1000_phy_82577)) { e1e_rphy(hw, HV_COLC_UPPER, &phy_data); - e1e_rphy(hw, HV_COLC_LOWER, &phy_data); - hw->mac.collision_delta = phy_data; + if (!e1e_rphy(hw, HV_COLC_LOWER, &phy_data)) + hw->mac.collision_delta = phy_data; } else { hw->mac.collision_delta = er32(COLC); } @@ -3372,8 +3372,8 @@ void e1000e_update_stats(struct e1000_adapter *adapter) if ((hw->phy.type == e1000_phy_82578) || (hw->phy.type == e1000_phy_82577)) { e1e_rphy(hw, HV_TNCRS_UPPER, &phy_data); - e1e_rphy(hw, HV_TNCRS_LOWER, &phy_data); - adapter->stats.tncrs += phy_data; + if (!e1e_rphy(hw, HV_TNCRS_LOWER, &phy_data)) + adapter->stats.tncrs += phy_data; } else { if ((hw->mac.type != e1000_82574) && (hw->mac.type != e1000_82583)) -- cgit v0.10.2 From f464ba87fe7f346e270239354eb0d38f7a3b3e6b Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Thu, 7 Jan 2010 16:31:35 +0000 Subject: e1000e: perform 10/100 adaptive IFS only on parts that support it Adaptive IFS which involves writing to the Adaptive IFS Throttle register was being done for all devices supported by the driver even though it is not supported (i.e. the register doesn't even exist) on some devices. The feature is supported on 8257x/82583 and ICH/PCH based devices, but not on ESB2. Signed-off-by: Bruce Allan Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c index b979464..02d67d0 100644 --- a/drivers/net/e1000e/82571.c +++ b/drivers/net/e1000e/82571.c @@ -237,6 +237,8 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter) /* Set if manageability features are enabled. */ mac->arc_subsystem_valid = (er32(FWSM) & E1000_FWSM_MODE_MASK) ? true : false; + /* Adaptive IFS supported */ + mac->adaptive_ifs = true; /* check for link */ switch (hw->phy.media_type) { diff --git a/drivers/net/e1000e/es2lan.c b/drivers/net/e1000e/es2lan.c index 3028f23..e2aa3b7 100644 --- a/drivers/net/e1000e/es2lan.c +++ b/drivers/net/e1000e/es2lan.c @@ -224,6 +224,8 @@ static s32 e1000_init_mac_params_80003es2lan(struct e1000_adapter *adapter) /* Set if manageability features are enabled. */ mac->arc_subsystem_valid = (er32(FWSM) & E1000_FWSM_MODE_MASK) ? true : false; + /* Adaptive IFS not supported */ + mac->adaptive_ifs = false; /* check for link */ switch (hw->phy.media_type) { diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h index 2784cf4..eccf29b 100644 --- a/drivers/net/e1000e/hw.h +++ b/drivers/net/e1000e/hw.h @@ -818,6 +818,7 @@ struct e1000_mac_info { u8 forced_speed_duplex; + bool adaptive_ifs; bool arc_subsystem_valid; bool autoneg; bool autoneg_failed; diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index 9b09246..ad08cf3 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c @@ -454,6 +454,8 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_adapter *adapter) mac->rar_entry_count--; /* Set if manageability features are enabled. */ mac->arc_subsystem_valid = true; + /* Adaptive IFS supported */ + mac->adaptive_ifs = true; /* LED operations */ switch (mac->type) { diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c index a86c175..56b59e4 100644 --- a/drivers/net/e1000e/lib.c +++ b/drivers/net/e1000e/lib.c @@ -1609,6 +1609,11 @@ void e1000e_reset_adaptive(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; + if (!mac->adaptive_ifs) { + e_dbg("Not in Adaptive IFS mode!\n"); + goto out; + } + mac->current_ifs_val = 0; mac->ifs_min_val = IFS_MIN; mac->ifs_max_val = IFS_MAX; @@ -1617,6 +1622,8 @@ void e1000e_reset_adaptive(struct e1000_hw *hw) mac->in_ifs_mode = false; ew32(AIT, 0); +out: + return; } /** @@ -1630,6 +1637,11 @@ void e1000e_update_adaptive(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; + if (!mac->adaptive_ifs) { + e_dbg("Not in Adaptive IFS mode!\n"); + goto out; + } + if ((mac->collision_delta * mac->ifs_ratio) > mac->tx_packet_delta) { if (mac->tx_packet_delta > MIN_NUM_XMITS) { mac->in_ifs_mode = true; @@ -1650,6 +1662,8 @@ void e1000e_update_adaptive(struct e1000_hw *hw) ew32(AIT, 0); } } +out: + return; } /** -- cgit v0.10.2 From ca777f9c098f1ea1c9ec61318cc909d0c8f465e1 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Thu, 7 Jan 2010 16:31:54 +0000 Subject: e1000e: e1000e_enable_tx_pkt_filtering() returns wrong value e1000e_enable_tx_pkt_filtering() will return a non-zero value if the driver fails to enable the manageability interface on the host for any reason; instead it should retun zero to indicate filtering has been disabled. Also provide a single exit point for the function. Signed-off-by: Bruce Allan Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c index 56b59e4..97649bf 100644 --- a/drivers/net/e1000e/lib.c +++ b/drivers/net/e1000e/lib.c @@ -2301,10 +2301,12 @@ bool e1000e_enable_tx_pkt_filtering(struct e1000_hw *hw) s32 ret_val, hdr_csum, csum; u8 i, len; + hw->mac.tx_pkt_filtering = true; + /* No manageability, no filtering */ if (!e1000e_check_mng_mode(hw)) { hw->mac.tx_pkt_filtering = false; - return 0; + goto out; } /* @@ -2312,9 +2314,9 @@ bool e1000e_enable_tx_pkt_filtering(struct e1000_hw *hw) * reason, disable filtering. */ ret_val = e1000_mng_enable_host_if(hw); - if (ret_val != 0) { + if (ret_val) { hw->mac.tx_pkt_filtering = false; - return ret_val; + goto out; } /* Read in the header. Length and offset are in dwords. */ @@ -2333,17 +2335,17 @@ bool e1000e_enable_tx_pkt_filtering(struct e1000_hw *hw) */ if ((hdr_csum != csum) || (hdr->signature != E1000_IAMT_SIGNATURE)) { hw->mac.tx_pkt_filtering = true; - return 1; + goto out; } /* Cookie area is valid, make the final check for filtering. */ if (!(hdr->status & E1000_MNG_DHCP_COOKIE_STATUS_PARSING)) { hw->mac.tx_pkt_filtering = false; - return 0; + goto out; } - hw->mac.tx_pkt_filtering = true; - return 1; +out: + return hw->mac.tx_pkt_filtering; } /** -- cgit v0.10.2 From b7a9216c5a3205a6d721972bfd012c4eb5950e9c Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Thu, 7 Jan 2010 16:32:13 +0000 Subject: e1000e: fix and commonize code for setting the receive address registers Fix e1000e_rar_set() to flush consecutive register writes to avoid write combining which some parts cannot handle. Update e1000e_init_rx_addrs() to call the fixed e1000e_rar_set() instead of duplicating code. Also change e1000e_rar_set() to _not_ set the Address Valid bit if the MAC address is all zeros. Signed-off-by: Bruce Allan Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c index 97649bf..2fa9b36 100644 --- a/drivers/net/e1000e/lib.c +++ b/drivers/net/e1000e/lib.c @@ -125,6 +125,7 @@ void e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value) void e1000e_init_rx_addrs(struct e1000_hw *hw, u16 rar_count) { u32 i; + u8 mac_addr[ETH_ALEN] = {0}; /* Setup the receive address */ e_dbg("Programming MAC Address into RAR[0]\n"); @@ -133,12 +134,8 @@ void e1000e_init_rx_addrs(struct e1000_hw *hw, u16 rar_count) /* Zero out the other (rar_entry_count - 1) receive addresses */ e_dbg("Clearing RAR[1-%u]\n", rar_count-1); - for (i = 1; i < rar_count; i++) { - E1000_WRITE_REG_ARRAY(hw, E1000_RA, (i << 1), 0); - e1e_flush(); - E1000_WRITE_REG_ARRAY(hw, E1000_RA, ((i << 1) + 1), 0); - e1e_flush(); - } + for (i = 1; i < rar_count; i++) + e1000e_rar_set(hw, mac_addr, i); } /** @@ -164,10 +161,19 @@ void e1000e_rar_set(struct e1000_hw *hw, u8 *addr, u32 index) rar_high = ((u32) addr[4] | ((u32) addr[5] << 8)); - rar_high |= E1000_RAH_AV; + /* If MAC address zero, no need to set the AV bit */ + if (rar_low || rar_high) + rar_high |= E1000_RAH_AV; - E1000_WRITE_REG_ARRAY(hw, E1000_RA, (index << 1), rar_low); - E1000_WRITE_REG_ARRAY(hw, E1000_RA, ((index << 1) + 1), rar_high); + /* + * Some bridges will combine consecutive 32-bit writes into + * a single burst write, which will malfunction on some parts. + * The flushes avoid this. + */ + ew32(RAL(index), rar_low); + e1e_flush(); + ew32(RAH(index), rar_high); + e1e_flush(); } /** -- cgit v0.10.2 From 397bb3c2e0810d56518e5e111fcedb593823514f Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 3 Dec 2009 13:37:31 +0200 Subject: OMAP: DSS2: DSI: fix VC channels in send_short and send_null - dsi_vc_send_short() needs to use dest_per for the peripheral id - dsi_vc_send_null() was always using channel id 0 Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 5936487..341c6bb 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -1999,7 +1999,7 @@ static int dsi_vc_send_short(int channel, u8 data_type, u16 data, u8 ecc) return -EINVAL; } - data_id = data_type | channel << 6; + data_id = data_type | dsi.vc[channel].dest_per << 6; r = (data_id << 0) | (data << 8) | (ecc << 24); @@ -2011,7 +2011,7 @@ static int dsi_vc_send_short(int channel, u8 data_type, u16 data, u8 ecc) int dsi_vc_send_null(int channel) { u8 nullpkg[] = {0, 0, 0, 0}; - return dsi_vc_send_long(0, DSI_DT_NULL_PACKET, nullpkg, 4, 0); + return dsi_vc_send_long(channel, DSI_DT_NULL_PACKET, nullpkg, 4, 0); } EXPORT_SYMBOL(dsi_vc_send_null); -- cgit v0.10.2 From ff90a3488d98a63bf24bff37f77a9a37b00e7a54 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 3 Dec 2009 13:38:04 +0200 Subject: OMAP: DSS2: DSI: print debug DCS cmd in hex Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 341c6bb..e650563 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -2058,7 +2058,7 @@ int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen) int r; if (dsi.debug_read) - DSSDBG("dsi_vc_dcs_read(ch%d, dcs_cmd %u)\n", channel, dcs_cmd); + DSSDBG("dsi_vc_dcs_read(ch%d, dcs_cmd %x)\n", channel, dcs_cmd); r = dsi_vc_send_short(channel, DSI_DT_DCS_READ, dcs_cmd, 0); if (r) -- cgit v0.10.2 From dfc0fd8d8850ef11951ba6c251e06096d1b5a0bd Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 17 Dec 2009 14:35:21 +0200 Subject: OMAP: DSS2: Collect interrupt statistics Collect interrupt statistics, printable via debugfs: debugfs/omapdss/dispc_irq debugfs/omapdss/dsi_irq The counters are reset when printed. Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/omap2/dss/Kconfig index 71d8dec..c63ce76 100644 --- a/drivers/video/omap2/dss/Kconfig +++ b/drivers/video/omap2/dss/Kconfig @@ -25,6 +25,13 @@ config OMAP2_DSS_DEBUG_SUPPORT This enables debug messages. You need to enable printing with 'debug' module parameter. +config OMAP2_DSS_COLLECT_IRQ_STATS + bool "Collect DSS IRQ statistics" + depends on OMAP2_DSS_DEBUG_SUPPORT + default n + help + Collect DSS IRQ statistics, printable via debugfs + config OMAP2_DSS_RFBI bool "RFBI support" default n diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index 29497a0..dbb0ce2 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c @@ -395,6 +395,14 @@ static int dss_initialize_debugfs(void) debugfs_create_file("clk", S_IRUGO, dss_debugfs_dir, &dss_debug_dump_clocks, &dss_debug_fops); + debugfs_create_file("dispc_irq", S_IRUGO, dss_debugfs_dir, + &dispc_dump_irqs, &dss_debug_fops); + +#ifdef CONFIG_OMAP2_DSS_DSI + debugfs_create_file("dsi_irq", S_IRUGO, dss_debugfs_dir, + &dsi_dump_irqs, &dss_debug_fops); +#endif + debugfs_create_file("dss", S_IRUGO, dss_debugfs_dir, &dss_dump_regs, &dss_debug_fops); debugfs_create_file("dispc", S_IRUGO, dss_debugfs_dir, diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 6dabf4b..e2e0f9a 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -148,6 +148,12 @@ static const struct dispc_reg dispc_reg_att[] = { DISPC_GFX_ATTRIBUTES, DISPC_VID_ATTRIBUTES(0), DISPC_VID_ATTRIBUTES(1) }; +struct dispc_irq_stats { + unsigned long last_reset; + unsigned irq_count; + unsigned irqs[32]; +}; + static struct { void __iomem *base; @@ -160,6 +166,11 @@ static struct { struct work_struct error_work; u32 ctx[DISPC_SZ_REGS / sizeof(u32)]; + +#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS + spinlock_t irq_stats_lock; + struct dispc_irq_stats irq_stats; +#endif } dispc; static void _omap_dispc_set_irqs(void); @@ -2247,6 +2258,50 @@ void dispc_dump_clocks(struct seq_file *s) enable_clocks(0); } +#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS +void dispc_dump_irqs(struct seq_file *s) +{ + unsigned long flags; + struct dispc_irq_stats stats; + + spin_lock_irqsave(&dispc.irq_stats_lock, flags); + + stats = dispc.irq_stats; + memset(&dispc.irq_stats, 0, sizeof(dispc.irq_stats)); + dispc.irq_stats.last_reset = jiffies; + + spin_unlock_irqrestore(&dispc.irq_stats_lock, flags); + + seq_printf(s, "period %u ms\n", + jiffies_to_msecs(jiffies - stats.last_reset)); + + seq_printf(s, "irqs %d\n", stats.irq_count); +#define PIS(x) \ + seq_printf(s, "%-20s %10d\n", #x, stats.irqs[ffs(DISPC_IRQ_##x)-1]); + + PIS(FRAMEDONE); + PIS(VSYNC); + PIS(EVSYNC_EVEN); + PIS(EVSYNC_ODD); + PIS(ACBIAS_COUNT_STAT); + PIS(PROG_LINE_NUM); + PIS(GFX_FIFO_UNDERFLOW); + PIS(GFX_END_WIN); + PIS(PAL_GAMMA_MASK); + PIS(OCP_ERR); + PIS(VID1_FIFO_UNDERFLOW); + PIS(VID1_END_WIN); + PIS(VID2_FIFO_UNDERFLOW); + PIS(VID2_END_WIN); + PIS(SYNC_LOST); + PIS(SYNC_LOST_DIGIT); + PIS(WAKEUP); +#undef PIS +} +#else +void dispc_dump_irqs(struct seq_file *s) { } +#endif + void dispc_dump_regs(struct seq_file *s) { #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dispc_read_reg(r)) @@ -2665,6 +2720,13 @@ void dispc_irq_handler(void) irqstatus = dispc_read_reg(DISPC_IRQSTATUS); +#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS + spin_lock(&dispc.irq_stats_lock); + dispc.irq_stats.irq_count++; + dss_collect_irq_stats(irqstatus, dispc.irq_stats.irqs); + spin_unlock(&dispc.irq_stats_lock); +#endif + #ifdef DEBUG if (dss_debug) print_irq_status(irqstatus); @@ -3012,6 +3074,11 @@ int dispc_init(void) spin_lock_init(&dispc.irq_lock); +#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS + spin_lock_init(&dispc.irq_stats_lock); + dispc.irq_stats.last_reset = jiffies; +#endif + INIT_WORK(&dispc.error_work, dispc_error_worker); dispc.base = ioremap(DISPC_BASE, DISPC_SZ_REGS); diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index e650563..03f85df 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -204,6 +204,14 @@ struct dsi_update_region { struct omap_dss_device *device; }; +struct dsi_irq_stats { + unsigned long last_reset; + unsigned irq_count; + unsigned dsi_irqs[32]; + unsigned vc_irqs[4][32]; + unsigned cio_irqs[32]; +}; + static struct { void __iomem *base; @@ -258,6 +266,11 @@ static struct #endif int debug_read; int debug_write; + +#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS + spinlock_t irq_stats_lock; + struct dsi_irq_stats irq_stats; +#endif } dsi; #ifdef DEBUG @@ -528,6 +541,12 @@ void dsi_irq_handler(void) irqstatus = dsi_read_reg(DSI_IRQSTATUS); +#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS + spin_lock(&dsi.irq_stats_lock); + dsi.irq_stats.irq_count++; + dss_collect_irq_stats(irqstatus, dsi.irq_stats.dsi_irqs); +#endif + if (irqstatus & DSI_IRQ_ERROR_MASK) { DSSERR("DSI error, irqstatus %x\n", irqstatus); print_irq_status(irqstatus); @@ -549,6 +568,10 @@ void dsi_irq_handler(void) vcstatus = dsi_read_reg(DSI_VC_IRQSTATUS(i)); +#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS + dss_collect_irq_stats(vcstatus, dsi.irq_stats.vc_irqs[i]); +#endif + if (vcstatus & DSI_VC_IRQ_BTA) complete(&dsi.bta_completion); @@ -568,6 +591,10 @@ void dsi_irq_handler(void) if (irqstatus & DSI_IRQ_COMPLEXIO_ERR) { ciostatus = dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS); +#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS + dss_collect_irq_stats(ciostatus, dsi.irq_stats.cio_irqs); +#endif + dsi_write_reg(DSI_COMPLEXIO_IRQ_STATUS, ciostatus); /* flush posted write */ dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS); @@ -579,6 +606,10 @@ void dsi_irq_handler(void) dsi_write_reg(DSI_IRQSTATUS, irqstatus & ~DSI_IRQ_CHANNEL_MASK); /* flush posted write */ dsi_read_reg(DSI_IRQSTATUS); + +#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS + spin_unlock(&dsi.irq_stats_lock); +#endif } @@ -1226,6 +1257,95 @@ void dsi_dump_clocks(struct seq_file *s) enable_clocks(0); } +#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS +void dsi_dump_irqs(struct seq_file *s) +{ + unsigned long flags; + struct dsi_irq_stats stats; + + spin_lock_irqsave(&dsi.irq_stats_lock, flags); + + stats = dsi.irq_stats; + memset(&dsi.irq_stats, 0, sizeof(dsi.irq_stats)); + dsi.irq_stats.last_reset = jiffies; + + spin_unlock_irqrestore(&dsi.irq_stats_lock, flags); + + seq_printf(s, "period %u ms\n", + jiffies_to_msecs(jiffies - stats.last_reset)); + + seq_printf(s, "irqs %d\n", stats.irq_count); +#define PIS(x) \ + seq_printf(s, "%-20s %10d\n", #x, stats.dsi_irqs[ffs(DSI_IRQ_##x)-1]); + + seq_printf(s, "-- DSI interrupts --\n"); + PIS(VC0); + PIS(VC1); + PIS(VC2); + PIS(VC3); + PIS(WAKEUP); + PIS(RESYNC); + PIS(PLL_LOCK); + PIS(PLL_UNLOCK); + PIS(PLL_RECALL); + PIS(COMPLEXIO_ERR); + PIS(HS_TX_TIMEOUT); + PIS(LP_RX_TIMEOUT); + PIS(TE_TRIGGER); + PIS(ACK_TRIGGER); + PIS(SYNC_LOST); + PIS(LDO_POWER_GOOD); + PIS(TA_TIMEOUT); +#undef PIS + +#define PIS(x) \ + seq_printf(s, "%-20s %10d %10d %10d %10d\n", #x, \ + stats.vc_irqs[0][ffs(DSI_VC_IRQ_##x)-1], \ + stats.vc_irqs[1][ffs(DSI_VC_IRQ_##x)-1], \ + stats.vc_irqs[2][ffs(DSI_VC_IRQ_##x)-1], \ + stats.vc_irqs[3][ffs(DSI_VC_IRQ_##x)-1]); + + seq_printf(s, "-- VC interrupts --\n"); + PIS(CS); + PIS(ECC_CORR); + PIS(PACKET_SENT); + PIS(FIFO_TX_OVF); + PIS(FIFO_RX_OVF); + PIS(BTA); + PIS(ECC_NO_CORR); + PIS(FIFO_TX_UDF); + PIS(PP_BUSY_CHANGE); +#undef PIS + +#define PIS(x) \ + seq_printf(s, "%-20s %10d\n", #x, \ + stats.cio_irqs[ffs(DSI_CIO_IRQ_##x)-1]); + + seq_printf(s, "-- CIO interrupts --\n"); + PIS(ERRSYNCESC1); + PIS(ERRSYNCESC2); + PIS(ERRSYNCESC3); + PIS(ERRESC1); + PIS(ERRESC2); + PIS(ERRESC3); + PIS(ERRCONTROL1); + PIS(ERRCONTROL2); + PIS(ERRCONTROL3); + PIS(STATEULPS1); + PIS(STATEULPS2); + PIS(STATEULPS3); + PIS(ERRCONTENTIONLP0_1); + PIS(ERRCONTENTIONLP1_1); + PIS(ERRCONTENTIONLP0_2); + PIS(ERRCONTENTIONLP1_2); + PIS(ERRCONTENTIONLP0_3); + PIS(ERRCONTENTIONLP1_3); + PIS(ULPSACTIVENOT_ALL0); + PIS(ULPSACTIVENOT_ALL1); +#undef PIS +} +#endif + void dsi_dump_regs(struct seq_file *s) { #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dsi_read_reg(r)) @@ -3637,6 +3757,11 @@ int dsi_init(struct platform_device *pdev) spin_lock_init(&dsi.errors_lock); dsi.errors = 0; +#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS + spin_lock_init(&dsi.irq_stats_lock); + dsi.irq_stats.last_reset = jiffies; +#endif + init_completion(&dsi.bta_completion); init_completion(&dsi.update_completion); diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 8da5ac42..2bcb124 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -240,6 +240,7 @@ int dsi_init(struct platform_device *pdev); void dsi_exit(void); void dsi_dump_clocks(struct seq_file *s); +void dsi_dump_irqs(struct seq_file *s); void dsi_dump_regs(struct seq_file *s); void dsi_save_context(void); @@ -268,6 +269,7 @@ int dpi_init_display(struct omap_dss_device *dssdev); int dispc_init(void); void dispc_exit(void); void dispc_dump_clocks(struct seq_file *s); +void dispc_dump_irqs(struct seq_file *s); void dispc_dump_regs(struct seq_file *s); void dispc_irq_handler(void); void dispc_fake_vsync_irq(void); @@ -367,4 +369,16 @@ void rfbi_set_timings(int rfbi_module, struct rfbi_timings *t); unsigned long rfbi_get_max_tx_rate(void); int rfbi_init_display(struct omap_dss_device *display); + +#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS +static inline void dss_collect_irq_stats(u32 irqstatus, unsigned *irq_arr) +{ + int b; + for (b = 0; b < 32; ++b) { + if (irqstatus & (1 << b)) + irq_arr[b]++; + } +} +#endif + #endif -- cgit v0.10.2 From 7475e44246e8a7c435a7ed8fe1e94fc8898685d9 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Tue, 8 Dec 2009 17:30:24 +0200 Subject: OMAP: DSS2: Fix crash when panel doesn't define enable_te() DSI driver didn't check if the panel driver actually implements enable_te(). Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 03f85df..e32a53c 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -2932,11 +2932,15 @@ static int dsi_set_update_mode(struct omap_dss_device *dssdev, static int dsi_set_te(struct omap_dss_device *dssdev, bool enable) { - int r; - r = dssdev->driver->enable_te(dssdev, enable); - /* XXX for some reason, DSI TE breaks if we don't wait here. - * Panel bug? Needs more studying */ - msleep(100); + int r = 0; + + if (dssdev->driver->enable_te) { + r = dssdev->driver->enable_te(dssdev, enable); + /* XXX for some reason, DSI TE breaks if we don't wait here. + * Panel bug? Needs more studying */ + msleep(100); + } + return r; } -- cgit v0.10.2 From 56aa616a03feca630d5afce647367a5d8cfc67b8 Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Tue, 8 Dec 2009 10:25:33 +0000 Subject: GFS2: Ensure uptodate inode size when using O_APPEND The VFS reads the inode size during generic_file_aio_write() but with no locking around it. In order to get the expected result from O_APPEND opens, this patch updated the inode size before calling generic_file_aio_write() There is of course still a race here, in that there is nothing to prevent another node coming in and extending the file in the mean time. On the other hand, when used with file locking this will ensure that the expected results are obtained. Signed-off-by: Steven Whitehouse diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index 4eb308a..a6abbae8 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c @@ -569,6 +569,40 @@ static int gfs2_fsync(struct file *file, struct dentry *dentry, int datasync) return ret; } +/** + * gfs2_file_aio_write - Perform a write to a file + * @iocb: The io context + * @iov: The data to write + * @nr_segs: Number of @iov segments + * @pos: The file position + * + * We have to do a lock/unlock here to refresh the inode size for + * O_APPEND writes, otherwise we can land up writing at the wrong + * offset. There is still a race, but provided the app is using its + * own file locking, this will make O_APPEND work as expected. + * + */ + +static ssize_t gfs2_file_aio_write(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t pos) +{ + struct file *file = iocb->ki_filp; + + if (file->f_flags & O_APPEND) { + struct dentry *dentry = file->f_dentry; + struct gfs2_inode *ip = GFS2_I(dentry->d_inode); + struct gfs2_holder gh; + int ret; + + ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, 0, &gh); + if (ret) + return ret; + gfs2_glock_dq_uninit(&gh); + } + + return generic_file_aio_write(iocb, iov, nr_segs, pos); +} + #ifdef CONFIG_GFS2_FS_LOCKING_DLM /** @@ -711,7 +745,7 @@ const struct file_operations gfs2_file_fops = { .read = do_sync_read, .aio_read = generic_file_aio_read, .write = do_sync_write, - .aio_write = generic_file_aio_write, + .aio_write = gfs2_file_aio_write, .unlocked_ioctl = gfs2_ioctl, .mmap = gfs2_mmap, .open = gfs2_open, @@ -741,7 +775,7 @@ const struct file_operations gfs2_file_fops_nolock = { .read = do_sync_read, .aio_read = generic_file_aio_read, .write = do_sync_write, - .aio_write = generic_file_aio_write, + .aio_write = gfs2_file_aio_write, .unlocked_ioctl = gfs2_ioctl, .mmap = gfs2_mmap, .open = gfs2_open, -- cgit v0.10.2 From 24b977b5fdea09bf356428870d32c09a275c8a3e Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Wed, 9 Dec 2009 13:55:12 +0000 Subject: GFS2: Fix locking bug in rename The rename code was taking a resource group lock in cases where it wasn't actually needed, this caused problems if the rename was resulting in an inode being unlinked. The patch ensures that we only take the rgrp lock early if it is really needed. Signed-off-by: Steven Whitehouse diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c index 247436c..78f73ca 100644 --- a/fs/gfs2/ops_inode.c +++ b/fs/gfs2/ops_inode.c @@ -748,7 +748,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, struct gfs2_rgrpd *nrgd; unsigned int num_gh; int dir_rename = 0; - int alloc_required; + int alloc_required = 0; unsigned int x; int error; @@ -867,7 +867,9 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, goto out_gunlock; } - alloc_required = error = gfs2_diradd_alloc_required(ndir, &ndentry->d_name); + if (nip == NULL) + alloc_required = gfs2_diradd_alloc_required(ndir, &ndentry->d_name); + error = alloc_required; if (error < 0) goto out_gunlock; error = 0; -- cgit v0.10.2 From e412bdb1260d13ec5e7b90b537fec2179d6f8989 Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Mon, 21 Dec 2009 13:55:28 +0000 Subject: GFS2: Fix gfs2_xattr_acl_chmod() The ref counting for the bh returned by gfs2_ea_find() was wrong. This patch ensures that we always drop the ref count to that bh correctly. Signed-off-by: Steven Whitehouse diff --git a/fs/gfs2/xattr.c b/fs/gfs2/xattr.c index 8a04108..c2ebdf2 100644 --- a/fs/gfs2/xattr.c +++ b/fs/gfs2/xattr.c @@ -1296,6 +1296,7 @@ fail: int gfs2_xattr_acl_chmod(struct gfs2_inode *ip, struct iattr *attr, char *data) { + struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); struct gfs2_ea_location el; struct buffer_head *dibh; int error; @@ -1305,16 +1306,17 @@ int gfs2_xattr_acl_chmod(struct gfs2_inode *ip, struct iattr *attr, char *data) return error; if (GFS2_EA_IS_STUFFED(el.el_ea)) { - error = gfs2_trans_begin(GFS2_SB(&ip->i_inode), RES_DINODE + RES_EATTR, 0); - if (error) - return error; - - gfs2_trans_add_bh(ip->i_gl, el.el_bh, 1); - memcpy(GFS2_EA2DATA(el.el_ea), data, - GFS2_EA_DATA_LEN(el.el_ea)); - } else + error = gfs2_trans_begin(sdp, RES_DINODE + RES_EATTR, 0); + if (error == 0) { + gfs2_trans_add_bh(ip->i_gl, el.el_bh, 1); + memcpy(GFS2_EA2DATA(el.el_ea), data, + GFS2_EA_DATA_LEN(el.el_ea)); + } + } else { error = ea_acl_chmod_unstuffed(ip, el.el_ea, data); + } + brelse(el.el_bh); if (error) return error; @@ -1327,8 +1329,7 @@ int gfs2_xattr_acl_chmod(struct gfs2_inode *ip, struct iattr *attr, char *data) brelse(dibh); } - gfs2_trans_end(GFS2_SB(&ip->i_inode)); - + gfs2_trans_end(sdp); return error; } -- cgit v0.10.2 From 092a4e957a835cbf6b2ec82a6a4d6ff06c0a362e Mon Sep 17 00:00:00 2001 From: Jamie Iles Date: Wed, 6 Jan 2010 10:50:08 +0100 Subject: ARM: 5866/1: arm ptrace: use unsigned types for kernel pt_regs Make registers unsigned for kernel space. This is important for example in the perf events where the PC is stored into a u64. We don't want it sign extended so make the regs unsigned to prevent casts throughout the kernel. Signed-off-by: Jamie Iles Signed-off-by: Russell King diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h index bbecccd..eec6e89 100644 --- a/arch/arm/include/asm/ptrace.h +++ b/arch/arm/include/asm/ptrace.h @@ -97,9 +97,15 @@ * stack during a system call. Note that sizeof(struct pt_regs) * has to be a multiple of 8. */ +#ifndef __KERNEL__ struct pt_regs { long uregs[18]; }; +#else /* __KERNEL__ */ +struct pt_regs { + unsigned long uregs[18]; +}; +#endif /* __KERNEL__ */ #define ARM_cpsr uregs[16] #define ARM_pc uregs[15] -- cgit v0.10.2 From 406eb02029ea95545c08dba75da393fa47d3fb43 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 7 Jan 2010 11:25:42 +0100 Subject: ARM: 5867/1: Update U300 defconfig This updates the U300 defconfig to include the DMA driver merged in 2.6.33-rc1 and adds a codepage that's needed to mount VFAT MMC cards as default. The rest is new config options. Signed-off-by: Linus Walleij Signed-off-by: Russell King diff --git a/arch/arm/configs/u300_defconfig b/arch/arm/configs/u300_defconfig index 610ac3c..9155196 100644 --- a/arch/arm/configs/u300_defconfig +++ b/arch/arm/configs/u300_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.32-rc5 -# Sat Oct 17 23:32:24 2009 +# Linux kernel version: 2.6.33-rc2 +# Wed Jan 6 00:01:36 2010 # CONFIG_ARM=y CONFIG_SYS_SUPPORTS_APM_EMULATION=y @@ -46,6 +46,7 @@ CONFIG_SYSVIPC_SYSCTL=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -119,14 +120,41 @@ CONFIG_BLOCK=y # IO Schedulers # CONFIG_IOSCHED_NOOP=y -# CONFIG_IOSCHED_AS is not set CONFIG_IOSCHED_DEADLINE=y # CONFIG_IOSCHED_CFQ is not set -# CONFIG_DEFAULT_AS is not set CONFIG_DEFAULT_DEADLINE=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="deadline" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +# CONFIG_INLINE_SPIN_UNLOCK is not set +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +# CONFIG_INLINE_READ_UNLOCK is not set +# CONFIG_INLINE_READ_UNLOCK_BH is not set +# CONFIG_INLINE_READ_UNLOCK_IRQ is not set +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +# CONFIG_INLINE_WRITE_UNLOCK is not set +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set # CONFIG_FREEZER is not set # @@ -155,6 +183,7 @@ CONFIG_MMU=y # CONFIG_ARCH_IXP2000 is not set # CONFIG_ARCH_IXP4XX is not set # CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_DOVE is not set # CONFIG_ARCH_KIRKWOOD is not set # CONFIG_ARCH_LOKI is not set # CONFIG_ARCH_MV78XX0 is not set @@ -177,6 +206,7 @@ CONFIG_ARCH_U300=y # CONFIG_ARCH_DAVINCI is not set # CONFIG_ARCH_OMAP is not set # CONFIG_ARCH_BCMRING is not set +# CONFIG_ARCH_U8500 is not set # # ST-Ericsson AB U300/U330/U335/U365 Platform @@ -265,12 +295,10 @@ CONFIG_FLATMEM_MANUAL=y CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_PAGEFLAGS_EXTENDED=y -CONFIG_SPLIT_PTLOCK_CPUS=4096 +CONFIG_SPLIT_PTLOCK_CPUS=999999 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_VIRT_TO_BUS=y -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 CONFIG_ALIGNMENT_TRAP=y @@ -499,14 +527,21 @@ CONFIG_MTD_NAND_IDS=y CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_RAM is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set CONFIG_MISC_DEVICES=y +# CONFIG_AD525X_DPOT is not set # CONFIG_ICS932S401 is not set # CONFIG_ENCLOSURE_SERVICES is not set # CONFIG_ISL29003 is not set +# CONFIG_DS1682 is not set +# CONFIG_TI_DAC7512 is not set # CONFIG_C2PORT is not set # @@ -517,6 +552,7 @@ CONFIG_MISC_DEVICES=y # CONFIG_EEPROM_LEGACY is not set # CONFIG_EEPROM_MAX6875 is not set # CONFIG_EEPROM_93CX6 is not set +# CONFIG_IWMC3200TOP is not set CONFIG_HAVE_IDE=y # CONFIG_IDE is not set @@ -539,6 +575,7 @@ CONFIG_HAVE_IDE=y CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set # CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set # # Userland interfaces @@ -645,7 +682,6 @@ CONFIG_I2C_STU300=y # # Miscellaneous I2C Chip support # -# CONFIG_DS1682 is not set # CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set @@ -661,6 +697,8 @@ CONFIG_SPI_MASTER=y # CONFIG_SPI_BITBANG is not set # CONFIG_SPI_GPIO is not set CONFIG_SPI_PL022=y +# CONFIG_SPI_XILINX is not set +# CONFIG_SPI_DESIGNWARE is not set # # SPI Protocol Masters @@ -708,6 +746,7 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_T7L66XB is not set # CONFIG_MFD_TC6387XB is not set # CONFIG_PMIC_DA903X is not set +# CONFIG_PMIC_ADP5520 is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set @@ -716,6 +755,8 @@ CONFIG_SSB_POSSIBLE=y CONFIG_AB3100_CORE=y CONFIG_AB3100_OTP=y # CONFIG_EZX_PCAP is not set +# CONFIG_MFD_88PM8607 is not set +# CONFIG_AB4500_CORE is not set CONFIG_REGULATOR=y # CONFIG_REGULATOR_DEBUG is not set # CONFIG_REGULATOR_FIXED_VOLTAGE is not set @@ -723,6 +764,7 @@ CONFIG_REGULATOR=y # CONFIG_REGULATOR_USERSPACE_CONSUMER is not set # CONFIG_REGULATOR_BQ24022 is not set # CONFIG_REGULATOR_MAX1586 is not set +# CONFIG_REGULATOR_MAX8660 is not set # CONFIG_REGULATOR_LP3971 is not set CONFIG_REGULATOR_AB3100=y # CONFIG_REGULATOR_TPS65023 is not set @@ -840,7 +882,9 @@ CONFIG_LEDS_CLASS=y # CONFIG_LEDS_LP3944 is not set # CONFIG_LEDS_PCA955X is not set # CONFIG_LEDS_DAC124S085 is not set +# CONFIG_LEDS_REGULATOR is not set # CONFIG_LEDS_BD2802 is not set +# CONFIG_LEDS_LT3593 is not set # # LED Triggers @@ -882,6 +926,7 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_PCF8563 is not set # CONFIG_RTC_DRV_PCF8583 is not set # CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set # CONFIG_RTC_DRV_S35390A is not set # CONFIG_RTC_DRV_FM3130 is not set # CONFIG_RTC_DRV_RX8581 is not set @@ -911,7 +956,9 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_M48T86 is not set # CONFIG_RTC_DRV_M48T35 is not set # CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set # CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set # CONFIG_RTC_DRV_V3020 is not set CONFIG_RTC_DRV_AB3100=y @@ -926,6 +973,15 @@ CONFIG_DMADEVICES=y # # DMA Devices # +CONFIG_COH901318=y +CONFIG_DMA_ENGINE=y + +# +# DMA Clients +# +# CONFIG_NET_DMA is not set +# CONFIG_ASYNC_TX_DMA is not set +# CONFIG_DMATEST is not set # CONFIG_AUXDISPLAY is not set # CONFIG_UIO is not set @@ -1018,7 +1074,7 @@ CONFIG_MISC_FILESYSTEMS=y CONFIG_MSDOS_PARTITION=y CONFIG_NLS=y CONFIG_NLS_DEFAULT="iso8859-1" -# CONFIG_NLS_CODEPAGE_437 is not set +CONFIG_NLS_CODEPAGE_437=y # CONFIG_NLS_CODEPAGE_737 is not set # CONFIG_NLS_CODEPAGE_775 is not set # CONFIG_NLS_CODEPAGE_850 is not set @@ -1135,6 +1191,7 @@ CONFIG_ARM_UNWIND=y # CONFIG_DEBUG_ERRORS is not set # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_DEBUG_LL is not set +# CONFIG_OC_ETM is not set # # Security options @@ -1142,7 +1199,11 @@ CONFIG_ARM_UNWIND=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" # CONFIG_CRYPTO is not set # CONFIG_BINARY_PRINTF is not set -- cgit v0.10.2 From 22325525d8bb1478daddefec1b762e7882bcd515 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Fri, 8 Jan 2010 16:59:34 +0100 Subject: ARM: 5868/1: ARM: fix "BUG: using smp_processor_id() in preemptible code" Fix the following warning, which appears when the register dump for a faulting process is printed in a kernel with SMP, DEBUG_PREEMPT, and DEBUG_USER (with user_debug=31) enabled: BUG: using smp_processor_id() in preemptible [00000000] code: init/1 caller is __show_regs+0x18/0x234 Backtrace: [] (dump_backtrace+0x0/0x114) from [] (dump_stack+0x18/0x1c) r6:c781a000 r5:c0157544 r4:00000001 r3:00000000 [] (dump_stack+0x0/0x1c) from [] (debug_smp_processor_id+0xc4/0xf8) [] (debug_smp_processor_id+0x0/0xf8) from [] (__show_regs+0x18/0x234) r6:c781bfb0 r5:00000000 r4:c781bfb0 r3:00000000 [] (__show_regs+0x0/0x234) from [] (show_regs+0x40/0x50) [] (show_regs+0x0/0x50) from [] (__do_user_fault+0x5c/0xa4) r4:c781c000 r3:00000000 [] (__do_user_fault+0x0/0xa4) from [] (do_page_fault+0x1b4/0x1e4) r7:00000000 r6:00010000 r5:c781bfb0 r4:c781c000 [] (do_page_fault+0x0/0x1e4) from [] (do_DataAbort+0x3c/0xa0) [] (do_DataAbort+0x0/0xa0) from [] (ret_from_exception+0x0/0x10) Signed-off-by: Rabin Vincent Signed-off-by: Russell King diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 6730413..ba2adef 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -212,7 +212,8 @@ void __show_regs(struct pt_regs *regs) char buf[64]; printk("CPU: %d %s (%s %.*s)\n", - smp_processor_id(), print_tainted(), init_utsname()->release, + raw_smp_processor_id(), print_tainted(), + init_utsname()->release, (int)strcspn(init_utsname()->version, " "), init_utsname()->version); print_symbol("PC is at %s\n", instruction_pointer(regs)); -- cgit v0.10.2 From 5ee518ecbcb5934e284ea51a19a939c891f5f7ea Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 7 Jan 2010 16:29:20 +0000 Subject: ASoC: Fix WM8350 DSP mode B configuration We need to set the LRCLK inversion bit to select DSP mode. Signed-off-by: Mark Brown Acked-by: Liam Girdwood Cc: stable@kernel.org diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index ebbf11b..718ef91 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c @@ -925,7 +925,7 @@ static int wm8350_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) iface |= 0x3 << 8; break; case SND_SOC_DAIFMT_DSP_B: - iface |= 0x3 << 8; /* lg not sure which mode */ + iface |= 0x3 << 8 | WM8350_AIF_LRCLK_INV; break; default: return -EINVAL; -- cgit v0.10.2 From dce766af541f6605fa9889892c0280bab31c66ab Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Fri, 8 Jan 2010 17:31:24 +0100 Subject: netfilter: ebtables: enforce CAP_NET_ADMIN normal users are currently allowed to set/modify ebtables rules. Restrict it to processes with CAP_NET_ADMIN. Note that this cannot be reproduced with unmodified ebtables binary because it uses SOCK_RAW. Signed-off-by: Florian Westphal Cc: stable@kernel.org Signed-off-by: Patrick McHardy diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index bd1c654..0b7f262 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c @@ -1406,6 +1406,9 @@ static int do_ebt_set_ctl(struct sock *sk, { int ret; + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + switch(cmd) { case EBT_SO_SET_ENTRIES: ret = do_replace(sock_net(sk), user, len); @@ -1425,6 +1428,9 @@ static int do_ebt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) struct ebt_replace tmp; struct ebt_table *t; + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + if (copy_from_user(&tmp, user, sizeof(tmp))) return -EFAULT; -- cgit v0.10.2 From 1866b54525d13402b2d129b906c4d189377f89c5 Mon Sep 17 00:00:00 2001 From: Janusz Krzysztofik Date: Fri, 8 Jan 2010 10:29:04 -0800 Subject: omap: McBSP: Fix possible port lockout In its current form, the omap_mcbsp_request() function can return after irq_request() failure without any cleanups, effectively locking out the port forever with clocks left running. Fix it. Signed-off-by: Janusz Krzysztofik Acked-by: Jarkko Nikula Acked-by: Peter Ujfalusi Signed-off-by: Tony Lindgren diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c index 2cc1cc3..f757672 100644 --- a/arch/arm/plat-omap/mcbsp.c +++ b/arch/arm/plat-omap/mcbsp.c @@ -436,7 +436,7 @@ int omap_mcbsp_request(unsigned int id) dev_err(mcbsp->dev, "Unable to request TX IRQ %d " "for McBSP%d\n", mcbsp->tx_irq, mcbsp->id); - return err; + goto error; } init_completion(&mcbsp->rx_irq_completion); @@ -446,12 +446,26 @@ int omap_mcbsp_request(unsigned int id) dev_err(mcbsp->dev, "Unable to request RX IRQ %d " "for McBSP%d\n", mcbsp->rx_irq, mcbsp->id); - free_irq(mcbsp->tx_irq, (void *)mcbsp); - return err; + goto tx_irq; } } return 0; +tx_irq: + free_irq(mcbsp->tx_irq, (void *)mcbsp); +error: + if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free) + mcbsp->pdata->ops->free(id); + + /* Do procedure specific to omap34xx arch, if applicable */ + omap34xx_mcbsp_free(mcbsp); + + clk_disable(mcbsp->fclk); + clk_disable(mcbsp->iclk); + + mcbsp->free = 1; + + return err; } EXPORT_SYMBOL(omap_mcbsp_request); -- cgit v0.10.2 From 4318f36b7c93a60a100f43fc6b7f13bebc59d017 Mon Sep 17 00:00:00 2001 From: Cory Maccarrone Date: Fri, 8 Jan 2010 10:29:04 -0800 Subject: omap: gpio: Simultaneously requested rising and falling edge Some chips, namely any OMAP1 chips using METHOD_MPUIO, OMAP15xx and OMAP7xx, cannot be setup to respond to on-chip GPIO interrupts in both rising and falling edge directions -- they can only respond to one direction or the other, depending on how the ICR is configured. Additionally, current code forces rising edge detection if both flags are specified: if (trigger & IRQ_TYPE_EDGE_RISING) l |= 1 << gpio; else if (trigger & IRQ_TYPE_EDGE_FALLING) l &= ~(1 << gpio); else goto bad; This change implements a toggle function that will modify the ICR to flip the direction of interrupt for IRQs that are requested with both rising and falling flags. The toggle function is not called for chips and GPIOs it does not apply to through the use of a flip_mask that's added on a per-bank basis. The mask is only set for those GPIOs where a toggle is necessary. Edge detection starts out the same as above with FALLING mode first. The toggle happens on EACH interrupt; without it, we have the following sequence of actions on GPIO transition: ICR GPIO Result 0x1 0 -> 1 (rising) Interrupt 0x1 1 -> 0 (falling) No interrupt (set ICR to 0x0 manually) 0x0 0 -> 1 (rising) No interrupt 0x0 1 -> 0 (falling) Interrupt That is, with the ICR set to 1 for a gpio, only rising edge interrupts are caught, and with it set to 0, only falling edge interrupts are caught. If we add in the toggle, we get this: ICR GPIO Result 0x1 0 -> 1 (rising) Interrupt (ICR set to 0x0) 0x0 1 -> 0 (falling) Interrupt (ICR set to 0x1) 0x1 0 -> 1 ... so, both rising and falling are caught, per the request for both (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING). Signed-off-by: Cory Maccarrone Acked-by: Kevin Hilman Signed-off-by: Tony Lindgren diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index 0484681..f8dfa8d 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c @@ -192,6 +192,7 @@ struct gpio_bank { u32 saved_risingdetect; #endif u32 level_mask; + u32 toggle_mask; spinlock_t lock; struct gpio_chip chip; struct clk *dbck; @@ -749,6 +750,44 @@ static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio, } #endif +/* + * This only applies to chips that can't do both rising and falling edge + * detection at once. For all other chips, this function is a noop. + */ +static void _toggle_gpio_edge_triggering(struct gpio_bank *bank, int gpio) +{ + void __iomem *reg = bank->base; + u32 l = 0; + + switch (bank->method) { +#ifdef CONFIG_ARCH_OMAP1 + case METHOD_MPUIO: + reg += OMAP_MPUIO_GPIO_INT_EDGE; + break; +#endif +#ifdef CONFIG_ARCH_OMAP15XX + case METHOD_GPIO_1510: + reg += OMAP1510_GPIO_INT_CONTROL; + break; +#endif +#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) + case METHOD_GPIO_7XX: + reg += OMAP7XX_GPIO_INT_CONTROL; + break; +#endif + default: + return; + } + + l = __raw_readl(reg); + if ((l >> gpio) & 1) + l &= ~(1 << gpio); + else + l |= 1 << gpio; + + __raw_writel(l, reg); +} + static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) { void __iomem *reg = bank->base; @@ -759,6 +798,8 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) case METHOD_MPUIO: reg += OMAP_MPUIO_GPIO_INT_EDGE; l = __raw_readl(reg); + if (trigger & IRQ_TYPE_EDGE_BOTH) + bank->toggle_mask |= 1 << gpio; if (trigger & IRQ_TYPE_EDGE_RISING) l |= 1 << gpio; else if (trigger & IRQ_TYPE_EDGE_FALLING) @@ -771,6 +812,8 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) case METHOD_GPIO_1510: reg += OMAP1510_GPIO_INT_CONTROL; l = __raw_readl(reg); + if (trigger & IRQ_TYPE_EDGE_BOTH) + bank->toggle_mask |= 1 << gpio; if (trigger & IRQ_TYPE_EDGE_RISING) l |= 1 << gpio; else if (trigger & IRQ_TYPE_EDGE_FALLING) @@ -803,6 +846,8 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) case METHOD_GPIO_7XX: reg += OMAP7XX_GPIO_INT_CONTROL; l = __raw_readl(reg); + if (trigger & IRQ_TYPE_EDGE_BOTH) + bank->toggle_mask |= 1 << gpio; if (trigger & IRQ_TYPE_EDGE_RISING) l |= 1 << gpio; else if (trigger & IRQ_TYPE_EDGE_FALLING) @@ -1217,7 +1262,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) { void __iomem *isr_reg = NULL; u32 isr; - unsigned int gpio_irq; + unsigned int gpio_irq, gpio_index; struct gpio_bank *bank; u32 retrigger = 0; int unmasked = 0; @@ -1284,9 +1329,23 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) gpio_irq = bank->virtual_irq_start; for (; isr != 0; isr >>= 1, gpio_irq++) { + gpio_index = get_gpio_index(irq_to_gpio(gpio_irq)); + if (!(isr & 1)) continue; +#ifdef CONFIG_ARCH_OMAP1 + /* + * Some chips can't respond to both rising and falling + * at the same time. If this irq was requested with + * both flags, we need to flip the ICR data for the IRQ + * to respond to the IRQ for the opposite direction. + * This will be indicated in the bank toggle_mask. + */ + if (bank->toggle_mask & (1 << gpio_index)) + _toggle_gpio_edge_triggering(bank, gpio_index); +#endif + generic_handle_irq(gpio_irq); } } -- cgit v0.10.2 From acf9d467dc951daa0071b5a1f4bed8c108f7ebec Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Fri, 8 Jan 2010 10:29:05 -0800 Subject: omap: &&/|| confusion in iommu_put() obj can't be both NULL and be an error pointer. Signed-off-by: Roel Kluin Signed-off-by: Tony Lindgren diff --git a/arch/arm/plat-omap/iommu.c b/arch/arm/plat-omap/iommu.c index c0ff1e3..463d638 100644 --- a/arch/arm/plat-omap/iommu.c +++ b/arch/arm/plat-omap/iommu.c @@ -827,7 +827,7 @@ EXPORT_SYMBOL_GPL(iommu_get); **/ void iommu_put(struct iommu *obj) { - if (!obj && IS_ERR(obj)) + if (!obj || IS_ERR(obj)) return; mutex_lock(&obj->iommu_lock); -- cgit v0.10.2 From 4cc6420c123317489e6c0d4bf7112f7098ac82ef Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Fri, 8 Jan 2010 10:29:05 -0800 Subject: omap: Remove uninitialized warning for gpio.c Flags is not used on 15xx. Signed-off-by: Tony Lindgren diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index f8dfa8d..d17620c 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c @@ -1117,7 +1117,7 @@ static inline void _set_gpio_irqenable(struct gpio_bank *bank, int gpio, int ena */ static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable) { - unsigned long flags; + unsigned long uninitialized_var(flags); switch (bank->method) { #ifdef CONFIG_ARCH_OMAP16XX -- cgit v0.10.2 From c5c4dce45d7538ada6e9aac4cdb2909bc1cb28f6 Mon Sep 17 00:00:00 2001 From: Cory Maccarrone Date: Fri, 8 Jan 2010 10:29:05 -0800 Subject: omap1: Add 7xx clocks and pin muxes for SPI Commit 35c9049b27040d09461bc90928ad770be7ddf661 added drivers/spi/omap_spi_100k.c. This patch add the related clocks and pin muxing entries to make the driver work on omap7xx platforms. Signed-off-by: Cory Maccarrone Signed-off-by: Tony Lindgren diff --git a/arch/arm/mach-omap1/clock_data.c b/arch/arm/mach-omap1/clock_data.c index ab995a9..6887bf3 100644 --- a/arch/arm/mach-omap1/clock_data.c +++ b/arch/arm/mach-omap1/clock_data.c @@ -658,6 +658,10 @@ static struct omap_clk omap_clks[] = { CLK("i2c_omap.1", "fck", &i2c_fck, CK_16XX | CK_1510 | CK_310 | CK_7XX), CLK("i2c_omap.1", "ick", &i2c_ick, CK_16XX), CLK("i2c_omap.1", "ick", &dummy_ck, CK_1510 | CK_310 | CK_7XX), + CLK("omap1_spi100k.1", "fck", &dummy_ck, CK_7XX), + CLK("omap1_spi100k.1", "ick", &dummy_ck, CK_7XX), + CLK("omap1_spi100k.2", "fck", &dummy_ck, CK_7XX), + CLK("omap1_spi100k.2", "ick", &dummy_ck, CK_7XX), CLK("omap_uwire", "fck", &armxor_ck.clk, CK_16XX | CK_1510 | CK_310), CLK("omap-mcbsp.1", "ick", &dspper_ck, CK_16XX), CLK("omap-mcbsp.1", "ick", &dummy_ck, CK_1510 | CK_310), diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c index 23ded2d..a2d07aa 100644 --- a/arch/arm/mach-omap1/devices.c +++ b/arch/arm/mach-omap1/devices.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -23,6 +24,7 @@ #include #include #include +#include /*-------------------------------------------------------------------------*/ @@ -196,6 +198,38 @@ void __init omap1_init_mmc(struct omap_mmc_platform_data **mmc_data, /*-------------------------------------------------------------------------*/ +/* OMAP7xx SPI support */ +#if defined(CONFIG_SPI_OMAP_100K) || defined(CONFIG_SPI_OMAP_100K_MODULE) + +struct platform_device omap_spi1 = { + .name = "omap1_spi100k", + .id = 1, +}; + +struct platform_device omap_spi2 = { + .name = "omap1_spi100k", + .id = 2, +}; + +static void omap_init_spi100k(void) +{ + omap_spi1.dev.platform_data = ioremap(OMAP7XX_SPI1_BASE, 0x7ff); + if (omap_spi1.dev.platform_data) + platform_device_register(&omap_spi1); + + omap_spi2.dev.platform_data = ioremap(OMAP7XX_SPI2_BASE, 0x7ff); + if (omap_spi2.dev.platform_data) + platform_device_register(&omap_spi2); +} + +#else +static inline void omap_init_spi100k(void) +{ +} +#endif + +/*-------------------------------------------------------------------------*/ + #if defined(CONFIG_OMAP_STI) #define OMAP1_STI_BASE 0xfffea000 @@ -263,6 +297,7 @@ static int __init omap1_init_devices(void) omap_init_mbox(); omap_init_rtc(); + omap_init_spi100k(); omap_init_sti(); return 0; diff --git a/arch/arm/mach-omap1/mux.c b/arch/arm/mach-omap1/mux.c index 07212cc..8434137 100644 --- a/arch/arm/mach-omap1/mux.c +++ b/arch/arm/mach-omap1/mux.c @@ -62,6 +62,14 @@ MUX_CFG_7XX("MMC_7XX_DAT0", 2, 17, 0, 16, 1, 0) /* I2C interface */ MUX_CFG_7XX("I2C_7XX_SCL", 5, 1, 0, 0, 1, 0) MUX_CFG_7XX("I2C_7XX_SDA", 5, 5, 0, 0, 1, 0) + +/* SPI pins */ +MUX_CFG_7XX("SPI_7XX_1", 6, 5, 4, 4, 1, 0) +MUX_CFG_7XX("SPI_7XX_2", 6, 9, 4, 8, 1, 0) +MUX_CFG_7XX("SPI_7XX_3", 6, 13, 4, 12, 1, 0) +MUX_CFG_7XX("SPI_7XX_4", 6, 17, 4, 16, 1, 0) +MUX_CFG_7XX("SPI_7XX_5", 8, 25, 0, 24, 0, 0) +MUX_CFG_7XX("SPI_7XX_6", 9, 5, 0, 4, 0, 0) }; #define OMAP7XX_PINS_SZ ARRAY_SIZE(omap7xx_pins) #else diff --git a/arch/arm/plat-omap/include/plat/mux.h b/arch/arm/plat-omap/include/plat/mux.h index 8f069cc..692c90e 100644 --- a/arch/arm/plat-omap/include/plat/mux.h +++ b/arch/arm/plat-omap/include/plat/mux.h @@ -183,6 +183,14 @@ enum omap7xx_index { /* I2C */ I2C_7XX_SCL, I2C_7XX_SDA, + + /* SPI */ + SPI_7XX_1, + SPI_7XX_2, + SPI_7XX_3, + SPI_7XX_4, + SPI_7XX_5, + SPI_7XX_6, }; enum omap1xxx_index { diff --git a/arch/arm/plat-omap/include/plat/omap7xx.h b/arch/arm/plat-omap/include/plat/omap7xx.h index 53f5241..48e4757 100644 --- a/arch/arm/plat-omap/include/plat/omap7xx.h +++ b/arch/arm/plat-omap/include/plat/omap7xx.h @@ -46,6 +46,9 @@ #define OMAP7XX_DSPREG_SIZE SZ_128K #define OMAP7XX_DSPREG_START 0xE1000000 +#define OMAP7XX_SPI1_BASE 0xfffc0800 +#define OMAP7XX_SPI2_BASE 0xfffc1000 + /* * ---------------------------------------------------------------------------- * OMAP7XX specific configuration registers -- cgit v0.10.2 From 66215949e6512f61c2c92b65ea79f8566e9e650a Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Fri, 8 Jan 2010 10:29:06 -0800 Subject: omap1: Fix compile for omap1_bl.c Commit 9905a43b made struct backlight_ops const. Omap was setting check_fb dynamically, which caused the following compile error: drivers/video/backlight/omap1_bl.c: In function 'omapbl_probe': drivers/video/backlight/omap1_bl.c:142: error: assignment of read-only variable 'omapbl_ops' Turns out pdata->check_fb is not being used, so just remove it to fix the compile. Cc: Emese Revfy Cc: Richard Purdie Signed-off-by: Tony Lindgren diff --git a/arch/arm/plat-omap/include/plat/board.h b/arch/arm/plat-omap/include/plat/board.h index 376ce18..5cd6220 100644 --- a/arch/arm/plat-omap/include/plat/board.h +++ b/arch/arm/plat-omap/include/plat/board.h @@ -99,7 +99,6 @@ struct fb_info; struct omap_backlight_config { int default_intensity; int (*set_power)(struct device *dev, int state); - int (*check_fb)(struct fb_info *fb); }; struct omap_fbmem_config { diff --git a/drivers/video/backlight/omap1_bl.c b/drivers/video/backlight/omap1_bl.c index 409ca96..a3a7f89 100644 --- a/drivers/video/backlight/omap1_bl.c +++ b/drivers/video/backlight/omap1_bl.c @@ -139,8 +139,6 @@ static int omapbl_probe(struct platform_device *pdev) if (!pdata) return -ENXIO; - omapbl_ops.check_fb = pdata->check_fb; - bl = kzalloc(sizeof(struct omap_backlight), GFP_KERNEL); if (unlikely(!bl)) return -ENOMEM; -- cgit v0.10.2 From 9230372aeecc0a634f708e9eb8668769daa1ed5a Mon Sep 17 00:00:00 2001 From: Alexander Shishkin Date: Fri, 8 Jan 2010 10:29:06 -0800 Subject: omap2/3: make serial_in_override() address the right uart port Commit f62349ee9788b1d94c55eb6c291d74a1f69bdd9e makes it possible to have some other than first uart port as ttyS0, which breaks the workaround serial_in_override() function which will try to address the first uart port (for ttyS0) and not the one that was initialized. Signed-off-by: Alexander Shishkin CC: Mika Westerberg Acked-by: Kevin Hilman Signed-off-by: Tony Lindgren diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 19805a7..8c964be 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -125,6 +125,13 @@ static struct plat_serial8250_port serial_platform_data3[] = { } }; #endif +static inline unsigned int __serial_read_reg(struct uart_port *up, + int offset) +{ + offset <<= up->regshift; + return (unsigned int)__raw_readb(up->membase + offset); +} + static inline unsigned int serial_read_reg(struct plat_serial8250_port *up, int offset) { @@ -583,11 +590,12 @@ static unsigned int serial_in_override(struct uart_port *up, int offset) { if (UART_RX == offset) { unsigned int lsr; - lsr = serial_read_reg(omap_uart[up->line].p, UART_LSR); + lsr = __serial_read_reg(up, UART_LSR); if (!(lsr & UART_LSR_DR)) return -EPERM; } - return serial_read_reg(omap_uart[up->line].p, offset); + + return __serial_read_reg(up, offset); } void __init omap_serial_early_init(void) -- cgit v0.10.2 From 6b06ebdfbd3100ffa789d3893bc7c08b1f91ea30 Mon Sep 17 00:00:00 2001 From: Vimal Singh Date: Fri, 8 Jan 2010 10:29:07 -0800 Subject: omap2/3: ZOOM: Correcting key mapping for few keys Keys: 'right arrow', 'up arrow' and 'select' were mapped wrongly. This patch corrects them. This patch also adds one missing key present in the board, currently I added it as 'unknown' key, as I am not able to find proper description for this key. One key entry (r: 7, c: 5) is present in the keymap, which is really not present in the board, removing it. Signed-off-by: Vimal Singh Signed-off-by: Tony Lindgren diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c index 8dd277c..1e3dfb6 100755 --- a/arch/arm/mach-omap2/board-zoom-peripherals.c +++ b/arch/arm/mach-omap2/board-zoom-peripherals.c @@ -63,21 +63,21 @@ static int board_keymap[] = { KEY(5, 1, KEY_H), KEY(5, 2, KEY_J), KEY(5, 3, KEY_F3), + KEY(5, 4, KEY_UNKNOWN), KEY(5, 5, KEY_VOLUMEDOWN), KEY(5, 6, KEY_M), - KEY(5, 7, KEY_ENTER), + KEY(5, 7, KEY_RIGHT), KEY(6, 0, KEY_Q), KEY(6, 1, KEY_A), KEY(6, 2, KEY_N), KEY(6, 3, KEY_BACKSPACE), KEY(6, 6, KEY_P), - KEY(6, 7, KEY_SELECT), + KEY(6, 7, KEY_UP), KEY(7, 0, KEY_PROG1), /*MACRO 1 */ KEY(7, 1, KEY_PROG2), /*MACRO 2 */ KEY(7, 2, KEY_PROG3), /*MACRO 3 */ KEY(7, 3, KEY_PROG4), /*MACRO 4 */ - KEY(7, 5, KEY_RIGHT), - KEY(7, 6, KEY_UP), + KEY(7, 6, KEY_SELECT), KEY(7, 7, KEY_DOWN) }; -- cgit v0.10.2 From 83969bfa2022962c12272f4f860c05e28ee4509d Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Fri, 8 Jan 2010 10:29:07 -0800 Subject: omap3: add missing parentheses not(!) has a higher precedence than bit and(&). Signed-off-by: Roel Kluin Signed-off-by: Tony Lindgren diff --git a/arch/arm/plat-omap/include/plat/control.h b/arch/arm/plat-omap/include/plat/control.h index 2ae8843..a745d62 100644 --- a/arch/arm/plat-omap/include/plat/control.h +++ b/arch/arm/plat-omap/include/plat/control.h @@ -147,7 +147,7 @@ #define OMAP343X_CONTROL_IVA2_BOOTADDR (OMAP2_CONTROL_GENERAL + 0x0190) #define OMAP343X_CONTROL_IVA2_BOOTMOD (OMAP2_CONTROL_GENERAL + 0x0194) #define OMAP343X_CONTROL_DEBOBS(i) (OMAP2_CONTROL_GENERAL + 0x01B0 \ - + ((i) >> 1) * 4 + (!(i) & 1) * 2) + + ((i) >> 1) * 4 + (!((i) & 1)) * 2) #define OMAP343X_CONTROL_PROG_IO0 (OMAP2_CONTROL_GENERAL + 0x01D4) #define OMAP343X_CONTROL_PROG_IO1 (OMAP2_CONTROL_GENERAL + 0x01D8) #define OMAP343X_CONTROL_DSS_DPLL_SPREADING (OMAP2_CONTROL_GENERAL + 0x01E0) -- cgit v0.10.2 From 1b6e821f234f9e22ad1ef4919e140625af251935 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Fri, 8 Jan 2010 10:29:07 -0800 Subject: omap3: add missing parentheses `!' has a higher precedence than `&' so parentheses are required. Signed-off-by: Roel Kluin Signed-off-by: Tony Lindgren diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 81ed252..c6cc809 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -124,8 +124,8 @@ static void omap3_core_save_context(void) control_padconf_off |= START_PADCONF_SAVE; omap_ctrl_writel(control_padconf_off, OMAP343X_CONTROL_PADCONF_OFF); /* wait for the save to complete */ - while (!omap_ctrl_readl(OMAP343X_CONTROL_GENERAL_PURPOSE_STATUS) - & PADCONF_SAVE_DONE) + while (!(omap_ctrl_readl(OMAP343X_CONTROL_GENERAL_PURPOSE_STATUS) + & PADCONF_SAVE_DONE)) ; /* Save the Interrupt controller context */ omap_intc_save_context(); -- cgit v0.10.2 From d04eb60066ed532d2e5da9f39cc0c79883d8a33c Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Fri, 8 Jan 2010 10:29:08 -0800 Subject: omap3: Fix booting if package is uninitialized Otherwise bringing up new boards can be harder: Unable to handle kernel NULL pointer dereference at virtual address 00000000 pgd = c0004000 [00000000] *pgd=00000000 Internal error: Oops: 5 [#1] last sysfs file: Modules linked in: CPU: 0 Not tainted (2.6.33-rc2-00015-g0bc9c93-dirty #37) PC is at omap_mux_init+0xa4/0x3d8 LR is at omap_mux_init+0x3c/0x3d8 ... Signed-off-by: Tony Lindgren diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c index e071b3f..459ef23a 100644 --- a/arch/arm/mach-omap2/mux.c +++ b/arch/arm/mach-omap2/mux.c @@ -994,8 +994,10 @@ int __init omap_mux_init(u32 mux_pbase, u32 mux_size, } #ifdef CONFIG_OMAP_MUX - omap_mux_package_fixup(package_subset, superset); - omap_mux_package_init_balls(package_balls, superset); + if (package_subset) + omap_mux_package_fixup(package_subset, superset); + if (package_balls) + omap_mux_package_init_balls(package_balls, superset); omap_mux_set_cmdline_signals(); omap_mux_set_board_signals(board_mux); #endif -- cgit v0.10.2 From 342aa2c1721e2714f43d957c3dd0bdaaa688c207 Mon Sep 17 00:00:00 2001 From: Vaibhav Hiremath Date: Fri, 8 Jan 2010 10:29:08 -0800 Subject: omap3: EVM: Choose OMAP_PACKAGE_CBB Without this the kernel doesn't boot, it craches in omap_mux_package_fixup(), since the package_subset becomes NULL. Signed-off-by: Vaibhav Hiremath Signed-off-by: Tony Lindgren diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 10eafa7..606bf04 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -80,6 +80,7 @@ config MACH_OVERO config MACH_OMAP3EVM bool "OMAP 3530 EVM board" depends on ARCH_OMAP3 && ARCH_OMAP34XX + select OMAP_PACKAGE_CBB config MACH_OMAP3517EVM bool "OMAP3517/ AM3517 EVM board" -- cgit v0.10.2 From a651d80c7136029de3c044308fd63d88348915ff Mon Sep 17 00:00:00 2001 From: Tony Luck Date: Fri, 8 Jan 2010 10:53:28 -0800 Subject: [IA64] move fnptr definition inside #ifdef __KERNEL__ Linus pointed out that this definition should not be exported to user space. Signed-off-by: Tony Luck diff --git a/arch/ia64/include/asm/types.h b/arch/ia64/include/asm/types.h index b8e5d97..93773fd 100644 --- a/arch/ia64/include/asm/types.h +++ b/arch/ia64/include/asm/types.h @@ -30,16 +30,16 @@ typedef unsigned int umode_t; -struct fnptr { - unsigned long ip; - unsigned long gp; -}; - /* * These aren't exported outside the kernel to avoid name space clashes */ # ifdef __KERNEL__ +struct fnptr { + unsigned long ip; + unsigned long gp; +}; + /* DMA addresses are 64-bits wide, in general. */ typedef u64 dma_addr_t; -- cgit v0.10.2 From a539bd8c86549b545b4ed27a0cfaf53fe649054d Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Thu, 17 Dec 2009 00:20:07 +0000 Subject: xfs: kill some warnings on i386 builds Randy Dunlap Reported printk() format-related warnings reported on i386 builds in his environment. Dave Chinner provided this patch to eliminate them. Signed-off by: Dave Chinner Acked-by: Randy Dunlap Signed-off-by: Alex Elder diff --git a/fs/xfs/linux-2.6/xfs_trace.h b/fs/xfs/linux-2.6/xfs_trace.h index c40834b..d4ded59 100644 --- a/fs/xfs/linux-2.6/xfs_trace.h +++ b/fs/xfs/linux-2.6/xfs_trace.h @@ -815,7 +815,7 @@ TRACE_EVENT(name, \ ), \ TP_printk("dev %d:%d ino 0x%llx size 0x%llx new_size 0x%llx " \ "offset 0x%llx count %zd flags %s " \ - "startoff 0x%llx startblock 0x%llx blockcount 0x%llx", \ + "startoff 0x%llx startblock %s blockcount 0x%llx", \ MAJOR(__entry->dev), MINOR(__entry->dev), \ __entry->ino, \ __entry->size, \ @@ -824,7 +824,7 @@ TRACE_EVENT(name, \ __entry->count, \ __print_flags(__entry->flags, "|", BMAPI_FLAGS), \ __entry->startoff, \ - __entry->startblock, \ + xfs_fmtfsblock(__entry->startblock), \ __entry->blockcount) \ ) DEFINE_IOMAP_EVENT(xfs_iomap_enter); @@ -1201,7 +1201,7 @@ TRACE_EVENT(name, \ TP_printk("dev %d:%d agno %u agbno %u minlen %u maxlen %u mod %u " \ "prod %u minleft %u total %u alignment %u minalignslop %u " \ "len %u type %s otype %s wasdel %d wasfromfl %d isfl %d " \ - "userdata %d firstblock 0x%llx", \ + "userdata %d firstblock %s", \ MAJOR(__entry->dev), MINOR(__entry->dev), \ __entry->agno, \ __entry->agbno, \ @@ -1220,7 +1220,7 @@ TRACE_EVENT(name, \ __entry->wasfromfl, \ __entry->isfl, \ __entry->userdata, \ - __entry->firstblock) \ + xfs_fmtfsblock(__entry->firstblock)) \ ) DEFINE_ALLOC_EVENT(xfs_alloc_exact_done); -- cgit v0.10.2 From 48bca0e9c7f428dc75ea2a9c37601e6cb47dae6f Mon Sep 17 00:00:00 2001 From: Huang Weiyi Date: Fri, 8 Jan 2010 15:23:03 -0700 Subject: OMAP2: remove duplicated #include Remove duplicated #include('s) in arch/arm/mach-omap2/clock34xx.c arch/arm/mach-omap2/io.c Signed-off-by: Huang Weiyi Signed-off-by: Paul Walmsley diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c index ded3236..d4217b9 100644 --- a/arch/arm/mach-omap2/clock34xx.c +++ b/arch/arm/mach-omap2/clock34xx.c @@ -34,7 +34,6 @@ #include #include -#include #include "clock.h" #include "clock34xx.h" #include "sdrc.h" diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index a8749e8..ac9ea60 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include "clock.h" -- cgit v0.10.2 From 98bb155130aca96f26b12b50a38db806a0021e59 Mon Sep 17 00:00:00 2001 From: Abhijit Pagare Date: Fri, 8 Jan 2010 15:23:04 -0700 Subject: ARM: OMAP3: PM: Fix the Invalid CM_CLKSTCTRL reg access. In OMAP2/3 some of the clock-domains which did not have control facility were being falsely written to and read using the CM_CLKSTCTRL register though it did not exist for them. One check is added to remove this flaw. Signed-off-by: Abhijit Pagare Signed-off-by: Paul Walmsley Cc: Benoit Cousson Cc: Rajendra Nayak diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c index 1a45ed1..dd285f0 100644 --- a/arch/arm/mach-omap2/clockdomain.c +++ b/arch/arm/mach-omap2/clockdomain.c @@ -559,7 +559,7 @@ int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk) * downstream clocks for debugging purposes? */ - if (!clkdm || !clk) + if (!clkdm || !clk || !clkdm->clktrctrl_mask) return -EINVAL; if (atomic_inc_return(&clkdm->usecount) > 1) @@ -610,7 +610,7 @@ int omap2_clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk) * downstream clocks for debugging purposes? */ - if (!clkdm || !clk) + if (!clkdm || !clk || !clkdm->clktrctrl_mask) return -EINVAL; #ifdef DEBUG -- cgit v0.10.2 From 7adb9987177f7aa269505ef65f4b4ed84bbc17b5 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Fri, 8 Jan 2010 15:23:05 -0700 Subject: OMAP2xxx IO mapping: mark DSP mappings as being 2420-only Out of the three major OMAP2 chip types, OMAP2420, OMAP2430, and OMAP3430, we only map the IVA on OMAP2420. The memory mapping is not shared between OMAP2420 and OMAP2430, so it is inappropriate to label those macros as '24XX'; this patch changes them to '2420'. Signed-off-by: Paul Walmsley diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index ac9ea60..5a79964 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -72,21 +72,21 @@ static struct map_desc omap24xx_io_desc[] __initdata = { #ifdef CONFIG_ARCH_OMAP2420 static struct map_desc omap242x_io_desc[] __initdata = { { - .virtual = DSP_MEM_24XX_VIRT, - .pfn = __phys_to_pfn(DSP_MEM_24XX_PHYS), - .length = DSP_MEM_24XX_SIZE, + .virtual = DSP_MEM_2420_VIRT, + .pfn = __phys_to_pfn(DSP_MEM_2420_PHYS), + .length = DSP_MEM_2420_SIZE, .type = MT_DEVICE }, { - .virtual = DSP_IPI_24XX_VIRT, - .pfn = __phys_to_pfn(DSP_IPI_24XX_PHYS), - .length = DSP_IPI_24XX_SIZE, + .virtual = DSP_IPI_2420_VIRT, + .pfn = __phys_to_pfn(DSP_IPI_2420_PHYS), + .length = DSP_IPI_2420_SIZE, .type = MT_DEVICE }, { - .virtual = DSP_MMU_24XX_VIRT, - .pfn = __phys_to_pfn(DSP_MMU_24XX_PHYS), - .length = DSP_MMU_24XX_SIZE, + .virtual = DSP_MMU_2420_VIRT, + .pfn = __phys_to_pfn(DSP_MMU_2420_PHYS), + .length = DSP_MMU_2420_SIZE, .type = MT_DEVICE }, }; diff --git a/arch/arm/plat-omap/include/plat/io.h b/arch/arm/plat-omap/include/plat/io.h index 7e5319f..7d6f45f 100644 --- a/arch/arm/plat-omap/include/plat/io.h +++ b/arch/arm/plat-omap/include/plat/io.h @@ -122,16 +122,18 @@ #define OMAP243X_SMS_VIRT (OMAP243X_SMS_PHYS + OMAP2_L3_IO_OFFSET) #define OMAP243X_SMS_SIZE SZ_1M -/* DSP */ -#define DSP_MEM_24XX_PHYS OMAP2420_DSP_MEM_BASE /* 0x58000000 */ -#define DSP_MEM_24XX_VIRT 0xe0000000 -#define DSP_MEM_24XX_SIZE 0x28000 -#define DSP_IPI_24XX_PHYS OMAP2420_DSP_IPI_BASE /* 0x59000000 */ -#define DSP_IPI_24XX_VIRT 0xe1000000 -#define DSP_IPI_24XX_SIZE SZ_4K -#define DSP_MMU_24XX_PHYS OMAP2420_DSP_MMU_BASE /* 0x5a000000 */ -#define DSP_MMU_24XX_VIRT 0xe2000000 -#define DSP_MMU_24XX_SIZE SZ_4K +/* 2420 IVA */ +#define DSP_MEM_2420_PHYS OMAP2420_DSP_MEM_BASE /* 0x58000000 */ +#define DSP_MEM_2420_VIRT 0xe0000000 +#define DSP_MEM_2420_SIZE 0x28000 +#define DSP_IPI_2420_PHYS OMAP2420_DSP_IPI_BASE /* 0x59000000 */ +#define DSP_IPI_2420_VIRT 0xe1000000 +#define DSP_IPI_2420_SIZE SZ_4K +#define DSP_MMU_2420_PHYS OMAP2420_DSP_MMU_BASE /* 0x5a000000 */ +#define DSP_MMU_2420_VIRT 0xe2000000 +#define DSP_MMU_2420_SIZE SZ_4K + +/* 2430 IVA2.1 - currently unmapped */ /* * ---------------------------------------------------------------------------- @@ -182,16 +184,7 @@ #define OMAP343X_SDRC_VIRT (OMAP343X_SDRC_PHYS + OMAP2_L3_IO_OFFSET) #define OMAP343X_SDRC_SIZE SZ_1M -/* DSP */ -#define DSP_MEM_34XX_PHYS OMAP34XX_DSP_MEM_BASE /* 0x58000000 */ -#define DSP_MEM_34XX_VIRT 0xe0000000 -#define DSP_MEM_34XX_SIZE 0x28000 -#define DSP_IPI_34XX_PHYS OMAP34XX_DSP_IPI_BASE /* 0x59000000 */ -#define DSP_IPI_34XX_VIRT 0xe1000000 -#define DSP_IPI_34XX_SIZE SZ_4K -#define DSP_MMU_34XX_PHYS OMAP34XX_DSP_MMU_BASE /* 0x5a000000 */ -#define DSP_MMU_34XX_VIRT 0xe2000000 -#define DSP_MMU_34XX_SIZE SZ_4K +/* 3430 IVA - currently unmapped */ /* * ---------------------------------------------------------------------------- diff --git a/arch/arm/plat-omap/io.c b/arch/arm/plat-omap/io.c index 11f5d79..0cfd54f 100644 --- a/arch/arm/plat-omap/io.c +++ b/arch/arm/plat-omap/io.c @@ -66,12 +66,12 @@ void __iomem *omap_ioremap(unsigned long p, size_t size, unsigned int type) return XLATE(p, L4_24XX_PHYS, L4_24XX_VIRT); } if (cpu_is_omap2420()) { - if (BETWEEN(p, DSP_MEM_24XX_PHYS, DSP_MEM_24XX_SIZE)) - return XLATE(p, DSP_MEM_24XX_PHYS, DSP_MEM_24XX_VIRT); - if (BETWEEN(p, DSP_IPI_24XX_PHYS, DSP_IPI_24XX_SIZE)) - return XLATE(p, DSP_IPI_24XX_PHYS, DSP_IPI_24XX_SIZE); - if (BETWEEN(p, DSP_MMU_24XX_PHYS, DSP_MMU_24XX_SIZE)) - return XLATE(p, DSP_MMU_24XX_PHYS, DSP_MMU_24XX_VIRT); + if (BETWEEN(p, DSP_MEM_2420_PHYS, DSP_MEM_2420_SIZE)) + return XLATE(p, DSP_MEM_2420_PHYS, DSP_MEM_2420_VIRT); + if (BETWEEN(p, DSP_IPI_2420_PHYS, DSP_IPI_2420_SIZE)) + return XLATE(p, DSP_IPI_2420_PHYS, DSP_IPI_2420_SIZE); + if (BETWEEN(p, DSP_MMU_2420_PHYS, DSP_MMU_2420_SIZE)) + return XLATE(p, DSP_MMU_2420_PHYS, DSP_MMU_2420_VIRT); } if (cpu_is_omap2430()) { if (BETWEEN(p, L4_WK_243X_PHYS, L4_WK_243X_SIZE)) -- cgit v0.10.2 From 51e888d705d29824aebb22ddf8a1f478083386e7 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Fri, 8 Jan 2010 15:23:06 -0700 Subject: OMAP2420 IO mapping: move IVA mapping virtual address out of vmalloc space Commit 10db25fea4c11661070b97832b8cc3d2af495092 causes the following kernel messages during N800 boot (and presumably all other 2420 boards): [ 0.000000] BUG: mapping for 0x58000000 at 0xe0000000 overlaps vmalloc space [ 0.000000] BUG: mapping for 0x59000000 at 0xe1000000 overlaps vmalloc space [ 0.000000] BUG: mapping for 0x5a000000 at 0xe2000000 overlaps vmalloc space Fix by remapping the IVA memory areas somewhere outside vmalloc space. Signed-off-by: Paul Walmsley Cc: Santosh Shilimkar Cc: Tony Lindgren diff --git a/arch/arm/plat-omap/include/plat/io.h b/arch/arm/plat-omap/include/plat/io.h index 7d6f45f..a3e7b47 100644 --- a/arch/arm/plat-omap/include/plat/io.h +++ b/arch/arm/plat-omap/include/plat/io.h @@ -123,14 +123,17 @@ #define OMAP243X_SMS_SIZE SZ_1M /* 2420 IVA */ -#define DSP_MEM_2420_PHYS OMAP2420_DSP_MEM_BASE /* 0x58000000 */ -#define DSP_MEM_2420_VIRT 0xe0000000 +#define DSP_MEM_2420_PHYS OMAP2420_DSP_MEM_BASE + /* 0x58000000 --> 0xfc100000 */ +#define DSP_MEM_2420_VIRT 0xfc100000 #define DSP_MEM_2420_SIZE 0x28000 -#define DSP_IPI_2420_PHYS OMAP2420_DSP_IPI_BASE /* 0x59000000 */ -#define DSP_IPI_2420_VIRT 0xe1000000 +#define DSP_IPI_2420_PHYS OMAP2420_DSP_IPI_BASE + /* 0x59000000 --> 0xfc128000 */ +#define DSP_IPI_2420_VIRT 0xfc128000 #define DSP_IPI_2420_SIZE SZ_4K -#define DSP_MMU_2420_PHYS OMAP2420_DSP_MMU_BASE /* 0x5a000000 */ -#define DSP_MMU_2420_VIRT 0xe2000000 +#define DSP_MMU_2420_PHYS OMAP2420_DSP_MMU_BASE + /* 0x5a000000 --> 0xfc129000 */ +#define DSP_MMU_2420_VIRT 0xfc129000 #define DSP_MMU_2420_SIZE SZ_4K /* 2430 IVA2.1 - currently unmapped */ -- cgit v0.10.2 From 9b5bc5fa4b68fe2f51a5197786a8b5df82d1b8bf Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Fri, 8 Jan 2010 15:23:06 -0700 Subject: OMAP3: clock: add clockdomains for UART1 & 2 UART1 & 2 were missing clockdomains resulting in broken omap_hwmod init for these devices. Signed-off-by: Kevin Hilman Signed-off-by: Paul Walmsley diff --git a/arch/arm/mach-omap2/clock34xx_data.c b/arch/arm/mach-omap2/clock34xx_data.c index 8bdcc9cc..c60b19a 100644 --- a/arch/arm/mach-omap2/clock34xx_data.c +++ b/arch/arm/mach-omap2/clock34xx_data.c @@ -1500,6 +1500,7 @@ static struct clk uart2_fck = { .parent = &core_48m_fck, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP3430_EN_UART2_SHIFT, + .clkdm_name = "core_l4_clkdm", .recalc = &followparent_recalc, }; @@ -1509,6 +1510,7 @@ static struct clk uart1_fck = { .parent = &core_48m_fck, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP3430_EN_UART1_SHIFT, + .clkdm_name = "core_l4_clkdm", .recalc = &followparent_recalc, }; -- cgit v0.10.2 From 073463ca4011d4f6f8e2334273f3b062b2b19b85 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Fri, 8 Jan 2010 15:23:07 -0700 Subject: OMAP3 clock: McBSP 2, 3, 4 functional clock parent is PER_96M_FCLK, not CORE_96M_FCLK The correct parent of the McBSP 2, 3, and 4 functional clocks is PER_96M_FCLK, not CORE_96M_FCLK. Fix this in the OMAP clock tree. Reported by Nicole Chalhoub . Signed-off-by: Paul Walmsley Cc: Nicole Chalhoub diff --git a/arch/arm/mach-omap2/clock34xx_data.c b/arch/arm/mach-omap2/clock34xx_data.c index c60b19a..7eea9fb 100644 --- a/arch/arm/mach-omap2/clock34xx_data.c +++ b/arch/arm/mach-omap2/clock34xx_data.c @@ -2747,7 +2747,7 @@ static struct clk mcbsp4_ick = { }; static const struct clksel mcbsp_234_clksel[] = { - { .parent = &core_96m_fck, .rates = common_mcbsp_96m_rates }, + { .parent = &per_96m_fck, .rates = common_mcbsp_96m_rates }, { .parent = &mcbsp_clks, .rates = common_mcbsp_mcbsp_rates }, { .parent = NULL } }; -- cgit v0.10.2 From 3e3ee1560daaf09bb5dbe3afd35ca2f75e2e116a Mon Sep 17 00:00:00 2001 From: Tuukka Toivonen Date: Fri, 8 Jan 2010 15:23:08 -0700 Subject: OMAP3 clock: Add capability to change rate of dpll4_m5_ck MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add necessary definitions to clock framework to allow changing dpll4_m5_ck rate. This is used by the camera code. Signed-off-by: Jouni Högander Signed-off-by: Tuukka Toivonen Signed-off-by: Paul Walmsley diff --git a/arch/arm/mach-omap2/clock34xx_data.c b/arch/arm/mach-omap2/clock34xx_data.c index 7eea9fb..c6031d7 100644 --- a/arch/arm/mach-omap2/clock34xx_data.c +++ b/arch/arm/mach-omap2/clock34xx_data.c @@ -776,6 +776,8 @@ static struct clk dpll4_m5_ck = { .clksel_mask = OMAP3430_CLKSEL_CAM_MASK, .clksel = div16_dpll4_clksel, .clkdm_name = "dpll4_clkdm", + .set_rate = &omap2_clksel_set_rate, + .round_rate = &omap2_clksel_round_rate, .recalc = &omap2_clksel_recalc, }; -- cgit v0.10.2 From d1e624982194e617b6f5c7d61305a3e8d9078952 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Fri, 8 Jan 2010 15:23:09 -0700 Subject: OMAP clock: remove incorrect EXPORT_SYMBOL()s The only symbols that should be exported are symbols that are to be called from loadable kernel modules, e.g., device drivers. In the context of plat-omap/clock.c, these should only be the Linux clock interface symbols as defined by include/linux/clk.h. Core code doesn't need these symbols to be exported. Also, clean up an old comment while here. Signed-off-by: Paul Walmsley diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c index 89cafc9..a64d84c 100644 --- a/arch/arm/plat-omap/clock.c +++ b/arch/arm/plat-omap/clock.c @@ -36,10 +36,6 @@ static struct clk_functions *arch_clock; * Standard clock functions defined in include/linux/clk.h *-------------------------------------------------------------------------*/ -/* This functions is moved to arch/arm/common/clkdev.c. For OMAP4 since - * clock framework is not up , it is defined here to avoid rework in - * every driver. Also dummy prcm reset function is added */ - int clk_enable(struct clk *clk) { unsigned long flags; @@ -305,7 +301,6 @@ void clk_enable_init_clocks(void) clk_enable(clkp); } } -EXPORT_SYMBOL(clk_enable_init_clocks); /* * Low level helpers @@ -334,7 +329,6 @@ void clk_init_cpufreq_table(struct cpufreq_frequency_table **table) arch_clock->clk_init_cpufreq_table(table); spin_unlock_irqrestore(&clockfw_lock, flags); } -EXPORT_SYMBOL(clk_init_cpufreq_table); #endif /*-------------------------------------------------------------------------*/ -- cgit v0.10.2 From e8ae6b6e4dec43db4ae6fc67550fe63f16247667 Mon Sep 17 00:00:00 2001 From: Cory Maccarrone Date: Fri, 8 Jan 2010 15:23:10 -0700 Subject: OMAP1 clock: Add missing clocks for OMAP 7xx This change adds in some missing clocks that were needed as a result of 526505... (OMAP1 clock: convert mach-omap1/clock.h to mach-omap1/clock_data.c). Prior to this, it was just assumed that these clocks existed for all devices, and it was used directly instead of calling it out with a clock_get call or similar. So, not having the CK_7XX meant these clocks weren't being used anymore for omap 7xx devices, which broke things badly. Signed-off-by: Cory Maccarrone [paul@pwsan.com: commit message edited] Signed-off-by: Paul Walmsley diff --git a/arch/arm/mach-omap1/clock_data.c b/arch/arm/mach-omap1/clock_data.c index ab995a9..31fba07 100644 --- a/arch/arm/mach-omap1/clock_data.c +++ b/arch/arm/mach-omap1/clock_data.c @@ -599,7 +599,7 @@ static struct clk i2c_ick = { static struct omap_clk omap_clks[] = { /* non-ULPD clocks */ CLK(NULL, "ck_ref", &ck_ref, CK_16XX | CK_1510 | CK_310 | CK_7XX), - CLK(NULL, "ck_dpll1", &ck_dpll1, CK_16XX | CK_1510 | CK_310), + CLK(NULL, "ck_dpll1", &ck_dpll1, CK_16XX | CK_1510 | CK_310 | CK_7XX), /* CK_GEN1 clocks */ CLK(NULL, "ck_dpll1out", &ck_dpll1out.clk, CK_16XX), CLK(NULL, "ck_sossi", &sossi_ck, CK_16XX), @@ -627,7 +627,7 @@ static struct omap_clk omap_clks[] = { CLK(NULL, "tc2_ck", &tc2_ck, CK_16XX), CLK(NULL, "dma_ck", &dma_ck, CK_16XX | CK_1510 | CK_310), CLK(NULL, "dma_lcdfree_ck", &dma_lcdfree_ck, CK_16XX), - CLK(NULL, "api_ck", &api_ck.clk, CK_16XX | CK_1510 | CK_310), + CLK(NULL, "api_ck", &api_ck.clk, CK_16XX | CK_1510 | CK_310 | CK_7XX), CLK(NULL, "lb_ck", &lb_ck.clk, CK_1510 | CK_310), CLK(NULL, "rhea1_ck", &rhea1_ck, CK_16XX), CLK(NULL, "rhea2_ck", &rhea2_ck, CK_16XX), -- cgit v0.10.2 From 9b11769f998e138cbc89ba822316aa3e63912856 Mon Sep 17 00:00:00 2001 From: Cory Maccarrone Date: Fri, 8 Jan 2010 15:23:14 -0700 Subject: OMAP1 clock: remove __initdata from struct clk_functions to prevent crash Commit 52650505fbf3a6ab851c801f54e73e76c55ab8da added an __initdata decoration to the structure containing the clk_enable and clk_disable functions. Once init data was freed, these pointers went to null, and the next enable or disable call caused the kernel to crash. This change removes this decoration. Signed-off-by: Cory Maccarrone [paul@pwsan.com: patch manually split and commit message edited] Signed-off-by: Paul Walmsley diff --git a/arch/arm/mach-omap1/clock_data.c b/arch/arm/mach-omap1/clock_data.c index 31fba07..8a85bbb 100644 --- a/arch/arm/mach-omap1/clock_data.c +++ b/arch/arm/mach-omap1/clock_data.c @@ -674,7 +674,7 @@ static struct omap_clk omap_clks[] = { * init */ -static struct clk_functions omap1_clk_functions __initdata = { +static struct clk_functions omap1_clk_functions = { .clk_enable = omap1_clk_enable, .clk_disable = omap1_clk_disable, .clk_round_rate = omap1_clk_round_rate, -- cgit v0.10.2 From 19fe458310915a216bbba32a210b6f29ac7c929f Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 8 Jan 2010 15:23:15 -0700 Subject: OMAP2xxx clock: clk2xxx.c doesn't compile if CPUFREQ is enabled if we enable CPUFREQ we can't build omap2 for two reasons, one of them is fixed by the patch below. It's failing because the __must_be_array() check in ARRAY_SIZE() is failing and printing the following message: arch/arm/mach-omap2/clock2xxx.c:453: error: negative width in bit-field '' Signed-off-by: Felipe Balbi [paul@pwsan.com: commit message updated; changed rate variable name] Signed-off-by: Paul Walmsley diff --git a/arch/arm/mach-omap2/clock2xxx.c b/arch/arm/mach-omap2/clock2xxx.c index d0e3fb7..ce6742f 100644 --- a/arch/arm/mach-omap2/clock2xxx.c +++ b/arch/arm/mach-omap2/clock2xxx.c @@ -455,12 +455,15 @@ static struct cpufreq_frequency_table freq_table[ARRAY_SIZE(rate_table)]; void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table) { struct prcm_config *prcm; + long sys_ck_rate; int i = 0; + sys_ck_rate = clk_get_rate(sclk); + for (prcm = rate_table; prcm->mpu_speed; prcm++) { if (!(prcm->flags & cpu_mask)) continue; - if (prcm->xtal_speed != sys_ck.rate) + if (prcm->xtal_speed != sys_ck_rate) continue; /* don't put bypass rates in table */ -- cgit v0.10.2 From ca6eccb31ef63722b35ea695f75089adeec319d7 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Fri, 8 Jan 2010 15:23:15 -0700 Subject: OMAP2xxx OPP: clean up comments in OPP data Revise some of the comments in the OMAP2xxx OPP data for clarity. Signed-off-by: Paul Walmsley Cc: Richard Woodruff diff --git a/arch/arm/mach-omap2/opp2420_data.c b/arch/arm/mach-omap2/opp2420_data.c index 126a939..e6dda69 100644 --- a/arch/arm/mach-omap2/opp2420_data.c +++ b/arch/arm/mach-omap2/opp2420_data.c @@ -9,45 +9,47 @@ * The OMAP2 processor can be run at several discrete 'PRCM configurations'. * These configurations are characterized by voltage and speed for clocks. * The device is only validated for certain combinations. One way to express - * these combinations is via the 'ratio's' which the clocks operate with + * these combinations is via the 'ratios' which the clocks operate with * respect to each other. These ratio sets are for a given voltage/DPLL - * setting. All configurations can be described by a DPLL setting and a ratio - * There are 3 ratio sets for the 2430 and X ratio sets for 2420. - * - * 2430 differs from 2420 in that there are no more phase synchronizers used. - * They both have a slightly different clock domain setup. 2420(iva1,dsp) vs - * 2430 (iva2.1, NOdsp, mdm) + * setting. All configurations can be described by a DPLL setting and a ratio. * * XXX Missing voltage data. + * XXX Missing 19.2MHz sys_clk rate sets (needed for N800/N810) * * THe format described in this file is deprecated. Once a reasonable * OPP API exists, the data in this file should be converted to use it. * * This is technically part of the OMAP2xxx clock code. + * + * Considerable work is still needed to fully support dynamic frequency + * changes on OMAP2xxx-series chips. Readers interested in such a + * project are encouraged to review the Maemo Diablo RX-34 and RX-44 + * kernel source at: + * http://repository.maemo.org/pool/diablo/free/k/kernel-source-diablo/ */ #include "opp2xxx.h" #include "sdrc.h" #include "clock.h" -/*------------------------------------------------------------------------- - * Key dividers which make up a PRCM set. Ratio's for a PRCM are mandated. +/* + * Key dividers which make up a PRCM set. Ratios for a PRCM are mandated. * xtal_speed, dpll_speed, mpu_speed, CM_CLKSEL_MPU, * CM_CLKSEL_DSP, CM_CLKSEL_GFX, CM_CLKSEL1_CORE, CM_CLKSEL1_PLL, * CM_CLKSEL2_PLL, CM_CLKSEL_MDM * - * Filling in table based on H4 boards and 2430-SDPs variants available. - * There are quite a few more rates combinations which could be defined. + * Filling in table based on H4 boards available. There are quite a + * few more rate combinations which could be defined. * - * When multiple values are defined the start up will try and choose the - * fastest one. If a 'fast' value is defined, then automatically, the /2 - * one should be included as it can be used. Generally having more that - * one fast set does not make sense, as static timings need to be changed - * to change the set. The exception is the bypass setting which is - * availble for low power bypass. + * When multiple values are defined the start up will try and choose + * the fastest one. If a 'fast' value is defined, then automatically, + * the /2 one should be included as it can be used. Generally having + * more than one fast set does not make sense, as static timings need + * to be changed to change the set. The exception is the bypass + * setting which is available for low power bypass. * * Note: This table needs to be sorted, fastest to slowest. - *-------------------------------------------------------------------------*/ + **/ const struct prcm_config omap2420_rate_table[] = { /* PRCM I - FAST */ {S12M, S660M, S330M, RI_CM_CLKSEL_MPU_VAL, /* 330MHz ARM */ diff --git a/arch/arm/mach-omap2/opp2430_data.c b/arch/arm/mach-omap2/opp2430_data.c index edb8167..1b9596a 100644 --- a/arch/arm/mach-omap2/opp2430_data.c +++ b/arch/arm/mach-omap2/opp2430_data.c @@ -1,5 +1,5 @@ /* - * opp2420_data.c - old-style "OPP" table for OMAP2420 + * opp2430_data.c - old-style "OPP" table for OMAP2430 * * Copyright (C) 2005-2009 Texas Instruments, Inc. * Copyright (C) 2004-2009 Nokia Corporation @@ -9,16 +9,16 @@ * The OMAP2 processor can be run at several discrete 'PRCM configurations'. * These configurations are characterized by voltage and speed for clocks. * The device is only validated for certain combinations. One way to express - * these combinations is via the 'ratio's' which the clocks operate with + * these combinations is via the 'ratios' which the clocks operate with * respect to each other. These ratio sets are for a given voltage/DPLL - * setting. All configurations can be described by a DPLL setting and a ratio - * There are 3 ratio sets for the 2430 and X ratio sets for 2420. + * setting. All configurations can be described by a DPLL setting and a ratio. * * 2430 differs from 2420 in that there are no more phase synchronizers used. * They both have a slightly different clock domain setup. 2420(iva1,dsp) vs * 2430 (iva2.1, NOdsp, mdm) * * XXX Missing voltage data. + * XXX Missing 19.2MHz sys_clk rate sets. * * THe format described in this file is deprecated. Once a reasonable * OPP API exists, the data in this file should be converted to use it. @@ -30,24 +30,24 @@ #include "sdrc.h" #include "clock.h" -/*------------------------------------------------------------------------- - * Key dividers which make up a PRCM set. Ratio's for a PRCM are mandated. +/* + * Key dividers which make up a PRCM set. Ratios for a PRCM are mandated. * xtal_speed, dpll_speed, mpu_speed, CM_CLKSEL_MPU, * CM_CLKSEL_DSP, CM_CLKSEL_GFX, CM_CLKSEL1_CORE, CM_CLKSEL1_PLL, * CM_CLKSEL2_PLL, CM_CLKSEL_MDM * - * Filling in table based on H4 boards and 2430-SDPs variants available. - * There are quite a few more rates combinations which could be defined. + * Filling in table based on 2430-SDPs variants available. There are + * quite a few more rate combinations which could be defined. * - * When multiple values are defined the start up will try and choose the - * fastest one. If a 'fast' value is defined, then automatically, the /2 - * one should be included as it can be used. Generally having more that - * one fast set does not make sense, as static timings need to be changed - * to change the set. The exception is the bypass setting which is - * availble for low power bypass. + * When multiple values are defined the start up will try and choose + * the fastest one. If a 'fast' value is defined, then automatically, + * the /2 one should be included as it can be used. Generally having + * more than one fast set does not make sense, as static timings need + * to be changed to change the set. The exception is the bypass + * setting which is available for low power bypass. * * Note: This table needs to be sorted, fastest to slowest. - *-------------------------------------------------------------------------*/ + */ const struct prcm_config omap2430_rate_table[] = { /* PRCM #4 - ratio2 (ES2.1) - FAST */ {S13M, S798M, S399M, R2_CM_CLKSEL_MPU_VAL, /* 399MHz ARM */ -- cgit v0.10.2 From 4e37c10d8a721b19933491df7af296aac9281004 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Fri, 8 Jan 2010 15:23:16 -0700 Subject: OMAP clock/CPUFreq: add clk_exit_cpufreq_table() A subsequent patch adds code on OMAP2xxx to dynamically allocate the CPUFreq frequency table in clk_init_cpufreq_table(), so for it to avoid a leak, it will need a corresponding function to free the memory. This patch adds clk_exit_cpufreq_table() with generic code to call a chip-specific variant inside the clockfw_lock spinlock via struct clk_functions. Signed-off-by: Paul Walmsley diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c index a64d84c..d9f8c84 100644 --- a/arch/arm/plat-omap/clock.c +++ b/arch/arm/plat-omap/clock.c @@ -329,6 +329,16 @@ void clk_init_cpufreq_table(struct cpufreq_frequency_table **table) arch_clock->clk_init_cpufreq_table(table); spin_unlock_irqrestore(&clockfw_lock, flags); } + +void clk_exit_cpufreq_table(struct cpufreq_frequency_table **table) +{ + unsigned long flags; + + spin_lock_irqsave(&clockfw_lock, flags); + if (arch_clock->clk_exit_cpufreq_table) + arch_clock->clk_exit_cpufreq_table(table); + spin_unlock_irqrestore(&clockfw_lock, flags); +} #endif /*-------------------------------------------------------------------------*/ diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c index f8ddbdd..6d3d333 100644 --- a/arch/arm/plat-omap/cpu-omap.c +++ b/arch/arm/plat-omap/cpu-omap.c @@ -134,6 +134,7 @@ static int __init omap_cpu_init(struct cpufreq_policy *policy) static int omap_cpu_exit(struct cpufreq_policy *policy) { + clk_exit_cpufreq_table(&freq_table); clk_put(mpu_clk); return 0; } diff --git a/arch/arm/plat-omap/include/plat/clock.h b/arch/arm/plat-omap/include/plat/clock.h index 309b6d1..94fe2a0 100644 --- a/arch/arm/plat-omap/include/plat/clock.h +++ b/arch/arm/plat-omap/include/plat/clock.h @@ -119,6 +119,7 @@ struct clk_functions { void (*clk_disable_unused)(struct clk *clk); #ifdef CONFIG_CPU_FREQ void (*clk_init_cpufreq_table)(struct cpufreq_frequency_table **); + void (*clk_exit_cpufreq_table)(struct cpufreq_frequency_table **); #endif }; @@ -135,6 +136,7 @@ extern unsigned long followparent_recalc(struct clk *clk); extern void clk_enable_init_clocks(void); #ifdef CONFIG_CPU_FREQ extern void clk_init_cpufreq_table(struct cpufreq_frequency_table **table); +extern void clk_exit_cpufreq_table(struct cpufreq_frequency_table **table); #endif extern const struct clkops clkops_null; -- cgit v0.10.2 From cdf1a915569ea9c3f6b9b4ef48a189d531d3954c Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Fri, 8 Jan 2010 15:23:17 -0700 Subject: OMAP2 clock: dynamically allocate CPUFreq frequency table Dynamically allocate the CPUFreq frequency table on OMAP2xxx chips. This fixes some compilation problems, since the kernel may not know what chip it is running on until boot-time. This also reduces the size of the CPUFreq frequency table. Problem originally reported by Felipe Balbi . Thanks also for comments on the patch from Felipe and Kevin. Signed-off-by: Paul Walmsley Cc: Felipe Balbi Cc: Kevin Hilman diff --git a/arch/arm/mach-omap2/clock2xxx.c b/arch/arm/mach-omap2/clock2xxx.c index ce6742f..5420356 100644 --- a/arch/arm/mach-omap2/clock2xxx.c +++ b/arch/arm/mach-omap2/clock2xxx.c @@ -449,14 +449,16 @@ int omap2_select_table_rate(struct clk *clk, unsigned long rate) #ifdef CONFIG_CPU_FREQ /* * Walk PRCM rate table and fillout cpufreq freq_table + * XXX This should be replaced by an OPP layer in the near future */ -static struct cpufreq_frequency_table freq_table[ARRAY_SIZE(rate_table)]; +static struct cpufreq_frequency_table *freq_table; void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table) { - struct prcm_config *prcm; + const struct prcm_config *prcm; long sys_ck_rate; int i = 0; + int tbl_sz = 0; sys_ck_rate = clk_get_rate(sclk); @@ -470,22 +472,55 @@ void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table) if (prcm->dpll_speed == prcm->xtal_speed) continue; - freq_table[i].index = i; - freq_table[i].frequency = prcm->mpu_speed / 1000; - i++; + tbl_sz++; } - if (i == 0) { - printk(KERN_WARNING "%s: failed to initialize frequency " - "table\n", __func__); + /* + * XXX Ensure that we're doing what CPUFreq expects for this error + * case and the following one + */ + if (tbl_sz == 0) { + pr_warning("%s: no matching entries in rate_table\n", + __func__); return; } + /* Include the CPUFREQ_TABLE_END terminator entry */ + tbl_sz++; + + freq_table = kzalloc(sizeof(struct cpufreq_frequency_table) * tbl_sz, + GFP_ATOMIC); + if (!freq_table) { + pr_err("%s: could not kzalloc frequency table\n", __func__); + return; + } + + for (prcm = rate_table; prcm->mpu_speed; prcm++) { + if (!(prcm->flags & cpu_mask)) + continue; + if (prcm->xtal_speed != sys_ck_rate) + continue; + + /* don't put bypass rates in table */ + if (prcm->dpll_speed == prcm->xtal_speed) + continue; + + freq_table[i].index = i; + freq_table[i].frequency = prcm->mpu_speed / 1000; + i++; + } + freq_table[i].index = i; freq_table[i].frequency = CPUFREQ_TABLE_END; *table = &freq_table[0]; } + +void omap2_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table) +{ + kfree(freq_table); +} + #endif struct clk_functions omap2_clk_functions = { @@ -497,6 +532,7 @@ struct clk_functions omap2_clk_functions = { .clk_disable_unused = omap2_clk_disable_unused, #ifdef CONFIG_CPU_FREQ .clk_init_cpufreq_table = omap2_clk_init_cpufreq_table, + .clk_exit_cpufreq_table = omap2_clk_exit_cpufreq_table, #endif }; -- cgit v0.10.2 From 50f411e34d623efbf4e4b4b0c1a4a20e04c5cc9e Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sat, 9 Jan 2010 00:45:33 +0100 Subject: DRM / i915: Fix resume regression on MSI Wind U100 w/o KMS Commit cbda12d77ea590082edb6d30bd342a67ebc459e0 (drm/i915: implement new pm ops for i915), among other things, removed the .suspend and .resume pointers from the struct drm_driver object in i915_drv.c, which broke resume without KMS on my MSI Wind U100. Fix this by reverting that part of commit cbda12d77ea59. [ The DRM layer will not use the class-specific suspend/resume functions if the driver is marked MODESET-aware, and conversely it will not register the PCI device if the drievr isn't so marked, so you always end up with _either_ the drm-class suspend/resume _or_ the PCI layer PM functionality, never both. - Linus ] Signed-off-by: Rafael J. Wysocki Acked-by: Jesse Barnes Signed-off-by: Linus Torvalds diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 2ffffd7..be631cc 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -464,6 +464,8 @@ static struct drm_driver driver = { .lastclose = i915_driver_lastclose, .preclose = i915_driver_preclose, .postclose = i915_driver_postclose, + .suspend = i915_suspend, + .resume = i915_resume, .device_is_agp = i915_driver_device_is_agp, .enable_vblank = i915_enable_vblank, .disable_vblank = i915_disable_vblank, -- cgit v0.10.2 From f892027c02f8d985455ba239ce280ac13b68a7fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20H=C3=BCwe?= Date: Sat, 9 Jan 2010 13:46:08 +0100 Subject: ARM: 5870/1: arch/arm: Fix build failure for defconfigs without CONFIG_ISA_DMA_API set A lot of ARM-defconfigs (those without CONFIG_ISA_DMA_API set) fail to build [1][2][3] due to the changes of the patch [PATCH] PCI: Clean up build for CONFIG_PCI_QUIRKS unset by Rafael J. Wysocki (Sat, 2 Jan 2010 22:57:24 +0100) [4] as the referenced variable 'isa_dma_bridge_buggy' in asm/dma.h is enclosed by the CONFIG_ISA_DMA_API conditional all configs without this setting fail to build. I'm not sure wether moving the condition is the right way to solve the issue, but atleast it fixes the issue :) References: [1] http://kisskb.ellerman.id.au/kisskb/buildresult/1983354/ [2] http://kisskb.ellerman.id.au/kisskb/buildresult/1983333/ [3] http://kisskb.ellerman.id.au/kisskb/buildresult/1983337/ [4] http://lkml.org/lkml/2010/1/2/102 Signed-off-by: Peter Huewe Signed-off-by: Russell King diff --git a/arch/arm/include/asm/dma.h b/arch/arm/include/asm/dma.h index 7edf353..ca51143 100644 --- a/arch/arm/include/asm/dma.h +++ b/arch/arm/include/asm/dma.h @@ -138,12 +138,12 @@ extern int get_dma_residue(unsigned int chan); #define NO_DMA 255 #endif +#endif /* CONFIG_ISA_DMA_API */ + #ifdef CONFIG_PCI extern int isa_dma_bridge_buggy; #else #define isa_dma_bridge_buggy (0) #endif -#endif /* CONFIG_ISA_DMA_API */ - #endif /* __ASM_ARM_DMA_H */ -- cgit v0.10.2 From 657b366a2827f35c020712e46696e56ab116d3c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20H=C3=BCwe?= Date: Sat, 9 Jan 2010 13:46:57 +0100 Subject: ARM: 5871/1: arch/arm: Fix build failure for lpd7a404_defconfig caused by missing includes This patch fixes a build failure [1] due to missing includes This should make the arm tree build again with lpd7a404_defconfig References: http://kisskb.ellerman.id.au/kisskb/buildresult/1983329/ Signed-off-by: Peter Huewe Signed-off-by: Russell King diff --git a/arch/arm/mach-lh7a40x/clocks.c b/arch/arm/mach-lh7a40x/clocks.c index fcaf876..0651f96 100644 --- a/arch/arm/mach-lh7a40x/clocks.c +++ b/arch/arm/mach-lh7a40x/clocks.c @@ -10,6 +10,8 @@ #include #include #include +#include +#include struct module; -- cgit v0.10.2 From 62a8c5bcb547c0aca1c3af810695dfb9b25e5351 Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Sun, 10 Jan 2010 09:21:53 +0100 Subject: ARM: 5872/1: ARM: include needed linux/cpu.h in asm/cpu.h The file arch/arm/include/asm/cpu.h needs to include 'linux/cpu.h' to meet its dependency. Otherwise when using "struct cpuinfo_arm" and including just 'asm/cpu.h' throws below error - arch/arm/include/asm/cpu.h:16: error: field 'cpu' has incomplete type To fix this otherway, one can also include both linux/cpu.h and asm/cpu.h but it shoudn't be that way. So this patch fixes this by including the linux/cpu.h in asm/cpu.h, so that including alone asm/cpu.h is enough. Signed-off-by: Santosh Shilimkar Signed-off-by: Russell King diff --git a/arch/arm/include/asm/cpu.h b/arch/arm/include/asm/cpu.h index 634b2d7..7939681 100644 --- a/arch/arm/include/asm/cpu.h +++ b/arch/arm/include/asm/cpu.h @@ -11,6 +11,7 @@ #define __ASM_ARM_CPU_H #include +#include struct cpuinfo_arm { struct cpu cpu; -- cgit v0.10.2 From af9a75dd1a1f8a9aa406466cc8bb16208120488a Mon Sep 17 00:00:00 2001 From: Daniel T Chen Date: Sat, 9 Jan 2010 01:22:29 -0500 Subject: ALSA: ac97: Add Dell Dimension 2400 to Headphone/Line Jack Sense blacklist This model needs both 'Headphone Jack Sense' and 'Line Jack Sense' muted for audible playback, so just add it to the ad1981 jack sense blacklist. Cc: stable@kernel.org Tested-by: Pete Signed-off-by: Daniel T Chen Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index 139cf3b..d9266ba 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c @@ -1870,6 +1870,7 @@ static unsigned int ad1981_jacks_blacklist[] = { 0x10140554, /* Thinkpad T42p/R50p */ 0x10140567, /* Thinkpad T43p 2668-G7U */ 0x10140581, /* Thinkpad X41-2527 */ + 0x10280160, /* Dell Dimension 2400 */ 0x104380b0, /* Asus A7V8X-MX */ 0x11790241, /* Toshiba Satellite A-15 S127 */ 0x144dc01a, /* Samsung NP-X20C004/SEG */ -- cgit v0.10.2 From c68db7175f4dcb3d5789bb50bea6376fb81f87fe Mon Sep 17 00:00:00 2001 From: Krzysztof Helt Date: Sun, 10 Jan 2010 17:21:14 +0100 Subject: ALSA: ac97: add AC97 STMicroelectronics' codecs Add the STMicroelectronics ST7597 codec and an unknown codec from the same manufacturer found on the Creative SB 128 card (CT4810). Signed-off-by: Krzysztof Helt Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index c119206..a7630e9e 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c @@ -83,6 +83,7 @@ static const struct ac97_codec_id snd_ac97_codec_id_vendors[] = { { 0x4e534300, 0xffffff00, "National Semiconductor", NULL, NULL }, { 0x50534300, 0xffffff00, "Philips", NULL, NULL }, { 0x53494c00, 0xffffff00, "Silicon Laboratory", NULL, NULL }, +{ 0x53544d00, 0xffffff00, "STMicroelectronics", NULL, NULL }, { 0x54524100, 0xffffff00, "TriTech", NULL, NULL }, { 0x54584e00, 0xffffff00, "Texas Instruments", NULL, NULL }, { 0x56494100, 0xffffff00, "VIA Technologies", NULL, NULL }, @@ -161,6 +162,7 @@ static const struct ac97_codec_id snd_ac97_codec_ids[] = { { 0x4e534350, 0xffffffff, "LM4550", patch_lm4550, NULL }, // volume wrap fix { 0x50534304, 0xffffffff, "UCB1400", patch_ucb1400, NULL }, { 0x53494c20, 0xffffffe0, "Si3036,8", mpatch_si3036, mpatch_si3036, AC97_MODEM_PATCH }, +{ 0x53544d02, 0xffffffff, "ST7597", NULL, NULL }, { 0x54524102, 0xffffffff, "TR28022", NULL, NULL }, { 0x54524103, 0xffffffff, "TR28023", NULL, NULL }, { 0x54524106, 0xffffffff, "TR28026", NULL, NULL }, @@ -213,6 +215,14 @@ static int snd_ac97_valid_reg(struct snd_ac97 *ac97, unsigned short reg) { /* filter some registers for buggy codecs */ switch (ac97->id) { + case AC97_ID_ST_AC97_ID4: + if (reg == 0x08) + return 0; + /* fall through */ + case AC97_ID_ST7597: + if (reg == 0x22 || reg == 0x7a) + return 1; + /* fall through */ case AC97_ID_AK4540: case AC97_ID_AK4542: if (reg <= 0x1c || reg == 0x20 || reg == 0x26 || reg >= 0x7c) diff --git a/sound/pci/ac97/ac97_id.h b/sound/pci/ac97/ac97_id.h index c129492..d603147 100644 --- a/sound/pci/ac97/ac97_id.h +++ b/sound/pci/ac97/ac97_id.h @@ -62,3 +62,5 @@ #define AC97_ID_CM9761_78 0x434d4978 #define AC97_ID_CM9761_82 0x434d4982 #define AC97_ID_CM9761_83 0x434d4983 +#define AC97_ID_ST7597 0x53544d02 +#define AC97_ID_ST_AC97_ID4 0x53544d04 -- cgit v0.10.2 From ea9a48881e093a41a79305fb1545ca0794b203dc Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 21 Dec 2009 14:03:03 +0000 Subject: xfs: use DECLARE_EVENT_CLASS Using DECLARE_EVENT_CLASS allows us to to use trace event code instead of duplicating it in the binary. This was not available before 2.6.33 so it had to be done as a separate step once the prerequisite was merged. This only requires changes to xfs_trace.h and the results are rather impressive: hch@brick:~/work/linux-2.6/obj-kvm$ size fs/xfs/xfs.o* text data bss dec hex filename 607732 41884 3616 653232 9f7b0 fs/xfs/xfs.o 1026732 41884 3808 1072424 105d28 fs/xfs/xfs.o.old Signed-off-by: Christoph Hellwig Signed-off-by: Alex Elder diff --git a/fs/xfs/linux-2.6/xfs_trace.h b/fs/xfs/linux-2.6/xfs_trace.h index d4ded59..8cb42b4 100644 --- a/fs/xfs/linux-2.6/xfs_trace.h +++ b/fs/xfs/linux-2.6/xfs_trace.h @@ -33,51 +33,55 @@ struct xfs_dquot; struct xlog_ticket; struct log; +DECLARE_EVENT_CLASS(xfs_attr_list_class, + TP_PROTO(struct xfs_attr_list_context *ctx), + TP_ARGS(ctx), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_ino_t, ino) + __field(u32, hashval) + __field(u32, blkno) + __field(u32, offset) + __field(void *, alist) + __field(int, bufsize) + __field(int, count) + __field(int, firstu) + __field(int, dupcnt) + __field(int, flags) + ), + TP_fast_assign( + __entry->dev = VFS_I(ctx->dp)->i_sb->s_dev; + __entry->ino = ctx->dp->i_ino; + __entry->hashval = ctx->cursor->hashval; + __entry->blkno = ctx->cursor->blkno; + __entry->offset = ctx->cursor->offset; + __entry->alist = ctx->alist; + __entry->bufsize = ctx->bufsize; + __entry->count = ctx->count; + __entry->firstu = ctx->firstu; + __entry->flags = ctx->flags; + ), + TP_printk("dev %d:%d ino 0x%llx cursor h/b/o 0x%x/0x%x/%u dupcnt %u " + "alist 0x%p size %u count %u firstu %u flags %d %s", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->ino, + __entry->hashval, + __entry->blkno, + __entry->offset, + __entry->dupcnt, + __entry->alist, + __entry->bufsize, + __entry->count, + __entry->firstu, + __entry->flags, + __print_flags(__entry->flags, "|", XFS_ATTR_FLAGS) + ) +) + #define DEFINE_ATTR_LIST_EVENT(name) \ -TRACE_EVENT(name, \ +DEFINE_EVENT(xfs_attr_list_class, name, \ TP_PROTO(struct xfs_attr_list_context *ctx), \ - TP_ARGS(ctx), \ - TP_STRUCT__entry( \ - __field(dev_t, dev) \ - __field(xfs_ino_t, ino) \ - __field(u32, hashval) \ - __field(u32, blkno) \ - __field(u32, offset) \ - __field(void *, alist) \ - __field(int, bufsize) \ - __field(int, count) \ - __field(int, firstu) \ - __field(int, dupcnt) \ - __field(int, flags) \ - ), \ - TP_fast_assign( \ - __entry->dev = VFS_I(ctx->dp)->i_sb->s_dev; \ - __entry->ino = ctx->dp->i_ino; \ - __entry->hashval = ctx->cursor->hashval; \ - __entry->blkno = ctx->cursor->blkno; \ - __entry->offset = ctx->cursor->offset; \ - __entry->alist = ctx->alist; \ - __entry->bufsize = ctx->bufsize; \ - __entry->count = ctx->count; \ - __entry->firstu = ctx->firstu; \ - __entry->flags = ctx->flags; \ - ), \ - TP_printk("dev %d:%d ino 0x%llx cursor h/b/o 0x%x/0x%x/%u dupcnt %u " \ - "alist 0x%p size %u count %u firstu %u flags %d %s", \ - MAJOR(__entry->dev), MINOR(__entry->dev), \ - __entry->ino, \ - __entry->hashval, \ - __entry->blkno, \ - __entry->offset, \ - __entry->dupcnt, \ - __entry->alist, \ - __entry->bufsize, \ - __entry->count, \ - __entry->firstu, \ - __entry->flags, \ - __print_flags(__entry->flags, "|", XFS_ATTR_FLAGS) \ - ) \ -) + TP_ARGS(ctx)) DEFINE_ATTR_LIST_EVENT(xfs_attr_list_sf); DEFINE_ATTR_LIST_EVENT(xfs_attr_list_sf_all); DEFINE_ATTR_LIST_EVENT(xfs_attr_list_leaf); @@ -178,91 +182,99 @@ TRACE_EVENT(xfs_iext_insert, (char *)__entry->caller_ip) ); +DECLARE_EVENT_CLASS(xfs_bmap_class, + TP_PROTO(struct xfs_inode *ip, xfs_extnum_t idx, int state, + unsigned long caller_ip), + TP_ARGS(ip, idx, state, caller_ip), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_ino_t, ino) + __field(xfs_extnum_t, idx) + __field(xfs_fileoff_t, startoff) + __field(xfs_fsblock_t, startblock) + __field(xfs_filblks_t, blockcount) + __field(xfs_exntst_t, state) + __field(int, bmap_state) + __field(unsigned long, caller_ip) + ), + TP_fast_assign( + struct xfs_ifork *ifp = (state & BMAP_ATTRFORK) ? + ip->i_afp : &ip->i_df; + struct xfs_bmbt_irec r; + + xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx), &r); + __entry->dev = VFS_I(ip)->i_sb->s_dev; + __entry->ino = ip->i_ino; + __entry->idx = idx; + __entry->startoff = r.br_startoff; + __entry->startblock = r.br_startblock; + __entry->blockcount = r.br_blockcount; + __entry->state = r.br_state; + __entry->bmap_state = state; + __entry->caller_ip = caller_ip; + ), + TP_printk("dev %d:%d ino 0x%llx state %s idx %ld " + "offset %lld block %s count %lld flag %d caller %pf", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->ino, + __print_flags(__entry->bmap_state, "|", XFS_BMAP_EXT_FLAGS), + (long)__entry->idx, + __entry->startoff, + xfs_fmtfsblock(__entry->startblock), + __entry->blockcount, + __entry->state, + (char *)__entry->caller_ip) +) + #define DEFINE_BMAP_EVENT(name) \ -TRACE_EVENT(name, \ +DEFINE_EVENT(xfs_bmap_class, name, \ TP_PROTO(struct xfs_inode *ip, xfs_extnum_t idx, int state, \ unsigned long caller_ip), \ - TP_ARGS(ip, idx, state, caller_ip), \ - TP_STRUCT__entry( \ - __field(dev_t, dev) \ - __field(xfs_ino_t, ino) \ - __field(xfs_extnum_t, idx) \ - __field(xfs_fileoff_t, startoff) \ - __field(xfs_fsblock_t, startblock) \ - __field(xfs_filblks_t, blockcount) \ - __field(xfs_exntst_t, state) \ - __field(int, bmap_state) \ - __field(unsigned long, caller_ip) \ - ), \ - TP_fast_assign( \ - struct xfs_ifork *ifp = (state & BMAP_ATTRFORK) ? \ - ip->i_afp : &ip->i_df; \ - struct xfs_bmbt_irec r; \ - \ - xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx), &r); \ - __entry->dev = VFS_I(ip)->i_sb->s_dev; \ - __entry->ino = ip->i_ino; \ - __entry->idx = idx; \ - __entry->startoff = r.br_startoff; \ - __entry->startblock = r.br_startblock; \ - __entry->blockcount = r.br_blockcount; \ - __entry->state = r.br_state; \ - __entry->bmap_state = state; \ - __entry->caller_ip = caller_ip; \ - ), \ - TP_printk("dev %d:%d ino 0x%llx state %s idx %ld " \ - "offset %lld block %s count %lld flag %d caller %pf", \ - MAJOR(__entry->dev), MINOR(__entry->dev), \ - __entry->ino, \ - __print_flags(__entry->bmap_state, "|", XFS_BMAP_EXT_FLAGS), \ - (long)__entry->idx, \ - __entry->startoff, \ - xfs_fmtfsblock(__entry->startblock), \ - __entry->blockcount, \ - __entry->state, \ - (char *)__entry->caller_ip) \ -) - + TP_ARGS(ip, idx, state, caller_ip)) DEFINE_BMAP_EVENT(xfs_iext_remove); DEFINE_BMAP_EVENT(xfs_bmap_pre_update); DEFINE_BMAP_EVENT(xfs_bmap_post_update); DEFINE_BMAP_EVENT(xfs_extlist); -#define DEFINE_BUF_EVENT(tname) \ -TRACE_EVENT(tname, \ - TP_PROTO(struct xfs_buf *bp, unsigned long caller_ip), \ - TP_ARGS(bp, caller_ip), \ - TP_STRUCT__entry( \ - __field(dev_t, dev) \ - __field(xfs_daddr_t, bno) \ - __field(size_t, buffer_length) \ - __field(int, hold) \ - __field(int, pincount) \ - __field(unsigned, lockval) \ - __field(unsigned, flags) \ - __field(unsigned long, caller_ip) \ - ), \ - TP_fast_assign( \ - __entry->dev = bp->b_target->bt_dev; \ - __entry->bno = bp->b_bn; \ - __entry->buffer_length = bp->b_buffer_length; \ - __entry->hold = atomic_read(&bp->b_hold); \ - __entry->pincount = atomic_read(&bp->b_pin_count); \ - __entry->lockval = xfs_buf_lock_value(bp); \ - __entry->flags = bp->b_flags; \ - __entry->caller_ip = caller_ip; \ - ), \ - TP_printk("dev %d:%d bno 0x%llx len 0x%zx hold %d pincount %d " \ - "lock %d flags %s caller %pf", \ - MAJOR(__entry->dev), MINOR(__entry->dev), \ - (unsigned long long)__entry->bno, \ - __entry->buffer_length, \ - __entry->hold, \ - __entry->pincount, \ - __entry->lockval, \ - __print_flags(__entry->flags, "|", XFS_BUF_FLAGS), \ - (void *)__entry->caller_ip) \ +DECLARE_EVENT_CLASS(xfs_buf_class, + TP_PROTO(struct xfs_buf *bp, unsigned long caller_ip), + TP_ARGS(bp, caller_ip), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_daddr_t, bno) + __field(size_t, buffer_length) + __field(int, hold) + __field(int, pincount) + __field(unsigned, lockval) + __field(unsigned, flags) + __field(unsigned long, caller_ip) + ), + TP_fast_assign( + __entry->dev = bp->b_target->bt_dev; + __entry->bno = bp->b_bn; + __entry->buffer_length = bp->b_buffer_length; + __entry->hold = atomic_read(&bp->b_hold); + __entry->pincount = atomic_read(&bp->b_pin_count); + __entry->lockval = xfs_buf_lock_value(bp); + __entry->flags = bp->b_flags; + __entry->caller_ip = caller_ip; + ), + TP_printk("dev %d:%d bno 0x%llx len 0x%zx hold %d pincount %d " + "lock %d flags %s caller %pf", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long long)__entry->bno, + __entry->buffer_length, + __entry->hold, + __entry->pincount, + __entry->lockval, + __print_flags(__entry->flags, "|", XFS_BUF_FLAGS), + (void *)__entry->caller_ip) ) + +#define DEFINE_BUF_EVENT(name) \ +DEFINE_EVENT(xfs_buf_class, name, \ + TP_PROTO(struct xfs_buf *bp, unsigned long caller_ip), \ + TP_ARGS(bp, caller_ip)) DEFINE_BUF_EVENT(xfs_buf_init); DEFINE_BUF_EVENT(xfs_buf_free); DEFINE_BUF_EVENT(xfs_buf_hold); @@ -299,41 +311,45 @@ DEFINE_BUF_EVENT(xfs_reset_dqcounts); DEFINE_BUF_EVENT(xfs_inode_item_push); /* pass flags explicitly */ -#define DEFINE_BUF_FLAGS_EVENT(tname) \ -TRACE_EVENT(tname, \ - TP_PROTO(struct xfs_buf *bp, unsigned flags, unsigned long caller_ip), \ - TP_ARGS(bp, flags, caller_ip), \ - TP_STRUCT__entry( \ - __field(dev_t, dev) \ - __field(xfs_daddr_t, bno) \ - __field(size_t, buffer_length) \ - __field(int, hold) \ - __field(int, pincount) \ - __field(unsigned, lockval) \ - __field(unsigned, flags) \ - __field(unsigned long, caller_ip) \ - ), \ - TP_fast_assign( \ - __entry->dev = bp->b_target->bt_dev; \ - __entry->bno = bp->b_bn; \ - __entry->buffer_length = bp->b_buffer_length; \ - __entry->flags = flags; \ - __entry->hold = atomic_read(&bp->b_hold); \ - __entry->pincount = atomic_read(&bp->b_pin_count); \ - __entry->lockval = xfs_buf_lock_value(bp); \ - __entry->caller_ip = caller_ip; \ - ), \ - TP_printk("dev %d:%d bno 0x%llx len 0x%zx hold %d pincount %d " \ - "lock %d flags %s caller %pf", \ - MAJOR(__entry->dev), MINOR(__entry->dev), \ - (unsigned long long)__entry->bno, \ - __entry->buffer_length, \ - __entry->hold, \ - __entry->pincount, \ - __entry->lockval, \ - __print_flags(__entry->flags, "|", XFS_BUF_FLAGS), \ - (void *)__entry->caller_ip) \ +DECLARE_EVENT_CLASS(xfs_buf_flags_class, + TP_PROTO(struct xfs_buf *bp, unsigned flags, unsigned long caller_ip), + TP_ARGS(bp, flags, caller_ip), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_daddr_t, bno) + __field(size_t, buffer_length) + __field(int, hold) + __field(int, pincount) + __field(unsigned, lockval) + __field(unsigned, flags) + __field(unsigned long, caller_ip) + ), + TP_fast_assign( + __entry->dev = bp->b_target->bt_dev; + __entry->bno = bp->b_bn; + __entry->buffer_length = bp->b_buffer_length; + __entry->flags = flags; + __entry->hold = atomic_read(&bp->b_hold); + __entry->pincount = atomic_read(&bp->b_pin_count); + __entry->lockval = xfs_buf_lock_value(bp); + __entry->caller_ip = caller_ip; + ), + TP_printk("dev %d:%d bno 0x%llx len 0x%zx hold %d pincount %d " + "lock %d flags %s caller %pf", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long long)__entry->bno, + __entry->buffer_length, + __entry->hold, + __entry->pincount, + __entry->lockval, + __print_flags(__entry->flags, "|", XFS_BUF_FLAGS), + (void *)__entry->caller_ip) ) + +#define DEFINE_BUF_FLAGS_EVENT(name) \ +DEFINE_EVENT(xfs_buf_flags_class, name, \ + TP_PROTO(struct xfs_buf *bp, unsigned flags, unsigned long caller_ip), \ + TP_ARGS(bp, flags, caller_ip)) DEFINE_BUF_FLAGS_EVENT(xfs_buf_find); DEFINE_BUF_FLAGS_EVENT(xfs_buf_get); DEFINE_BUF_FLAGS_EVENT(xfs_buf_read); @@ -376,55 +392,58 @@ TRACE_EVENT(xfs_buf_ioerror, (void *)__entry->caller_ip) ); -#define DEFINE_BUF_ITEM_EVENT(tname) \ -TRACE_EVENT(tname, \ - TP_PROTO(struct xfs_buf_log_item *bip), \ - TP_ARGS(bip), \ - TP_STRUCT__entry( \ - __field(dev_t, dev) \ - __field(xfs_daddr_t, buf_bno) \ - __field(size_t, buf_len) \ - __field(int, buf_hold) \ - __field(int, buf_pincount) \ - __field(int, buf_lockval) \ - __field(unsigned, buf_flags) \ - __field(unsigned, bli_recur) \ - __field(int, bli_refcount) \ - __field(unsigned, bli_flags) \ - __field(void *, li_desc) \ - __field(unsigned, li_flags) \ - ), \ - TP_fast_assign( \ - __entry->dev = bip->bli_buf->b_target->bt_dev; \ - __entry->bli_flags = bip->bli_flags; \ - __entry->bli_recur = bip->bli_recur; \ - __entry->bli_refcount = atomic_read(&bip->bli_refcount); \ - __entry->buf_bno = bip->bli_buf->b_bn; \ - __entry->buf_len = bip->bli_buf->b_buffer_length; \ - __entry->buf_flags = bip->bli_buf->b_flags; \ - __entry->buf_hold = atomic_read(&bip->bli_buf->b_hold); \ - __entry->buf_pincount = \ - atomic_read(&bip->bli_buf->b_pin_count); \ - __entry->buf_lockval = xfs_buf_lock_value(bip->bli_buf); \ - __entry->li_desc = bip->bli_item.li_desc; \ - __entry->li_flags = bip->bli_item.li_flags; \ - ), \ - TP_printk("dev %d:%d bno 0x%llx len 0x%zx hold %d pincount %d " \ - "lock %d flags %s recur %d refcount %d bliflags %s " \ - "lidesc 0x%p liflags %s", \ - MAJOR(__entry->dev), MINOR(__entry->dev), \ - (unsigned long long)__entry->buf_bno, \ - __entry->buf_len, \ - __entry->buf_hold, \ - __entry->buf_pincount, \ - __entry->buf_lockval, \ - __print_flags(__entry->buf_flags, "|", XFS_BUF_FLAGS), \ - __entry->bli_recur, \ - __entry->bli_refcount, \ - __print_flags(__entry->bli_flags, "|", XFS_BLI_FLAGS), \ - __entry->li_desc, \ - __print_flags(__entry->li_flags, "|", XFS_LI_FLAGS)) \ +DECLARE_EVENT_CLASS(xfs_buf_item_class, + TP_PROTO(struct xfs_buf_log_item *bip), + TP_ARGS(bip), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_daddr_t, buf_bno) + __field(size_t, buf_len) + __field(int, buf_hold) + __field(int, buf_pincount) + __field(int, buf_lockval) + __field(unsigned, buf_flags) + __field(unsigned, bli_recur) + __field(int, bli_refcount) + __field(unsigned, bli_flags) + __field(void *, li_desc) + __field(unsigned, li_flags) + ), + TP_fast_assign( + __entry->dev = bip->bli_buf->b_target->bt_dev; + __entry->bli_flags = bip->bli_flags; + __entry->bli_recur = bip->bli_recur; + __entry->bli_refcount = atomic_read(&bip->bli_refcount); + __entry->buf_bno = bip->bli_buf->b_bn; + __entry->buf_len = bip->bli_buf->b_buffer_length; + __entry->buf_flags = bip->bli_buf->b_flags; + __entry->buf_hold = atomic_read(&bip->bli_buf->b_hold); + __entry->buf_pincount = atomic_read(&bip->bli_buf->b_pin_count); + __entry->buf_lockval = xfs_buf_lock_value(bip->bli_buf); + __entry->li_desc = bip->bli_item.li_desc; + __entry->li_flags = bip->bli_item.li_flags; + ), + TP_printk("dev %d:%d bno 0x%llx len 0x%zx hold %d pincount %d " + "lock %d flags %s recur %d refcount %d bliflags %s " + "lidesc 0x%p liflags %s", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long long)__entry->buf_bno, + __entry->buf_len, + __entry->buf_hold, + __entry->buf_pincount, + __entry->buf_lockval, + __print_flags(__entry->buf_flags, "|", XFS_BUF_FLAGS), + __entry->bli_recur, + __entry->bli_refcount, + __print_flags(__entry->bli_flags, "|", XFS_BLI_FLAGS), + __entry->li_desc, + __print_flags(__entry->li_flags, "|", XFS_LI_FLAGS)) ) + +#define DEFINE_BUF_ITEM_EVENT(name) \ +DEFINE_EVENT(xfs_buf_item_class, name, \ + TP_PROTO(struct xfs_buf_log_item *bip), \ + TP_ARGS(bip)) DEFINE_BUF_ITEM_EVENT(xfs_buf_item_size); DEFINE_BUF_ITEM_EVENT(xfs_buf_item_size_stale); DEFINE_BUF_ITEM_EVENT(xfs_buf_item_format); @@ -450,78 +469,90 @@ DEFINE_BUF_ITEM_EVENT(xfs_trans_bhold); DEFINE_BUF_ITEM_EVENT(xfs_trans_bhold_release); DEFINE_BUF_ITEM_EVENT(xfs_trans_binval); +DECLARE_EVENT_CLASS(xfs_lock_class, + TP_PROTO(struct xfs_inode *ip, unsigned lock_flags, + unsigned long caller_ip), + TP_ARGS(ip, lock_flags, caller_ip), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_ino_t, ino) + __field(int, lock_flags) + __field(unsigned long, caller_ip) + ), + TP_fast_assign( + __entry->dev = VFS_I(ip)->i_sb->s_dev; + __entry->ino = ip->i_ino; + __entry->lock_flags = lock_flags; + __entry->caller_ip = caller_ip; + ), + TP_printk("dev %d:%d ino 0x%llx flags %s caller %pf", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->ino, + __print_flags(__entry->lock_flags, "|", XFS_LOCK_FLAGS), + (void *)__entry->caller_ip) +) + #define DEFINE_LOCK_EVENT(name) \ -TRACE_EVENT(name, \ +DEFINE_EVENT(xfs_lock_class, name, \ TP_PROTO(struct xfs_inode *ip, unsigned lock_flags, \ unsigned long caller_ip), \ - TP_ARGS(ip, lock_flags, caller_ip), \ - TP_STRUCT__entry( \ - __field(dev_t, dev) \ - __field(xfs_ino_t, ino) \ - __field(int, lock_flags) \ - __field(unsigned long, caller_ip) \ - ), \ - TP_fast_assign( \ - __entry->dev = VFS_I(ip)->i_sb->s_dev; \ - __entry->ino = ip->i_ino; \ - __entry->lock_flags = lock_flags; \ - __entry->caller_ip = caller_ip; \ - ), \ - TP_printk("dev %d:%d ino 0x%llx flags %s caller %pf", \ - MAJOR(__entry->dev), MINOR(__entry->dev), \ - __entry->ino, \ - __print_flags(__entry->lock_flags, "|", XFS_LOCK_FLAGS), \ - (void *)__entry->caller_ip) \ -) - + TP_ARGS(ip, lock_flags, caller_ip)) DEFINE_LOCK_EVENT(xfs_ilock); DEFINE_LOCK_EVENT(xfs_ilock_nowait); DEFINE_LOCK_EVENT(xfs_ilock_demote); DEFINE_LOCK_EVENT(xfs_iunlock); +DECLARE_EVENT_CLASS(xfs_iget_class, + TP_PROTO(struct xfs_inode *ip), + TP_ARGS(ip), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_ino_t, ino) + ), + TP_fast_assign( + __entry->dev = VFS_I(ip)->i_sb->s_dev; + __entry->ino = ip->i_ino; + ), + TP_printk("dev %d:%d ino 0x%llx", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->ino) +) + #define DEFINE_IGET_EVENT(name) \ -TRACE_EVENT(name, \ +DEFINE_EVENT(xfs_iget_class, name, \ TP_PROTO(struct xfs_inode *ip), \ - TP_ARGS(ip), \ - TP_STRUCT__entry( \ - __field(dev_t, dev) \ - __field(xfs_ino_t, ino) \ - ), \ - TP_fast_assign( \ - __entry->dev = VFS_I(ip)->i_sb->s_dev; \ - __entry->ino = ip->i_ino; \ - ), \ - TP_printk("dev %d:%d ino 0x%llx", \ - MAJOR(__entry->dev), MINOR(__entry->dev), \ - __entry->ino) \ -) + TP_ARGS(ip)) DEFINE_IGET_EVENT(xfs_iget_skip); DEFINE_IGET_EVENT(xfs_iget_reclaim); DEFINE_IGET_EVENT(xfs_iget_found); DEFINE_IGET_EVENT(xfs_iget_alloc); +DECLARE_EVENT_CLASS(xfs_inode_class, + TP_PROTO(struct xfs_inode *ip, unsigned long caller_ip), + TP_ARGS(ip, caller_ip), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_ino_t, ino) + __field(int, count) + __field(unsigned long, caller_ip) + ), + TP_fast_assign( + __entry->dev = VFS_I(ip)->i_sb->s_dev; + __entry->ino = ip->i_ino; + __entry->count = atomic_read(&VFS_I(ip)->i_count); + __entry->caller_ip = caller_ip; + ), + TP_printk("dev %d:%d ino 0x%llx count %d caller %pf", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->ino, + __entry->count, + (char *)__entry->caller_ip) +) + #define DEFINE_INODE_EVENT(name) \ -TRACE_EVENT(name, \ +DEFINE_EVENT(xfs_inode_class, name, \ TP_PROTO(struct xfs_inode *ip, unsigned long caller_ip), \ - TP_ARGS(ip, caller_ip), \ - TP_STRUCT__entry( \ - __field(dev_t, dev) \ - __field(xfs_ino_t, ino) \ - __field(int, count) \ - __field(unsigned long, caller_ip) \ - ), \ - TP_fast_assign( \ - __entry->dev = VFS_I(ip)->i_sb->s_dev; \ - __entry->ino = ip->i_ino; \ - __entry->count = atomic_read(&VFS_I(ip)->i_count); \ - __entry->caller_ip = caller_ip; \ - ), \ - TP_printk("dev %d:%d ino 0x%llx count %d caller %pf", \ - MAJOR(__entry->dev), MINOR(__entry->dev), \ - __entry->ino, \ - __entry->count, \ - (char *)__entry->caller_ip) \ -) + TP_ARGS(ip, caller_ip)) DEFINE_INODE_EVENT(xfs_ihold); DEFINE_INODE_EVENT(xfs_irele); /* the old xfs_itrace_entry tracer - to be replaced by s.th. in the VFS */ @@ -529,55 +560,59 @@ DEFINE_INODE_EVENT(xfs_inode); #define xfs_itrace_entry(ip) \ trace_xfs_inode(ip, _THIS_IP_) -#define DEFINE_DQUOT_EVENT(tname) \ -TRACE_EVENT(tname, \ - TP_PROTO(struct xfs_dquot *dqp), \ - TP_ARGS(dqp), \ - TP_STRUCT__entry( \ - __field(dev_t, dev) \ - __field(__be32, id) \ - __field(unsigned, flags) \ - __field(unsigned, nrefs) \ - __field(unsigned long long, res_bcount) \ - __field(unsigned long long, bcount) \ - __field(unsigned long long, icount) \ - __field(unsigned long long, blk_hardlimit) \ - __field(unsigned long long, blk_softlimit) \ - __field(unsigned long long, ino_hardlimit) \ - __field(unsigned long long, ino_softlimit) \ - ), \ - TP_fast_assign( \ - __entry->dev = dqp->q_mount->m_super->s_dev; \ - __entry->id = dqp->q_core.d_id; \ - __entry->flags = dqp->dq_flags; \ - __entry->nrefs = dqp->q_nrefs; \ - __entry->res_bcount = dqp->q_res_bcount; \ - __entry->bcount = be64_to_cpu(dqp->q_core.d_bcount); \ - __entry->icount = be64_to_cpu(dqp->q_core.d_icount); \ - __entry->blk_hardlimit = \ - be64_to_cpu(dqp->q_core.d_blk_hardlimit); \ - __entry->blk_softlimit = \ - be64_to_cpu(dqp->q_core.d_blk_softlimit); \ - __entry->ino_hardlimit = \ - be64_to_cpu(dqp->q_core.d_ino_hardlimit); \ - __entry->ino_softlimit = \ - be64_to_cpu(dqp->q_core.d_ino_softlimit); \ +DECLARE_EVENT_CLASS(xfs_dquot_class, + TP_PROTO(struct xfs_dquot *dqp), + TP_ARGS(dqp), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(__be32, id) + __field(unsigned, flags) + __field(unsigned, nrefs) + __field(unsigned long long, res_bcount) + __field(unsigned long long, bcount) + __field(unsigned long long, icount) + __field(unsigned long long, blk_hardlimit) + __field(unsigned long long, blk_softlimit) + __field(unsigned long long, ino_hardlimit) + __field(unsigned long long, ino_softlimit) ), \ - TP_printk("dev %d:%d id 0x%x flags %s nrefs %u res_bc 0x%llx " \ - "bcnt 0x%llx [hard 0x%llx | soft 0x%llx] " \ - "icnt 0x%llx [hard 0x%llx | soft 0x%llx]", \ - MAJOR(__entry->dev), MINOR(__entry->dev), \ - be32_to_cpu(__entry->id), \ - __print_flags(__entry->flags, "|", XFS_DQ_FLAGS), \ - __entry->nrefs, \ - __entry->res_bcount, \ - __entry->bcount, \ - __entry->blk_hardlimit, \ - __entry->blk_softlimit, \ - __entry->icount, \ - __entry->ino_hardlimit, \ - __entry->ino_softlimit) \ + TP_fast_assign( + __entry->dev = dqp->q_mount->m_super->s_dev; + __entry->id = dqp->q_core.d_id; + __entry->flags = dqp->dq_flags; + __entry->nrefs = dqp->q_nrefs; + __entry->res_bcount = dqp->q_res_bcount; + __entry->bcount = be64_to_cpu(dqp->q_core.d_bcount); + __entry->icount = be64_to_cpu(dqp->q_core.d_icount); + __entry->blk_hardlimit = + be64_to_cpu(dqp->q_core.d_blk_hardlimit); + __entry->blk_softlimit = + be64_to_cpu(dqp->q_core.d_blk_softlimit); + __entry->ino_hardlimit = + be64_to_cpu(dqp->q_core.d_ino_hardlimit); + __entry->ino_softlimit = + be64_to_cpu(dqp->q_core.d_ino_softlimit); + ), + TP_printk("dev %d:%d id 0x%x flags %s nrefs %u res_bc 0x%llx " + "bcnt 0x%llx [hard 0x%llx | soft 0x%llx] " + "icnt 0x%llx [hard 0x%llx | soft 0x%llx]", + MAJOR(__entry->dev), MINOR(__entry->dev), + be32_to_cpu(__entry->id), + __print_flags(__entry->flags, "|", XFS_DQ_FLAGS), + __entry->nrefs, + __entry->res_bcount, + __entry->bcount, + __entry->blk_hardlimit, + __entry->blk_softlimit, + __entry->icount, + __entry->ino_hardlimit, + __entry->ino_softlimit) ) + +#define DEFINE_DQUOT_EVENT(name) \ +DEFINE_EVENT(xfs_dquot_class, name, \ + TP_PROTO(struct xfs_dquot *dqp), \ + TP_ARGS(dqp)) DEFINE_DQUOT_EVENT(xfs_dqadjust); DEFINE_DQUOT_EVENT(xfs_dqshake_dirty); DEFINE_DQUOT_EVENT(xfs_dqshake_unlink); @@ -610,72 +645,75 @@ DEFINE_DQUOT_EVENT(xfs_dqflush_done); DEFINE_IGET_EVENT(xfs_dquot_dqalloc); DEFINE_IGET_EVENT(xfs_dquot_dqdetach); +DECLARE_EVENT_CLASS(xfs_loggrant_class, + TP_PROTO(struct log *log, struct xlog_ticket *tic), + TP_ARGS(log, tic), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(unsigned, trans_type) + __field(char, ocnt) + __field(char, cnt) + __field(int, curr_res) + __field(int, unit_res) + __field(unsigned int, flags) + __field(void *, reserve_headq) + __field(void *, write_headq) + __field(int, grant_reserve_cycle) + __field(int, grant_reserve_bytes) + __field(int, grant_write_cycle) + __field(int, grant_write_bytes) + __field(int, curr_cycle) + __field(int, curr_block) + __field(xfs_lsn_t, tail_lsn) + ), + TP_fast_assign( + __entry->dev = log->l_mp->m_super->s_dev; + __entry->trans_type = tic->t_trans_type; + __entry->ocnt = tic->t_ocnt; + __entry->cnt = tic->t_cnt; + __entry->curr_res = tic->t_curr_res; + __entry->unit_res = tic->t_unit_res; + __entry->flags = tic->t_flags; + __entry->reserve_headq = log->l_reserve_headq; + __entry->write_headq = log->l_write_headq; + __entry->grant_reserve_cycle = log->l_grant_reserve_cycle; + __entry->grant_reserve_bytes = log->l_grant_reserve_bytes; + __entry->grant_write_cycle = log->l_grant_write_cycle; + __entry->grant_write_bytes = log->l_grant_write_bytes; + __entry->curr_cycle = log->l_curr_cycle; + __entry->curr_block = log->l_curr_block; + __entry->tail_lsn = log->l_tail_lsn; + ), + TP_printk("dev %d:%d type %s t_ocnt %u t_cnt %u t_curr_res %u " + "t_unit_res %u t_flags %s reserve_headq 0x%p " + "write_headq 0x%p grant_reserve_cycle %d " + "grant_reserve_bytes %d grant_write_cycle %d " + "grant_write_bytes %d curr_cycle %d curr_block %d " + "tail_cycle %d tail_block %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __print_symbolic(__entry->trans_type, XFS_TRANS_TYPES), + __entry->ocnt, + __entry->cnt, + __entry->curr_res, + __entry->unit_res, + __print_flags(__entry->flags, "|", XLOG_TIC_FLAGS), + __entry->reserve_headq, + __entry->write_headq, + __entry->grant_reserve_cycle, + __entry->grant_reserve_bytes, + __entry->grant_write_cycle, + __entry->grant_write_bytes, + __entry->curr_cycle, + __entry->curr_block, + CYCLE_LSN(__entry->tail_lsn), + BLOCK_LSN(__entry->tail_lsn) + ) +) -#define DEFINE_LOGGRANT_EVENT(tname) \ -TRACE_EVENT(tname, \ +#define DEFINE_LOGGRANT_EVENT(name) \ +DEFINE_EVENT(xfs_loggrant_class, name, \ TP_PROTO(struct log *log, struct xlog_ticket *tic), \ - TP_ARGS(log, tic), \ - TP_STRUCT__entry( \ - __field(dev_t, dev) \ - __field(unsigned, trans_type) \ - __field(char, ocnt) \ - __field(char, cnt) \ - __field(int, curr_res) \ - __field(int, unit_res) \ - __field(unsigned int, flags) \ - __field(void *, reserve_headq) \ - __field(void *, write_headq) \ - __field(int, grant_reserve_cycle) \ - __field(int, grant_reserve_bytes) \ - __field(int, grant_write_cycle) \ - __field(int, grant_write_bytes) \ - __field(int, curr_cycle) \ - __field(int, curr_block) \ - __field(xfs_lsn_t, tail_lsn) \ - ), \ - TP_fast_assign( \ - __entry->dev = log->l_mp->m_super->s_dev; \ - __entry->trans_type = tic->t_trans_type; \ - __entry->ocnt = tic->t_ocnt; \ - __entry->cnt = tic->t_cnt; \ - __entry->curr_res = tic->t_curr_res; \ - __entry->unit_res = tic->t_unit_res; \ - __entry->flags = tic->t_flags; \ - __entry->reserve_headq = log->l_reserve_headq; \ - __entry->write_headq = log->l_write_headq; \ - __entry->grant_reserve_cycle = log->l_grant_reserve_cycle; \ - __entry->grant_reserve_bytes = log->l_grant_reserve_bytes; \ - __entry->grant_write_cycle = log->l_grant_write_cycle; \ - __entry->grant_write_bytes = log->l_grant_write_bytes; \ - __entry->curr_cycle = log->l_curr_cycle; \ - __entry->curr_block = log->l_curr_block; \ - __entry->tail_lsn = log->l_tail_lsn; \ - ), \ - TP_printk("dev %d:%d type %s t_ocnt %u t_cnt %u t_curr_res %u " \ - "t_unit_res %u t_flags %s reserve_headq 0x%p " \ - "write_headq 0x%p grant_reserve_cycle %d " \ - "grant_reserve_bytes %d grant_write_cycle %d " \ - "grant_write_bytes %d curr_cycle %d curr_block %d " \ - "tail_cycle %d tail_block %d", \ - MAJOR(__entry->dev), MINOR(__entry->dev), \ - __print_symbolic(__entry->trans_type, XFS_TRANS_TYPES), \ - __entry->ocnt, \ - __entry->cnt, \ - __entry->curr_res, \ - __entry->unit_res, \ - __print_flags(__entry->flags, "|", XLOG_TIC_FLAGS), \ - __entry->reserve_headq, \ - __entry->write_headq, \ - __entry->grant_reserve_cycle, \ - __entry->grant_reserve_bytes, \ - __entry->grant_write_cycle, \ - __entry->grant_write_bytes, \ - __entry->curr_cycle, \ - __entry->curr_block, \ - CYCLE_LSN(__entry->tail_lsn), \ - BLOCK_LSN(__entry->tail_lsn) \ - ) \ -) + TP_ARGS(log, tic)) DEFINE_LOGGRANT_EVENT(xfs_log_done_nonperm); DEFINE_LOGGRANT_EVENT(xfs_log_done_perm); DEFINE_LOGGRANT_EVENT(xfs_log_reserve); @@ -897,28 +935,32 @@ TRACE_EVENT(xfs_itruncate_start, __entry->toss_finish) ); +DECLARE_EVENT_CLASS(xfs_itrunc_class, + TP_PROTO(struct xfs_inode *ip, xfs_fsize_t new_size), + TP_ARGS(ip, new_size), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_ino_t, ino) + __field(xfs_fsize_t, size) + __field(xfs_fsize_t, new_size) + ), + TP_fast_assign( + __entry->dev = VFS_I(ip)->i_sb->s_dev; + __entry->ino = ip->i_ino; + __entry->size = ip->i_d.di_size; + __entry->new_size = new_size; + ), + TP_printk("dev %d:%d ino 0x%llx size 0x%llx new_size 0x%llx", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->ino, + __entry->size, + __entry->new_size) +) + #define DEFINE_ITRUNC_EVENT(name) \ -TRACE_EVENT(name, \ +DEFINE_EVENT(xfs_itrunc_class, name, \ TP_PROTO(struct xfs_inode *ip, xfs_fsize_t new_size), \ - TP_ARGS(ip, new_size), \ - TP_STRUCT__entry( \ - __field(dev_t, dev) \ - __field(xfs_ino_t, ino) \ - __field(xfs_fsize_t, size) \ - __field(xfs_fsize_t, new_size) \ - ), \ - TP_fast_assign( \ - __entry->dev = VFS_I(ip)->i_sb->s_dev; \ - __entry->ino = ip->i_ino; \ - __entry->size = ip->i_d.di_size; \ - __entry->new_size = new_size; \ - ), \ - TP_printk("dev %d:%d ino 0x%llx size 0x%llx new_size 0x%llx", \ - MAJOR(__entry->dev), MINOR(__entry->dev), \ - __entry->ino, \ - __entry->size, \ - __entry->new_size) \ -) + TP_ARGS(ip, new_size)) DEFINE_ITRUNC_EVENT(xfs_itruncate_finish_start); DEFINE_ITRUNC_EVENT(xfs_itruncate_finish_end); @@ -1152,77 +1194,80 @@ TRACE_EVENT(xfs_free_extent, ); -#define DEFINE_ALLOC_EVENT(name) \ -TRACE_EVENT(name, \ - TP_PROTO(struct xfs_alloc_arg *args), \ - TP_ARGS(args), \ - TP_STRUCT__entry( \ - __field(dev_t, dev) \ - __field(xfs_agnumber_t, agno) \ - __field(xfs_agblock_t, agbno) \ - __field(xfs_extlen_t, minlen) \ - __field(xfs_extlen_t, maxlen) \ - __field(xfs_extlen_t, mod) \ - __field(xfs_extlen_t, prod) \ - __field(xfs_extlen_t, minleft) \ - __field(xfs_extlen_t, total) \ - __field(xfs_extlen_t, alignment) \ - __field(xfs_extlen_t, minalignslop) \ - __field(xfs_extlen_t, len) \ - __field(short, type) \ - __field(short, otype) \ - __field(char, wasdel) \ - __field(char, wasfromfl) \ - __field(char, isfl) \ - __field(char, userdata) \ - __field(xfs_fsblock_t, firstblock) \ - ), \ - TP_fast_assign( \ - __entry->dev = args->mp->m_super->s_dev; \ - __entry->agno = args->agno; \ - __entry->agbno = args->agbno; \ - __entry->minlen = args->minlen; \ - __entry->maxlen = args->maxlen; \ - __entry->mod = args->mod; \ - __entry->prod = args->prod; \ - __entry->minleft = args->minleft; \ - __entry->total = args->total; \ - __entry->alignment = args->alignment; \ - __entry->minalignslop = args->minalignslop; \ - __entry->len = args->len; \ - __entry->type = args->type; \ - __entry->otype = args->otype; \ - __entry->wasdel = args->wasdel; \ - __entry->wasfromfl = args->wasfromfl; \ - __entry->isfl = args->isfl; \ - __entry->userdata = args->userdata; \ - __entry->firstblock = args->firstblock; \ - ), \ - TP_printk("dev %d:%d agno %u agbno %u minlen %u maxlen %u mod %u " \ - "prod %u minleft %u total %u alignment %u minalignslop %u " \ - "len %u type %s otype %s wasdel %d wasfromfl %d isfl %d " \ - "userdata %d firstblock %s", \ - MAJOR(__entry->dev), MINOR(__entry->dev), \ - __entry->agno, \ - __entry->agbno, \ - __entry->minlen, \ - __entry->maxlen, \ - __entry->mod, \ - __entry->prod, \ - __entry->minleft, \ - __entry->total, \ - __entry->alignment, \ - __entry->minalignslop, \ - __entry->len, \ - __print_symbolic(__entry->type, XFS_ALLOC_TYPES), \ - __print_symbolic(__entry->otype, XFS_ALLOC_TYPES), \ - __entry->wasdel, \ - __entry->wasfromfl, \ - __entry->isfl, \ - __entry->userdata, \ - xfs_fmtfsblock(__entry->firstblock)) \ +DECLARE_EVENT_CLASS(xfs_alloc_class, + TP_PROTO(struct xfs_alloc_arg *args), + TP_ARGS(args), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_agnumber_t, agno) + __field(xfs_agblock_t, agbno) + __field(xfs_extlen_t, minlen) + __field(xfs_extlen_t, maxlen) + __field(xfs_extlen_t, mod) + __field(xfs_extlen_t, prod) + __field(xfs_extlen_t, minleft) + __field(xfs_extlen_t, total) + __field(xfs_extlen_t, alignment) + __field(xfs_extlen_t, minalignslop) + __field(xfs_extlen_t, len) + __field(short, type) + __field(short, otype) + __field(char, wasdel) + __field(char, wasfromfl) + __field(char, isfl) + __field(char, userdata) + __field(xfs_fsblock_t, firstblock) + ), + TP_fast_assign( + __entry->dev = args->mp->m_super->s_dev; + __entry->agno = args->agno; + __entry->agbno = args->agbno; + __entry->minlen = args->minlen; + __entry->maxlen = args->maxlen; + __entry->mod = args->mod; + __entry->prod = args->prod; + __entry->minleft = args->minleft; + __entry->total = args->total; + __entry->alignment = args->alignment; + __entry->minalignslop = args->minalignslop; + __entry->len = args->len; + __entry->type = args->type; + __entry->otype = args->otype; + __entry->wasdel = args->wasdel; + __entry->wasfromfl = args->wasfromfl; + __entry->isfl = args->isfl; + __entry->userdata = args->userdata; + __entry->firstblock = args->firstblock; + ), + TP_printk("dev %d:%d agno %u agbno %u minlen %u maxlen %u mod %u " + "prod %u minleft %u total %u alignment %u minalignslop %u " + "len %u type %s otype %s wasdel %d wasfromfl %d isfl %d " + "userdata %d firstblock 0x%llx", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->agno, + __entry->agbno, + __entry->minlen, + __entry->maxlen, + __entry->mod, + __entry->prod, + __entry->minleft, + __entry->total, + __entry->alignment, + __entry->minalignslop, + __entry->len, + __print_symbolic(__entry->type, XFS_ALLOC_TYPES), + __print_symbolic(__entry->otype, XFS_ALLOC_TYPES), + __entry->wasdel, + __entry->wasfromfl, + __entry->isfl, + __entry->userdata, + __entry->firstblock) ) +#define DEFINE_ALLOC_EVENT(name) \ +DEFINE_EVENT(xfs_alloc_class, name, \ + TP_PROTO(struct xfs_alloc_arg *args), \ + TP_ARGS(args)) DEFINE_ALLOC_EVENT(xfs_alloc_exact_done); DEFINE_ALLOC_EVENT(xfs_alloc_exact_error); DEFINE_ALLOC_EVENT(xfs_alloc_near_nominleft); @@ -1245,92 +1290,100 @@ DEFINE_ALLOC_EVENT(xfs_alloc_vextent_noagbp); DEFINE_ALLOC_EVENT(xfs_alloc_vextent_loopfailed); DEFINE_ALLOC_EVENT(xfs_alloc_vextent_allfailed); -#define DEFINE_DIR2_TRACE(tname) \ -TRACE_EVENT(tname, \ +DECLARE_EVENT_CLASS(xfs_dir2_class, + TP_PROTO(struct xfs_da_args *args), + TP_ARGS(args), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_ino_t, ino) + __dynamic_array(char, name, args->namelen) + __field(int, namelen) + __field(xfs_dahash_t, hashval) + __field(xfs_ino_t, inumber) + __field(int, op_flags) + ), + TP_fast_assign( + __entry->dev = VFS_I(args->dp)->i_sb->s_dev; + __entry->ino = args->dp->i_ino; + if (args->namelen) + memcpy(__get_str(name), args->name, args->namelen); + __entry->namelen = args->namelen; + __entry->hashval = args->hashval; + __entry->inumber = args->inumber; + __entry->op_flags = args->op_flags; + ), + TP_printk("dev %d:%d ino 0x%llx name %.*s namelen %d hashval 0x%x " + "inumber 0x%llx op_flags %s", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->ino, + __entry->namelen, + __entry->namelen ? __get_str(name) : NULL, + __entry->namelen, + __entry->hashval, + __entry->inumber, + __print_flags(__entry->op_flags, "|", XFS_DA_OP_FLAGS)) +) + +#define DEFINE_DIR2_EVENT(name) \ +DEFINE_EVENT(xfs_dir2_class, name, \ TP_PROTO(struct xfs_da_args *args), \ - TP_ARGS(args), \ - TP_STRUCT__entry( \ - __field(dev_t, dev) \ - __field(xfs_ino_t, ino) \ - __dynamic_array(char, name, args->namelen) \ - __field(int, namelen) \ - __field(xfs_dahash_t, hashval) \ - __field(xfs_ino_t, inumber) \ - __field(int, op_flags) \ - ), \ - TP_fast_assign( \ - __entry->dev = VFS_I(args->dp)->i_sb->s_dev; \ - __entry->ino = args->dp->i_ino; \ - if (args->namelen) \ - memcpy(__get_str(name), args->name, args->namelen); \ - __entry->namelen = args->namelen; \ - __entry->hashval = args->hashval; \ - __entry->inumber = args->inumber; \ - __entry->op_flags = args->op_flags; \ - ), \ - TP_printk("dev %d:%d ino 0x%llx name %.*s namelen %d hashval 0x%x " \ - "inumber 0x%llx op_flags %s", \ - MAJOR(__entry->dev), MINOR(__entry->dev), \ - __entry->ino, \ - __entry->namelen, \ - __entry->namelen ? __get_str(name) : NULL, \ - __entry->namelen, \ - __entry->hashval, \ - __entry->inumber, \ - __print_flags(__entry->op_flags, "|", XFS_DA_OP_FLAGS)) \ + TP_ARGS(args)) +DEFINE_DIR2_EVENT(xfs_dir2_sf_addname); +DEFINE_DIR2_EVENT(xfs_dir2_sf_create); +DEFINE_DIR2_EVENT(xfs_dir2_sf_lookup); +DEFINE_DIR2_EVENT(xfs_dir2_sf_replace); +DEFINE_DIR2_EVENT(xfs_dir2_sf_removename); +DEFINE_DIR2_EVENT(xfs_dir2_sf_toino4); +DEFINE_DIR2_EVENT(xfs_dir2_sf_toino8); +DEFINE_DIR2_EVENT(xfs_dir2_sf_to_block); +DEFINE_DIR2_EVENT(xfs_dir2_block_addname); +DEFINE_DIR2_EVENT(xfs_dir2_block_lookup); +DEFINE_DIR2_EVENT(xfs_dir2_block_replace); +DEFINE_DIR2_EVENT(xfs_dir2_block_removename); +DEFINE_DIR2_EVENT(xfs_dir2_block_to_sf); +DEFINE_DIR2_EVENT(xfs_dir2_block_to_leaf); +DEFINE_DIR2_EVENT(xfs_dir2_leaf_addname); +DEFINE_DIR2_EVENT(xfs_dir2_leaf_lookup); +DEFINE_DIR2_EVENT(xfs_dir2_leaf_replace); +DEFINE_DIR2_EVENT(xfs_dir2_leaf_removename); +DEFINE_DIR2_EVENT(xfs_dir2_leaf_to_block); +DEFINE_DIR2_EVENT(xfs_dir2_leaf_to_node); +DEFINE_DIR2_EVENT(xfs_dir2_node_addname); +DEFINE_DIR2_EVENT(xfs_dir2_node_lookup); +DEFINE_DIR2_EVENT(xfs_dir2_node_replace); +DEFINE_DIR2_EVENT(xfs_dir2_node_removename); +DEFINE_DIR2_EVENT(xfs_dir2_node_to_leaf); + +DECLARE_EVENT_CLASS(xfs_dir2_space_class, + TP_PROTO(struct xfs_da_args *args, int idx), + TP_ARGS(args, idx), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_ino_t, ino) + __field(int, op_flags) + __field(int, idx) + ), + TP_fast_assign( + __entry->dev = VFS_I(args->dp)->i_sb->s_dev; + __entry->ino = args->dp->i_ino; + __entry->op_flags = args->op_flags; + __entry->idx = idx; + ), + TP_printk("dev %d:%d ino 0x%llx op_flags %s index %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->ino, + __print_flags(__entry->op_flags, "|", XFS_DA_OP_FLAGS), + __entry->idx) ) -DEFINE_DIR2_TRACE(xfs_dir2_sf_addname); -DEFINE_DIR2_TRACE(xfs_dir2_sf_create); -DEFINE_DIR2_TRACE(xfs_dir2_sf_lookup); -DEFINE_DIR2_TRACE(xfs_dir2_sf_replace); -DEFINE_DIR2_TRACE(xfs_dir2_sf_removename); -DEFINE_DIR2_TRACE(xfs_dir2_sf_toino4); -DEFINE_DIR2_TRACE(xfs_dir2_sf_toino8); -DEFINE_DIR2_TRACE(xfs_dir2_sf_to_block); -DEFINE_DIR2_TRACE(xfs_dir2_block_addname); -DEFINE_DIR2_TRACE(xfs_dir2_block_lookup); -DEFINE_DIR2_TRACE(xfs_dir2_block_replace); -DEFINE_DIR2_TRACE(xfs_dir2_block_removename); -DEFINE_DIR2_TRACE(xfs_dir2_block_to_sf); -DEFINE_DIR2_TRACE(xfs_dir2_block_to_leaf); -DEFINE_DIR2_TRACE(xfs_dir2_leaf_addname); -DEFINE_DIR2_TRACE(xfs_dir2_leaf_lookup); -DEFINE_DIR2_TRACE(xfs_dir2_leaf_replace); -DEFINE_DIR2_TRACE(xfs_dir2_leaf_removename); -DEFINE_DIR2_TRACE(xfs_dir2_leaf_to_block); -DEFINE_DIR2_TRACE(xfs_dir2_leaf_to_node); -DEFINE_DIR2_TRACE(xfs_dir2_node_addname); -DEFINE_DIR2_TRACE(xfs_dir2_node_lookup); -DEFINE_DIR2_TRACE(xfs_dir2_node_replace); -DEFINE_DIR2_TRACE(xfs_dir2_node_removename); -DEFINE_DIR2_TRACE(xfs_dir2_node_to_leaf); -#define DEFINE_DIR2_SPACE_TRACE(tname) \ -TRACE_EVENT(tname, \ +#define DEFINE_DIR2_SPACE_EVENT(name) \ +DEFINE_EVENT(xfs_dir2_space_class, name, \ TP_PROTO(struct xfs_da_args *args, int idx), \ - TP_ARGS(args, idx), \ - TP_STRUCT__entry( \ - __field(dev_t, dev) \ - __field(xfs_ino_t, ino) \ - __field(int, op_flags) \ - __field(int, idx) \ - ), \ - TP_fast_assign( \ - __entry->dev = VFS_I(args->dp)->i_sb->s_dev; \ - __entry->ino = args->dp->i_ino; \ - __entry->op_flags = args->op_flags; \ - __entry->idx = idx; \ - ), \ - TP_printk("dev %d:%d ino 0x%llx op_flags %s index %d", \ - MAJOR(__entry->dev), MINOR(__entry->dev), \ - __entry->ino, \ - __print_flags(__entry->op_flags, "|", XFS_DA_OP_FLAGS), \ - __entry->idx) \ -) -DEFINE_DIR2_SPACE_TRACE(xfs_dir2_leafn_add); -DEFINE_DIR2_SPACE_TRACE(xfs_dir2_leafn_remove); -DEFINE_DIR2_SPACE_TRACE(xfs_dir2_grow_inode); -DEFINE_DIR2_SPACE_TRACE(xfs_dir2_shrink_inode); + TP_ARGS(args, idx)) +DEFINE_DIR2_SPACE_EVENT(xfs_dir2_leafn_add); +DEFINE_DIR2_SPACE_EVENT(xfs_dir2_leafn_remove); +DEFINE_DIR2_SPACE_EVENT(xfs_dir2_grow_inode); +DEFINE_DIR2_SPACE_EVENT(xfs_dir2_shrink_inode); TRACE_EVENT(xfs_dir2_leafn_moveents, TP_PROTO(struct xfs_da_args *args, int src_idx, int dst_idx, int count), -- cgit v0.10.2 From d6d59bada372bcf8bd36c3bbc71c485c29dd2a4b Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 23 Dec 2009 16:09:13 +0000 Subject: xfs: fix timestamp handling in xfs_setattr We currently have some rather odd code in xfs_setattr for updating the a/c/mtime timestamps: - first we do a non-transaction update if all three are updated together - second we implicitly update the ctime for various changes instead of relying on the ATTR_CTIME flag - third we set the timestamps to the current time instead of the arguments in the iattr structure in many cases. This patch makes sure we update it in a consistent way: - always transactional - ctime is only updated if ATTR_CTIME is set or we do a size update, which is a special case - always to the times passed in from the caller instead of the current time The only non-size caller of xfs_setattr that doesn't come from the VFS is updated to set ATTR_CTIME and pass in a valid ctime value. Reported-by: Eric Blake Signed-off-by: Christoph Hellwig Signed-off-by: Alex Elder diff --git a/fs/xfs/linux-2.6/xfs_acl.c b/fs/xfs/linux-2.6/xfs_acl.c index 2512125..883ca5a 100644 --- a/fs/xfs/linux-2.6/xfs_acl.c +++ b/fs/xfs/linux-2.6/xfs_acl.c @@ -251,8 +251,9 @@ xfs_set_mode(struct inode *inode, mode_t mode) if (mode != inode->i_mode) { struct iattr iattr; - iattr.ia_valid = ATTR_MODE; + iattr.ia_valid = ATTR_MODE | ATTR_CTIME; iattr.ia_mode = mode; + iattr.ia_ctime = current_fs_time(inode->i_sb); error = -xfs_setattr(XFS_I(inode), &iattr, XFS_ATTR_NOACL); } diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 6558ffd..6f26875 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c @@ -70,7 +70,6 @@ xfs_setattr( uint commit_flags=0; uid_t uid=0, iuid=0; gid_t gid=0, igid=0; - int timeflags = 0; struct xfs_dquot *udqp, *gdqp, *olddquot1, *olddquot2; int need_iolock = 1; @@ -135,16 +134,13 @@ xfs_setattr( if (flags & XFS_ATTR_NOLOCK) need_iolock = 0; if (!(mask & ATTR_SIZE)) { - if ((mask != (ATTR_CTIME|ATTR_ATIME|ATTR_MTIME)) || - (mp->m_flags & XFS_MOUNT_WSYNC)) { - tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_NOT_SIZE); - commit_flags = 0; - if ((code = xfs_trans_reserve(tp, 0, - XFS_ICHANGE_LOG_RES(mp), 0, - 0, 0))) { - lock_flags = 0; - goto error_return; - } + tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_NOT_SIZE); + commit_flags = 0; + code = xfs_trans_reserve(tp, 0, XFS_ICHANGE_LOG_RES(mp), + 0, 0, 0); + if (code) { + lock_flags = 0; + goto error_return; } } else { if (DM_EVENT_ENABLED(ip, DM_EVENT_TRUNCATE) && @@ -295,15 +291,23 @@ xfs_setattr( * or we are explicitly asked to change it. This handles * the semantic difference between truncate() and ftruncate() * as implemented in the VFS. + * + * The regular truncate() case without ATTR_CTIME and ATTR_MTIME + * is a special case where we need to update the times despite + * not having these flags set. For all other operations the + * VFS set these flags explicitly if it wants a timestamp + * update. */ - if (iattr->ia_size != ip->i_size || (mask & ATTR_CTIME)) - timeflags |= XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG; + if (iattr->ia_size != ip->i_size && + (!(mask & (ATTR_CTIME | ATTR_MTIME)))) { + iattr->ia_ctime = iattr->ia_mtime = + current_fs_time(inode->i_sb); + mask |= ATTR_CTIME | ATTR_MTIME; + } if (iattr->ia_size > ip->i_size) { ip->i_d.di_size = iattr->ia_size; ip->i_size = iattr->ia_size; - if (!(flags & XFS_ATTR_DMI)) - xfs_ichgtime(ip, XFS_ICHGTIME_CHG); xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); } else if (iattr->ia_size <= ip->i_size || (iattr->ia_size == 0 && ip->i_d.di_nextents)) { @@ -374,9 +378,6 @@ xfs_setattr( ip->i_d.di_gid = gid; inode->i_gid = gid; } - - xfs_trans_log_inode (tp, ip, XFS_ILOG_CORE); - timeflags |= XFS_ICHGTIME_CHG; } /* @@ -393,51 +394,37 @@ xfs_setattr( inode->i_mode &= S_IFMT; inode->i_mode |= mode & ~S_IFMT; - - xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); - timeflags |= XFS_ICHGTIME_CHG; } /* * Change file access or modified times. */ - if (mask & (ATTR_ATIME|ATTR_MTIME)) { - if (mask & ATTR_ATIME) { - inode->i_atime = iattr->ia_atime; - ip->i_d.di_atime.t_sec = iattr->ia_atime.tv_sec; - ip->i_d.di_atime.t_nsec = iattr->ia_atime.tv_nsec; - ip->i_update_core = 1; - } - if (mask & ATTR_MTIME) { - inode->i_mtime = iattr->ia_mtime; - ip->i_d.di_mtime.t_sec = iattr->ia_mtime.tv_sec; - ip->i_d.di_mtime.t_nsec = iattr->ia_mtime.tv_nsec; - timeflags &= ~XFS_ICHGTIME_MOD; - timeflags |= XFS_ICHGTIME_CHG; - } - if (tp && (mask & (ATTR_MTIME_SET|ATTR_ATIME_SET))) - xfs_trans_log_inode (tp, ip, XFS_ILOG_CORE); + if (mask & ATTR_ATIME) { + inode->i_atime = iattr->ia_atime; + ip->i_d.di_atime.t_sec = iattr->ia_atime.tv_sec; + ip->i_d.di_atime.t_nsec = iattr->ia_atime.tv_nsec; + ip->i_update_core = 1; } - - /* - * Change file inode change time only if ATTR_CTIME set - * AND we have been called by a DMI function. - */ - - if ((flags & XFS_ATTR_DMI) && (mask & ATTR_CTIME)) { + if (mask & ATTR_CTIME) { inode->i_ctime = iattr->ia_ctime; ip->i_d.di_ctime.t_sec = iattr->ia_ctime.tv_sec; ip->i_d.di_ctime.t_nsec = iattr->ia_ctime.tv_nsec; ip->i_update_core = 1; - timeflags &= ~XFS_ICHGTIME_CHG; + } + if (mask & ATTR_MTIME) { + inode->i_mtime = iattr->ia_mtime; + ip->i_d.di_mtime.t_sec = iattr->ia_mtime.tv_sec; + ip->i_d.di_mtime.t_nsec = iattr->ia_mtime.tv_nsec; + ip->i_update_core = 1; } /* - * Send out timestamp changes that need to be set to the - * current time. Not done when called by a DMI function. + * And finally, log the inode core if any attribute in it + * has been changed. */ - if (timeflags && !(flags & XFS_ATTR_DMI)) - xfs_ichgtime(ip, timeflags); + if (mask & (ATTR_UID|ATTR_GID|ATTR_MODE| + ATTR_ATIME|ATTR_CTIME|ATTR_MTIME)) + xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); XFS_STATS_INC(xs_ig_attrchg); @@ -452,12 +439,10 @@ xfs_setattr( * mix so this probably isn't worth the trouble to optimize. */ code = 0; - if (tp) { - if (mp->m_flags & XFS_MOUNT_WSYNC) - xfs_trans_set_sync(tp); + if (mp->m_flags & XFS_MOUNT_WSYNC) + xfs_trans_set_sync(tp); - code = xfs_trans_commit(tp, commit_flags); - } + code = xfs_trans_commit(tp, commit_flags); xfs_iunlock(ip, lock_flags); -- cgit v0.10.2 From 44e08c45cc14e6190a424be8d450070c8e508fad Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Sat, 2 Jan 2010 02:39:40 +0000 Subject: xfs: Don't flush stale inodes Because inodes remain in cache much longer than inode buffers do under memory pressure, we can get the situation where we have stale, dirty inodes being reclaimed but the backing storage has been freed. Hence we should never, ever flush XFS_ISTALE inodes to disk as there is no guarantee that the backing buffer is in cache and still marked stale when the flush occurs. Signed-off-by: Dave Chinner Signed-off-by: Alex Elder diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index ce278b3..391d36b 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -2841,10 +2841,14 @@ xfs_iflush( mp = ip->i_mount; /* - * If the inode isn't dirty, then just release the inode - * flush lock and do nothing. + * If the inode isn't dirty, then just release the inode flush lock and + * do nothing. Treat stale inodes the same; we cannot rely on the + * backing buffer remaining stale in cache for the remaining life of + * the stale inode and so xfs_itobp() below may give us a buffer that + * no longer contains inodes below. Doing this stale check here also + * avoids forcing the log on pinned, stale inodes. */ - if (xfs_inode_clean(ip)) { + if (xfs_inode_clean(ip) || xfs_iflags_test(ip, XFS_ISTALE)) { xfs_ifunlock(ip); return 0; } -- cgit v0.10.2 From fd45e4784164d1017521086524e3442318c67370 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Sat, 2 Jan 2010 02:38:56 +0000 Subject: xfs: Ensure we force all busy extents in range to disk When we search for and find a busy extent during allocation we force the log out to ensure the extent free transaction is on disk before the allocation transaction. The current implementation has a subtle bug in it--it does not handle multiple overlapping ranges. That is, if we free lots of little extents into a single contiguous extent, then allocate the contiguous extent, the busy search code stops searching at the first extent it finds that overlaps the allocated range. It then uses the commit LSN of the transaction to force the log out to. Unfortunately, the other busy ranges might have more recent commit LSNs than the first busy extent that is found, and this results in xfs_alloc_search_busy() returning before all the extent free transactions are on disk for the range being allocated. This can lead to potential metadata corruption or stale data exposure after a crash because log replay won't replay all the extent free transactions that cover the allocation range. Modified-by: Alex Elder (Dropped the "found" argument from the xfs_alloc_busysearch trace event.) Signed-off-by: Dave Chinner Reviewed-by: Christoph Hellwig Signed-off-by: Alex Elder diff --git a/fs/xfs/linux-2.6/xfs_trace.h b/fs/xfs/linux-2.6/xfs_trace.h index 8cb42b4..c22a608 100644 --- a/fs/xfs/linux-2.6/xfs_trace.h +++ b/fs/xfs/linux-2.6/xfs_trace.h @@ -1079,28 +1079,28 @@ TRACE_EVENT(xfs_alloc_unbusy, TRACE_EVENT(xfs_alloc_busysearch, TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, xfs_agblock_t agbno, - xfs_extlen_t len, int found), - TP_ARGS(mp, agno, agbno, len, found), + xfs_extlen_t len, xfs_lsn_t lsn), + TP_ARGS(mp, agno, agbno, len, lsn), TP_STRUCT__entry( __field(dev_t, dev) __field(xfs_agnumber_t, agno) __field(xfs_agblock_t, agbno) __field(xfs_extlen_t, len) - __field(int, found) + __field(xfs_lsn_t, lsn) ), TP_fast_assign( __entry->dev = mp->m_super->s_dev; __entry->agno = agno; __entry->agbno = agbno; __entry->len = len; - __entry->found = found; + __entry->lsn = lsn; ), - TP_printk("dev %d:%d agno %u agbno %u len %u %s", + TP_printk("dev %d:%d agno %u agbno %u len %u force lsn 0x%llx", MAJOR(__entry->dev), MINOR(__entry->dev), __entry->agno, __entry->agbno, __entry->len, - __print_symbolic(__entry->found, XFS_BUSY_STATES)) + __entry->lsn) ); TRACE_EVENT(xfs_agf, diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c index a1c65fc..275b1f4 100644 --- a/fs/xfs/xfs_alloc.c +++ b/fs/xfs/xfs_alloc.c @@ -2563,43 +2563,41 @@ xfs_alloc_search_busy(xfs_trans_t *tp, xfs_mount_t *mp; xfs_perag_busy_t *bsy; xfs_agblock_t uend, bend; - xfs_lsn_t lsn; + xfs_lsn_t lsn = 0; int cnt; mp = tp->t_mountp; spin_lock(&mp->m_perag[agno].pagb_lock); - cnt = mp->m_perag[agno].pagb_count; uend = bno + len - 1; - /* search pagb_list for this slot, skipping open slots */ - for (bsy = mp->m_perag[agno].pagb_list; cnt; bsy++) { + /* + * search pagb_list for this slot, skipping open slots. We have to + * search the entire array as there may be multiple overlaps and + * we have to get the most recent LSN for the log force to push out + * all the transactions that span the range. + */ + for (cnt = 0; cnt < mp->m_perag[agno].pagb_count; cnt++) { + bsy = &mp->m_perag[agno].pagb_list[cnt]; + if (!bsy->busy_tp) + continue; - /* - * (start1,length1) within (start2, length2) - */ - if (bsy->busy_tp != NULL) { - bend = bsy->busy_start + bsy->busy_length - 1; - if ((bno > bend) || (uend < bsy->busy_start)) { - cnt--; - } else { - break; - } - } - } + bend = bsy->busy_start + bsy->busy_length - 1; + if (bno > bend || uend < bsy->busy_start) + continue; - trace_xfs_alloc_busysearch(mp, agno, bno, len, !!cnt); + /* (start1,length1) within (start2, length2) */ + if (XFS_LSN_CMP(bsy->busy_tp->t_commit_lsn, lsn) > 0) + lsn = bsy->busy_tp->t_commit_lsn; + } + spin_unlock(&mp->m_perag[agno].pagb_lock); + trace_xfs_alloc_busysearch(tp->t_mountp, agno, bno, len, lsn); /* * If a block was found, force the log through the LSN of the * transaction that freed the block */ - if (cnt) { - lsn = bsy->busy_tp->t_commit_lsn; - spin_unlock(&mp->m_perag[agno].pagb_lock); + if (lsn) xfs_log_force(mp, lsn, XFS_LOG_FORCE|XFS_LOG_SYNC); - } else { - spin_unlock(&mp->m_perag[agno].pagb_lock); - } } -- cgit v0.10.2 From bb595c923bc51dff9cdd112de18deb57ac7945d2 Mon Sep 17 00:00:00 2001 From: Roger Blofeld Date: Sun, 10 Jan 2010 20:52:32 +0100 Subject: hwmon: (adt7462) Fix pin 28 monitoring The ADT7462_PIN28_VOLT value is a 4-bit field, so the corresponding shift must be 4. Signed-off-by: Roger Blofeld Signed-off-by: Jean Delvare diff --git a/drivers/hwmon/adt7462.c b/drivers/hwmon/adt7462.c index a1a7ef1..a31e77c 100644 --- a/drivers/hwmon/adt7462.c +++ b/drivers/hwmon/adt7462.c @@ -94,7 +94,7 @@ static const unsigned short normal_i2c[] = { 0x58, 0x5C, I2C_CLIENT_END }; #define ADT7462_PIN24_SHIFT 6 #define ADT7462_PIN26_VOLT_INPUT 0x08 #define ADT7462_PIN25_VOLT_INPUT 0x20 -#define ADT7462_PIN28_SHIFT 6 /* cfg3 */ +#define ADT7462_PIN28_SHIFT 4 /* cfg3 */ #define ADT7462_PIN28_VOLT 0x5 #define ADT7462_REG_ALARM1 0xB8 -- cgit v0.10.2 From 8ba406be53713efdd705666e2178cfe486fcfb27 Mon Sep 17 00:00:00 2001 From: Luca Tettamanti Date: Sun, 10 Jan 2010 20:52:33 +0100 Subject: hwmon: (asus_atk0110) Refactor interface probe code The behaviour is unmodified, this makes easier to override the heuristic (which is probably needed for some boards). Signed-off-by: Luca Tettamanti Signed-off-by: Jean Delvare diff --git a/drivers/hwmon/asus_atk0110.c b/drivers/hwmon/asus_atk0110.c index 5a3ee00..1173981 100644 --- a/drivers/hwmon/asus_atk0110.c +++ b/drivers/hwmon/asus_atk0110.c @@ -1047,76 +1047,75 @@ remove: return err; } -static int atk_check_old_if(struct atk_data *data) +static int atk_probe_if(struct atk_data *data) { struct device *dev = &data->acpi_dev->dev; acpi_handle ret; acpi_status status; + int err = 0; /* RTMP: read temperature */ status = acpi_get_handle(data->atk_handle, METHOD_OLD_READ_TMP, &ret); - if (status != AE_OK) { + if (ACPI_SUCCESS(status)) + data->rtmp_handle = ret; + else dev_dbg(dev, "method " METHOD_OLD_READ_TMP " not found: %s\n", acpi_format_exception(status)); - return -ENODEV; - } - data->rtmp_handle = ret; /* RVLT: read voltage */ status = acpi_get_handle(data->atk_handle, METHOD_OLD_READ_VLT, &ret); - if (status != AE_OK) { + if (ACPI_SUCCESS(status)) + data->rvlt_handle = ret; + else dev_dbg(dev, "method " METHOD_OLD_READ_VLT " not found: %s\n", acpi_format_exception(status)); - return -ENODEV; - } - data->rvlt_handle = ret; /* RFAN: read fan status */ status = acpi_get_handle(data->atk_handle, METHOD_OLD_READ_FAN, &ret); - if (status != AE_OK) { + if (ACPI_SUCCESS(status)) + data->rfan_handle = ret; + else dev_dbg(dev, "method " METHOD_OLD_READ_FAN " not found: %s\n", acpi_format_exception(status)); - return -ENODEV; - } - data->rfan_handle = ret; - - return 0; -} - -static int atk_check_new_if(struct atk_data *data) -{ - struct device *dev = &data->acpi_dev->dev; - acpi_handle ret; - acpi_status status; /* Enumeration */ status = acpi_get_handle(data->atk_handle, METHOD_ENUMERATE, &ret); - if (status != AE_OK) { + if (ACPI_SUCCESS(status)) + data->enumerate_handle = ret; + else dev_dbg(dev, "method " METHOD_ENUMERATE " not found: %s\n", acpi_format_exception(status)); - return -ENODEV; - } - data->enumerate_handle = ret; /* De-multiplexer (read) */ status = acpi_get_handle(data->atk_handle, METHOD_READ, &ret); - if (status != AE_OK) { + if (ACPI_SUCCESS(status)) + data->read_handle = ret; + else dev_dbg(dev, "method " METHOD_READ " not found: %s\n", acpi_format_exception(status)); - return -ENODEV; - } - data->read_handle = ret; /* De-multiplexer (write) */ status = acpi_get_handle(data->atk_handle, METHOD_WRITE, &ret); - if (status != AE_OK) { - dev_dbg(dev, "method " METHOD_READ " not found: %s\n", + if (ACPI_SUCCESS(status)) + data->write_handle = ret; + else + dev_dbg(dev, "method " METHOD_WRITE " not found: %s\n", acpi_format_exception(status)); - return -ENODEV; - } - data->write_handle = ret; - return 0; + /* Check for hwmon methods: first check "old" style methods; note that + * both may be present: in this case we stick to the old interface; + * analysis of multiple DSDTs indicates that when both interfaces + * are present the new one (GGRP/GITM) is not functional. + */ + if (data->rtmp_handle && data->rvlt_handle && data->rfan_handle) + data->old_interface = true; + else if (data->enumerate_handle && data->read_handle && + data->write_handle) + data->old_interface = false; + else + err = -ENODEV; + + return err; } static int atk_add(struct acpi_device *device) @@ -1155,28 +1154,19 @@ static int atk_add(struct acpi_device *device) } ACPI_FREE(buf.pointer); - /* Check for hwmon methods: first check "old" style methods; note that - * both may be present: in this case we stick to the old interface; - * analysis of multiple DSDTs indicates that when both interfaces - * are present the new one (GGRP/GITM) is not functional. - */ - err = atk_check_old_if(data); - if (!err) { - dev_dbg(&device->dev, "Using old hwmon interface\n"); - data->old_interface = true; - } else { - err = atk_check_new_if(data); - if (err) - goto out; - - dev_dbg(&device->dev, "Using new hwmon interface\n"); - data->old_interface = false; + err = atk_probe_if(data); + if (err) { + dev_err(&device->dev, "No usable hwmon interface detected\n"); + goto out; } - if (data->old_interface) + if (data->old_interface) { + dev_dbg(&device->dev, "Using old hwmon interface\n"); err = atk_enumerate_old_hwmon(data); - else + } else { + dev_dbg(&device->dev, "Using new hwmon interface\n"); err = atk_enumerate_new_hwmon(data); + } if (err < 0) goto out; if (err == 0) { -- cgit v0.10.2 From 7e5eab1128a05b99b8c81c01ff6515a3ca25e5aa Mon Sep 17 00:00:00 2001 From: Luca Tettamanti Date: Sun, 10 Jan 2010 20:52:33 +0100 Subject: hwmon: (asus_atk0110) Add debugfs interface Expose the raw GGRP/GITM interface via debugfs. The hwmon interface is reverse engineered and the driver tends to break on newer boards... Using this interface it's possible to poke directly at the ACPI methods without the need to recompile, reducing the guesswork and the round trips needed to support a new revision of the interface. Signed-off-by: Luca Tettamanti Signed-off-by: Jean Delvare diff --git a/drivers/hwmon/asus_atk0110.c b/drivers/hwmon/asus_atk0110.c index 1173981..6811346 100644 --- a/drivers/hwmon/asus_atk0110.c +++ b/drivers/hwmon/asus_atk0110.c @@ -5,6 +5,7 @@ * See COPYING in the top level directory of the kernel tree. */ +#include #include #include #include @@ -101,6 +102,11 @@ struct atk_data { int temperature_count; int fan_count; struct list_head sensor_list; + + struct { + struct dentry *root; + u32 id; + } debugfs; }; @@ -624,6 +630,187 @@ static int atk_read_value(struct atk_sensor_data *sensor, u64 *value) return err; } +#ifdef CONFIG_DEBUG_FS +static int atk_debugfs_gitm_get(void *p, u64 *val) +{ + struct atk_data *data = p; + union acpi_object *ret; + struct atk_acpi_ret_buffer *buf; + int err = 0; + + if (!data->read_handle) + return -ENODEV; + + if (!data->debugfs.id) + return -EINVAL; + + ret = atk_gitm(data, data->debugfs.id); + if (IS_ERR(ret)) + return PTR_ERR(ret); + + buf = (struct atk_acpi_ret_buffer *)ret->buffer.pointer; + if (buf->flags) + *val = buf->value; + else + err = -EIO; + + return err; +} + +DEFINE_SIMPLE_ATTRIBUTE(atk_debugfs_gitm, + atk_debugfs_gitm_get, + NULL, + "0x%08llx\n") + +static int atk_acpi_print(char *buf, size_t sz, union acpi_object *obj) +{ + int ret = 0; + + switch (obj->type) { + case ACPI_TYPE_INTEGER: + ret = snprintf(buf, sz, "0x%08llx\n", obj->integer.value); + break; + case ACPI_TYPE_STRING: + ret = snprintf(buf, sz, "%s\n", obj->string.pointer); + break; + } + + return ret; +} + +static void atk_pack_print(char *buf, size_t sz, union acpi_object *pack) +{ + int ret; + int i; + + for (i = 0; i < pack->package.count; i++) { + union acpi_object *obj = &pack->package.elements[i]; + + ret = atk_acpi_print(buf, sz, obj); + if (ret >= sz) + break; + buf += ret; + sz -= ret; + } +} + +static int atk_debugfs_ggrp_open(struct inode *inode, struct file *file) +{ + struct atk_data *data = inode->i_private; + char *buf = NULL; + union acpi_object *ret; + u8 cls; + int i; + + if (!data->enumerate_handle) + return -ENODEV; + if (!data->debugfs.id) + return -EINVAL; + + cls = (data->debugfs.id & 0xff000000) >> 24; + ret = atk_ggrp(data, cls); + if (IS_ERR(ret)) + return PTR_ERR(ret); + + for (i = 0; i < ret->package.count; i++) { + union acpi_object *pack = &ret->package.elements[i]; + union acpi_object *id; + + if (pack->type != ACPI_TYPE_PACKAGE) + continue; + if (!pack->package.count) + continue; + id = &pack->package.elements[0]; + if (id->integer.value == data->debugfs.id) { + /* Print the package */ + buf = kzalloc(512, GFP_KERNEL); + if (!buf) { + ACPI_FREE(ret); + return -ENOMEM; + } + atk_pack_print(buf, 512, pack); + break; + } + } + ACPI_FREE(ret); + + if (!buf) + return -EINVAL; + + file->private_data = buf; + + return nonseekable_open(inode, file); +} + +static ssize_t atk_debugfs_ggrp_read(struct file *file, char __user *buf, + size_t count, loff_t *pos) +{ + char *str = file->private_data; + size_t len = strlen(str); + + return simple_read_from_buffer(buf, count, pos, str, len); +} + +static int atk_debugfs_ggrp_release(struct inode *inode, struct file *file) +{ + kfree(file->private_data); + return 0; +} + +static const struct file_operations atk_debugfs_ggrp_fops = { + .read = atk_debugfs_ggrp_read, + .open = atk_debugfs_ggrp_open, + .release = atk_debugfs_ggrp_release, +}; + +static void atk_debugfs_init(struct atk_data *data) +{ + struct dentry *d; + struct dentry *f; + + data->debugfs.id = 0; + + d = debugfs_create_dir("asus_atk0110", NULL); + if (!d || IS_ERR(d)) + return; + + f = debugfs_create_x32("id", S_IRUSR | S_IWUSR, d, &data->debugfs.id); + if (!f || IS_ERR(f)) + goto cleanup; + + f = debugfs_create_file("gitm", S_IRUSR, d, data, + &atk_debugfs_gitm); + if (!f || IS_ERR(f)) + goto cleanup; + + f = debugfs_create_file("ggrp", S_IRUSR, d, data, + &atk_debugfs_ggrp_fops); + if (!f || IS_ERR(f)) + goto cleanup; + + data->debugfs.root = d; + + return; +cleanup: + debugfs_remove_recursive(d); +} + +static void atk_debugfs_cleanup(struct atk_data *data) +{ + debugfs_remove_recursive(data->debugfs.root); +} + +#else /* CONFIG_DEBUG_FS */ + +static void atk_debugfs_init(struct atk_data *data) +{ +} + +static void atk_debugfs_cleanup(struct atk_data *data) +{ +} +#endif + static int atk_add_sensor(struct atk_data *data, union acpi_object *obj) { struct device *dev = &data->acpi_dev->dev; @@ -1180,6 +1367,8 @@ static int atk_add(struct acpi_device *device) if (err) goto cleanup; + atk_debugfs_init(data); + device->driver_data = data; return 0; cleanup: @@ -1198,6 +1387,8 @@ static int atk_remove(struct acpi_device *device, int type) device->driver_data = NULL; + atk_debugfs_cleanup(data); + atk_remove_files(data); atk_free_sensors(data); hwmon_device_unregister(data->hwmon_dev); -- cgit v0.10.2 From c5114a1cd6d84b2b3144c1c3e093c80ca6c30f47 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Sun, 10 Jan 2010 20:52:34 +0100 Subject: hwmon: (k10temp) Blacklist more family 10h processors The latest version of the Revision Guide for AMD Family 10h Processors lists two more processor revisions which may be affected by erratum 319. Change the blacklisting code to correctly detect those processors, by implementing AMD's recommended algorithm. Signed-off-by: Clemens Ladisch Signed-off-by: Jean Delvare Cc: Andreas Herrmann diff --git a/Documentation/hwmon/k10temp b/Documentation/hwmon/k10temp index a7a18d4..6526eee 100644 --- a/Documentation/hwmon/k10temp +++ b/Documentation/hwmon/k10temp @@ -3,8 +3,8 @@ Kernel driver k10temp Supported chips: * AMD Family 10h processors: - Socket F: Quad-Core/Six-Core/Embedded Opteron - Socket AM2+: Opteron, Phenom (II) X3/X4 + Socket F: Quad-Core/Six-Core/Embedded Opteron (but see below) + Socket AM2+: Quad-Core Opteron, Phenom (II) X3/X4, Athlon X2 (but see below) Socket AM3: Quad-Core Opteron, Athlon/Phenom II X2/X3/X4, Sempron II Socket S1G3: Athlon II, Sempron, Turion II * AMD Family 11h processors: @@ -36,10 +36,15 @@ Description This driver permits reading of the internal temperature sensor of AMD Family 10h and 11h processors. -All these processors have a sensor, but on older revisions of Family 10h -processors, the sensor may return inconsistent values (erratum 319). The -driver will refuse to load on these revisions unless you specify the -"force=1" module parameter. +All these processors have a sensor, but on those for Socket F or AM2+, +the sensor may return inconsistent values (erratum 319). The driver +will refuse to load on these revisions unless you specify the "force=1" +module parameter. + +Due to technical reasons, the driver can detect only the mainboard's +socket type, not the processor's actual capabilities. Therefore, if you +are using an AM3 processor on an AM2+ mainboard, you can safely use the +"force=1" parameter. There is one temperature measurement value, available as temp1_input in sysfs. It is measured in degrees Celsius with a resolution of 1/8th degree. diff --git a/drivers/hwmon/k10temp.c b/drivers/hwmon/k10temp.c index d8a26d1..4c9d349 100644 --- a/drivers/hwmon/k10temp.c +++ b/drivers/hwmon/k10temp.c @@ -33,6 +33,16 @@ static bool force; module_param(force, bool, 0444); MODULE_PARM_DESC(force, "force loading on processors with erratum 319"); +/* CPUID function 0x80000001, ebx */ +#define CPUID_PKGTYPE_MASK 0xf0000000 +#define CPUID_PKGTYPE_F 0x00000000 +#define CPUID_PKGTYPE_AM2R2_AM3 0x10000000 + +/* DRAM controller (PCI function 2) */ +#define REG_DCT0_CONFIG_HIGH 0x094 +#define DDR3_MODE 0x00000100 + +/* miscellaneous (PCI function 3) */ #define REG_HARDWARE_THERMAL_CONTROL 0x64 #define HTC_ENABLE 0x00000001 @@ -85,13 +95,28 @@ static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, show_temp_crit, NULL, 0); static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IRUGO, show_temp_crit, NULL, 1); static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); -static bool __devinit has_erratum_319(void) +static bool __devinit has_erratum_319(struct pci_dev *pdev) { + u32 pkg_type, reg_dram_cfg; + + if (boot_cpu_data.x86 != 0x10) + return false; + /* - * Erratum 319: The thermal sensor of older Family 10h processors - * (B steppings) may be unreliable. + * Erratum 319: The thermal sensor of Socket F/AM2+ processors + * may be unreliable. */ - return boot_cpu_data.x86 == 0x10 && boot_cpu_data.x86_model <= 2; + pkg_type = cpuid_ebx(0x80000001) & CPUID_PKGTYPE_MASK; + if (pkg_type == CPUID_PKGTYPE_F) + return true; + if (pkg_type != CPUID_PKGTYPE_AM2R2_AM3) + return false; + + /* Differentiate between AM2+ (bad) and AM3 (good) */ + pci_bus_read_config_dword(pdev->bus, + PCI_DEVFN(PCI_SLOT(pdev->devfn), 2), + REG_DCT0_CONFIG_HIGH, ®_dram_cfg); + return !(reg_dram_cfg & DDR3_MODE); } static int __devinit k10temp_probe(struct pci_dev *pdev, @@ -99,9 +124,10 @@ static int __devinit k10temp_probe(struct pci_dev *pdev, { struct device *hwmon_dev; u32 reg_caps, reg_htc; + int unreliable = has_erratum_319(pdev); int err; - if (has_erratum_319() && !force) { + if (unreliable && !force) { dev_err(&pdev->dev, "unreliable CPU thermal sensor; monitoring disabled\n"); err = -ENODEV; @@ -139,7 +165,7 @@ static int __devinit k10temp_probe(struct pci_dev *pdev, } dev_set_drvdata(&pdev->dev, hwmon_dev); - if (has_erratum_319() && force) + if (unreliable && force) dev_warn(&pdev->dev, "unreliable CPU thermal sensor; check erratum 319\n"); return 0; -- cgit v0.10.2 From 1fe63ab47a617ee95f562eaa7ddbbc59981ff8c6 Mon Sep 17 00:00:00 2001 From: Yong Wang Date: Sun, 10 Jan 2010 20:52:34 +0100 Subject: hwmon: (coretemp) Fix TjMax for Atom N450/D410/D510 CPUs The max junction temperature of Atom N450/D410/D510 CPUs is 100 degrees Celsius. Since these CPUs are always coupled with Intel NM10 chipset in one package, the best way to verify whether an Atom CPU is N450/D410/D510 is to check the host bridge device. Signed-off-by: Yong Wang Acked-by: Huaxu Wan Signed-off-by: Jean Delvare diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 46c3c56..435ae72 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -392,7 +392,7 @@ config SENSORS_GL520SM config SENSORS_CORETEMP tristate "Intel Core/Core2/Atom temperature sensor" - depends on X86 && EXPERIMENTAL + depends on X86 && PCI && EXPERIMENTAL help If you say yes here you get support for the temperature sensor inside your CPU. Most of the family 6 CPUs diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index caef39c..2d7bcee 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -161,6 +162,7 @@ static int __devinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device * int usemsr_ee = 1; int err; u32 eax, edx; + struct pci_dev *host_bridge; /* Early chips have no MSR for TjMax */ @@ -168,11 +170,21 @@ static int __devinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device * usemsr_ee = 0; } - /* Atoms seems to have TjMax at 90C */ + /* Atom CPUs */ if (c->x86_model == 0x1c) { usemsr_ee = 0; - tjmax = 90000; + + host_bridge = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0)); + + if (host_bridge && host_bridge->vendor == PCI_VENDOR_ID_INTEL + && (host_bridge->device == 0xa000 /* NM10 based nettop */ + || host_bridge->device == 0xa010)) /* NM10 based netbook */ + tjmax = 100000; + else + tjmax = 90000; + + pci_dev_put(host_bridge); } if ((c->x86_model > 0xe) && (usemsr_ee)) { -- cgit v0.10.2 From 3dd3a156355e7e6bec0dc9a0bbb6eeecbd965d50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20N=C3=A9meth?= Date: Sun, 10 Jan 2010 20:52:35 +0100 Subject: hwmon: Make PCI device ids constant MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The id_table field of the struct pci_driver is constant in so it is worth to make pci_device_id also constant. The semantic match that finds this kind of pattern is as follows: (http://coccinelle.lip6.fr/) // @r@ identifier I1, I2, x; @@ struct I1 { ... const struct I2 *x; ... }; @s@ identifier r.I1, y; identifier r.x, E; @@ struct I1 y = { .x = E, }; @c@ identifier r.I2; identifier s.E; @@ const struct I2 E[] = ... ; @depends on !c@ identifier r.I2; identifier s.E; @@ + const struct I2 E[] = ...; // Signed-off-by: Márton Németh Cc: Julia Lawall Signed-off-by: Jean Delvare diff --git a/drivers/hwmon/k10temp.c b/drivers/hwmon/k10temp.c index 4c9d349..099a213 100644 --- a/drivers/hwmon/k10temp.c +++ b/drivers/hwmon/k10temp.c @@ -195,7 +195,7 @@ static void __devexit k10temp_remove(struct pci_dev *pdev) dev_set_drvdata(&pdev->dev, NULL); } -static struct pci_device_id k10temp_id_table[] = { +static const struct pci_device_id k10temp_id_table[] = { { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_10H_NB_MISC) }, { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_11H_NB_MISC) }, {} diff --git a/drivers/hwmon/k8temp.c b/drivers/hwmon/k8temp.c index 1fe9951..0ceb6d6 100644 --- a/drivers/hwmon/k8temp.c +++ b/drivers/hwmon/k8temp.c @@ -136,7 +136,7 @@ static SENSOR_DEVICE_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 1, 0); static SENSOR_DEVICE_ATTR_2(temp4_input, S_IRUGO, show_temp, NULL, 1, 1); static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); -static struct pci_device_id k8temp_ids[] = { +static const struct pci_device_id k8temp_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) }, { 0 }, }; diff --git a/drivers/hwmon/sis5595.c b/drivers/hwmon/sis5595.c index 12f2e70..79c2931 100644 --- a/drivers/hwmon/sis5595.c +++ b/drivers/hwmon/sis5595.c @@ -697,7 +697,7 @@ static struct sis5595_data *sis5595_update_device(struct device *dev) return data; } -static struct pci_device_id sis5595_pci_ids[] = { +static const struct pci_device_id sis5595_pci_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) }, { 0, } }; diff --git a/drivers/hwmon/via686a.c b/drivers/hwmon/via686a.c index 39e82a4..f397ce7 100644 --- a/drivers/hwmon/via686a.c +++ b/drivers/hwmon/via686a.c @@ -767,7 +767,7 @@ static struct via686a_data *via686a_update_device(struct device *dev) return data; } -static struct pci_device_id via686a_pci_ids[] = { +static const struct pci_device_id via686a_pci_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4) }, { 0, } }; diff --git a/drivers/hwmon/vt8231.c b/drivers/hwmon/vt8231.c index 470a122..d47b4c9 100644 --- a/drivers/hwmon/vt8231.c +++ b/drivers/hwmon/vt8231.c @@ -697,7 +697,7 @@ static struct platform_driver vt8231_driver = { .remove = __devexit_p(vt8231_remove), }; -static struct pci_device_id vt8231_pci_ids[] = { +static const struct pci_device_id vt8231_pci_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231_4) }, { 0, } }; -- cgit v0.10.2 From fa15e99b6bb44aa86b241a43ca8c509e91f80153 Mon Sep 17 00:00:00 2001 From: Denis Kirjanov Date: Sun, 10 Jan 2010 13:40:10 -0800 Subject: vxge: use pci_dma_mapping_error to test return value pci_dma_mapping_error should be used to test return value of pci_map_single or pci_map_page. Signed-off-by: Denis Kirjanov Signed-off-by: David S. Miller diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index 0fdfd58..b9685e8 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c @@ -310,7 +310,7 @@ static int vxge_rx_map(void *dtrh, struct vxge_ring *ring) dma_addr = pci_map_single(ring->pdev, rx_priv->skb_data, rx_priv->data_size, PCI_DMA_FROMDEVICE); - if (dma_addr == 0) { + if (unlikely(pci_dma_mapping_error(ring->pdev, dma_addr))) { ring->stats.pci_map_fail++; return -EIO; } -- cgit v0.10.2 From 804c7559e9376c3ba78ae15a30337b1e24f8ae80 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 8 Jan 2010 15:58:49 -0500 Subject: drm/radeon/kms: add additional safe regs for r4xx/rs6xx and r5xx - r4xx/rs6xx: add support for extended pixel shader instruction/temp regs - r5xx: add SM3 regs Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile index b5f5fe7..1cc7b93 100644 --- a/drivers/gpu/drm/radeon/Makefile +++ b/drivers/gpu/drm/radeon/Makefile @@ -24,6 +24,9 @@ $(obj)/rv515_reg_safe.h: $(src)/reg_srcs/rv515 $(obj)/mkregtable $(obj)/r300_reg_safe.h: $(src)/reg_srcs/r300 $(obj)/mkregtable $(call if_changed,mkregtable) +$(obj)/r420_reg_safe.h: $(src)/reg_srcs/r420 $(obj)/mkregtable + $(call if_changed,mkregtable) + $(obj)/rs600_reg_safe.h: $(src)/reg_srcs/rs600 $(obj)/mkregtable $(call if_changed,mkregtable) @@ -35,6 +38,8 @@ $(obj)/rv515.o: $(obj)/rv515_reg_safe.h $(obj)/r300.o: $(obj)/r300_reg_safe.h +$(obj)/r420.o: $(obj)/r420_reg_safe.h + $(obj)/rs600.o: $(obj)/rs600_reg_safe.h radeon-y := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o \ diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c index 1d4d16e..053404e 100644 --- a/drivers/gpu/drm/radeon/r420.c +++ b/drivers/gpu/drm/radeon/r420.c @@ -32,6 +32,13 @@ #include "atom.h" #include "r100d.h" #include "r420d.h" +#include "r420_reg_safe.h" + +static void r420_set_reg_safe(struct radeon_device *rdev) +{ + rdev->config.r300.reg_safe_bm = r420_reg_safe_bm; + rdev->config.r300.reg_safe_bm_size = ARRAY_SIZE(r420_reg_safe_bm); +} int r420_mc_init(struct radeon_device *rdev) { @@ -378,7 +385,7 @@ int r420_init(struct radeon_device *rdev) if (r) return r; } - r300_set_reg_safe(rdev); + r420_set_reg_safe(rdev); rdev->accel_working = true; r = r420_startup(rdev); if (r) { diff --git a/drivers/gpu/drm/radeon/reg_srcs/r420 b/drivers/gpu/drm/radeon/reg_srcs/r420 new file mode 100644 index 0000000..989f7a0 --- /dev/null +++ b/drivers/gpu/drm/radeon/reg_srcs/r420 @@ -0,0 +1,795 @@ +r420 0x4f60 +0x1434 SRC_Y_X +0x1438 DST_Y_X +0x143C DST_HEIGHT_WIDTH +0x146C DP_GUI_MASTER_CNTL +0x1474 BRUSH_Y_X +0x1478 DP_BRUSH_BKGD_CLR +0x147C DP_BRUSH_FRGD_CLR +0x1480 BRUSH_DATA0 +0x1484 BRUSH_DATA1 +0x1598 DST_WIDTH_HEIGHT +0x15C0 CLR_CMP_CNTL +0x15C4 CLR_CMP_CLR_SRC +0x15C8 CLR_CMP_CLR_DST +0x15CC CLR_CMP_MSK +0x15D8 DP_SRC_FRGD_CLR +0x15DC DP_SRC_BKGD_CLR +0x1600 DST_LINE_START +0x1604 DST_LINE_END +0x1608 DST_LINE_PATCOUNT +0x16C0 DP_CNTL +0x16CC DP_WRITE_MSK +0x16D0 DP_CNTL_XDIR_YDIR_YMAJOR +0x16E8 DEFAULT_SC_BOTTOM_RIGHT +0x16EC SC_TOP_LEFT +0x16F0 SC_BOTTOM_RIGHT +0x16F4 SRC_SC_BOTTOM_RIGHT +0x1714 DSTCACHE_CTLSTAT +0x1720 WAIT_UNTIL +0x172C RBBM_GUICNTL +0x1D98 VAP_VPORT_XSCALE +0x1D9C VAP_VPORT_XOFFSET +0x1DA0 VAP_VPORT_YSCALE +0x1DA4 VAP_VPORT_YOFFSET +0x1DA8 VAP_VPORT_ZSCALE +0x1DAC VAP_VPORT_ZOFFSET +0x2080 VAP_CNTL +0x2090 VAP_OUT_VTX_FMT_0 +0x2094 VAP_OUT_VTX_FMT_1 +0x20B0 VAP_VTE_CNTL +0x2138 VAP_VF_MIN_VTX_INDX +0x2140 VAP_CNTL_STATUS +0x2150 VAP_PROG_STREAM_CNTL_0 +0x2154 VAP_PROG_STREAM_CNTL_1 +0x2158 VAP_PROG_STREAM_CNTL_2 +0x215C VAP_PROG_STREAM_CNTL_3 +0x2160 VAP_PROG_STREAM_CNTL_4 +0x2164 VAP_PROG_STREAM_CNTL_5 +0x2168 VAP_PROG_STREAM_CNTL_6 +0x216C VAP_PROG_STREAM_CNTL_7 +0x2180 VAP_VTX_STATE_CNTL +0x2184 VAP_VSM_VTX_ASSM +0x2188 VAP_VTX_STATE_IND_REG_0 +0x218C VAP_VTX_STATE_IND_REG_1 +0x2190 VAP_VTX_STATE_IND_REG_2 +0x2194 VAP_VTX_STATE_IND_REG_3 +0x2198 VAP_VTX_STATE_IND_REG_4 +0x219C VAP_VTX_STATE_IND_REG_5 +0x21A0 VAP_VTX_STATE_IND_REG_6 +0x21A4 VAP_VTX_STATE_IND_REG_7 +0x21A8 VAP_VTX_STATE_IND_REG_8 +0x21AC VAP_VTX_STATE_IND_REG_9 +0x21B0 VAP_VTX_STATE_IND_REG_10 +0x21B4 VAP_VTX_STATE_IND_REG_11 +0x21B8 VAP_VTX_STATE_IND_REG_12 +0x21BC VAP_VTX_STATE_IND_REG_13 +0x21C0 VAP_VTX_STATE_IND_REG_14 +0x21C4 VAP_VTX_STATE_IND_REG_15 +0x21DC VAP_PSC_SGN_NORM_CNTL +0x21E0 VAP_PROG_STREAM_CNTL_EXT_0 +0x21E4 VAP_PROG_STREAM_CNTL_EXT_1 +0x21E8 VAP_PROG_STREAM_CNTL_EXT_2 +0x21EC VAP_PROG_STREAM_CNTL_EXT_3 +0x21F0 VAP_PROG_STREAM_CNTL_EXT_4 +0x21F4 VAP_PROG_STREAM_CNTL_EXT_5 +0x21F8 VAP_PROG_STREAM_CNTL_EXT_6 +0x21FC VAP_PROG_STREAM_CNTL_EXT_7 +0x2200 VAP_PVS_VECTOR_INDX_REG +0x2204 VAP_PVS_VECTOR_DATA_REG +0x2208 VAP_PVS_VECTOR_DATA_REG_128 +0x221C VAP_CLIP_CNTL +0x2220 VAP_GB_VERT_CLIP_ADJ +0x2224 VAP_GB_VERT_DISC_ADJ +0x2228 VAP_GB_HORZ_CLIP_ADJ +0x222C VAP_GB_HORZ_DISC_ADJ +0x2230 VAP_PVS_FLOW_CNTL_ADDRS_0 +0x2234 VAP_PVS_FLOW_CNTL_ADDRS_1 +0x2238 VAP_PVS_FLOW_CNTL_ADDRS_2 +0x223C VAP_PVS_FLOW_CNTL_ADDRS_3 +0x2240 VAP_PVS_FLOW_CNTL_ADDRS_4 +0x2244 VAP_PVS_FLOW_CNTL_ADDRS_5 +0x2248 VAP_PVS_FLOW_CNTL_ADDRS_6 +0x224C VAP_PVS_FLOW_CNTL_ADDRS_7 +0x2250 VAP_PVS_FLOW_CNTL_ADDRS_8 +0x2254 VAP_PVS_FLOW_CNTL_ADDRS_9 +0x2258 VAP_PVS_FLOW_CNTL_ADDRS_10 +0x225C VAP_PVS_FLOW_CNTL_ADDRS_11 +0x2260 VAP_PVS_FLOW_CNTL_ADDRS_12 +0x2264 VAP_PVS_FLOW_CNTL_ADDRS_13 +0x2268 VAP_PVS_FLOW_CNTL_ADDRS_14 +0x226C VAP_PVS_FLOW_CNTL_ADDRS_15 +0x2284 VAP_PVS_STATE_FLUSH_REG +0x2288 VAP_PVS_VTX_TIMEOUT_REG +0x2290 VAP_PVS_FLOW_CNTL_LOOP_INDEX_0 +0x2294 VAP_PVS_FLOW_CNTL_LOOP_INDEX_1 +0x2298 VAP_PVS_FLOW_CNTL_LOOP_INDEX_2 +0x229C VAP_PVS_FLOW_CNTL_LOOP_INDEX_3 +0x22A0 VAP_PVS_FLOW_CNTL_LOOP_INDEX_4 +0x22A4 VAP_PVS_FLOW_CNTL_LOOP_INDEX_5 +0x22A8 VAP_PVS_FLOW_CNTL_LOOP_INDEX_6 +0x22AC VAP_PVS_FLOW_CNTL_LOOP_INDEX_7 +0x22B0 VAP_PVS_FLOW_CNTL_LOOP_INDEX_8 +0x22B4 VAP_PVS_FLOW_CNTL_LOOP_INDEX_9 +0x22B8 VAP_PVS_FLOW_CNTL_LOOP_INDEX_10 +0x22BC VAP_PVS_FLOW_CNTL_LOOP_INDEX_11 +0x22C0 VAP_PVS_FLOW_CNTL_LOOP_INDEX_12 +0x22C4 VAP_PVS_FLOW_CNTL_LOOP_INDEX_13 +0x22C8 VAP_PVS_FLOW_CNTL_LOOP_INDEX_14 +0x22CC VAP_PVS_FLOW_CNTL_LOOP_INDEX_15 +0x22D0 VAP_PVS_CODE_CNTL_0 +0x22D4 VAP_PVS_CONST_CNTL +0x22D8 VAP_PVS_CODE_CNTL_1 +0x22DC VAP_PVS_FLOW_CNTL_OPC +0x342C RB2D_DSTCACHE_CTLSTAT +0x4000 GB_VAP_RASTER_VTX_FMT_0 +0x4004 GB_VAP_RASTER_VTX_FMT_1 +0x4008 GB_ENABLE +0x401C GB_SELECT +0x4020 GB_AA_CONFIG +0x4024 GB_FIFO_SIZE +0x4100 TX_INVALTAGS +0x4200 GA_POINT_S0 +0x4204 GA_POINT_T0 +0x4208 GA_POINT_S1 +0x420C GA_POINT_T1 +0x4214 GA_TRIANGLE_STIPPLE +0x421C GA_POINT_SIZE +0x4230 GA_POINT_MINMAX +0x4234 GA_LINE_CNTL +0x4238 GA_LINE_STIPPLE_CONFIG +0x4260 GA_LINE_STIPPLE_VALUE +0x4264 GA_LINE_S0 +0x4268 GA_LINE_S1 +0x4278 GA_COLOR_CONTROL +0x427C GA_SOLID_RG +0x4280 GA_SOLID_BA +0x4288 GA_POLY_MODE +0x428C GA_ROUND_MODE +0x4290 GA_OFFSET +0x4294 GA_FOG_SCALE +0x4298 GA_FOG_OFFSET +0x42A0 SU_TEX_WRAP +0x42A4 SU_POLY_OFFSET_FRONT_SCALE +0x42A8 SU_POLY_OFFSET_FRONT_OFFSET +0x42AC SU_POLY_OFFSET_BACK_SCALE +0x42B0 SU_POLY_OFFSET_BACK_OFFSET +0x42B4 SU_POLY_OFFSET_ENABLE +0x42B8 SU_CULL_MODE +0x42C0 SU_DEPTH_SCALE +0x42C4 SU_DEPTH_OFFSET +0x42C8 SU_REG_DEST +0x4300 RS_COUNT +0x4304 RS_INST_COUNT +0x4310 RS_IP_0 +0x4314 RS_IP_1 +0x4318 RS_IP_2 +0x431C RS_IP_3 +0x4320 RS_IP_4 +0x4324 RS_IP_5 +0x4328 RS_IP_6 +0x432C RS_IP_7 +0x4330 RS_INST_0 +0x4334 RS_INST_1 +0x4338 RS_INST_2 +0x433C RS_INST_3 +0x4340 RS_INST_4 +0x4344 RS_INST_5 +0x4348 RS_INST_6 +0x434C RS_INST_7 +0x4350 RS_INST_8 +0x4354 RS_INST_9 +0x4358 RS_INST_10 +0x435C RS_INST_11 +0x4360 RS_INST_12 +0x4364 RS_INST_13 +0x4368 RS_INST_14 +0x436C RS_INST_15 +0x43A4 SC_HYPERZ_EN +0x43A8 SC_EDGERULE +0x43B0 SC_CLIP_0_A +0x43B4 SC_CLIP_0_B +0x43B8 SC_CLIP_1_A +0x43BC SC_CLIP_1_B +0x43C0 SC_CLIP_2_A +0x43C4 SC_CLIP_2_B +0x43C8 SC_CLIP_3_A +0x43CC SC_CLIP_3_B +0x43D0 SC_CLIP_RULE +0x43E0 SC_SCISSOR0 +0x43E8 SC_SCREENDOOR +0x4440 TX_FILTER1_0 +0x4444 TX_FILTER1_1 +0x4448 TX_FILTER1_2 +0x444C TX_FILTER1_3 +0x4450 TX_FILTER1_4 +0x4454 TX_FILTER1_5 +0x4458 TX_FILTER1_6 +0x445C TX_FILTER1_7 +0x4460 TX_FILTER1_8 +0x4464 TX_FILTER1_9 +0x4468 TX_FILTER1_10 +0x446C TX_FILTER1_11 +0x4470 TX_FILTER1_12 +0x4474 TX_FILTER1_13 +0x4478 TX_FILTER1_14 +0x447C TX_FILTER1_15 +0x4580 TX_CHROMA_KEY_0 +0x4584 TX_CHROMA_KEY_1 +0x4588 TX_CHROMA_KEY_2 +0x458C TX_CHROMA_KEY_3 +0x4590 TX_CHROMA_KEY_4 +0x4594 TX_CHROMA_KEY_5 +0x4598 TX_CHROMA_KEY_6 +0x459C TX_CHROMA_KEY_7 +0x45A0 TX_CHROMA_KEY_8 +0x45A4 TX_CHROMA_KEY_9 +0x45A8 TX_CHROMA_KEY_10 +0x45AC TX_CHROMA_KEY_11 +0x45B0 TX_CHROMA_KEY_12 +0x45B4 TX_CHROMA_KEY_13 +0x45B8 TX_CHROMA_KEY_14 +0x45BC TX_CHROMA_KEY_15 +0x45C0 TX_BORDER_COLOR_0 +0x45C4 TX_BORDER_COLOR_1 +0x45C8 TX_BORDER_COLOR_2 +0x45CC TX_BORDER_COLOR_3 +0x45D0 TX_BORDER_COLOR_4 +0x45D4 TX_BORDER_COLOR_5 +0x45D8 TX_BORDER_COLOR_6 +0x45DC TX_BORDER_COLOR_7 +0x45E0 TX_BORDER_COLOR_8 +0x45E4 TX_BORDER_COLOR_9 +0x45E8 TX_BORDER_COLOR_10 +0x45EC TX_BORDER_COLOR_11 +0x45F0 TX_BORDER_COLOR_12 +0x45F4 TX_BORDER_COLOR_13 +0x45F8 TX_BORDER_COLOR_14 +0x45FC TX_BORDER_COLOR_15 +0x4600 US_CONFIG +0x4604 US_PIXSIZE +0x4608 US_CODE_OFFSET +0x460C US_RESET +0x4610 US_CODE_ADDR_0 +0x4614 US_CODE_ADDR_1 +0x4618 US_CODE_ADDR_2 +0x461C US_CODE_ADDR_3 +0x4620 US_TEX_INST_0 +0x4624 US_TEX_INST_1 +0x4628 US_TEX_INST_2 +0x462C US_TEX_INST_3 +0x4630 US_TEX_INST_4 +0x4634 US_TEX_INST_5 +0x4638 US_TEX_INST_6 +0x463C US_TEX_INST_7 +0x4640 US_TEX_INST_8 +0x4644 US_TEX_INST_9 +0x4648 US_TEX_INST_10 +0x464C US_TEX_INST_11 +0x4650 US_TEX_INST_12 +0x4654 US_TEX_INST_13 +0x4658 US_TEX_INST_14 +0x465C US_TEX_INST_15 +0x4660 US_TEX_INST_16 +0x4664 US_TEX_INST_17 +0x4668 US_TEX_INST_18 +0x466C US_TEX_INST_19 +0x4670 US_TEX_INST_20 +0x4674 US_TEX_INST_21 +0x4678 US_TEX_INST_22 +0x467C US_TEX_INST_23 +0x4680 US_TEX_INST_24 +0x4684 US_TEX_INST_25 +0x4688 US_TEX_INST_26 +0x468C US_TEX_INST_27 +0x4690 US_TEX_INST_28 +0x4694 US_TEX_INST_29 +0x4698 US_TEX_INST_30 +0x469C US_TEX_INST_31 +0x46A4 US_OUT_FMT_0 +0x46A8 US_OUT_FMT_1 +0x46AC US_OUT_FMT_2 +0x46B0 US_OUT_FMT_3 +0x46B4 US_W_FMT +0x46B8 US_CODE_BANK +0x46BC US_CODE_EXT +0x46C0 US_ALU_RGB_ADDR_0 +0x46C4 US_ALU_RGB_ADDR_1 +0x46C8 US_ALU_RGB_ADDR_2 +0x46CC US_ALU_RGB_ADDR_3 +0x46D0 US_ALU_RGB_ADDR_4 +0x46D4 US_ALU_RGB_ADDR_5 +0x46D8 US_ALU_RGB_ADDR_6 +0x46DC US_ALU_RGB_ADDR_7 +0x46E0 US_ALU_RGB_ADDR_8 +0x46E4 US_ALU_RGB_ADDR_9 +0x46E8 US_ALU_RGB_ADDR_10 +0x46EC US_ALU_RGB_ADDR_11 +0x46F0 US_ALU_RGB_ADDR_12 +0x46F4 US_ALU_RGB_ADDR_13 +0x46F8 US_ALU_RGB_ADDR_14 +0x46FC US_ALU_RGB_ADDR_15 +0x4700 US_ALU_RGB_ADDR_16 +0x4704 US_ALU_RGB_ADDR_17 +0x4708 US_ALU_RGB_ADDR_18 +0x470C US_ALU_RGB_ADDR_19 +0x4710 US_ALU_RGB_ADDR_20 +0x4714 US_ALU_RGB_ADDR_21 +0x4718 US_ALU_RGB_ADDR_22 +0x471C US_ALU_RGB_ADDR_23 +0x4720 US_ALU_RGB_ADDR_24 +0x4724 US_ALU_RGB_ADDR_25 +0x4728 US_ALU_RGB_ADDR_26 +0x472C US_ALU_RGB_ADDR_27 +0x4730 US_ALU_RGB_ADDR_28 +0x4734 US_ALU_RGB_ADDR_29 +0x4738 US_ALU_RGB_ADDR_30 +0x473C US_ALU_RGB_ADDR_31 +0x4740 US_ALU_RGB_ADDR_32 +0x4744 US_ALU_RGB_ADDR_33 +0x4748 US_ALU_RGB_ADDR_34 +0x474C US_ALU_RGB_ADDR_35 +0x4750 US_ALU_RGB_ADDR_36 +0x4754 US_ALU_RGB_ADDR_37 +0x4758 US_ALU_RGB_ADDR_38 +0x475C US_ALU_RGB_ADDR_39 +0x4760 US_ALU_RGB_ADDR_40 +0x4764 US_ALU_RGB_ADDR_41 +0x4768 US_ALU_RGB_ADDR_42 +0x476C US_ALU_RGB_ADDR_43 +0x4770 US_ALU_RGB_ADDR_44 +0x4774 US_ALU_RGB_ADDR_45 +0x4778 US_ALU_RGB_ADDR_46 +0x477C US_ALU_RGB_ADDR_47 +0x4780 US_ALU_RGB_ADDR_48 +0x4784 US_ALU_RGB_ADDR_49 +0x4788 US_ALU_RGB_ADDR_50 +0x478C US_ALU_RGB_ADDR_51 +0x4790 US_ALU_RGB_ADDR_52 +0x4794 US_ALU_RGB_ADDR_53 +0x4798 US_ALU_RGB_ADDR_54 +0x479C US_ALU_RGB_ADDR_55 +0x47A0 US_ALU_RGB_ADDR_56 +0x47A4 US_ALU_RGB_ADDR_57 +0x47A8 US_ALU_RGB_ADDR_58 +0x47AC US_ALU_RGB_ADDR_59 +0x47B0 US_ALU_RGB_ADDR_60 +0x47B4 US_ALU_RGB_ADDR_61 +0x47B8 US_ALU_RGB_ADDR_62 +0x47BC US_ALU_RGB_ADDR_63 +0x47C0 US_ALU_ALPHA_ADDR_0 +0x47C4 US_ALU_ALPHA_ADDR_1 +0x47C8 US_ALU_ALPHA_ADDR_2 +0x47CC US_ALU_ALPHA_ADDR_3 +0x47D0 US_ALU_ALPHA_ADDR_4 +0x47D4 US_ALU_ALPHA_ADDR_5 +0x47D8 US_ALU_ALPHA_ADDR_6 +0x47DC US_ALU_ALPHA_ADDR_7 +0x47E0 US_ALU_ALPHA_ADDR_8 +0x47E4 US_ALU_ALPHA_ADDR_9 +0x47E8 US_ALU_ALPHA_ADDR_10 +0x47EC US_ALU_ALPHA_ADDR_11 +0x47F0 US_ALU_ALPHA_ADDR_12 +0x47F4 US_ALU_ALPHA_ADDR_13 +0x47F8 US_ALU_ALPHA_ADDR_14 +0x47FC US_ALU_ALPHA_ADDR_15 +0x4800 US_ALU_ALPHA_ADDR_16 +0x4804 US_ALU_ALPHA_ADDR_17 +0x4808 US_ALU_ALPHA_ADDR_18 +0x480C US_ALU_ALPHA_ADDR_19 +0x4810 US_ALU_ALPHA_ADDR_20 +0x4814 US_ALU_ALPHA_ADDR_21 +0x4818 US_ALU_ALPHA_ADDR_22 +0x481C US_ALU_ALPHA_ADDR_23 +0x4820 US_ALU_ALPHA_ADDR_24 +0x4824 US_ALU_ALPHA_ADDR_25 +0x4828 US_ALU_ALPHA_ADDR_26 +0x482C US_ALU_ALPHA_ADDR_27 +0x4830 US_ALU_ALPHA_ADDR_28 +0x4834 US_ALU_ALPHA_ADDR_29 +0x4838 US_ALU_ALPHA_ADDR_30 +0x483C US_ALU_ALPHA_ADDR_31 +0x4840 US_ALU_ALPHA_ADDR_32 +0x4844 US_ALU_ALPHA_ADDR_33 +0x4848 US_ALU_ALPHA_ADDR_34 +0x484C US_ALU_ALPHA_ADDR_35 +0x4850 US_ALU_ALPHA_ADDR_36 +0x4854 US_ALU_ALPHA_ADDR_37 +0x4858 US_ALU_ALPHA_ADDR_38 +0x485C US_ALU_ALPHA_ADDR_39 +0x4860 US_ALU_ALPHA_ADDR_40 +0x4864 US_ALU_ALPHA_ADDR_41 +0x4868 US_ALU_ALPHA_ADDR_42 +0x486C US_ALU_ALPHA_ADDR_43 +0x4870 US_ALU_ALPHA_ADDR_44 +0x4874 US_ALU_ALPHA_ADDR_45 +0x4878 US_ALU_ALPHA_ADDR_46 +0x487C US_ALU_ALPHA_ADDR_47 +0x4880 US_ALU_ALPHA_ADDR_48 +0x4884 US_ALU_ALPHA_ADDR_49 +0x4888 US_ALU_ALPHA_ADDR_50 +0x488C US_ALU_ALPHA_ADDR_51 +0x4890 US_ALU_ALPHA_ADDR_52 +0x4894 US_ALU_ALPHA_ADDR_53 +0x4898 US_ALU_ALPHA_ADDR_54 +0x489C US_ALU_ALPHA_ADDR_55 +0x48A0 US_ALU_ALPHA_ADDR_56 +0x48A4 US_ALU_ALPHA_ADDR_57 +0x48A8 US_ALU_ALPHA_ADDR_58 +0x48AC US_ALU_ALPHA_ADDR_59 +0x48B0 US_ALU_ALPHA_ADDR_60 +0x48B4 US_ALU_ALPHA_ADDR_61 +0x48B8 US_ALU_ALPHA_ADDR_62 +0x48BC US_ALU_ALPHA_ADDR_63 +0x48C0 US_ALU_RGB_INST_0 +0x48C4 US_ALU_RGB_INST_1 +0x48C8 US_ALU_RGB_INST_2 +0x48CC US_ALU_RGB_INST_3 +0x48D0 US_ALU_RGB_INST_4 +0x48D4 US_ALU_RGB_INST_5 +0x48D8 US_ALU_RGB_INST_6 +0x48DC US_ALU_RGB_INST_7 +0x48E0 US_ALU_RGB_INST_8 +0x48E4 US_ALU_RGB_INST_9 +0x48E8 US_ALU_RGB_INST_10 +0x48EC US_ALU_RGB_INST_11 +0x48F0 US_ALU_RGB_INST_12 +0x48F4 US_ALU_RGB_INST_13 +0x48F8 US_ALU_RGB_INST_14 +0x48FC US_ALU_RGB_INST_15 +0x4900 US_ALU_RGB_INST_16 +0x4904 US_ALU_RGB_INST_17 +0x4908 US_ALU_RGB_INST_18 +0x490C US_ALU_RGB_INST_19 +0x4910 US_ALU_RGB_INST_20 +0x4914 US_ALU_RGB_INST_21 +0x4918 US_ALU_RGB_INST_22 +0x491C US_ALU_RGB_INST_23 +0x4920 US_ALU_RGB_INST_24 +0x4924 US_ALU_RGB_INST_25 +0x4928 US_ALU_RGB_INST_26 +0x492C US_ALU_RGB_INST_27 +0x4930 US_ALU_RGB_INST_28 +0x4934 US_ALU_RGB_INST_29 +0x4938 US_ALU_RGB_INST_30 +0x493C US_ALU_RGB_INST_31 +0x4940 US_ALU_RGB_INST_32 +0x4944 US_ALU_RGB_INST_33 +0x4948 US_ALU_RGB_INST_34 +0x494C US_ALU_RGB_INST_35 +0x4950 US_ALU_RGB_INST_36 +0x4954 US_ALU_RGB_INST_37 +0x4958 US_ALU_RGB_INST_38 +0x495C US_ALU_RGB_INST_39 +0x4960 US_ALU_RGB_INST_40 +0x4964 US_ALU_RGB_INST_41 +0x4968 US_ALU_RGB_INST_42 +0x496C US_ALU_RGB_INST_43 +0x4970 US_ALU_RGB_INST_44 +0x4974 US_ALU_RGB_INST_45 +0x4978 US_ALU_RGB_INST_46 +0x497C US_ALU_RGB_INST_47 +0x4980 US_ALU_RGB_INST_48 +0x4984 US_ALU_RGB_INST_49 +0x4988 US_ALU_RGB_INST_50 +0x498C US_ALU_RGB_INST_51 +0x4990 US_ALU_RGB_INST_52 +0x4994 US_ALU_RGB_INST_53 +0x4998 US_ALU_RGB_INST_54 +0x499C US_ALU_RGB_INST_55 +0x49A0 US_ALU_RGB_INST_56 +0x49A4 US_ALU_RGB_INST_57 +0x49A8 US_ALU_RGB_INST_58 +0x49AC US_ALU_RGB_INST_59 +0x49B0 US_ALU_RGB_INST_60 +0x49B4 US_ALU_RGB_INST_61 +0x49B8 US_ALU_RGB_INST_62 +0x49BC US_ALU_RGB_INST_63 +0x49C0 US_ALU_ALPHA_INST_0 +0x49C4 US_ALU_ALPHA_INST_1 +0x49C8 US_ALU_ALPHA_INST_2 +0x49CC US_ALU_ALPHA_INST_3 +0x49D0 US_ALU_ALPHA_INST_4 +0x49D4 US_ALU_ALPHA_INST_5 +0x49D8 US_ALU_ALPHA_INST_6 +0x49DC US_ALU_ALPHA_INST_7 +0x49E0 US_ALU_ALPHA_INST_8 +0x49E4 US_ALU_ALPHA_INST_9 +0x49E8 US_ALU_ALPHA_INST_10 +0x49EC US_ALU_ALPHA_INST_11 +0x49F0 US_ALU_ALPHA_INST_12 +0x49F4 US_ALU_ALPHA_INST_13 +0x49F8 US_ALU_ALPHA_INST_14 +0x49FC US_ALU_ALPHA_INST_15 +0x4A00 US_ALU_ALPHA_INST_16 +0x4A04 US_ALU_ALPHA_INST_17 +0x4A08 US_ALU_ALPHA_INST_18 +0x4A0C US_ALU_ALPHA_INST_19 +0x4A10 US_ALU_ALPHA_INST_20 +0x4A14 US_ALU_ALPHA_INST_21 +0x4A18 US_ALU_ALPHA_INST_22 +0x4A1C US_ALU_ALPHA_INST_23 +0x4A20 US_ALU_ALPHA_INST_24 +0x4A24 US_ALU_ALPHA_INST_25 +0x4A28 US_ALU_ALPHA_INST_26 +0x4A2C US_ALU_ALPHA_INST_27 +0x4A30 US_ALU_ALPHA_INST_28 +0x4A34 US_ALU_ALPHA_INST_29 +0x4A38 US_ALU_ALPHA_INST_30 +0x4A3C US_ALU_ALPHA_INST_31 +0x4A40 US_ALU_ALPHA_INST_32 +0x4A44 US_ALU_ALPHA_INST_33 +0x4A48 US_ALU_ALPHA_INST_34 +0x4A4C US_ALU_ALPHA_INST_35 +0x4A50 US_ALU_ALPHA_INST_36 +0x4A54 US_ALU_ALPHA_INST_37 +0x4A58 US_ALU_ALPHA_INST_38 +0x4A5C US_ALU_ALPHA_INST_39 +0x4A60 US_ALU_ALPHA_INST_40 +0x4A64 US_ALU_ALPHA_INST_41 +0x4A68 US_ALU_ALPHA_INST_42 +0x4A6C US_ALU_ALPHA_INST_43 +0x4A70 US_ALU_ALPHA_INST_44 +0x4A74 US_ALU_ALPHA_INST_45 +0x4A78 US_ALU_ALPHA_INST_46 +0x4A7C US_ALU_ALPHA_INST_47 +0x4A80 US_ALU_ALPHA_INST_48 +0x4A84 US_ALU_ALPHA_INST_49 +0x4A88 US_ALU_ALPHA_INST_50 +0x4A8C US_ALU_ALPHA_INST_51 +0x4A90 US_ALU_ALPHA_INST_52 +0x4A94 US_ALU_ALPHA_INST_53 +0x4A98 US_ALU_ALPHA_INST_54 +0x4A9C US_ALU_ALPHA_INST_55 +0x4AA0 US_ALU_ALPHA_INST_56 +0x4AA4 US_ALU_ALPHA_INST_57 +0x4AA8 US_ALU_ALPHA_INST_58 +0x4AAC US_ALU_ALPHA_INST_59 +0x4AB0 US_ALU_ALPHA_INST_60 +0x4AB4 US_ALU_ALPHA_INST_61 +0x4AB8 US_ALU_ALPHA_INST_62 +0x4ABC US_ALU_ALPHA_INST_63 +0x4AC0 US_ALU_EXT_ADDR_0 +0x4AC4 US_ALU_EXT_ADDR_1 +0x4AC8 US_ALU_EXT_ADDR_2 +0x4ACC US_ALU_EXT_ADDR_3 +0x4AD0 US_ALU_EXT_ADDR_4 +0x4AD4 US_ALU_EXT_ADDR_5 +0x4AD8 US_ALU_EXT_ADDR_6 +0x4ADC US_ALU_EXT_ADDR_7 +0x4AE0 US_ALU_EXT_ADDR_8 +0x4AE4 US_ALU_EXT_ADDR_9 +0x4AE8 US_ALU_EXT_ADDR_10 +0x4AEC US_ALU_EXT_ADDR_11 +0x4AF0 US_ALU_EXT_ADDR_12 +0x4AF4 US_ALU_EXT_ADDR_13 +0x4AF8 US_ALU_EXT_ADDR_14 +0x4AFC US_ALU_EXT_ADDR_15 +0x4B00 US_ALU_EXT_ADDR_16 +0x4B04 US_ALU_EXT_ADDR_17 +0x4B08 US_ALU_EXT_ADDR_18 +0x4B0C US_ALU_EXT_ADDR_19 +0x4B10 US_ALU_EXT_ADDR_20 +0x4B14 US_ALU_EXT_ADDR_21 +0x4B18 US_ALU_EXT_ADDR_22 +0x4B1C US_ALU_EXT_ADDR_23 +0x4B20 US_ALU_EXT_ADDR_24 +0x4B24 US_ALU_EXT_ADDR_25 +0x4B28 US_ALU_EXT_ADDR_26 +0x4B2C US_ALU_EXT_ADDR_27 +0x4B30 US_ALU_EXT_ADDR_28 +0x4B34 US_ALU_EXT_ADDR_29 +0x4B38 US_ALU_EXT_ADDR_30 +0x4B3C US_ALU_EXT_ADDR_31 +0x4B40 US_ALU_EXT_ADDR_32 +0x4B44 US_ALU_EXT_ADDR_33 +0x4B48 US_ALU_EXT_ADDR_34 +0x4B4C US_ALU_EXT_ADDR_35 +0x4B50 US_ALU_EXT_ADDR_36 +0x4B54 US_ALU_EXT_ADDR_37 +0x4B58 US_ALU_EXT_ADDR_38 +0x4B5C US_ALU_EXT_ADDR_39 +0x4B60 US_ALU_EXT_ADDR_40 +0x4B64 US_ALU_EXT_ADDR_41 +0x4B68 US_ALU_EXT_ADDR_42 +0x4B6C US_ALU_EXT_ADDR_43 +0x4B70 US_ALU_EXT_ADDR_44 +0x4B74 US_ALU_EXT_ADDR_45 +0x4B78 US_ALU_EXT_ADDR_46 +0x4B7C US_ALU_EXT_ADDR_47 +0x4B80 US_ALU_EXT_ADDR_48 +0x4B84 US_ALU_EXT_ADDR_49 +0x4B88 US_ALU_EXT_ADDR_50 +0x4B8C US_ALU_EXT_ADDR_51 +0x4B90 US_ALU_EXT_ADDR_52 +0x4B94 US_ALU_EXT_ADDR_53 +0x4B98 US_ALU_EXT_ADDR_54 +0x4B9C US_ALU_EXT_ADDR_55 +0x4BA0 US_ALU_EXT_ADDR_56 +0x4BA4 US_ALU_EXT_ADDR_57 +0x4BA8 US_ALU_EXT_ADDR_58 +0x4BAC US_ALU_EXT_ADDR_59 +0x4BB0 US_ALU_EXT_ADDR_60 +0x4BB4 US_ALU_EXT_ADDR_61 +0x4BB8 US_ALU_EXT_ADDR_62 +0x4BBC US_ALU_EXT_ADDR_63 +0x4BC0 FG_FOG_BLEND +0x4BC4 FG_FOG_FACTOR +0x4BC8 FG_FOG_COLOR_R +0x4BCC FG_FOG_COLOR_G +0x4BD0 FG_FOG_COLOR_B +0x4BD4 FG_ALPHA_FUNC +0x4BD8 FG_DEPTH_SRC +0x4C00 US_ALU_CONST_R_0 +0x4C04 US_ALU_CONST_G_0 +0x4C08 US_ALU_CONST_B_0 +0x4C0C US_ALU_CONST_A_0 +0x4C10 US_ALU_CONST_R_1 +0x4C14 US_ALU_CONST_G_1 +0x4C18 US_ALU_CONST_B_1 +0x4C1C US_ALU_CONST_A_1 +0x4C20 US_ALU_CONST_R_2 +0x4C24 US_ALU_CONST_G_2 +0x4C28 US_ALU_CONST_B_2 +0x4C2C US_ALU_CONST_A_2 +0x4C30 US_ALU_CONST_R_3 +0x4C34 US_ALU_CONST_G_3 +0x4C38 US_ALU_CONST_B_3 +0x4C3C US_ALU_CONST_A_3 +0x4C40 US_ALU_CONST_R_4 +0x4C44 US_ALU_CONST_G_4 +0x4C48 US_ALU_CONST_B_4 +0x4C4C US_ALU_CONST_A_4 +0x4C50 US_ALU_CONST_R_5 +0x4C54 US_ALU_CONST_G_5 +0x4C58 US_ALU_CONST_B_5 +0x4C5C US_ALU_CONST_A_5 +0x4C60 US_ALU_CONST_R_6 +0x4C64 US_ALU_CONST_G_6 +0x4C68 US_ALU_CONST_B_6 +0x4C6C US_ALU_CONST_A_6 +0x4C70 US_ALU_CONST_R_7 +0x4C74 US_ALU_CONST_G_7 +0x4C78 US_ALU_CONST_B_7 +0x4C7C US_ALU_CONST_A_7 +0x4C80 US_ALU_CONST_R_8 +0x4C84 US_ALU_CONST_G_8 +0x4C88 US_ALU_CONST_B_8 +0x4C8C US_ALU_CONST_A_8 +0x4C90 US_ALU_CONST_R_9 +0x4C94 US_ALU_CONST_G_9 +0x4C98 US_ALU_CONST_B_9 +0x4C9C US_ALU_CONST_A_9 +0x4CA0 US_ALU_CONST_R_10 +0x4CA4 US_ALU_CONST_G_10 +0x4CA8 US_ALU_CONST_B_10 +0x4CAC US_ALU_CONST_A_10 +0x4CB0 US_ALU_CONST_R_11 +0x4CB4 US_ALU_CONST_G_11 +0x4CB8 US_ALU_CONST_B_11 +0x4CBC US_ALU_CONST_A_11 +0x4CC0 US_ALU_CONST_R_12 +0x4CC4 US_ALU_CONST_G_12 +0x4CC8 US_ALU_CONST_B_12 +0x4CCC US_ALU_CONST_A_12 +0x4CD0 US_ALU_CONST_R_13 +0x4CD4 US_ALU_CONST_G_13 +0x4CD8 US_ALU_CONST_B_13 +0x4CDC US_ALU_CONST_A_13 +0x4CE0 US_ALU_CONST_R_14 +0x4CE4 US_ALU_CONST_G_14 +0x4CE8 US_ALU_CONST_B_14 +0x4CEC US_ALU_CONST_A_14 +0x4CF0 US_ALU_CONST_R_15 +0x4CF4 US_ALU_CONST_G_15 +0x4CF8 US_ALU_CONST_B_15 +0x4CFC US_ALU_CONST_A_15 +0x4D00 US_ALU_CONST_R_16 +0x4D04 US_ALU_CONST_G_16 +0x4D08 US_ALU_CONST_B_16 +0x4D0C US_ALU_CONST_A_16 +0x4D10 US_ALU_CONST_R_17 +0x4D14 US_ALU_CONST_G_17 +0x4D18 US_ALU_CONST_B_17 +0x4D1C US_ALU_CONST_A_17 +0x4D20 US_ALU_CONST_R_18 +0x4D24 US_ALU_CONST_G_18 +0x4D28 US_ALU_CONST_B_18 +0x4D2C US_ALU_CONST_A_18 +0x4D30 US_ALU_CONST_R_19 +0x4D34 US_ALU_CONST_G_19 +0x4D38 US_ALU_CONST_B_19 +0x4D3C US_ALU_CONST_A_19 +0x4D40 US_ALU_CONST_R_20 +0x4D44 US_ALU_CONST_G_20 +0x4D48 US_ALU_CONST_B_20 +0x4D4C US_ALU_CONST_A_20 +0x4D50 US_ALU_CONST_R_21 +0x4D54 US_ALU_CONST_G_21 +0x4D58 US_ALU_CONST_B_21 +0x4D5C US_ALU_CONST_A_21 +0x4D60 US_ALU_CONST_R_22 +0x4D64 US_ALU_CONST_G_22 +0x4D68 US_ALU_CONST_B_22 +0x4D6C US_ALU_CONST_A_22 +0x4D70 US_ALU_CONST_R_23 +0x4D74 US_ALU_CONST_G_23 +0x4D78 US_ALU_CONST_B_23 +0x4D7C US_ALU_CONST_A_23 +0x4D80 US_ALU_CONST_R_24 +0x4D84 US_ALU_CONST_G_24 +0x4D88 US_ALU_CONST_B_24 +0x4D8C US_ALU_CONST_A_24 +0x4D90 US_ALU_CONST_R_25 +0x4D94 US_ALU_CONST_G_25 +0x4D98 US_ALU_CONST_B_25 +0x4D9C US_ALU_CONST_A_25 +0x4DA0 US_ALU_CONST_R_26 +0x4DA4 US_ALU_CONST_G_26 +0x4DA8 US_ALU_CONST_B_26 +0x4DAC US_ALU_CONST_A_26 +0x4DB0 US_ALU_CONST_R_27 +0x4DB4 US_ALU_CONST_G_27 +0x4DB8 US_ALU_CONST_B_27 +0x4DBC US_ALU_CONST_A_27 +0x4DC0 US_ALU_CONST_R_28 +0x4DC4 US_ALU_CONST_G_28 +0x4DC8 US_ALU_CONST_B_28 +0x4DCC US_ALU_CONST_A_28 +0x4DD0 US_ALU_CONST_R_29 +0x4DD4 US_ALU_CONST_G_29 +0x4DD8 US_ALU_CONST_B_29 +0x4DDC US_ALU_CONST_A_29 +0x4DE0 US_ALU_CONST_R_30 +0x4DE4 US_ALU_CONST_G_30 +0x4DE8 US_ALU_CONST_B_30 +0x4DEC US_ALU_CONST_A_30 +0x4DF0 US_ALU_CONST_R_31 +0x4DF4 US_ALU_CONST_G_31 +0x4DF8 US_ALU_CONST_B_31 +0x4DFC US_ALU_CONST_A_31 +0x4E04 RB3D_BLENDCNTL_R3 +0x4E08 RB3D_ABLENDCNTL_R3 +0x4E0C RB3D_COLOR_CHANNEL_MASK +0x4E10 RB3D_CONSTANT_COLOR +0x4E14 RB3D_COLOR_CLEAR_VALUE +0x4E18 RB3D_ROPCNTL_R3 +0x4E1C RB3D_CLRCMP_FLIPE_R3 +0x4E20 RB3D_CLRCMP_CLR_R3 +0x4E24 RB3D_CLRCMP_MSK_R3 +0x4E48 RB3D_DEBUG_CTL +0x4E4C RB3D_DSTCACHE_CTLSTAT_R3 +0x4E50 RB3D_DITHER_CTL +0x4E54 RB3D_CMASK_OFFSET0 +0x4E58 RB3D_CMASK_OFFSET1 +0x4E5C RB3D_CMASK_OFFSET2 +0x4E60 RB3D_CMASK_OFFSET3 +0x4E64 RB3D_CMASK_PITCH0 +0x4E68 RB3D_CMASK_PITCH1 +0x4E6C RB3D_CMASK_PITCH2 +0x4E70 RB3D_CMASK_PITCH3 +0x4E74 RB3D_CMASK_WRINDEX +0x4E78 RB3D_CMASK_DWORD +0x4E7C RB3D_CMASK_RDINDEX +0x4E80 RB3D_AARESOLVE_OFFSET +0x4E84 RB3D_AARESOLVE_PITCH +0x4E88 RB3D_AARESOLVE_CTL +0x4EA0 RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD +0x4EA4 RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD +0x4F04 ZB_ZSTENCILCNTL +0x4F08 ZB_STENCILREFMASK +0x4F14 ZB_ZTOP +0x4F18 ZB_ZCACHE_CTLSTAT +0x4F1C ZB_BW_CNTL +0x4F28 ZB_DEPTHCLEARVALUE +0x4F30 ZB_ZMASK_OFFSET +0x4F34 ZB_ZMASK_PITCH +0x4F38 ZB_ZMASK_WRINDEX +0x4F3C ZB_ZMASK_DWORD +0x4F40 ZB_ZMASK_RDINDEX +0x4F44 ZB_HIZ_OFFSET +0x4F48 ZB_HIZ_WRINDEX +0x4F4C ZB_HIZ_DWORD +0x4F50 ZB_HIZ_RDINDEX +0x4F54 ZB_HIZ_PITCH +0x4F58 ZB_ZPASS_DATA diff --git a/drivers/gpu/drm/radeon/reg_srcs/rs600 b/drivers/gpu/drm/radeon/reg_srcs/rs600 index 8e3c0b8..6801b86 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/rs600 +++ b/drivers/gpu/drm/radeon/reg_srcs/rs600 @@ -153,7 +153,7 @@ rs600 0x6d40 0x42A4 SU_POLY_OFFSET_FRONT_SCALE 0x42A8 SU_POLY_OFFSET_FRONT_OFFSET 0x42AC SU_POLY_OFFSET_BACK_SCALE -0x42B0 SU_POLY_OFFSET_BACK_OFFSET +0x42B0 SU_POLY_OFFSET_BACK_OFFSET 0x42B4 SU_POLY_OFFSET_ENABLE 0x42B8 SU_CULL_MODE 0x42C0 SU_DEPTH_SCALE @@ -291,6 +291,8 @@ rs600 0x6d40 0x46AC US_OUT_FMT_2 0x46B0 US_OUT_FMT_3 0x46B4 US_W_FMT +0x46B8 US_CODE_BANK +0x46BC US_CODE_EXT 0x46C0 US_ALU_RGB_ADDR_0 0x46C4 US_ALU_RGB_ADDR_1 0x46C8 US_ALU_RGB_ADDR_2 @@ -547,6 +549,70 @@ rs600 0x6d40 0x4AB4 US_ALU_ALPHA_INST_61 0x4AB8 US_ALU_ALPHA_INST_62 0x4ABC US_ALU_ALPHA_INST_63 +0x4AC0 US_ALU_EXT_ADDR_0 +0x4AC4 US_ALU_EXT_ADDR_1 +0x4AC8 US_ALU_EXT_ADDR_2 +0x4ACC US_ALU_EXT_ADDR_3 +0x4AD0 US_ALU_EXT_ADDR_4 +0x4AD4 US_ALU_EXT_ADDR_5 +0x4AD8 US_ALU_EXT_ADDR_6 +0x4ADC US_ALU_EXT_ADDR_7 +0x4AE0 US_ALU_EXT_ADDR_8 +0x4AE4 US_ALU_EXT_ADDR_9 +0x4AE8 US_ALU_EXT_ADDR_10 +0x4AEC US_ALU_EXT_ADDR_11 +0x4AF0 US_ALU_EXT_ADDR_12 +0x4AF4 US_ALU_EXT_ADDR_13 +0x4AF8 US_ALU_EXT_ADDR_14 +0x4AFC US_ALU_EXT_ADDR_15 +0x4B00 US_ALU_EXT_ADDR_16 +0x4B04 US_ALU_EXT_ADDR_17 +0x4B08 US_ALU_EXT_ADDR_18 +0x4B0C US_ALU_EXT_ADDR_19 +0x4B10 US_ALU_EXT_ADDR_20 +0x4B14 US_ALU_EXT_ADDR_21 +0x4B18 US_ALU_EXT_ADDR_22 +0x4B1C US_ALU_EXT_ADDR_23 +0x4B20 US_ALU_EXT_ADDR_24 +0x4B24 US_ALU_EXT_ADDR_25 +0x4B28 US_ALU_EXT_ADDR_26 +0x4B2C US_ALU_EXT_ADDR_27 +0x4B30 US_ALU_EXT_ADDR_28 +0x4B34 US_ALU_EXT_ADDR_29 +0x4B38 US_ALU_EXT_ADDR_30 +0x4B3C US_ALU_EXT_ADDR_31 +0x4B40 US_ALU_EXT_ADDR_32 +0x4B44 US_ALU_EXT_ADDR_33 +0x4B48 US_ALU_EXT_ADDR_34 +0x4B4C US_ALU_EXT_ADDR_35 +0x4B50 US_ALU_EXT_ADDR_36 +0x4B54 US_ALU_EXT_ADDR_37 +0x4B58 US_ALU_EXT_ADDR_38 +0x4B5C US_ALU_EXT_ADDR_39 +0x4B60 US_ALU_EXT_ADDR_40 +0x4B64 US_ALU_EXT_ADDR_41 +0x4B68 US_ALU_EXT_ADDR_42 +0x4B6C US_ALU_EXT_ADDR_43 +0x4B70 US_ALU_EXT_ADDR_44 +0x4B74 US_ALU_EXT_ADDR_45 +0x4B78 US_ALU_EXT_ADDR_46 +0x4B7C US_ALU_EXT_ADDR_47 +0x4B80 US_ALU_EXT_ADDR_48 +0x4B84 US_ALU_EXT_ADDR_49 +0x4B88 US_ALU_EXT_ADDR_50 +0x4B8C US_ALU_EXT_ADDR_51 +0x4B90 US_ALU_EXT_ADDR_52 +0x4B94 US_ALU_EXT_ADDR_53 +0x4B98 US_ALU_EXT_ADDR_54 +0x4B9C US_ALU_EXT_ADDR_55 +0x4BA0 US_ALU_EXT_ADDR_56 +0x4BA4 US_ALU_EXT_ADDR_57 +0x4BA8 US_ALU_EXT_ADDR_58 +0x4BAC US_ALU_EXT_ADDR_59 +0x4BB0 US_ALU_EXT_ADDR_60 +0x4BB4 US_ALU_EXT_ADDR_61 +0x4BB8 US_ALU_EXT_ADDR_62 +0x4BBC US_ALU_EXT_ADDR_63 0x4BC0 FG_FOG_BLEND 0x4BC4 FG_FOG_FACTOR 0x4BC8 FG_FOG_COLOR_R diff --git a/drivers/gpu/drm/radeon/reg_srcs/rv515 b/drivers/gpu/drm/radeon/reg_srcs/rv515 index 0102a0d..38abf63 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/rv515 +++ b/drivers/gpu/drm/radeon/reg_srcs/rv515 @@ -161,7 +161,12 @@ rv515 0x6d40 0x401C GB_SELECT 0x4020 GB_AA_CONFIG 0x4024 GB_FIFO_SIZE +0x4028 GB_Z_PEQ_CONFIG 0x4100 TX_INVALTAGS +0x4114 SU_TEX_WRAP_PS3 +0x4118 PS3_ENABLE +0x411c PS3_VTX_FMT +0x4120 PS3_TEX_SOURCE 0x4200 GA_POINT_S0 0x4204 GA_POINT_T0 0x4208 GA_POINT_S1 @@ -171,6 +176,7 @@ rv515 0x6d40 0x4230 GA_POINT_MINMAX 0x4234 GA_LINE_CNTL 0x4238 GA_LINE_STIPPLE_CONFIG +0x4258 GA_COLOR_CONTROL_PS3 0x4260 GA_LINE_STIPPLE_VALUE 0x4264 GA_LINE_S0 0x4268 GA_LINE_S1 -- cgit v0.10.2 From 89347bb8ef2d0af1ae8d847b7df91e9f04eccf2a Mon Sep 17 00:00:00 2001 From: David John Date: Thu, 31 Dec 2009 12:00:46 +0530 Subject: drm: Keep disabled outputs disabled after suspend / resume With the current DRM code, an output that has been powered off from userspace will automatically power back on when resuming from suspend. This patch fixes this behaviour. Tested only with the Intel i915 driver on an Intel GM45 Express chipset. Signed-off-by: David John Reviewed-by: Jesse Barnes Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 4231d6d..aba79c4 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -216,7 +216,7 @@ bool drm_helper_crtc_in_use(struct drm_crtc *crtc) EXPORT_SYMBOL(drm_helper_crtc_in_use); /** - * drm_disable_unused_functions - disable unused objects + * drm_helper_disable_unused_functions - disable unused objects * @dev: DRM device * * LOCKING: @@ -1162,6 +1162,9 @@ EXPORT_SYMBOL(drm_helper_mode_fill_fb_struct); int drm_helper_resume_force_mode(struct drm_device *dev) { struct drm_crtc *crtc; + struct drm_encoder *encoder; + struct drm_encoder_helper_funcs *encoder_funcs; + struct drm_crtc_helper_funcs *crtc_funcs; int ret; list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { @@ -1174,6 +1177,25 @@ int drm_helper_resume_force_mode(struct drm_device *dev) if (ret == false) DRM_ERROR("failed to set mode on crtc %p\n", crtc); + + /* Turn off outputs that were already powered off */ + if (drm_helper_choose_crtc_dpms(crtc)) { + list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { + + if(encoder->crtc != crtc) + continue; + + encoder_funcs = encoder->helper_private; + if (encoder_funcs->dpms) + (*encoder_funcs->dpms) (encoder, + drm_helper_choose_encoder_dpms(encoder)); + + crtc_funcs = crtc->helper_private; + if (crtc_funcs->dpms) + (*crtc_funcs->dpms) (crtc, + drm_helper_choose_crtc_dpms(crtc)); + } + } } /* disable the unused connectors while restoring the modesetting */ drm_helper_disable_unused_functions(dev); -- cgit v0.10.2 From 509c7d83c3b18a50a0bd02afa43c8ee3c7605bc9 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 8 Jan 2010 09:27:08 +1000 Subject: drm/kms/fb: check for depth changes from userspace for resizing. If userspace (plymouth in this case) asks for a deeper depth, refuse it as well due to lack of resizing. This fixes an issue since < 32MB cards went to 8bpp and plymouth crashes on startup. Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 100ee48..1c2b7d4 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -606,11 +606,10 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo *var, return -EINVAL; /* Need to resize the fb object !!! */ - if (var->xres > fb->width || var->yres > fb->height) { - DRM_ERROR("Requested width/height is greater than current fb " - "object %dx%d > %dx%d\n", var->xres, var->yres, - fb->width, fb->height); - DRM_ERROR("Need resizing code.\n"); + if (var->bits_per_pixel > fb->bits_per_pixel || var->xres > fb->width || var->yres > fb->height) { + DRM_DEBUG("fb userspace requested width/height/bpp is greater than current fb " + "object %dx%d-%d > %dx%d-%d\n", var->xres, var->yres, var->bits_per_pixel, + fb->width, fb->height, fb->bits_per_pixel); return -EINVAL; } -- cgit v0.10.2 From 94fd163d86b049842856864cdeac318131ec576d Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 11 Jan 2010 14:20:55 +1000 Subject: drm: reduce WARN_ON to a printk. Lots of ppl keep thinking this is an oops, it was just a warning for me to see, just make it a printk now. Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index aba79c4..077313f 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -1032,7 +1032,7 @@ bool drm_helper_initial_config(struct drm_device *dev) /* * we shouldn't end up with no modes here. */ - WARN(!count, "No connectors reported connected with modes\n"); + printk(KERN_INFO "No connectors reported conncted with modes\n"); drm_setup_crtcs(dev); -- cgit v0.10.2 From 617e234b01757698ed5f8c9a5fbf12717b76e371 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Sun, 13 Dec 2009 20:07:42 +0100 Subject: drm/nouveau: Add cache_flush/pull fifo engine functions. Signed-off-by: Francisco Jerez diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 5f8cbb7..48d0ad9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -292,6 +292,8 @@ struct nouveau_fifo_engine { void (*disable)(struct drm_device *); void (*enable)(struct drm_device *); bool (*reassign)(struct drm_device *, bool enable); + bool (*cache_flush)(struct drm_device *dev); + bool (*cache_pull)(struct drm_device *dev, bool enable); int (*channel_id)(struct drm_device *); @@ -889,6 +891,8 @@ extern int nv04_fifo_init(struct drm_device *); extern void nv04_fifo_disable(struct drm_device *); extern void nv04_fifo_enable(struct drm_device *); extern bool nv04_fifo_reassign(struct drm_device *, bool); +extern bool nv04_fifo_cache_flush(struct drm_device *); +extern bool nv04_fifo_cache_pull(struct drm_device *, bool); extern int nv04_fifo_channel_id(struct drm_device *); extern int nv04_fifo_create_context(struct nouveau_channel *); extern void nv04_fifo_destroy_context(struct nouveau_channel *); diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index e76ec2d..9f98843 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -76,6 +76,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->fifo.disable = nv04_fifo_disable; engine->fifo.enable = nv04_fifo_enable; engine->fifo.reassign = nv04_fifo_reassign; + engine->fifo.cache_flush = nv04_fifo_cache_flush; + engine->fifo.cache_pull = nv04_fifo_cache_pull; engine->fifo.channel_id = nv04_fifo_channel_id; engine->fifo.create_context = nv04_fifo_create_context; engine->fifo.destroy_context = nv04_fifo_destroy_context; @@ -115,6 +117,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->fifo.disable = nv04_fifo_disable; engine->fifo.enable = nv04_fifo_enable; engine->fifo.reassign = nv04_fifo_reassign; + engine->fifo.cache_flush = nv04_fifo_cache_flush; + engine->fifo.cache_pull = nv04_fifo_cache_pull; engine->fifo.channel_id = nv10_fifo_channel_id; engine->fifo.create_context = nv10_fifo_create_context; engine->fifo.destroy_context = nv10_fifo_destroy_context; @@ -154,6 +158,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->fifo.disable = nv04_fifo_disable; engine->fifo.enable = nv04_fifo_enable; engine->fifo.reassign = nv04_fifo_reassign; + engine->fifo.cache_flush = nv04_fifo_cache_flush; + engine->fifo.cache_pull = nv04_fifo_cache_pull; engine->fifo.channel_id = nv10_fifo_channel_id; engine->fifo.create_context = nv10_fifo_create_context; engine->fifo.destroy_context = nv10_fifo_destroy_context; @@ -193,6 +199,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->fifo.disable = nv04_fifo_disable; engine->fifo.enable = nv04_fifo_enable; engine->fifo.reassign = nv04_fifo_reassign; + engine->fifo.cache_flush = nv04_fifo_cache_flush; + engine->fifo.cache_pull = nv04_fifo_cache_pull; engine->fifo.channel_id = nv10_fifo_channel_id; engine->fifo.create_context = nv10_fifo_create_context; engine->fifo.destroy_context = nv10_fifo_destroy_context; @@ -233,6 +241,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->fifo.disable = nv04_fifo_disable; engine->fifo.enable = nv04_fifo_enable; engine->fifo.reassign = nv04_fifo_reassign; + engine->fifo.cache_flush = nv04_fifo_cache_flush; + engine->fifo.cache_pull = nv04_fifo_cache_pull; engine->fifo.channel_id = nv10_fifo_channel_id; engine->fifo.create_context = nv40_fifo_create_context; engine->fifo.destroy_context = nv40_fifo_destroy_context; diff --git a/drivers/gpu/drm/nouveau/nv04_fifo.c b/drivers/gpu/drm/nouveau/nv04_fifo.c index 0c3cd53..f31347b 100644 --- a/drivers/gpu/drm/nouveau/nv04_fifo.c +++ b/drivers/gpu/drm/nouveau/nv04_fifo.c @@ -71,6 +71,40 @@ nv04_fifo_reassign(struct drm_device *dev, bool enable) return (reassign == 1); } +bool +nv04_fifo_cache_flush(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; + uint64_t start = ptimer->read(dev); + + do { + if (nv_rd32(dev, NV03_PFIFO_CACHE1_GET) == + nv_rd32(dev, NV03_PFIFO_CACHE1_PUT)) + return true; + + } while (ptimer->read(dev) - start < 100000000); + + NV_ERROR(dev, "Timeout flushing the PFIFO cache.\n"); + + return false; +} + +bool +nv04_fifo_cache_pull(struct drm_device *dev, bool enable) +{ + uint32_t pull = nv_rd32(dev, NV04_PFIFO_CACHE1_PULL0); + + if (enable) { + nv_wr32(dev, NV04_PFIFO_CACHE1_PULL0, pull | 1); + } else { + nv_wr32(dev, NV04_PFIFO_CACHE1_PULL0, pull & ~1); + nv_wr32(dev, NV04_PFIFO_CACHE1_HASH, 0); + } + + return !!(pull & 1); +} + int nv04_fifo_channel_id(struct drm_device *dev) { -- cgit v0.10.2 From 0d87c100312ce75d9bb75a456d8a542e84a1722f Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Wed, 16 Dec 2009 12:12:27 +0100 Subject: drm/nouveau: Pre-G80 tiling support. Signed-off-by: Francisco Jerez diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 48d0ad9..446a92a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -277,8 +277,13 @@ struct nouveau_timer_engine { }; struct nouveau_fb_engine { + int num_tiles; + int (*init)(struct drm_device *dev); void (*takedown)(struct drm_device *dev); + + void (*set_region_tiling)(struct drm_device *dev, int i, uint32_t addr, + uint32_t size, uint32_t pitch); }; struct nouveau_fifo_engine { @@ -332,6 +337,9 @@ struct nouveau_pgraph_engine { void (*destroy_context)(struct nouveau_channel *); int (*load_context)(struct nouveau_channel *); int (*unload_context)(struct drm_device *); + + void (*set_region_tiling)(struct drm_device *dev, int i, uint32_t addr, + uint32_t size, uint32_t pitch); }; struct nouveau_engine { @@ -881,10 +889,14 @@ extern void nv04_fb_takedown(struct drm_device *); /* nv10_fb.c */ extern int nv10_fb_init(struct drm_device *); extern void nv10_fb_takedown(struct drm_device *); +extern void nv10_fb_set_region_tiling(struct drm_device *, int, uint32_t, + uint32_t, uint32_t); /* nv40_fb.c */ extern int nv40_fb_init(struct drm_device *); extern void nv40_fb_takedown(struct drm_device *); +extern void nv40_fb_set_region_tiling(struct drm_device *, int, uint32_t, + uint32_t, uint32_t); /* nv04_fifo.c */ extern int nv04_fifo_init(struct drm_device *); @@ -945,6 +957,8 @@ extern void nv10_graph_destroy_context(struct nouveau_channel *); extern int nv10_graph_load_context(struct nouveau_channel *); extern int nv10_graph_unload_context(struct drm_device *); extern void nv10_graph_context_switch(struct drm_device *); +extern void nv10_graph_set_region_tiling(struct drm_device *, int, uint32_t, + uint32_t, uint32_t); /* nv20_graph.c */ extern struct nouveau_pgraph_object_class nv20_graph_grclass[]; @@ -956,6 +970,8 @@ extern int nv20_graph_unload_context(struct drm_device *); extern int nv20_graph_init(struct drm_device *); extern void nv20_graph_takedown(struct drm_device *); extern int nv30_graph_init(struct drm_device *); +extern void nv20_graph_set_region_tiling(struct drm_device *, int, uint32_t, + uint32_t, uint32_t); /* nv40_graph.c */ extern struct nouveau_pgraph_object_class nv40_graph_grclass[]; @@ -967,6 +983,8 @@ extern void nv40_graph_destroy_context(struct nouveau_channel *); extern int nv40_graph_load_context(struct nouveau_channel *); extern int nv40_graph_unload_context(struct drm_device *); extern void nv40_grctx_init(struct nouveau_grctx *); +extern void nv40_graph_set_region_tiling(struct drm_device *, int, uint32_t, + uint32_t, uint32_t); /* nv50_graph.c */ extern struct nouveau_pgraph_object_class nv50_graph_grclass[]; diff --git a/drivers/gpu/drm/nouveau/nouveau_reg.h b/drivers/gpu/drm/nouveau/nouveau_reg.h index fa1b0e7..251f1b3 100644 --- a/drivers/gpu/drm/nouveau/nouveau_reg.h +++ b/drivers/gpu/drm/nouveau/nouveau_reg.h @@ -349,19 +349,19 @@ #define NV04_PGRAPH_BLEND 0x00400824 #define NV04_PGRAPH_STORED_FMT 0x00400830 #define NV04_PGRAPH_PATT_COLORRAM 0x00400900 -#define NV40_PGRAPH_TILE0(i) (0x00400900 + (i*16)) -#define NV40_PGRAPH_TLIMIT0(i) (0x00400904 + (i*16)) -#define NV40_PGRAPH_TSIZE0(i) (0x00400908 + (i*16)) -#define NV40_PGRAPH_TSTATUS0(i) (0x0040090C + (i*16)) +#define NV20_PGRAPH_TILE(i) (0x00400900 + (i*16)) +#define NV20_PGRAPH_TLIMIT(i) (0x00400904 + (i*16)) +#define NV20_PGRAPH_TSIZE(i) (0x00400908 + (i*16)) +#define NV20_PGRAPH_TSTATUS(i) (0x0040090C + (i*16)) #define NV10_PGRAPH_TILE(i) (0x00400B00 + (i*16)) #define NV10_PGRAPH_TLIMIT(i) (0x00400B04 + (i*16)) #define NV10_PGRAPH_TSIZE(i) (0x00400B08 + (i*16)) #define NV10_PGRAPH_TSTATUS(i) (0x00400B0C + (i*16)) #define NV04_PGRAPH_U_RAM 0x00400D00 -#define NV47_PGRAPH_TILE0(i) (0x00400D00 + (i*16)) -#define NV47_PGRAPH_TLIMIT0(i) (0x00400D04 + (i*16)) -#define NV47_PGRAPH_TSIZE0(i) (0x00400D08 + (i*16)) -#define NV47_PGRAPH_TSTATUS0(i) (0x00400D0C + (i*16)) +#define NV47_PGRAPH_TILE(i) (0x00400D00 + (i*16)) +#define NV47_PGRAPH_TLIMIT(i) (0x00400D04 + (i*16)) +#define NV47_PGRAPH_TSIZE(i) (0x00400D08 + (i*16)) +#define NV47_PGRAPH_TSTATUS(i) (0x00400D0C + (i*16)) #define NV04_PGRAPH_V_RAM 0x00400D40 #define NV04_PGRAPH_W_RAM 0x00400D80 #define NV10_PGRAPH_COMBINER0_IN_ALPHA 0x00400E40 diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 9f98843..6a45913 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -102,6 +102,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->timer.takedown = nv04_timer_takedown; engine->fb.init = nv10_fb_init; engine->fb.takedown = nv10_fb_takedown; + engine->fb.set_region_tiling = nv10_fb_set_region_tiling; engine->graph.grclass = nv10_graph_grclass; engine->graph.init = nv10_graph_init; engine->graph.takedown = nv10_graph_takedown; @@ -111,6 +112,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->graph.fifo_access = nv04_graph_fifo_access; engine->graph.load_context = nv10_graph_load_context; engine->graph.unload_context = nv10_graph_unload_context; + engine->graph.set_region_tiling = nv10_graph_set_region_tiling; engine->fifo.channels = 32; engine->fifo.init = nv10_fifo_init; engine->fifo.takedown = nouveau_stub_takedown; @@ -143,6 +145,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->timer.takedown = nv04_timer_takedown; engine->fb.init = nv10_fb_init; engine->fb.takedown = nv10_fb_takedown; + engine->fb.set_region_tiling = nv10_fb_set_region_tiling; engine->graph.grclass = nv20_graph_grclass; engine->graph.init = nv20_graph_init; engine->graph.takedown = nv20_graph_takedown; @@ -152,6 +155,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->graph.fifo_access = nv04_graph_fifo_access; engine->graph.load_context = nv20_graph_load_context; engine->graph.unload_context = nv20_graph_unload_context; + engine->graph.set_region_tiling = nv20_graph_set_region_tiling; engine->fifo.channels = 32; engine->fifo.init = nv10_fifo_init; engine->fifo.takedown = nouveau_stub_takedown; @@ -184,6 +188,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->timer.takedown = nv04_timer_takedown; engine->fb.init = nv10_fb_init; engine->fb.takedown = nv10_fb_takedown; + engine->fb.set_region_tiling = nv10_fb_set_region_tiling; engine->graph.grclass = nv30_graph_grclass; engine->graph.init = nv30_graph_init; engine->graph.takedown = nv20_graph_takedown; @@ -193,6 +198,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->graph.destroy_context = nv20_graph_destroy_context; engine->graph.load_context = nv20_graph_load_context; engine->graph.unload_context = nv20_graph_unload_context; + engine->graph.set_region_tiling = nv20_graph_set_region_tiling; engine->fifo.channels = 32; engine->fifo.init = nv10_fifo_init; engine->fifo.takedown = nouveau_stub_takedown; @@ -226,6 +232,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->timer.takedown = nv04_timer_takedown; engine->fb.init = nv40_fb_init; engine->fb.takedown = nv40_fb_takedown; + engine->fb.set_region_tiling = nv40_fb_set_region_tiling; engine->graph.grclass = nv40_graph_grclass; engine->graph.init = nv40_graph_init; engine->graph.takedown = nv40_graph_takedown; @@ -235,6 +242,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->graph.destroy_context = nv40_graph_destroy_context; engine->graph.load_context = nv40_graph_load_context; engine->graph.unload_context = nv40_graph_unload_context; + engine->graph.set_region_tiling = nv40_graph_set_region_tiling; engine->fifo.channels = 32; engine->fifo.init = nv40_fifo_init; engine->fifo.takedown = nouveau_stub_takedown; diff --git a/drivers/gpu/drm/nouveau/nv10_fb.c b/drivers/gpu/drm/nouveau/nv10_fb.c index 79e2d10..cc5cda4 100644 --- a/drivers/gpu/drm/nouveau/nv10_fb.c +++ b/drivers/gpu/drm/nouveau/nv10_fb.c @@ -3,17 +3,37 @@ #include "nouveau_drv.h" #include "nouveau_drm.h" +void +nv10_fb_set_region_tiling(struct drm_device *dev, int i, uint32_t addr, + uint32_t size, uint32_t pitch) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + uint32_t limit = max(1u, addr + size) - 1; + + if (pitch) { + if (dev_priv->card_type >= NV_20) + addr |= 1; + else + addr |= 1 << 31; + } + + nv_wr32(dev, NV10_PFB_TLIMIT(i), limit); + nv_wr32(dev, NV10_PFB_TSIZE(i), pitch); + nv_wr32(dev, NV10_PFB_TILE(i), addr); +} + int nv10_fb_init(struct drm_device *dev) { - uint32_t fb_bar_size; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; int i; - fb_bar_size = drm_get_resource_len(dev, 0) - 1; - for (i = 0; i < NV10_PFB_TILE__SIZE; i++) { - nv_wr32(dev, NV10_PFB_TILE(i), 0); - nv_wr32(dev, NV10_PFB_TLIMIT(i), fb_bar_size); - } + pfb->num_tiles = NV10_PFB_TILE__SIZE; + + /* Turn all the tiling regions off. */ + for (i = 0; i < pfb->num_tiles; i++) + pfb->set_region_tiling(dev, i, 0, 0, 0); return 0; } diff --git a/drivers/gpu/drm/nouveau/nv10_graph.c b/drivers/gpu/drm/nouveau/nv10_graph.c index 6870e0e..fcf2cdd 100644 --- a/drivers/gpu/drm/nouveau/nv10_graph.c +++ b/drivers/gpu/drm/nouveau/nv10_graph.c @@ -807,6 +807,20 @@ void nv10_graph_destroy_context(struct nouveau_channel *chan) chan->pgraph_ctx = NULL; } +void +nv10_graph_set_region_tiling(struct drm_device *dev, int i, uint32_t addr, + uint32_t size, uint32_t pitch) +{ + uint32_t limit = max(1u, addr + size) - 1; + + if (pitch) + addr |= 1 << 31; + + nv_wr32(dev, NV10_PGRAPH_TLIMIT(i), limit); + nv_wr32(dev, NV10_PGRAPH_TSIZE(i), pitch); + nv_wr32(dev, NV10_PGRAPH_TILE(i), addr); +} + int nv10_graph_init(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; @@ -838,17 +852,9 @@ int nv10_graph_init(struct drm_device *dev) } else nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x00000000); - /* copy tile info from PFB */ - for (i = 0; i < NV10_PFB_TILE__SIZE; i++) { - nv_wr32(dev, NV10_PGRAPH_TILE(i), - nv_rd32(dev, NV10_PFB_TILE(i))); - nv_wr32(dev, NV10_PGRAPH_TLIMIT(i), - nv_rd32(dev, NV10_PFB_TLIMIT(i))); - nv_wr32(dev, NV10_PGRAPH_TSIZE(i), - nv_rd32(dev, NV10_PFB_TSIZE(i))); - nv_wr32(dev, NV10_PGRAPH_TSTATUS(i), - nv_rd32(dev, NV10_PFB_TSTATUS(i))); - } + /* Turn all the tiling regions off. */ + for (i = 0; i < NV10_PFB_TILE__SIZE; i++) + nv10_graph_set_region_tiling(dev, i, 0, 0, 0); nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH1, 0x00000000); nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH2, 0x00000000); diff --git a/drivers/gpu/drm/nouveau/nv20_graph.c b/drivers/gpu/drm/nouveau/nv20_graph.c index 18ba74f..d6fc0a8 100644 --- a/drivers/gpu/drm/nouveau/nv20_graph.c +++ b/drivers/gpu/drm/nouveau/nv20_graph.c @@ -514,6 +514,27 @@ nv20_graph_rdi(struct drm_device *dev) nouveau_wait_for_idle(dev); } +void +nv20_graph_set_region_tiling(struct drm_device *dev, int i, uint32_t addr, + uint32_t size, uint32_t pitch) +{ + uint32_t limit = max(1u, addr + size) - 1; + + if (pitch) + addr |= 1; + + nv_wr32(dev, NV20_PGRAPH_TLIMIT(i), limit); + nv_wr32(dev, NV20_PGRAPH_TSIZE(i), pitch); + nv_wr32(dev, NV20_PGRAPH_TILE(i), addr); + + nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0030 + 4 * i); + nv_wr32(dev, NV10_PGRAPH_RDI_DATA, limit); + nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0050 + 4 * i); + nv_wr32(dev, NV10_PGRAPH_RDI_DATA, pitch); + nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0010 + 4 * i); + nv_wr32(dev, NV10_PGRAPH_RDI_DATA, addr); +} + int nv20_graph_init(struct drm_device *dev) { @@ -572,27 +593,10 @@ nv20_graph_init(struct drm_device *dev) nv_wr32(dev, NV10_PGRAPH_RDI_DATA , 0x00000030); } - /* copy tile info from PFB */ - for (i = 0; i < NV10_PFB_TILE__SIZE; i++) { - nv_wr32(dev, 0x00400904 + i * 0x10, - nv_rd32(dev, NV10_PFB_TLIMIT(i))); - /* which is NV40_PGRAPH_TLIMIT0(i) ?? */ - nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0030 + i * 4); - nv_wr32(dev, NV10_PGRAPH_RDI_DATA, - nv_rd32(dev, NV10_PFB_TLIMIT(i))); - nv_wr32(dev, 0x00400908 + i * 0x10, - nv_rd32(dev, NV10_PFB_TSIZE(i))); - /* which is NV40_PGRAPH_TSIZE0(i) ?? */ - nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0050 + i * 4); - nv_wr32(dev, NV10_PGRAPH_RDI_DATA, - nv_rd32(dev, NV10_PFB_TSIZE(i))); - nv_wr32(dev, 0x00400900 + i * 0x10, - nv_rd32(dev, NV10_PFB_TILE(i))); - /* which is NV40_PGRAPH_TILE0(i) ?? */ - nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0010 + i * 4); - nv_wr32(dev, NV10_PGRAPH_RDI_DATA, - nv_rd32(dev, NV10_PFB_TILE(i))); - } + /* Turn all the tiling regions off. */ + for (i = 0; i < NV10_PFB_TILE__SIZE; i++) + nv20_graph_set_region_tiling(dev, i, 0, 0, 0); + for (i = 0; i < 8; i++) { nv_wr32(dev, 0x400980 + i * 4, nv_rd32(dev, 0x100300 + i * 4)); nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0090 + i * 4); @@ -704,18 +708,9 @@ nv30_graph_init(struct drm_device *dev) nv_wr32(dev, 0x4000c0, 0x00000016); - /* copy tile info from PFB */ - for (i = 0; i < NV10_PFB_TILE__SIZE; i++) { - nv_wr32(dev, 0x00400904 + i * 0x10, - nv_rd32(dev, NV10_PFB_TLIMIT(i))); - /* which is NV40_PGRAPH_TLIMIT0(i) ?? */ - nv_wr32(dev, 0x00400908 + i * 0x10, - nv_rd32(dev, NV10_PFB_TSIZE(i))); - /* which is NV40_PGRAPH_TSIZE0(i) ?? */ - nv_wr32(dev, 0x00400900 + i * 0x10, - nv_rd32(dev, NV10_PFB_TILE(i))); - /* which is NV40_PGRAPH_TILE0(i) ?? */ - } + /* Turn all the tiling regions off. */ + for (i = 0; i < NV10_PFB_TILE__SIZE; i++) + nv20_graph_set_region_tiling(dev, i, 0, 0, 0); nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10000100); nv_wr32(dev, NV10_PGRAPH_STATE , 0xFFFFFFFF); diff --git a/drivers/gpu/drm/nouveau/nv40_fb.c b/drivers/gpu/drm/nouveau/nv40_fb.c index ca1d271..3cd07d8 100644 --- a/drivers/gpu/drm/nouveau/nv40_fb.c +++ b/drivers/gpu/drm/nouveau/nv40_fb.c @@ -3,12 +3,37 @@ #include "nouveau_drv.h" #include "nouveau_drm.h" +void +nv40_fb_set_region_tiling(struct drm_device *dev, int i, uint32_t addr, + uint32_t size, uint32_t pitch) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + uint32_t limit = max(1u, addr + size) - 1; + + if (pitch) + addr |= 1; + + switch (dev_priv->chipset) { + case 0x40: + nv_wr32(dev, NV10_PFB_TLIMIT(i), limit); + nv_wr32(dev, NV10_PFB_TSIZE(i), pitch); + nv_wr32(dev, NV10_PFB_TILE(i), addr); + break; + + default: + nv_wr32(dev, NV40_PFB_TLIMIT(i), limit); + nv_wr32(dev, NV40_PFB_TSIZE(i), pitch); + nv_wr32(dev, NV40_PFB_TILE(i), addr); + break; + } +} + int nv40_fb_init(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; - uint32_t fb_bar_size, tmp; - int num_tiles; + struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; + uint32_t tmp; int i; /* This is strictly a NV4x register (don't know about NV5x). */ @@ -23,35 +48,23 @@ nv40_fb_init(struct drm_device *dev) case 0x45: tmp = nv_rd32(dev, NV10_PFB_CLOSE_PAGE2); nv_wr32(dev, NV10_PFB_CLOSE_PAGE2, tmp & ~(1 << 15)); - num_tiles = NV10_PFB_TILE__SIZE; + pfb->num_tiles = NV10_PFB_TILE__SIZE; break; case 0x46: /* G72 */ case 0x47: /* G70 */ case 0x49: /* G71 */ case 0x4b: /* G73 */ case 0x4c: /* C51 (G7X version) */ - num_tiles = NV40_PFB_TILE__SIZE_1; + pfb->num_tiles = NV40_PFB_TILE__SIZE_1; break; default: - num_tiles = NV40_PFB_TILE__SIZE_0; + pfb->num_tiles = NV40_PFB_TILE__SIZE_0; break; } - fb_bar_size = drm_get_resource_len(dev, 0) - 1; - switch (dev_priv->chipset) { - case 0x40: - for (i = 0; i < num_tiles; i++) { - nv_wr32(dev, NV10_PFB_TILE(i), 0); - nv_wr32(dev, NV10_PFB_TLIMIT(i), fb_bar_size); - } - break; - default: - for (i = 0; i < num_tiles; i++) { - nv_wr32(dev, NV40_PFB_TILE(i), 0); - nv_wr32(dev, NV40_PFB_TLIMIT(i), fb_bar_size); - } - break; - } + /* Turn all the tiling regions off. */ + for (i = 0; i < pfb->num_tiles; i++) + pfb->set_region_tiling(dev, i, 0, 0, 0); return 0; } diff --git a/drivers/gpu/drm/nouveau/nv40_graph.c b/drivers/gpu/drm/nouveau/nv40_graph.c index 2b332bb..53e8afe 100644 --- a/drivers/gpu/drm/nouveau/nv40_graph.c +++ b/drivers/gpu/drm/nouveau/nv40_graph.c @@ -181,6 +181,48 @@ nv40_graph_unload_context(struct drm_device *dev) return ret; } +void +nv40_graph_set_region_tiling(struct drm_device *dev, int i, uint32_t addr, + uint32_t size, uint32_t pitch) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + uint32_t limit = max(1u, addr + size) - 1; + + if (pitch) + addr |= 1; + + switch (dev_priv->chipset) { + case 0x44: + case 0x4a: + case 0x4e: + nv_wr32(dev, NV20_PGRAPH_TSIZE(i), pitch); + nv_wr32(dev, NV20_PGRAPH_TLIMIT(i), limit); + nv_wr32(dev, NV20_PGRAPH_TILE(i), addr); + break; + + case 0x46: + case 0x47: + case 0x49: + case 0x4b: + nv_wr32(dev, NV47_PGRAPH_TSIZE(i), pitch); + nv_wr32(dev, NV47_PGRAPH_TLIMIT(i), limit); + nv_wr32(dev, NV47_PGRAPH_TILE(i), addr); + nv_wr32(dev, NV40_PGRAPH_TSIZE1(i), pitch); + nv_wr32(dev, NV40_PGRAPH_TLIMIT1(i), limit); + nv_wr32(dev, NV40_PGRAPH_TILE1(i), addr); + break; + + default: + nv_wr32(dev, NV20_PGRAPH_TSIZE(i), pitch); + nv_wr32(dev, NV20_PGRAPH_TLIMIT(i), limit); + nv_wr32(dev, NV20_PGRAPH_TILE(i), addr); + nv_wr32(dev, NV40_PGRAPH_TSIZE1(i), pitch); + nv_wr32(dev, NV40_PGRAPH_TLIMIT1(i), limit); + nv_wr32(dev, NV40_PGRAPH_TILE1(i), addr); + break; + } +} + /* * G70 0x47 * G71 0x49 @@ -195,7 +237,8 @@ nv40_graph_init(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = (struct drm_nouveau_private *)dev->dev_private; - uint32_t vramsz, tmp; + struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; + uint32_t vramsz; int i, j; nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) & @@ -292,74 +335,9 @@ nv40_graph_init(struct drm_device *dev) nv_wr32(dev, 0x400b38, 0x2ffff800); nv_wr32(dev, 0x400b3c, 0x00006000); - /* copy tile info from PFB */ - switch (dev_priv->chipset) { - case 0x40: /* vanilla NV40 */ - for (i = 0; i < NV10_PFB_TILE__SIZE; i++) { - tmp = nv_rd32(dev, NV10_PFB_TILE(i)); - nv_wr32(dev, NV40_PGRAPH_TILE0(i), tmp); - nv_wr32(dev, NV40_PGRAPH_TILE1(i), tmp); - tmp = nv_rd32(dev, NV10_PFB_TLIMIT(i)); - nv_wr32(dev, NV40_PGRAPH_TLIMIT0(i), tmp); - nv_wr32(dev, NV40_PGRAPH_TLIMIT1(i), tmp); - tmp = nv_rd32(dev, NV10_PFB_TSIZE(i)); - nv_wr32(dev, NV40_PGRAPH_TSIZE0(i), tmp); - nv_wr32(dev, NV40_PGRAPH_TSIZE1(i), tmp); - tmp = nv_rd32(dev, NV10_PFB_TSTATUS(i)); - nv_wr32(dev, NV40_PGRAPH_TSTATUS0(i), tmp); - nv_wr32(dev, NV40_PGRAPH_TSTATUS1(i), tmp); - } - break; - case 0x44: - case 0x4a: - case 0x4e: /* NV44-based cores don't have 0x406900? */ - for (i = 0; i < NV40_PFB_TILE__SIZE_0; i++) { - tmp = nv_rd32(dev, NV40_PFB_TILE(i)); - nv_wr32(dev, NV40_PGRAPH_TILE0(i), tmp); - tmp = nv_rd32(dev, NV40_PFB_TLIMIT(i)); - nv_wr32(dev, NV40_PGRAPH_TLIMIT0(i), tmp); - tmp = nv_rd32(dev, NV40_PFB_TSIZE(i)); - nv_wr32(dev, NV40_PGRAPH_TSIZE0(i), tmp); - tmp = nv_rd32(dev, NV40_PFB_TSTATUS(i)); - nv_wr32(dev, NV40_PGRAPH_TSTATUS0(i), tmp); - } - break; - case 0x46: - case 0x47: - case 0x49: - case 0x4b: /* G7X-based cores */ - for (i = 0; i < NV40_PFB_TILE__SIZE_1; i++) { - tmp = nv_rd32(dev, NV40_PFB_TILE(i)); - nv_wr32(dev, NV47_PGRAPH_TILE0(i), tmp); - nv_wr32(dev, NV40_PGRAPH_TILE1(i), tmp); - tmp = nv_rd32(dev, NV40_PFB_TLIMIT(i)); - nv_wr32(dev, NV47_PGRAPH_TLIMIT0(i), tmp); - nv_wr32(dev, NV40_PGRAPH_TLIMIT1(i), tmp); - tmp = nv_rd32(dev, NV40_PFB_TSIZE(i)); - nv_wr32(dev, NV47_PGRAPH_TSIZE0(i), tmp); - nv_wr32(dev, NV40_PGRAPH_TSIZE1(i), tmp); - tmp = nv_rd32(dev, NV40_PFB_TSTATUS(i)); - nv_wr32(dev, NV47_PGRAPH_TSTATUS0(i), tmp); - nv_wr32(dev, NV40_PGRAPH_TSTATUS1(i), tmp); - } - break; - default: /* everything else */ - for (i = 0; i < NV40_PFB_TILE__SIZE_0; i++) { - tmp = nv_rd32(dev, NV40_PFB_TILE(i)); - nv_wr32(dev, NV40_PGRAPH_TILE0(i), tmp); - nv_wr32(dev, NV40_PGRAPH_TILE1(i), tmp); - tmp = nv_rd32(dev, NV40_PFB_TLIMIT(i)); - nv_wr32(dev, NV40_PGRAPH_TLIMIT0(i), tmp); - nv_wr32(dev, NV40_PGRAPH_TLIMIT1(i), tmp); - tmp = nv_rd32(dev, NV40_PFB_TSIZE(i)); - nv_wr32(dev, NV40_PGRAPH_TSIZE0(i), tmp); - nv_wr32(dev, NV40_PGRAPH_TSIZE1(i), tmp); - tmp = nv_rd32(dev, NV40_PFB_TSTATUS(i)); - nv_wr32(dev, NV40_PGRAPH_TSTATUS0(i), tmp); - nv_wr32(dev, NV40_PGRAPH_TSTATUS1(i), tmp); - } - break; - } + /* Turn all the tiling regions off. */ + for (i = 0; i < pfb->num_tiles; i++) + nv40_graph_set_region_tiling(dev, i, 0, 0, 0); /* begin RAM config */ vramsz = drm_get_resource_len(dev, 0) - 1; -- cgit v0.10.2 From 287c1532145b63d394060d46c0309b123b862345 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Fri, 11 Dec 2009 16:51:09 +0100 Subject: drm/nouveau: Make the MM aware of pre-G80 tiling. This commit has also the following 3 bugfix commits squashed into it from the nouveau git tree: drm/nouveau: Fix up the tiling alignment restrictions for nv1x. drm/nouveau: Fix up the nv2x tiling alignment restrictions. drm/nv50: fix align typo for g9x Signed-off-by: Francisco Jerez diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 0cad6d8..1d6036f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -37,6 +37,7 @@ static void nouveau_bo_del_ttm(struct ttm_buffer_object *bo) { struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev); + struct drm_device *dev = dev_priv->dev; struct nouveau_bo *nvbo = nouveau_bo(bo); ttm_bo_kunmap(&nvbo->kmap); @@ -44,12 +45,83 @@ nouveau_bo_del_ttm(struct ttm_buffer_object *bo) if (unlikely(nvbo->gem)) DRM_ERROR("bo %p still attached to GEM object\n", bo); + if (nvbo->tile) + nv10_mem_expire_tiling(dev, nvbo->tile, NULL); + spin_lock(&dev_priv->ttm.bo_list_lock); list_del(&nvbo->head); spin_unlock(&dev_priv->ttm.bo_list_lock); kfree(nvbo); } +static void +nouveau_bo_fixup_align(struct drm_device *dev, + uint32_t tile_mode, uint32_t tile_flags, + int *align, int *size) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + + /* + * Some of the tile_flags have a periodic structure of N*4096 bytes, + * align to to that as well as the page size. Overallocate memory to + * avoid corruption of other buffer objects. + */ + if (dev_priv->card_type == NV_50) { + switch (tile_flags) { + case 0x1800: + case 0x2800: + case 0x4800: + case 0x7a00: + if (dev_priv->chipset >= 0xA0) { + /* This is based on high end cards with 448 bits + * memory bus, could be different elsewhere.*/ + *size += 6 * 28672; + /* 8 * 28672 is the actual alignment requirement + * but we must also align to page size. */ + *align = 2 * 8 * 28672; + } else if (dev_priv->chipset >= 0x90) { + *size += 3 * 16384; + *align = 12 * 16384; + } else { + *size += 3 * 8192; + /* 12 * 8192 is the actual alignment requirement + * but we must also align to page size. */ + *align = 2 * 12 * 8192; + } + break; + default: + break; + } + + } else { + if (tile_mode) { + if (dev_priv->chipset >= 0x40) { + *align = 65536; + *size = roundup(*size, 64 * tile_mode); + + } else if (dev_priv->chipset >= 0x30) { + *align = 32768; + *size = roundup(*size, 64 * tile_mode); + + } else if (dev_priv->chipset >= 0x20) { + *align = 16384; + *size = roundup(*size, 64 * tile_mode); + + } else if (dev_priv->chipset >= 0x10) { + *align = 16384; + *size = roundup(*size, 32 * tile_mode); + } + } + } + + *size = ALIGN(*size, PAGE_SIZE); + + if (dev_priv->card_type == NV_50) { + *size = ALIGN(*size, 65536); + *align = max(65536, *align); + } +} + int nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan, int size, int align, uint32_t flags, uint32_t tile_mode, @@ -70,46 +142,9 @@ nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan, nvbo->tile_mode = tile_mode; nvbo->tile_flags = tile_flags; - /* - * Some of the tile_flags have a periodic structure of N*4096 bytes, - * align to to that as well as the page size. Overallocate memory to - * avoid corruption of other buffer objects. - */ - switch (tile_flags) { - case 0x1800: - case 0x2800: - case 0x4800: - case 0x7a00: - if (dev_priv->chipset >= 0xA0) { - /* This is based on high end cards with 448 bits - * memory bus, could be different elsewhere.*/ - size += 6 * 28672; - /* 8 * 28672 is the actual alignment requirement, - * but we must also align to page size. */ - align = 2 * 8 * 28672; - } else if (dev_priv->chipset >= 0x90) { - size += 3 * 16384; - align = 12 * 16834; - } else { - size += 3 * 8192; - /* 12 * 8192 is the actual alignment requirement, - * but we must also align to page size. */ - align = 2 * 12 * 8192; - } - break; - default: - break; - } - + nouveau_bo_fixup_align(dev, tile_mode, tile_flags, &align, &size); align >>= PAGE_SHIFT; - size = (size + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1); - if (dev_priv->card_type == NV_50) { - size = (size + 65535) & ~65535; - if (align < (65536 / PAGE_SIZE)) - align = (65536 / PAGE_SIZE); - } - if (flags & TTM_PL_FLAG_VRAM) nvbo->placements[n++] = TTM_PL_FLAG_VRAM | TTM_PL_MASK_CACHING; if (flags & TTM_PL_FLAG_TT) @@ -421,6 +456,7 @@ nouveau_bo_evict_flags(struct ttm_buffer_object *bo, struct ttm_placement *pl) /* GPU-assisted copy using NV_MEMORY_TO_MEMORY_FORMAT, can access * TTM_PL_{VRAM,TT} directly. */ + static int nouveau_bo_move_accel_cleanup(struct nouveau_channel *chan, struct nouveau_bo *nvbo, bool evict, bool no_wait, @@ -455,11 +491,12 @@ nouveau_bo_mem_ctxdma(struct nouveau_bo *nvbo, struct nouveau_channel *chan, } static int -nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, int no_wait, - struct ttm_mem_reg *old_mem, struct ttm_mem_reg *new_mem) +nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr, + int no_wait, struct ttm_mem_reg *new_mem) { struct nouveau_bo *nvbo = nouveau_bo(bo); struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev); + struct ttm_mem_reg *old_mem = &bo->mem; struct nouveau_channel *chan; uint64_t src_offset, dst_offset; uint32_t page_count; @@ -559,7 +596,7 @@ nouveau_bo_move_flipd(struct ttm_buffer_object *bo, bool evict, bool intr, if (ret) goto out; - ret = nouveau_bo_move_m2mf(bo, true, no_wait, &bo->mem, &tmp_mem); + ret = nouveau_bo_move_m2mf(bo, true, intr, no_wait, &tmp_mem); if (ret) goto out; @@ -597,7 +634,7 @@ nouveau_bo_move_flips(struct ttm_buffer_object *bo, bool evict, bool intr, if (ret) goto out; - ret = nouveau_bo_move_m2mf(bo, true, no_wait, &bo->mem, new_mem); + ret = nouveau_bo_move_m2mf(bo, true, intr, no_wait, new_mem); if (ret) goto out; @@ -612,52 +649,106 @@ out: } static int -nouveau_bo_move(struct ttm_buffer_object *bo, bool evict, bool intr, - bool no_wait, struct ttm_mem_reg *new_mem) +nouveau_bo_vm_bind(struct ttm_buffer_object *bo, struct ttm_mem_reg *new_mem, + struct nouveau_tile_reg **new_tile) { struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev); - struct nouveau_bo *nvbo = nouveau_bo(bo); struct drm_device *dev = dev_priv->dev; - struct ttm_mem_reg *old_mem = &bo->mem; + struct nouveau_bo *nvbo = nouveau_bo(bo); + uint64_t offset; int ret; - if (dev_priv->card_type == NV_50 && new_mem->mem_type == TTM_PL_VRAM && - !nvbo->no_vm) { - uint64_t offset = new_mem->mm_node->start << PAGE_SHIFT; + if (nvbo->no_vm || new_mem->mem_type != TTM_PL_VRAM) { + /* Nothing to do. */ + *new_tile = NULL; + return 0; + } + + offset = new_mem->mm_node->start << PAGE_SHIFT; + if (dev_priv->card_type == NV_50) { ret = nv50_mem_vm_bind_linear(dev, offset + dev_priv->vm_vram_base, new_mem->size, nvbo->tile_flags, offset); if (ret) return ret; + + } else if (dev_priv->card_type >= NV_10) { + *new_tile = nv10_mem_set_tiling(dev, offset, new_mem->size, + nvbo->tile_mode); } + return 0; +} + +static void +nouveau_bo_vm_cleanup(struct ttm_buffer_object *bo, + struct nouveau_tile_reg *new_tile, + struct nouveau_tile_reg **old_tile) +{ + struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev); + struct drm_device *dev = dev_priv->dev; + + if (dev_priv->card_type >= NV_10 && + dev_priv->card_type < NV_50) { + if (*old_tile) + nv10_mem_expire_tiling(dev, *old_tile, bo->sync_obj); + + *old_tile = new_tile; + } +} + +static int +nouveau_bo_move(struct ttm_buffer_object *bo, bool evict, bool intr, + bool no_wait, struct ttm_mem_reg *new_mem) +{ + struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev); + struct nouveau_bo *nvbo = nouveau_bo(bo); + struct ttm_mem_reg *old_mem = &bo->mem; + struct nouveau_tile_reg *new_tile = NULL; + int ret = 0; + + ret = nouveau_bo_vm_bind(bo, new_mem, &new_tile); + if (ret) + return ret; + + /* Software copy if the card isn't up and running yet. */ if (dev_priv->init_state != NOUVEAU_CARD_INIT_DONE || - !dev_priv->channel) - return ttm_bo_move_memcpy(bo, evict, no_wait, new_mem); + !dev_priv->channel) { + ret = ttm_bo_move_memcpy(bo, evict, no_wait, new_mem); + goto out; + } + /* Fake bo copy. */ if (old_mem->mem_type == TTM_PL_SYSTEM && !bo->ttm) { BUG_ON(bo->mem.mm_node != NULL); bo->mem = *new_mem; new_mem->mm_node = NULL; - return 0; + goto out; } - if (new_mem->mem_type == TTM_PL_SYSTEM) { - if (old_mem->mem_type == TTM_PL_SYSTEM) - return ttm_bo_move_memcpy(bo, evict, no_wait, new_mem); - if (nouveau_bo_move_flipd(bo, evict, intr, no_wait, new_mem)) - return ttm_bo_move_memcpy(bo, evict, no_wait, new_mem); - } else if (old_mem->mem_type == TTM_PL_SYSTEM) { - if (nouveau_bo_move_flips(bo, evict, intr, no_wait, new_mem)) - return ttm_bo_move_memcpy(bo, evict, no_wait, new_mem); - } else { - if (nouveau_bo_move_m2mf(bo, evict, no_wait, old_mem, new_mem)) - return ttm_bo_move_memcpy(bo, evict, no_wait, new_mem); - } + /* Hardware assisted copy. */ + if (new_mem->mem_type == TTM_PL_SYSTEM) + ret = nouveau_bo_move_flipd(bo, evict, intr, no_wait, new_mem); + else if (old_mem->mem_type == TTM_PL_SYSTEM) + ret = nouveau_bo_move_flips(bo, evict, intr, no_wait, new_mem); + else + ret = nouveau_bo_move_m2mf(bo, evict, intr, no_wait, new_mem); - return 0; + if (!ret) + goto out; + + /* Fallback to software copy. */ + ret = ttm_bo_move_memcpy(bo, evict, no_wait, new_mem); + +out: + if (ret) + nouveau_bo_vm_cleanup(bo, NULL, &new_tile); + else + nouveau_bo_vm_cleanup(bo, new_tile, &nvbo->tile); + + return ret; } static int diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 446a92a..9c9815b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -59,11 +59,19 @@ struct nouveau_grctx; #define MAX_NUM_DCB_ENTRIES 16 #define NOUVEAU_MAX_CHANNEL_NR 128 +#define NOUVEAU_MAX_TILE_NR 15 #define NV50_VM_MAX_VRAM (2*1024*1024*1024ULL) #define NV50_VM_BLOCK (512*1024*1024ULL) #define NV50_VM_VRAM_NR (NV50_VM_MAX_VRAM / NV50_VM_BLOCK) +struct nouveau_tile_reg { + struct nouveau_fence *fence; + uint32_t addr; + uint32_t size; + bool used; +}; + struct nouveau_bo { struct ttm_buffer_object bo; struct ttm_placement placement; @@ -83,6 +91,7 @@ struct nouveau_bo { uint32_t tile_mode; uint32_t tile_flags; + struct nouveau_tile_reg *tile; struct drm_gem_object *gem; struct drm_file *cpu_filp; @@ -558,6 +567,12 @@ struct drm_nouveau_private { unsigned long sg_handle; } gart_info; + /* nv10-nv40 tiling regions */ + struct { + struct nouveau_tile_reg reg[NOUVEAU_MAX_TILE_NR]; + spinlock_t lock; + } tile; + /* G8x/G9x virtual address space */ uint64_t vm_gart_base; uint64_t vm_gart_size; @@ -695,6 +710,13 @@ extern void nouveau_mem_release(struct drm_file *, struct mem_block *heap); extern int nouveau_mem_init(struct drm_device *); extern int nouveau_mem_init_agp(struct drm_device *); extern void nouveau_mem_close(struct drm_device *); +extern struct nouveau_tile_reg *nv10_mem_set_tiling(struct drm_device *dev, + uint32_t addr, + uint32_t size, + uint32_t pitch); +extern void nv10_mem_expire_tiling(struct drm_device *dev, + struct nouveau_tile_reg *tile, + struct nouveau_fence *fence); extern int nv50_mem_vm_bind_linear(struct drm_device *, uint64_t virt, uint32_t size, uint32_t flags, uint64_t phys); diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index 5158a12..fb9bdd6 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c @@ -192,6 +192,92 @@ void nouveau_mem_release(struct drm_file *file_priv, struct mem_block *heap) } /* + * NV10-NV40 tiling helpers + */ + +static void +nv10_mem_set_region_tiling(struct drm_device *dev, int i, uint32_t addr, + uint32_t size, uint32_t pitch) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; + struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; + struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; + struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i]; + + tile->addr = addr; + tile->size = size; + tile->used = !!pitch; + nouveau_fence_unref((void **)&tile->fence); + + if (!pfifo->cache_flush(dev)) + return; + + pfifo->reassign(dev, false); + pfifo->cache_flush(dev); + pfifo->cache_pull(dev, false); + + nouveau_wait_for_idle(dev); + + pgraph->set_region_tiling(dev, i, addr, size, pitch); + pfb->set_region_tiling(dev, i, addr, size, pitch); + + pfifo->cache_pull(dev, true); + pfifo->reassign(dev, true); +} + +struct nouveau_tile_reg * +nv10_mem_set_tiling(struct drm_device *dev, uint32_t addr, uint32_t size, + uint32_t pitch) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; + struct nouveau_tile_reg *tile = dev_priv->tile.reg, *found = NULL; + int i; + + spin_lock(&dev_priv->tile.lock); + + for (i = 0; i < pfb->num_tiles; i++) { + if (tile[i].used) + /* Tile region in use. */ + continue; + + if (tile[i].fence && + !nouveau_fence_signalled(tile[i].fence, NULL)) + /* Pending tile region. */ + continue; + + if (max(tile[i].addr, addr) < + min(tile[i].addr + tile[i].size, addr + size)) + /* Kill an intersecting tile region. */ + nv10_mem_set_region_tiling(dev, i, 0, 0, 0); + + if (pitch && !found) { + /* Free tile region. */ + nv10_mem_set_region_tiling(dev, i, addr, size, pitch); + found = &tile[i]; + } + } + + spin_unlock(&dev_priv->tile.lock); + + return found; +} + +void +nv10_mem_expire_tiling(struct drm_device *dev, struct nouveau_tile_reg *tile, + struct nouveau_fence *fence) +{ + if (fence) { + /* Mark it as pending. */ + tile->fence = fence; + nouveau_fence_ref(fence); + } + + tile->used = false; +} + +/* * NV50 VM helpers */ int @@ -513,6 +599,7 @@ nouveau_mem_init(struct drm_device *dev) INIT_LIST_HEAD(&dev_priv->ttm.bo_list); spin_lock_init(&dev_priv->ttm.bo_list_lock); + spin_lock_init(&dev_priv->tile.lock); dev_priv->fb_available_size = nouveau_mem_fb_amount(dev); -- cgit v0.10.2 From 73cb9276fd189c19558a97600456bd13fa5debe8 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Wed, 16 Dec 2009 12:27:11 +0100 Subject: drm/i2c/ch7006: Drop build time dependency to nouveau. This partially reverts e4b41066, as this driver is intended to be useful with any KMS driver for suitable hardware. The missing build dependency that commit workarounded was DRM_KMS_HELPER. Signed-off-by: Francisco Jerez diff --git a/drivers/gpu/drm/nouveau/Kconfig b/drivers/gpu/drm/nouveau/Kconfig index b1bc1ea..1175429 100644 --- a/drivers/gpu/drm/nouveau/Kconfig +++ b/drivers/gpu/drm/nouveau/Kconfig @@ -30,12 +30,11 @@ config DRM_NOUVEAU_DEBUG via debugfs. menu "I2C encoder or helper chips" - depends on DRM && I2C + depends on DRM && DRM_KMS_HELPER && I2C config DRM_I2C_CH7006 tristate "Chrontel ch7006 TV encoder" - depends on DRM_NOUVEAU - default m + default m if DRM_NOUVEAU help Support for Chrontel ch7006 and similar TV encoders, found on some nVidia video cards. -- cgit v0.10.2 From c6af6053be60840dcbb037c3798557cbf71cbb08 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Wed, 16 Dec 2009 19:05:00 +0100 Subject: drm/nouveau: Fix "general protection fault" in the flipd/flips eviction path. Signed-off-by: Francisco Jerez diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 1d6036f..365fc65 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -584,7 +584,7 @@ nouveau_bo_move_flipd(struct ttm_buffer_object *bo, bool evict, bool intr, placement.fpfn = placement.lpfn = 0; placement.num_placement = placement.num_busy_placement = 1; - placement.placement = &placement_memtype; + placement.placement = placement.busy_placement = &placement_memtype; tmp_mem = *new_mem; tmp_mem.mm_node = NULL; @@ -622,7 +622,7 @@ nouveau_bo_move_flips(struct ttm_buffer_object *bo, bool evict, bool intr, placement.fpfn = placement.lpfn = 0; placement.num_placement = placement.num_busy_placement = 1; - placement.placement = &placement_memtype; + placement.placement = placement.busy_placement = &placement_memtype; tmp_mem = *new_mem; tmp_mem.mm_node = NULL; -- cgit v0.10.2 From 69a18c328b762eaec3f8ca3af8c7cbf10b536bf8 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Wed, 16 Dec 2009 19:05:38 +0100 Subject: drm/nouveau: No need to force evict=true when swapping evicted BOs back in. Signed-off-by: Francisco Jerez diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 365fc65..73af53f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -634,7 +634,7 @@ nouveau_bo_move_flips(struct ttm_buffer_object *bo, bool evict, bool intr, if (ret) goto out; - ret = nouveau_bo_move_m2mf(bo, true, intr, no_wait, new_mem); + ret = nouveau_bo_move_m2mf(bo, evict, intr, no_wait, new_mem); if (ret) goto out; -- cgit v0.10.2 From aeca15e596eba284c727049d0b9b855b13c48856 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Wed, 16 Dec 2009 19:03:28 +0100 Subject: drm/nouveau: Drop redundant placement initialization. Signed-off-by: Francisco Jerez diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 73af53f..5fd462f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -130,7 +130,7 @@ nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan, { struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_bo *nvbo; - int ret, n = 0; + int ret = 0; nvbo = kzalloc(sizeof(struct nouveau_bo), GFP_KERNEL); if (!nvbo) @@ -145,19 +145,11 @@ nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan, nouveau_bo_fixup_align(dev, tile_mode, tile_flags, &align, &size); align >>= PAGE_SHIFT; - if (flags & TTM_PL_FLAG_VRAM) - nvbo->placements[n++] = TTM_PL_FLAG_VRAM | TTM_PL_MASK_CACHING; - if (flags & TTM_PL_FLAG_TT) - nvbo->placements[n++] = TTM_PL_FLAG_TT | TTM_PL_MASK_CACHING; nvbo->placement.fpfn = 0; nvbo->placement.lpfn = mappable ? dev_priv->fb_mappable_pages : 0; - nvbo->placement.placement = nvbo->placements; - nvbo->placement.busy_placement = nvbo->placements; - nvbo->placement.num_placement = n; - nvbo->placement.num_busy_placement = n; + nouveau_bo_placement_set(nvbo, flags); nvbo->channel = chan; - nouveau_bo_placement_set(nvbo, flags); ret = ttm_bo_init(&dev_priv->ttm.bdev, &nvbo->bo, size, ttm_bo_type_device, &nvbo->placement, align, 0, false, NULL, size, nouveau_bo_del_ttm); -- cgit v0.10.2 From fbe36a7a069267b82b7b82a66d79a4406cfa90b2 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 21 Dec 2009 12:16:52 +1000 Subject: drm/nv50: ignore vbios table's claim to the contrary if EDID says >8bpc Should fix dim panel issues reported on Dell M6400/M6500. Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index a9263d9..90f0bf5 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -690,9 +690,21 @@ nv50_display_script_select(struct drm_device *dev, struct dcb_entry *dcbent, int pxclk) { struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_connector *nv_connector = NULL; + struct drm_encoder *encoder; struct nvbios *bios = &dev_priv->VBIOS; uint32_t mc, script = 0, or; + list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { + struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); + + if (nv_encoder->dcb != dcbent) + continue; + + nv_connector = nouveau_encoder_connector_get(nv_encoder); + break; + } + or = ffs(dcbent->or) - 1; mc = nv50_display_mode_ctrl(dev, dcbent->type != OUTPUT_ANALOG, or); switch (dcbent->type) { @@ -711,6 +723,11 @@ nv50_display_script_select(struct drm_device *dev, struct dcb_entry *dcbent, } else if (bios->fp.strapless_is_24bit & 1) script |= 0x0200; + + if (nv_connector && nv_connector->edid && + (nv_connector->edid->revision >= 4) && + (nv_connector->edid->input & 0x70) >= 0x20) + script |= 0x0200; } if (nouveau_uscript_lvds >= 0) { -- cgit v0.10.2 From e55ca7e68efc7c2d320cd9975ebc5e0fd27debf0 Mon Sep 17 00:00:00 2001 From: Marcin Slusarz Date: Mon, 21 Dec 2009 23:00:41 +0100 Subject: drm/nv50: fix fillrect color struct fb_fillrect->color is not a color, but index into pseudo_palette array Signed-off-by: Marcin Slusarz Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nv50_fbcon.c b/drivers/gpu/drm/nouveau/nv50_fbcon.c index 6bcc6d3..c966ef8 100644 --- a/drivers/gpu/drm/nouveau/nv50_fbcon.c +++ b/drivers/gpu/drm/nouveau/nv50_fbcon.c @@ -10,6 +10,7 @@ nv50_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) struct drm_device *dev = par->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_channel *chan = dev_priv->channel; + uint32_t color = ((uint32_t *) info->pseudo_palette)[rect->color]; if (info->state != FBINFO_STATE_RUNNING) return; @@ -31,7 +32,7 @@ nv50_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) OUT_RING(chan, 1); } BEGIN_RING(chan, NvSub2D, 0x0588, 1); - OUT_RING(chan, rect->color); + OUT_RING(chan, color); BEGIN_RING(chan, NvSub2D, 0x0600, 4); OUT_RING(chan, rect->dx); OUT_RING(chan, rect->dy); -- cgit v0.10.2 From 02076da97a15bbf7477bffed71d02f726de2afc2 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Thu, 17 Dec 2009 18:52:44 +0100 Subject: drm/nouveau: Clean up the nv17-nv4x load detection code a bit. Signed-off-by: Francisco Jerez diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 9c9815b..7da88a9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -1074,8 +1074,7 @@ extern long nouveau_compat_ioctl(struct file *file, unsigned int cmd, /* nv04_dac.c */ extern int nv04_dac_create(struct drm_device *dev, struct dcb_entry *entry); -extern enum drm_connector_status nv17_dac_detect(struct drm_encoder *encoder, - struct drm_connector *connector); +extern uint32_t nv17_dac_sample_load(struct drm_encoder *encoder); extern int nv04_dac_output_offset(struct drm_encoder *encoder); extern void nv04_dac_update_dacclk(struct drm_encoder *encoder, bool enable); @@ -1093,9 +1092,6 @@ extern int nv04_tv_create(struct drm_device *dev, struct dcb_entry *entry); /* nv17_tv.c */ extern int nv17_tv_create(struct drm_device *dev, struct dcb_entry *entry); -extern enum drm_connector_status nv17_tv_detect(struct drm_encoder *encoder, - struct drm_connector *connector, - uint32_t pin_mask); /* nv04_display.c */ extern int nv04_display_create(struct drm_device *); diff --git a/drivers/gpu/drm/nouveau/nv04_dac.c b/drivers/gpu/drm/nouveau/nv04_dac.c index d9f3287..d0e038d 100644 --- a/drivers/gpu/drm/nouveau/nv04_dac.c +++ b/drivers/gpu/drm/nouveau/nv04_dac.c @@ -212,16 +212,15 @@ out: return connector_status_disconnected; } -enum drm_connector_status nv17_dac_detect(struct drm_encoder *encoder, - struct drm_connector *connector) +uint32_t nv17_dac_sample_load(struct drm_encoder *encoder) { struct drm_device *dev = encoder->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb; - uint32_t testval, regoffset = nv04_dac_output_offset(encoder); + uint32_t sample, testval, regoffset = nv04_dac_output_offset(encoder); uint32_t saved_powerctrl_2 = 0, saved_powerctrl_4 = 0, saved_routput, saved_rtest_ctrl, saved_gpio0, saved_gpio1, temp, routput; - int head, present = 0; + int head; #define RGB_TEST_DATA(r, g, b) (r << 0 | g << 10 | b << 20) if (dcb->type == OUTPUT_TV) { @@ -287,13 +286,7 @@ enum drm_connector_status nv17_dac_detect(struct drm_encoder *encoder, temp | NV_PRAMDAC_TEST_CONTROL_TP_INS_EN_ASSERTED); msleep(5); - temp = NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset); - - if (dcb->type == OUTPUT_TV) - present = (nv17_tv_detect(encoder, connector, temp) - == connector_status_connected); - else - present = temp & NV_PRAMDAC_TEST_CONTROL_SENSEB_ALLHI; + sample = NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset); temp = NVReadRAMDAC(dev, head, NV_PRAMDAC_TEST_CONTROL); NVWriteRAMDAC(dev, head, NV_PRAMDAC_TEST_CONTROL, @@ -310,15 +303,25 @@ enum drm_connector_status nv17_dac_detect(struct drm_encoder *encoder, nv17_gpio_set(dev, DCB_GPIO_TVDAC1, saved_gpio1); nv17_gpio_set(dev, DCB_GPIO_TVDAC0, saved_gpio0); - if (present) { - NV_INFO(dev, "Load detected on output %c\n", '@' + ffs(dcb->or)); + return sample; +} + +static enum drm_connector_status +nv17_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) +{ + struct drm_device *dev = encoder->dev; + struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb; + uint32_t sample = nv17_dac_sample_load(encoder); + + if (sample & NV_PRAMDAC_TEST_CONTROL_SENSEB_ALLHI) { + NV_INFO(dev, "Load detected on output %c\n", + '@' + ffs(dcb->or)); return connector_status_connected; + } else { + return connector_status_disconnected; } - - return connector_status_disconnected; } - static bool nv04_dac_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) diff --git a/drivers/gpu/drm/nouveau/nv17_tv.c b/drivers/gpu/drm/nouveau/nv17_tv.c index 81c0135..5fa4242 100644 --- a/drivers/gpu/drm/nouveau/nv17_tv.c +++ b/drivers/gpu/drm/nouveau/nv17_tv.c @@ -33,13 +33,15 @@ #include "nouveau_hw.h" #include "nv17_tv.h" -enum drm_connector_status nv17_tv_detect(struct drm_encoder *encoder, - struct drm_connector *connector, - uint32_t pin_mask) +static enum drm_connector_status +nv17_tv_detect(struct drm_encoder *encoder, struct drm_connector *connector) { + struct drm_device *dev = encoder->dev; + struct drm_mode_config *conf = &dev->mode_config; struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder); + struct dcb_entry *dcb = tv_enc->base.dcb; - tv_enc->pin_mask = pin_mask >> 28 & 0xe; + tv_enc->pin_mask = nv17_dac_sample_load(encoder) >> 28 & 0xe; switch (tv_enc->pin_mask) { case 0x2: @@ -50,7 +52,7 @@ enum drm_connector_status nv17_tv_detect(struct drm_encoder *encoder, tv_enc->subconnector = DRM_MODE_SUBCONNECTOR_SVIDEO; break; case 0xe: - if (nouveau_encoder(encoder)->dcb->tvconf.has_component_output) + if (dcb->tvconf.has_component_output) tv_enc->subconnector = DRM_MODE_SUBCONNECTOR_Component; else tv_enc->subconnector = DRM_MODE_SUBCONNECTOR_SCART; @@ -61,11 +63,16 @@ enum drm_connector_status nv17_tv_detect(struct drm_encoder *encoder, } drm_connector_property_set_value(connector, - encoder->dev->mode_config.tv_subconnector_property, - tv_enc->subconnector); + conf->tv_subconnector_property, + tv_enc->subconnector); - return tv_enc->subconnector ? connector_status_connected : - connector_status_disconnected; + if (tv_enc->subconnector) { + NV_INFO(dev, "Load detected on output %c\n", + '@' + ffs(dcb->or)); + return connector_status_connected; + } else { + return connector_status_disconnected; + } } static const struct { @@ -633,7 +640,7 @@ static struct drm_encoder_helper_funcs nv17_tv_helper_funcs = { .prepare = nv17_tv_prepare, .commit = nv17_tv_commit, .mode_set = nv17_tv_mode_set, - .detect = nv17_dac_detect, + .detect = nv17_tv_detect, }; static struct drm_encoder_slave_funcs nv17_tv_slave_funcs = { -- cgit v0.10.2 From b7f7e41b895afd110d1f5121161fd401eccd98c9 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Thu, 17 Dec 2009 18:57:44 +0100 Subject: drm/nouveau: Implement nv42-nv43 TV load detection. Signed-off-by: Francisco Jerez diff --git a/drivers/gpu/drm/nouveau/nv17_tv.c b/drivers/gpu/drm/nouveau/nv17_tv.c index 5fa4242..58b917c 100644 --- a/drivers/gpu/drm/nouveau/nv17_tv.c +++ b/drivers/gpu/drm/nouveau/nv17_tv.c @@ -33,15 +33,103 @@ #include "nouveau_hw.h" #include "nv17_tv.h" +static uint32_t nv42_tv_sample_load(struct drm_encoder *encoder) +{ + struct drm_device *dev = encoder->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + uint32_t testval, regoffset = nv04_dac_output_offset(encoder); + uint32_t gpio0, gpio1, fp_htotal, fp_hsync_start, fp_hsync_end, + fp_control, test_ctrl, dacclk, ctv_14, ctv_1c, ctv_6c; + uint32_t sample = 0; + int head; + +#define RGB_TEST_DATA(r, g, b) (r << 0 | g << 10 | b << 20) + testval = RGB_TEST_DATA(0x82, 0xeb, 0x82); + if (dev_priv->vbios->tvdactestval) + testval = dev_priv->vbios->tvdactestval; + + dacclk = NVReadRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset); + head = (dacclk & 0x100) >> 8; + + /* Save the previous state. */ + gpio1 = nv17_gpio_get(dev, DCB_GPIO_TVDAC1); + gpio0 = nv17_gpio_get(dev, DCB_GPIO_TVDAC0); + fp_htotal = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_HTOTAL); + fp_hsync_start = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_START); + fp_hsync_end = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_END); + fp_control = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_TG_CONTROL); + test_ctrl = NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset); + ctv_1c = NVReadRAMDAC(dev, head, 0x680c1c); + ctv_14 = NVReadRAMDAC(dev, head, 0x680c14); + ctv_6c = NVReadRAMDAC(dev, head, 0x680c6c); + + /* Prepare the DAC for load detection. */ + nv17_gpio_set(dev, DCB_GPIO_TVDAC1, true); + nv17_gpio_set(dev, DCB_GPIO_TVDAC0, true); + + NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HTOTAL, 1343); + NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_START, 1047); + NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_END, 1183); + NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_TG_CONTROL, + NV_PRAMDAC_FP_TG_CONTROL_DISPEN_POS | + NV_PRAMDAC_FP_TG_CONTROL_WIDTH_12 | + NV_PRAMDAC_FP_TG_CONTROL_READ_PROG | + NV_PRAMDAC_FP_TG_CONTROL_HSYNC_POS | + NV_PRAMDAC_FP_TG_CONTROL_VSYNC_POS); + + NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset, 0); + + NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset, + (dacclk & ~0xff) | 0x22); + msleep(1); + NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset, + (dacclk & ~0xff) | 0x21); + + NVWriteRAMDAC(dev, head, 0x680c1c, 1 << 20); + NVWriteRAMDAC(dev, head, 0x680c14, 4 << 16); + + /* Sample pin 0x4 (usually S-video luma). */ + NVWriteRAMDAC(dev, head, 0x680c6c, testval >> 10 & 0x3ff); + msleep(20); + sample |= NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset) + & 0x4 << 28; + + /* Sample the remaining pins. */ + NVWriteRAMDAC(dev, head, 0x680c6c, testval & 0x3ff); + msleep(20); + sample |= NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset) + & 0xa << 28; + + /* Restore the previous state. */ + NVWriteRAMDAC(dev, head, 0x680c1c, ctv_1c); + NVWriteRAMDAC(dev, head, 0x680c14, ctv_14); + NVWriteRAMDAC(dev, head, 0x680c6c, ctv_6c); + NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset, dacclk); + NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset, test_ctrl); + NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_TG_CONTROL, fp_control); + NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_END, fp_hsync_end); + NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_START, fp_hsync_start); + NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HTOTAL, fp_htotal); + nv17_gpio_set(dev, DCB_GPIO_TVDAC1, gpio1); + nv17_gpio_set(dev, DCB_GPIO_TVDAC0, gpio0); + + return sample; +} + static enum drm_connector_status nv17_tv_detect(struct drm_encoder *encoder, struct drm_connector *connector) { struct drm_device *dev = encoder->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_mode_config *conf = &dev->mode_config; struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder); struct dcb_entry *dcb = tv_enc->base.dcb; - tv_enc->pin_mask = nv17_dac_sample_load(encoder) >> 28 & 0xe; + if (dev_priv->chipset == 0x42 || + dev_priv->chipset == 0x43) + tv_enc->pin_mask = nv42_tv_sample_load(encoder) >> 28 & 0xe; + else + tv_enc->pin_mask = nv17_dac_sample_load(encoder) >> 28 & 0xe; switch (tv_enc->pin_mask) { case 0x2: -- cgit v0.10.2 From 8f71c29e442e013212a98e2b37eb1074c4d1134f Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Tue, 22 Dec 2009 18:24:09 +0100 Subject: drm/nouveau: Don't skip card take down on nv0x. Signed-off-by: Francisco Jerez diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 6a45913..a6b573e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -722,8 +722,8 @@ static void nouveau_close(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; - /* In the case of an error dev_priv may not be be allocated yet */ - if (dev_priv && dev_priv->card_type) + /* In the case of an error dev_priv may not be allocated yet */ + if (dev_priv) nouveau_card_takedown(dev); } -- cgit v0.10.2 From c2b82924bda0c3de2b49bd3a4d8b6725721820bc Mon Sep 17 00:00:00 2001 From: Maarten Maathuis Date: Fri, 25 Dec 2009 18:51:17 +0100 Subject: drm/nouveau: better alignment of bo sizes and use roundup instead of ALIGN - Aligning to block size should ensure that the extra size is enough. - Using roundup, because not all sizes are powers of two. Signed-off-by: Maarten Maathuis diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 5fd462f..a0c9e00 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -73,6 +73,7 @@ nouveau_bo_fixup_align(struct drm_device *dev, case 0x4800: case 0x7a00: if (dev_priv->chipset >= 0xA0) { + *size = roundup(*size, 28672); /* This is based on high end cards with 448 bits * memory bus, could be different elsewhere.*/ *size += 6 * 28672; @@ -80,9 +81,11 @@ nouveau_bo_fixup_align(struct drm_device *dev, * but we must also align to page size. */ *align = 2 * 8 * 28672; } else if (dev_priv->chipset >= 0x90) { + *size = roundup(*size, 16384); *size += 3 * 16384; *align = 12 * 16384; } else { + *size = roundup(*size, 8192); *size += 3 * 8192; /* 12 * 8192 is the actual alignment requirement * but we must also align to page size. */ @@ -114,10 +117,11 @@ nouveau_bo_fixup_align(struct drm_device *dev, } } - *size = ALIGN(*size, PAGE_SIZE); + /* ALIGN works only on powers of two. */ + *size = roundup(*size, PAGE_SIZE); if (dev_priv->card_type == NV_50) { - *size = ALIGN(*size, 65536); + *size = roundup(*size, 65536); *align = max(65536, *align); } } diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 84af25c..44cbbee 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -212,11 +212,11 @@ nouveau_fbcon_create(struct drm_device *dev, uint32_t fb_width, mode_cmd.bpp = surface_bpp; mode_cmd.pitch = mode_cmd.width * (mode_cmd.bpp >> 3); - mode_cmd.pitch = ALIGN(mode_cmd.pitch, 256); + mode_cmd.pitch = roundup(mode_cmd.pitch, 256); mode_cmd.depth = surface_depth; size = mode_cmd.pitch * mode_cmd.height; - size = ALIGN(size, PAGE_SIZE); + size = roundup(size, PAGE_SIZE); ret = nouveau_gem_new(dev, dev_priv->channel, size, 0, TTM_PL_FLAG_VRAM, 0, 0x0000, false, true, &nvbo); -- cgit v0.10.2 From 0a2d090f99c9686e5107ed59533fc4210a9a47d1 Mon Sep 17 00:00:00 2001 From: Maarten Maathuis Date: Sat, 26 Dec 2009 21:46:36 +0100 Subject: drm/nv50: make the blocksize depend on vram size - This should be better than what we have now. - I'm less sure about the non power of two path. Signed-off-by: Maarten Maathuis diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index a0c9e00..e342a41 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -33,6 +33,8 @@ #include "nouveau_drv.h" #include "nouveau_dma.h" +#include + static void nouveau_bo_del_ttm(struct ttm_buffer_object *bo) { @@ -67,29 +69,29 @@ nouveau_bo_fixup_align(struct drm_device *dev, * avoid corruption of other buffer objects. */ if (dev_priv->card_type == NV_50) { + uint32_t block_size = nouveau_mem_fb_amount(dev) >> 15; + int i; + switch (tile_flags) { case 0x1800: case 0x2800: case 0x4800: case 0x7a00: - if (dev_priv->chipset >= 0xA0) { - *size = roundup(*size, 28672); - /* This is based on high end cards with 448 bits - * memory bus, could be different elsewhere.*/ - *size += 6 * 28672; - /* 8 * 28672 is the actual alignment requirement - * but we must also align to page size. */ - *align = 2 * 8 * 28672; - } else if (dev_priv->chipset >= 0x90) { - *size = roundup(*size, 16384); - *size += 3 * 16384; - *align = 12 * 16384; + *size = roundup(*size, block_size); + if (is_power_of_2(block_size)) { + *size += 3 * block_size; + for (i = 1; i < 10; i++) { + *align = 12 * i * block_size; + if (!(*align % 65536)) + break; + } } else { - *size = roundup(*size, 8192); - *size += 3 * 8192; - /* 12 * 8192 is the actual alignment requirement - * but we must also align to page size. */ - *align = 2 * 12 * 8192; + *size += 6 * block_size; + for (i = 1; i < 10; i++) { + *align = 8 * i * block_size; + if (!(*align % 65536)) + break; + } } break; default: -- cgit v0.10.2 From ca4362adb4c01807dfcf3f2b3152a7ee36f0d1ca Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Sat, 26 Dec 2009 02:42:45 +0100 Subject: drm/nouveau: Allocate a per-channel instance of NV_SW. It will be useful for various synchronization purposes, mostly stolen from "[PATCH] drm/nv50: synchronize user channel after buffer object move on kernel channel" by Maarten Maathuis. Signed-off-by: Francisco Jerez diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c index 9aaa972..4f378b6 100644 --- a/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c @@ -414,7 +414,9 @@ nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data, init->subchan[0].grclass = 0x0039; else init->subchan[0].grclass = 0x5039; - init->nr_subchan = 1; + init->subchan[1].handle = NvSw; + init->subchan[1].grclass = NV_SW; + init->nr_subchan = 2; /* Named memory object area */ ret = drm_gem_handle_create(file_priv, chan->notifier_bo->gem, diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c index 7035536..f1fd3f2 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dma.c +++ b/drivers/gpu/drm/nouveau/nouveau_dma.c @@ -35,6 +35,7 @@ nouveau_dma_init(struct nouveau_channel *chan) struct drm_device *dev = chan->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_gpuobj *m2mf = NULL; + struct nouveau_gpuobj *nvsw = NULL; int ret, i; /* Create NV_MEMORY_TO_MEMORY_FORMAT for buffer moves */ @@ -47,6 +48,15 @@ nouveau_dma_init(struct nouveau_channel *chan) if (ret) return ret; + /* Create an NV_SW object for various sync purposes */ + ret = nouveau_gpuobj_sw_new(chan, NV_SW, &nvsw); + if (ret) + return ret; + + ret = nouveau_gpuobj_ref_add(dev, chan, NvSw, nvsw, NULL); + if (ret) + return ret; + /* NV_MEMORY_TO_MEMORY_FORMAT requires a notifier object */ ret = nouveau_notifier_alloc(chan, NvNotify0, 32, &chan->m2mf_ntfy); if (ret) @@ -87,6 +97,13 @@ nouveau_dma_init(struct nouveau_channel *chan) BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1); OUT_RING(chan, NvNotify0); + /* Initialise NV_SW */ + ret = RING_SPACE(chan, 2); + if (ret) + return ret; + BEGIN_RING(chan, NvSubSw, 0, 1); + OUT_RING(chan, NvSw); + /* Sit back and pray the channel works.. */ FIRE_RING(chan); diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.h b/drivers/gpu/drm/nouveau/nouveau_dma.h index 04e85d8..dabfd65 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dma.h +++ b/drivers/gpu/drm/nouveau/nouveau_dma.h @@ -46,10 +46,11 @@ /* Hardcoded object assignments to subchannels (subchannel id). */ enum { NvSubM2MF = 0, - NvSub2D = 1, - NvSubCtxSurf2D = 1, - NvSubGdiRect = 2, - NvSubImageBlit = 3 + NvSubSw = 1, + NvSub2D = 2, + NvSubCtxSurf2D = 2, + NvSubGdiRect = 3, + NvSubImageBlit = 4 }; /* Object handles. */ @@ -67,6 +68,7 @@ enum { NvClipRect = 0x8000000b, NvGdiRect = 0x8000000c, NvImageBlit = 0x8000000d, + NvSw = 0x8000000e, /* G80+ display objects */ NvEvoVRAM = 0x01000000, diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 7da88a9..9181eae 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -788,6 +788,8 @@ extern int nouveau_gpuobj_gart_dma_new(struct nouveau_channel *, uint32_t *o_ret); extern int nouveau_gpuobj_gr_new(struct nouveau_channel *, int class, struct nouveau_gpuobj **); +extern int nouveau_gpuobj_sw_new(struct nouveau_channel *, int class, + struct nouveau_gpuobj **); extern int nouveau_ioctl_grobj_alloc(struct drm_device *, void *data, struct drm_file *); extern int nouveau_ioctl_gpuobj_free(struct drm_device *, void *data, @@ -1330,14 +1332,14 @@ nv_two_reg_pll(struct drm_device *dev) return false; } -#define NV50_NVSW 0x0000506e -#define NV50_NVSW_DMA_SEMAPHORE 0x00000060 -#define NV50_NVSW_SEMAPHORE_OFFSET 0x00000064 -#define NV50_NVSW_SEMAPHORE_ACQUIRE 0x00000068 -#define NV50_NVSW_SEMAPHORE_RELEASE 0x0000006c -#define NV50_NVSW_DMA_VBLSEM 0x0000018c -#define NV50_NVSW_VBLSEM_OFFSET 0x00000400 -#define NV50_NVSW_VBLSEM_RELEASE_VALUE 0x00000404 -#define NV50_NVSW_VBLSEM_RELEASE 0x00000408 +#define NV_SW 0x0000506e +#define NV_SW_DMA_SEMAPHORE 0x00000060 +#define NV_SW_SEMAPHORE_OFFSET 0x00000064 +#define NV_SW_SEMAPHORE_ACQUIRE 0x00000068 +#define NV_SW_SEMAPHORE_RELEASE 0x0000006c +#define NV_SW_DMA_VBLSEM 0x0000018c +#define NV_SW_VBLSEM_OFFSET 0x00000400 +#define NV_SW_VBLSEM_RELEASE_VALUE 0x00000404 +#define NV_SW_VBLSEM_RELEASE 0x00000408 #endif /* __NOUVEAU_DRV_H__ */ diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c index 93379bb..6c2cf817 100644 --- a/drivers/gpu/drm/nouveau/nouveau_object.c +++ b/drivers/gpu/drm/nouveau/nouveau_object.c @@ -881,7 +881,7 @@ nouveau_gpuobj_gr_new(struct nouveau_channel *chan, int class, return 0; } -static int +int nouveau_gpuobj_sw_new(struct nouveau_channel *chan, int class, struct nouveau_gpuobj **gpuobj_ret) { diff --git a/drivers/gpu/drm/nouveau/nv04_fbcon.c b/drivers/gpu/drm/nouveau/nv04_fbcon.c index 09a3107..d2d7f08 100644 --- a/drivers/gpu/drm/nouveau/nv04_fbcon.c +++ b/drivers/gpu/drm/nouveau/nv04_fbcon.c @@ -184,6 +184,7 @@ nv04_fbcon_accel_init(struct fb_info *info) struct drm_device *dev = par->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_channel *chan = dev_priv->channel; + const int sub = NvSubCtxSurf2D; int surface_fmt, pattern_fmt, rect_fmt; int ret; @@ -247,25 +248,25 @@ nv04_fbcon_accel_init(struct fb_info *info) return 0; } - BEGIN_RING(chan, 1, 0x0000, 1); + BEGIN_RING(chan, sub, 0x0000, 1); OUT_RING(chan, NvCtxSurf2D); - BEGIN_RING(chan, 1, 0x0184, 2); + BEGIN_RING(chan, sub, 0x0184, 2); OUT_RING(chan, NvDmaFB); OUT_RING(chan, NvDmaFB); - BEGIN_RING(chan, 1, 0x0300, 4); + BEGIN_RING(chan, sub, 0x0300, 4); OUT_RING(chan, surface_fmt); OUT_RING(chan, info->fix.line_length | (info->fix.line_length << 16)); OUT_RING(chan, info->fix.smem_start - dev->mode_config.fb_base); OUT_RING(chan, info->fix.smem_start - dev->mode_config.fb_base); - BEGIN_RING(chan, 1, 0x0000, 1); + BEGIN_RING(chan, sub, 0x0000, 1); OUT_RING(chan, NvRop); - BEGIN_RING(chan, 1, 0x0300, 1); + BEGIN_RING(chan, sub, 0x0300, 1); OUT_RING(chan, 0x55); - BEGIN_RING(chan, 1, 0x0000, 1); + BEGIN_RING(chan, sub, 0x0000, 1); OUT_RING(chan, NvImagePatt); - BEGIN_RING(chan, 1, 0x0300, 8); + BEGIN_RING(chan, sub, 0x0300, 8); OUT_RING(chan, pattern_fmt); #ifdef __BIG_ENDIAN OUT_RING(chan, 2); @@ -279,9 +280,9 @@ nv04_fbcon_accel_init(struct fb_info *info) OUT_RING(chan, ~0); OUT_RING(chan, ~0); - BEGIN_RING(chan, 1, 0x0000, 1); + BEGIN_RING(chan, sub, 0x0000, 1); OUT_RING(chan, NvClipRect); - BEGIN_RING(chan, 1, 0x0300, 2); + BEGIN_RING(chan, sub, 0x0300, 2); OUT_RING(chan, 0); OUT_RING(chan, (info->var.yres_virtual << 16) | info->var.xres_virtual); -- cgit v0.10.2 From a5027ccd3c1abe190d2b84a2d7e40d5f099e48a7 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Sat, 26 Dec 2009 02:09:36 +0100 Subject: drm/nouveau: Use the software object for fencing. This should avoid a race condition on nv0x, if we're doing it with actual PGRAPH objects and a there's a fence within the FIFO DMA fetch area when a context switch kicks in. In that case we get an ILLEGAL_MTHD interrupt as expected, but the values in PGRAPH_TRAPPED_ADDR aren't calculated correctly and they're almost useless (e.g. you can see ILLEGAL_MTHDs for the now inactive channel, with a wrong offset/data pair). Signed-off-by: Francisco Jerez diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index dacac9a..faddf53 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c @@ -142,7 +142,7 @@ nouveau_fence_emit(struct nouveau_fence *fence) list_add_tail(&fence->entry, &chan->fence.pending); spin_unlock_irqrestore(&chan->fence.lock, flags); - BEGIN_RING(chan, NvSubM2MF, USE_REFCNT ? 0x0050 : 0x0150, 1); + BEGIN_RING(chan, NvSubSw, USE_REFCNT ? 0x0050 : 0x0150, 1); OUT_RING(chan, fence->sequence); FIRE_RING(chan); diff --git a/drivers/gpu/drm/nouveau/nv04_graph.c b/drivers/gpu/drm/nouveau/nv04_graph.c index d561d77..82c77f9 100644 --- a/drivers/gpu/drm/nouveau/nv04_graph.c +++ b/drivers/gpu/drm/nouveau/nv04_graph.c @@ -547,7 +547,7 @@ nv04_graph_mthd_set_operation(struct nouveau_channel *chan, int grclass, return 0; } -static struct nouveau_pgraph_object_method nv04_graph_mthds_m2mf[] = { +static struct nouveau_pgraph_object_method nv04_graph_mthds_sw[] = { { 0x0150, nv04_graph_mthd_set_ref }, {} }; @@ -558,7 +558,7 @@ static struct nouveau_pgraph_object_method nv04_graph_mthds_set_operation[] = { }; struct nouveau_pgraph_object_class nv04_graph_grclass[] = { - { 0x0039, false, nv04_graph_mthds_m2mf }, + { 0x0039, false, NULL }, { 0x004a, false, nv04_graph_mthds_set_operation }, /* gdirect */ { 0x005f, false, nv04_graph_mthds_set_operation }, /* imageblit */ { 0x0061, false, nv04_graph_mthds_set_operation }, /* ifc */ @@ -574,6 +574,7 @@ struct nouveau_pgraph_object_class nv04_graph_grclass[] = { { 0x0053, false, NULL }, /* surf3d */ { 0x0054, false, NULL }, /* tex_tri */ { 0x0055, false, NULL }, /* multitex_tri */ + { 0x506e, true, nv04_graph_mthds_sw }, {} }; -- cgit v0.10.2 From ea911a1cf4f9c5bef18ff399ee2e2ec77792b650 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Sat, 26 Dec 2009 14:39:46 +0100 Subject: drm/nv04: Context switching fixes. Signed-off-by: Francisco Jerez diff --git a/drivers/gpu/drm/nouveau/nv04_graph.c b/drivers/gpu/drm/nouveau/nv04_graph.c index 82c77f9..98f3b40 100644 --- a/drivers/gpu/drm/nouveau/nv04_graph.c +++ b/drivers/gpu/drm/nouveau/nv04_graph.c @@ -28,6 +28,10 @@ #include "nouveau_drv.h" static uint32_t nv04_graph_ctx_regs[] = { + 0x0040053c, + 0x00400544, + 0x00400540, + 0x00400548, NV04_PGRAPH_CTX_SWITCH1, NV04_PGRAPH_CTX_SWITCH2, NV04_PGRAPH_CTX_SWITCH3, @@ -102,69 +106,69 @@ static uint32_t nv04_graph_ctx_regs[] = { NV04_PGRAPH_PATT_COLOR0, NV04_PGRAPH_PATT_COLOR1, NV04_PGRAPH_PATT_COLORRAM+0x00, - NV04_PGRAPH_PATT_COLORRAM+0x01, - NV04_PGRAPH_PATT_COLORRAM+0x02, - NV04_PGRAPH_PATT_COLORRAM+0x03, NV04_PGRAPH_PATT_COLORRAM+0x04, - NV04_PGRAPH_PATT_COLORRAM+0x05, - NV04_PGRAPH_PATT_COLORRAM+0x06, - NV04_PGRAPH_PATT_COLORRAM+0x07, NV04_PGRAPH_PATT_COLORRAM+0x08, - NV04_PGRAPH_PATT_COLORRAM+0x09, - NV04_PGRAPH_PATT_COLORRAM+0x0A, - NV04_PGRAPH_PATT_COLORRAM+0x0B, - NV04_PGRAPH_PATT_COLORRAM+0x0C, - NV04_PGRAPH_PATT_COLORRAM+0x0D, - NV04_PGRAPH_PATT_COLORRAM+0x0E, - NV04_PGRAPH_PATT_COLORRAM+0x0F, + NV04_PGRAPH_PATT_COLORRAM+0x0c, NV04_PGRAPH_PATT_COLORRAM+0x10, - NV04_PGRAPH_PATT_COLORRAM+0x11, - NV04_PGRAPH_PATT_COLORRAM+0x12, - NV04_PGRAPH_PATT_COLORRAM+0x13, NV04_PGRAPH_PATT_COLORRAM+0x14, - NV04_PGRAPH_PATT_COLORRAM+0x15, - NV04_PGRAPH_PATT_COLORRAM+0x16, - NV04_PGRAPH_PATT_COLORRAM+0x17, NV04_PGRAPH_PATT_COLORRAM+0x18, - NV04_PGRAPH_PATT_COLORRAM+0x19, - NV04_PGRAPH_PATT_COLORRAM+0x1A, - NV04_PGRAPH_PATT_COLORRAM+0x1B, - NV04_PGRAPH_PATT_COLORRAM+0x1C, - NV04_PGRAPH_PATT_COLORRAM+0x1D, - NV04_PGRAPH_PATT_COLORRAM+0x1E, - NV04_PGRAPH_PATT_COLORRAM+0x1F, + NV04_PGRAPH_PATT_COLORRAM+0x1c, NV04_PGRAPH_PATT_COLORRAM+0x20, - NV04_PGRAPH_PATT_COLORRAM+0x21, - NV04_PGRAPH_PATT_COLORRAM+0x22, - NV04_PGRAPH_PATT_COLORRAM+0x23, NV04_PGRAPH_PATT_COLORRAM+0x24, - NV04_PGRAPH_PATT_COLORRAM+0x25, - NV04_PGRAPH_PATT_COLORRAM+0x26, - NV04_PGRAPH_PATT_COLORRAM+0x27, NV04_PGRAPH_PATT_COLORRAM+0x28, - NV04_PGRAPH_PATT_COLORRAM+0x29, - NV04_PGRAPH_PATT_COLORRAM+0x2A, - NV04_PGRAPH_PATT_COLORRAM+0x2B, - NV04_PGRAPH_PATT_COLORRAM+0x2C, - NV04_PGRAPH_PATT_COLORRAM+0x2D, - NV04_PGRAPH_PATT_COLORRAM+0x2E, - NV04_PGRAPH_PATT_COLORRAM+0x2F, + NV04_PGRAPH_PATT_COLORRAM+0x2c, NV04_PGRAPH_PATT_COLORRAM+0x30, - NV04_PGRAPH_PATT_COLORRAM+0x31, - NV04_PGRAPH_PATT_COLORRAM+0x32, - NV04_PGRAPH_PATT_COLORRAM+0x33, NV04_PGRAPH_PATT_COLORRAM+0x34, - NV04_PGRAPH_PATT_COLORRAM+0x35, - NV04_PGRAPH_PATT_COLORRAM+0x36, - NV04_PGRAPH_PATT_COLORRAM+0x37, NV04_PGRAPH_PATT_COLORRAM+0x38, - NV04_PGRAPH_PATT_COLORRAM+0x39, - NV04_PGRAPH_PATT_COLORRAM+0x3A, - NV04_PGRAPH_PATT_COLORRAM+0x3B, - NV04_PGRAPH_PATT_COLORRAM+0x3C, - NV04_PGRAPH_PATT_COLORRAM+0x3D, - NV04_PGRAPH_PATT_COLORRAM+0x3E, - NV04_PGRAPH_PATT_COLORRAM+0x3F, + NV04_PGRAPH_PATT_COLORRAM+0x3c, + NV04_PGRAPH_PATT_COLORRAM+0x40, + NV04_PGRAPH_PATT_COLORRAM+0x44, + NV04_PGRAPH_PATT_COLORRAM+0x48, + NV04_PGRAPH_PATT_COLORRAM+0x4c, + NV04_PGRAPH_PATT_COLORRAM+0x50, + NV04_PGRAPH_PATT_COLORRAM+0x54, + NV04_PGRAPH_PATT_COLORRAM+0x58, + NV04_PGRAPH_PATT_COLORRAM+0x5c, + NV04_PGRAPH_PATT_COLORRAM+0x60, + NV04_PGRAPH_PATT_COLORRAM+0x64, + NV04_PGRAPH_PATT_COLORRAM+0x68, + NV04_PGRAPH_PATT_COLORRAM+0x6c, + NV04_PGRAPH_PATT_COLORRAM+0x70, + NV04_PGRAPH_PATT_COLORRAM+0x74, + NV04_PGRAPH_PATT_COLORRAM+0x78, + NV04_PGRAPH_PATT_COLORRAM+0x7c, + NV04_PGRAPH_PATT_COLORRAM+0x80, + NV04_PGRAPH_PATT_COLORRAM+0x84, + NV04_PGRAPH_PATT_COLORRAM+0x88, + NV04_PGRAPH_PATT_COLORRAM+0x8c, + NV04_PGRAPH_PATT_COLORRAM+0x90, + NV04_PGRAPH_PATT_COLORRAM+0x94, + NV04_PGRAPH_PATT_COLORRAM+0x98, + NV04_PGRAPH_PATT_COLORRAM+0x9c, + NV04_PGRAPH_PATT_COLORRAM+0xa0, + NV04_PGRAPH_PATT_COLORRAM+0xa4, + NV04_PGRAPH_PATT_COLORRAM+0xa8, + NV04_PGRAPH_PATT_COLORRAM+0xac, + NV04_PGRAPH_PATT_COLORRAM+0xb0, + NV04_PGRAPH_PATT_COLORRAM+0xb4, + NV04_PGRAPH_PATT_COLORRAM+0xb8, + NV04_PGRAPH_PATT_COLORRAM+0xbc, + NV04_PGRAPH_PATT_COLORRAM+0xc0, + NV04_PGRAPH_PATT_COLORRAM+0xc4, + NV04_PGRAPH_PATT_COLORRAM+0xc8, + NV04_PGRAPH_PATT_COLORRAM+0xcc, + NV04_PGRAPH_PATT_COLORRAM+0xd0, + NV04_PGRAPH_PATT_COLORRAM+0xd4, + NV04_PGRAPH_PATT_COLORRAM+0xd8, + NV04_PGRAPH_PATT_COLORRAM+0xdc, + NV04_PGRAPH_PATT_COLORRAM+0xe0, + NV04_PGRAPH_PATT_COLORRAM+0xe4, + NV04_PGRAPH_PATT_COLORRAM+0xe8, + NV04_PGRAPH_PATT_COLORRAM+0xec, + NV04_PGRAPH_PATT_COLORRAM+0xf0, + NV04_PGRAPH_PATT_COLORRAM+0xf4, + NV04_PGRAPH_PATT_COLORRAM+0xf8, + NV04_PGRAPH_PATT_COLORRAM+0xfc, NV04_PGRAPH_PATTERN, 0x0040080c, NV04_PGRAPH_PATTERN_SHAPE, @@ -247,14 +251,6 @@ static uint32_t nv04_graph_ctx_regs[] = { 0x004004f8, 0x0040047c, 0x004004fc, - 0x0040053c, - 0x00400544, - 0x00400540, - 0x00400548, - 0x00400560, - 0x00400568, - 0x00400564, - 0x0040056c, 0x00400534, 0x00400538, 0x00400514, @@ -341,9 +337,8 @@ static uint32_t nv04_graph_ctx_regs[] = { 0x00400500, 0x00400504, NV04_PGRAPH_VALID1, - NV04_PGRAPH_VALID2 - - + NV04_PGRAPH_VALID2, + NV04_PGRAPH_DEBUG_3 }; struct graph_state { @@ -388,6 +383,18 @@ nv04_graph_context_switch(struct drm_device *dev) pgraph->fifo_access(dev, true); } +static uint32_t *ctx_reg(struct graph_state *ctx, uint32_t reg) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(nv04_graph_ctx_regs); i++) { + if (nv04_graph_ctx_regs[i] == reg) + return &ctx->nv04[i]; + } + + return NULL; +} + int nv04_graph_create_context(struct nouveau_channel *chan) { struct graph_state *pgraph_ctx; @@ -398,15 +405,8 @@ int nv04_graph_create_context(struct nouveau_channel *chan) if (pgraph_ctx == NULL) return -ENOMEM; - /* dev_priv->fifos[channel].pgraph_ctx_user = channel << 24; */ - pgraph_ctx->nv04[0] = 0x0001ffff; - /* is it really needed ??? */ -#if 0 - dev_priv->fifos[channel].pgraph_ctx[1] = - nv_rd32(dev, NV_PGRAPH_DEBUG_4); - dev_priv->fifos[channel].pgraph_ctx[2] = - nv_rd32(dev, 0x004006b0); -#endif + *ctx_reg(pgraph_ctx, NV04_PGRAPH_DEBUG_3) = 0xfad4ff31; + return 0; } @@ -429,9 +429,13 @@ int nv04_graph_load_context(struct nouveau_channel *chan) nv_wr32(dev, nv04_graph_ctx_regs[i], pgraph_ctx->nv04[i]); nv_wr32(dev, NV04_PGRAPH_CTX_CONTROL, 0x10010100); - nv_wr32(dev, NV04_PGRAPH_CTX_USER, chan->id << 24); + + tmp = nv_rd32(dev, NV04_PGRAPH_CTX_USER) & 0x00ffffff; + nv_wr32(dev, NV04_PGRAPH_CTX_USER, tmp | chan->id << 24); + tmp = nv_rd32(dev, NV04_PGRAPH_FFINTFC_ST2); nv_wr32(dev, NV04_PGRAPH_FFINTFC_ST2, tmp & 0x000fffff); + return 0; } @@ -494,7 +498,7 @@ int nv04_graph_init(struct drm_device *dev) nv_wr32(dev, NV04_PGRAPH_STATE , 0xFFFFFFFF); nv_wr32(dev, NV04_PGRAPH_CTX_CONTROL , 0x10000100); tmp = nv_rd32(dev, NV04_PGRAPH_CTX_USER) & 0x00ffffff; - tmp |= dev_priv->engine.fifo.channels << 24; + tmp |= (dev_priv->engine.fifo.channels - 1) << 24; nv_wr32(dev, NV04_PGRAPH_CTX_USER, tmp); /* These don't belong here, they're part of a per-channel context */ -- cgit v0.10.2 From 7de3643f938af910bef4c1f800176a3ebdc29502 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 4 Jan 2010 09:10:55 +1000 Subject: drm/nouveau: fix handling of fbcon colours in 8bpp Depending on the visual, the colours handed to us in fillrect() can either be an actual colour, or an index into the pseudo-palette. Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nv04_fbcon.c b/drivers/gpu/drm/nouveau/nv04_fbcon.c index d2d7f08..bd08a0d 100644 --- a/drivers/gpu/drm/nouveau/nv04_fbcon.c +++ b/drivers/gpu/drm/nouveau/nv04_fbcon.c @@ -62,7 +62,6 @@ nv04_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) struct drm_device *dev = par->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_channel *chan = dev_priv->channel; - uint32_t color = ((uint32_t *) info->pseudo_palette)[rect->color]; if (info->state != FBINFO_STATE_RUNNING) return; @@ -80,7 +79,11 @@ nv04_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) BEGIN_RING(chan, NvSubGdiRect, 0x02fc, 1); OUT_RING(chan, (rect->rop != ROP_COPY) ? 1 : 3); BEGIN_RING(chan, NvSubGdiRect, 0x03fc, 1); - OUT_RING(chan, color); + if (info->fix.visual == FB_VISUAL_TRUECOLOR || + info->fix.visual == FB_VISUAL_DIRECTCOLOR) + OUT_RING(chan, ((uint32_t *)info->pseudo_palette)[rect->color]); + else + OUT_RING(chan, rect->color); BEGIN_RING(chan, NvSubGdiRect, 0x0400, 2); OUT_RING(chan, (rect->dx << 16) | rect->dy); OUT_RING(chan, (rect->width << 16) | rect->height); diff --git a/drivers/gpu/drm/nouveau/nv50_fbcon.c b/drivers/gpu/drm/nouveau/nv50_fbcon.c index c966ef8..cc34356 100644 --- a/drivers/gpu/drm/nouveau/nv50_fbcon.c +++ b/drivers/gpu/drm/nouveau/nv50_fbcon.c @@ -10,7 +10,6 @@ nv50_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) struct drm_device *dev = par->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_channel *chan = dev_priv->channel; - uint32_t color = ((uint32_t *) info->pseudo_palette)[rect->color]; if (info->state != FBINFO_STATE_RUNNING) return; @@ -32,7 +31,11 @@ nv50_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) OUT_RING(chan, 1); } BEGIN_RING(chan, NvSub2D, 0x0588, 1); - OUT_RING(chan, color); + if (info->fix.visual == FB_VISUAL_TRUECOLOR || + info->fix.visual == FB_VISUAL_DIRECTCOLOR) + OUT_RING(chan, ((uint32_t *)info->pseudo_palette)[rect->color]); + else + OUT_RING(chan, rect->color); BEGIN_RING(chan, NvSub2D, 0x0600, 4); OUT_RING(chan, rect->dx); OUT_RING(chan, rect->dy); -- cgit v0.10.2 From e9dd8e11edfff5e348f3dcfd152a70c5da921126 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 4 Jan 2010 12:53:01 +1000 Subject: drm/nouveau: remove unused nouveau_channel_idle() function Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c index 4f378b6..d1c7f8c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c @@ -235,47 +235,6 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, return 0; } -int -nouveau_channel_idle(struct nouveau_channel *chan) -{ - struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_engine *engine = &dev_priv->engine; - uint32_t caches; - int idle; - - if (!chan) { - NV_ERROR(dev, "no channel...\n"); - return 1; - } - - caches = nv_rd32(dev, NV03_PFIFO_CACHES); - nv_wr32(dev, NV03_PFIFO_CACHES, caches & ~1); - - if (engine->fifo.channel_id(dev) != chan->id) { - struct nouveau_gpuobj *ramfc = - chan->ramfc ? chan->ramfc->gpuobj : NULL; - - if (!ramfc) { - NV_ERROR(dev, "No RAMFC for channel %d\n", chan->id); - return 1; - } - - engine->instmem.prepare_access(dev, false); - if (nv_ro32(dev, ramfc, 0) != nv_ro32(dev, ramfc, 1)) - idle = 0; - else - idle = 1; - engine->instmem.finish_access(dev); - } else { - idle = (nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET) == - nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUT)); - } - - nv_wr32(dev, NV03_PFIFO_CACHES, caches); - return idle; -} - /* stops a fifo */ void nouveau_channel_free(struct nouveau_channel *chan) diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 9181eae..4087a9a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -745,7 +745,6 @@ extern int nouveau_channel_alloc(struct drm_device *dev, struct drm_file *file_priv, uint32_t fb_ctxdma, uint32_t tt_ctxdma); extern void nouveau_channel_free(struct nouveau_channel *); -extern int nouveau_channel_idle(struct nouveau_channel *chan); /* nouveau_object.c */ extern int nouveau_gpuobj_early_init(struct drm_device *); -- cgit v0.10.2 From c03ec7f91fcf20af177dbc728d518fb462bad42d Mon Sep 17 00:00:00 2001 From: Marcin Slusarz Date: Mon, 4 Jan 2010 19:25:09 +0100 Subject: drm/nouveau: create function for "dealing" with gpu lockup It's mostly a cleanup, but in nv50_fbcon_accel_init gpu lockup message was printed, but HWACCEL_DISBALED flag was not set. Signed-off-by: Marcin Slusarz Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 44cbbee..0b05c86 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -64,8 +64,7 @@ nouveau_fbcon_sync(struct fb_info *info) return 0; if (RING_SPACE(chan, 4)) { - NV_ERROR(dev, "GPU lockup - switching to software fbcon\n"); - info->flags |= FBINFO_HWACCEL_DISABLED; + nouveau_fbcon_gpu_lockup(info); return 0; } @@ -86,8 +85,7 @@ nouveau_fbcon_sync(struct fb_info *info) } if (ret) { - NV_ERROR(dev, "GPU lockup - switching to software fbcon\n"); - info->flags |= FBINFO_HWACCEL_DISABLED; + nouveau_fbcon_gpu_lockup(info); return 0; } @@ -380,3 +378,12 @@ nouveau_fbcon_remove(struct drm_device *dev, struct drm_framebuffer *fb) return 0; } + +void nouveau_fbcon_gpu_lockup(struct fb_info *info) +{ + struct nouveau_fbcon_par *par = info->par; + struct drm_device *dev = par->dev; + + NV_ERROR(dev, "GPU lockup - switching to software fbcon\n"); + info->flags |= FBINFO_HWACCEL_DISABLED; +} diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.h b/drivers/gpu/drm/nouveau/nouveau_fbcon.h index 8531140..462e0b8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.h +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.h @@ -43,5 +43,6 @@ void nouveau_fbcon_zfill(struct drm_device *dev); int nv04_fbcon_accel_init(struct fb_info *info); int nv50_fbcon_accel_init(struct fb_info *info); +void nouveau_fbcon_gpu_lockup(struct fb_info *info); #endif /* __NV50_FBCON_H__ */ diff --git a/drivers/gpu/drm/nouveau/nv04_fbcon.c b/drivers/gpu/drm/nouveau/nv04_fbcon.c index bd08a0d..d910873 100644 --- a/drivers/gpu/drm/nouveau/nv04_fbcon.c +++ b/drivers/gpu/drm/nouveau/nv04_fbcon.c @@ -39,8 +39,7 @@ nv04_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region) return; if (!(info->flags & FBINFO_HWACCEL_DISABLED) && RING_SPACE(chan, 4)) { - NV_ERROR(dev, "GPU lockup - switching to software fbcon\n"); - info->flags |= FBINFO_HWACCEL_DISABLED; + nouveau_fbcon_gpu_lockup(info); } if (info->flags & FBINFO_HWACCEL_DISABLED) { @@ -67,8 +66,7 @@ nv04_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) return; if (!(info->flags & FBINFO_HWACCEL_DISABLED) && RING_SPACE(chan, 7)) { - NV_ERROR(dev, "GPU lockup - switching to software fbcon\n"); - info->flags |= FBINFO_HWACCEL_DISABLED; + nouveau_fbcon_gpu_lockup(info); } if (info->flags & FBINFO_HWACCEL_DISABLED) { @@ -112,8 +110,7 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) } if (!(info->flags & FBINFO_HWACCEL_DISABLED) && RING_SPACE(chan, 8)) { - NV_ERROR(dev, "GPU lockup - switching to software fbcon\n"); - info->flags |= FBINFO_HWACCEL_DISABLED; + nouveau_fbcon_gpu_lockup(info); } if (info->flags & FBINFO_HWACCEL_DISABLED) { @@ -147,8 +144,7 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) int iter_len = dsize > 128 ? 128 : dsize; if (RING_SPACE(chan, iter_len + 1)) { - NV_ERROR(dev, "GPU lockup - switching to software fbcon\n"); - info->flags |= FBINFO_HWACCEL_DISABLED; + nouveau_fbcon_gpu_lockup(info); cfb_imageblit(info, image); return; } @@ -246,8 +242,7 @@ nv04_fbcon_accel_init(struct fb_info *info) return ret; if (RING_SPACE(chan, 49)) { - NV_ERROR(dev, "GPU lockup - switching to software fbcon\n"); - info->flags |= FBINFO_HWACCEL_DISABLED; + nouveau_fbcon_gpu_lockup(info); return 0; } diff --git a/drivers/gpu/drm/nouveau/nv50_fbcon.c b/drivers/gpu/drm/nouveau/nv50_fbcon.c index cc34356..e4f279e 100644 --- a/drivers/gpu/drm/nouveau/nv50_fbcon.c +++ b/drivers/gpu/drm/nouveau/nv50_fbcon.c @@ -16,9 +16,7 @@ nv50_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) if (!(info->flags & FBINFO_HWACCEL_DISABLED) && RING_SPACE(chan, rect->rop == ROP_COPY ? 7 : 11)) { - NV_ERROR(dev, "GPU lockup - switching to software fbcon\n"); - - info->flags |= FBINFO_HWACCEL_DISABLED; + nouveau_fbcon_gpu_lockup(info); } if (info->flags & FBINFO_HWACCEL_DISABLED) { @@ -60,9 +58,7 @@ nv50_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region) return; if (!(info->flags & FBINFO_HWACCEL_DISABLED) && RING_SPACE(chan, 12)) { - NV_ERROR(dev, "GPU lockup - switching to software fbcon\n"); - - info->flags |= FBINFO_HWACCEL_DISABLED; + nouveau_fbcon_gpu_lockup(info); } if (info->flags & FBINFO_HWACCEL_DISABLED) { @@ -105,8 +101,7 @@ nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) } if (!(info->flags & FBINFO_HWACCEL_DISABLED) && RING_SPACE(chan, 11)) { - NV_ERROR(dev, "GPU lockup - switching to software fbcon\n"); - info->flags |= FBINFO_HWACCEL_DISABLED; + nouveau_fbcon_gpu_lockup(info); } if (info->flags & FBINFO_HWACCEL_DISABLED) { @@ -139,9 +134,7 @@ nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) int push = dwords > 2047 ? 2047 : dwords; if (RING_SPACE(chan, push + 1)) { - NV_ERROR(dev, - "GPU lockup - switching to software fbcon\n"); - info->flags |= FBINFO_HWACCEL_DISABLED; + nouveau_fbcon_gpu_lockup(info); cfb_imageblit(info, image); return; } @@ -203,7 +196,7 @@ nv50_fbcon_accel_init(struct fb_info *info) ret = RING_SPACE(chan, 59); if (ret) { - NV_ERROR(dev, "GPU lockup - switching to software fbcon\n"); + nouveau_fbcon_gpu_lockup(info); return ret; } -- cgit v0.10.2 From a908b96c22883f967e4ddf5aa5b35e3b4a0629a5 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 5 Jan 2010 09:41:05 +1000 Subject: drm/nv50: restore correct cache1 get/put address on fifoctx load Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nv50_fifo.c b/drivers/gpu/drm/nouveau/nv50_fifo.c index b728228..39caf16 100644 --- a/drivers/gpu/drm/nouveau/nv50_fifo.c +++ b/drivers/gpu/drm/nouveau/nv50_fifo.c @@ -384,8 +384,8 @@ nv50_fifo_load_context(struct nouveau_channel *chan) nv_wr32(dev, NV40_PFIFO_CACHE1_DATA(ptr), nv_ro32(dev, cache, (ptr * 2) + 1)); } - nv_wr32(dev, 0x3210, cnt << 2); - nv_wr32(dev, 0x3270, 0); + nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, cnt << 2); + nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0); /* guessing that all the 0x34xx regs aren't on NV50 */ if (!IS_G80) { @@ -398,8 +398,6 @@ nv50_fifo_load_context(struct nouveau_channel *chan) dev_priv->engine.instmem.finish_access(dev); - nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0); - nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, 0); nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, chan->id | (1<<16)); return 0; } -- cgit v0.10.2 From 1959ca80e1f88b82c1cb7227f437910768ab0c94 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 4 Jan 2010 15:52:20 +1000 Subject: drm/nouveau: have ttm's fault handler called directly There's no good reason for us to have our own anymore, this is left over from an early port to these TTM interfaces. Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c index 187eb84..c385d50 100644 --- a/drivers/gpu/drm/nouveau/nouveau_ttm.c +++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c @@ -28,45 +28,17 @@ #include "nouveau_drv.h" -static struct vm_operations_struct nouveau_ttm_vm_ops; -static const struct vm_operations_struct *ttm_vm_ops; - -static int -nouveau_ttm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) -{ - struct ttm_buffer_object *bo = vma->vm_private_data; - int ret; - - if (unlikely(bo == NULL)) - return VM_FAULT_NOPAGE; - - ret = ttm_vm_ops->fault(vma, vmf); - return ret; -} - int nouveau_ttm_mmap(struct file *filp, struct vm_area_struct *vma) { struct drm_file *file_priv = filp->private_data; struct drm_nouveau_private *dev_priv = file_priv->minor->dev->dev_private; - int ret; if (unlikely(vma->vm_pgoff < DRM_FILE_PAGE_OFFSET)) return drm_mmap(filp, vma); - ret = ttm_bo_mmap(filp, vma, &dev_priv->ttm.bdev); - if (unlikely(ret != 0)) - return ret; - - if (unlikely(ttm_vm_ops == NULL)) { - ttm_vm_ops = vma->vm_ops; - nouveau_ttm_vm_ops = *ttm_vm_ops; - nouveau_ttm_vm_ops.fault = &nouveau_ttm_fault; - } - - vma->vm_ops = &nouveau_ttm_vm_ops; - return 0; + return ttm_bo_mmap(filp, vma, &dev_priv->ttm.bdev); } static int -- cgit v0.10.2 From dc8d76cac942e7344a72ad18afb90fa46cf20bb4 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 6 Jan 2010 12:00:02 +1000 Subject: drm/nv50: prevent a possible ctxprog hang The below is mainly an educated guess at what's going on, docs would sure be handy... NVIDIA? :P It appears it's possible for a ctxprog to run even while a GPU exception is pending. The GF8 and up ctxprogs appear to have a small snippet of code which detects this, and stalls the ctxprog until it's been handled, which essentially looks like: if (r2 & 0x00008000) { r0 |= 0x80000000; while (r0 & 0x80000000) {} } I don't know of any way that flag would get cleared unless the driver intervenes (and indeed, in the cases I've seen the hang, nothing steps in to automagically clear it for us). This patch causes the driver to clear the flag during the PGRAPH IRQ handler. Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c index 370c72c..919a619 100644 --- a/drivers/gpu/drm/nouveau/nouveau_irq.c +++ b/drivers/gpu/drm/nouveau/nouveau_irq.c @@ -635,6 +635,7 @@ nv50_pgraph_irq_handler(struct drm_device *dev) if ((nv_rd32(dev, 0x400500) & isb) != isb) nv_wr32(dev, 0x400500, nv_rd32(dev, 0x400500) | isb); + nv_wr32(dev, 0x400824, nv_rd32(dev, 0x400824) & ~(1 << 31)); } nv_wr32(dev, NV03_PMC_INTR_0, NV_PMC_INTR_0_PGRAPH_PENDING); -- cgit v0.10.2 From d6126c5c8b2019658aadc9754dca80a7573dbff5 Mon Sep 17 00:00:00 2001 From: Luca Barbieri Date: Wed, 6 Jan 2010 04:02:45 +0100 Subject: drm/nouveau: Fix null deref in nouveau_fence_emit due to deleted fence Currently Nouveau will unvalidate all buffers if it is forced to wait on one, and then start revalidating from the beginning. While doing so, it destroys the operation fence, causing nouveau_fence_emit to crash. This patch fixes this bug by taking the fence object out of validate_op and creating it just before emit. The fence pointer is initialized to 0 and unref'ed unconditionally. In addition to fixing the bug, this prevents its reintroduction and simplifies the code. Signed-off-by: Luca Barbieri Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 18fd8ac..2009db2 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -220,7 +220,6 @@ nouveau_gem_set_domain(struct drm_gem_object *gem, uint32_t read_domains, } struct validate_op { - struct nouveau_fence *fence; struct list_head vram_list; struct list_head gart_list; struct list_head both_list; @@ -252,17 +251,11 @@ validate_fini_list(struct list_head *list, struct nouveau_fence *fence) } static void -validate_fini(struct validate_op *op, bool success) +validate_fini(struct validate_op *op, struct nouveau_fence* fence) { - struct nouveau_fence *fence = op->fence; - - if (unlikely(!success)) - op->fence = NULL; - - validate_fini_list(&op->vram_list, op->fence); - validate_fini_list(&op->gart_list, op->fence); - validate_fini_list(&op->both_list, op->fence); - nouveau_fence_unref((void *)&fence); + validate_fini_list(&op->vram_list, fence); + validate_fini_list(&op->gart_list, fence); + validate_fini_list(&op->both_list, fence); } static int @@ -420,10 +413,6 @@ nouveau_gem_pushbuf_validate(struct nouveau_channel *chan, INIT_LIST_HEAD(&op->gart_list); INIT_LIST_HEAD(&op->both_list); - ret = nouveau_fence_new(chan, &op->fence, false); - if (ret) - return ret; - if (nr_buffers == 0) return 0; @@ -541,6 +530,7 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, struct drm_nouveau_gem_pushbuf_bo *bo = NULL; struct nouveau_channel *chan; struct validate_op op; + struct nouveau_fence* fence = 0; uint32_t *pushbuf = NULL; int ret = 0, do_reloc = 0, i; @@ -597,7 +587,7 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, OUT_RINGp(chan, pushbuf, req->nr_dwords); - ret = nouveau_fence_emit(op.fence); + ret = nouveau_fence_new(chan, &fence, true); if (ret) { NV_ERROR(dev, "error fencing pushbuf: %d\n", ret); WIND_RING(chan); @@ -605,7 +595,7 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, } if (nouveau_gem_pushbuf_sync(chan)) { - ret = nouveau_fence_wait(op.fence, NULL, false, false); + ret = nouveau_fence_wait(fence, NULL, false, false); if (ret) { for (i = 0; i < req->nr_dwords; i++) NV_ERROR(dev, "0x%08x\n", pushbuf[i]); @@ -614,7 +604,8 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, } out: - validate_fini(&op, ret == 0); + validate_fini(&op, fence); + nouveau_fence_unref((void**)&fence); mutex_unlock(&dev->struct_mutex); kfree(pushbuf); kfree(bo); @@ -634,6 +625,7 @@ nouveau_gem_ioctl_pushbuf_call(struct drm_device *dev, void *data, struct drm_gem_object *gem; struct nouveau_bo *pbbo; struct validate_op op; + struct nouveau_fence* fence = 0; int i, ret = 0, do_reloc = 0; NOUVEAU_CHECK_INITIALISED_WITH_RETURN; @@ -772,7 +764,7 @@ nouveau_gem_ioctl_pushbuf_call(struct drm_device *dev, void *data, OUT_RING(chan, 0); } - ret = nouveau_fence_emit(op.fence); + ret = nouveau_fence_new(chan, &fence, true); if (ret) { NV_ERROR(dev, "error fencing pushbuf: %d\n", ret); WIND_RING(chan); @@ -780,7 +772,8 @@ nouveau_gem_ioctl_pushbuf_call(struct drm_device *dev, void *data, } out: - validate_fini(&op, ret == 0); + validate_fini(&op, fence); + nouveau_fence_unref((void**)&fence); mutex_unlock(&dev->struct_mutex); kfree(bo); -- cgit v0.10.2 From cc6e496587502057af02139931736b0b7a49f637 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 7 Jan 2010 13:47:57 +1000 Subject: drm/nv04: differentiate between nv04/nv05 Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index a6b573e..09b9a46 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -642,7 +642,10 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) dev_priv->chipset = (reg0 & 0xff00000) >> 20; /* NV04 or NV05 */ } else if ((reg0 & 0xff00fff0) == 0x20004000) { - dev_priv->chipset = 0x04; + if (reg0 & 0x00f00000) + dev_priv->chipset = 0x05; + else + dev_priv->chipset = 0x04; } else dev_priv->chipset = 0xff; -- cgit v0.10.2 From 400f14ac4ef02b2f77c9d0e3ad7d66e2f6c8e663 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 8 Jan 2010 10:53:40 +1000 Subject: drm/nouveau: use dma.max rather than pushbuf size for checking GET validity Some upcoming G80 DMA changes will depend on this, but it's split out for bisectibility just in case it causes some unexpected issues. Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c index f1fd3f2..3f7f78e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dma.c +++ b/drivers/gpu/drm/nouveau/nouveau_dma.c @@ -130,7 +130,7 @@ READ_GET(struct nouveau_channel *chan, uint32_t *get) val = nvchan_rd32(chan, chan->user_get); if (val < chan->pushbuf_base || - val >= chan->pushbuf_base + chan->pushbuf_bo->bo.mem.size) { + val > chan->pushbuf_base + (chan->dma.max << 2)) { /* meaningless to dma_wait() except to know whether the * GPU has stalled or not */ -- cgit v0.10.2 From c63834e1db41b59d6c7bfb1d2a549c027a42a877 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 8 Jan 2010 10:57:39 +1000 Subject: drm/nouveau: initialise DMA tracking parameters earlier Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c index d1c7f8c..343d718 100644 --- a/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c @@ -158,6 +158,8 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, return ret; } + nouveau_dma_pre_init(chan); + /* Locate channel's user control regs */ if (dev_priv->card_type < NV_40) user = NV03_USER(channel); diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c index 3f7f78e..7afbe8b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dma.c +++ b/drivers/gpu/drm/nouveau/nouveau_dma.c @@ -29,6 +29,15 @@ #include "nouveau_drv.h" #include "nouveau_dma.h" +void +nouveau_dma_pre_init(struct nouveau_channel *chan) +{ + chan->dma.max = (chan->pushbuf_bo->bo.mem.size >> 2) - 2; + chan->dma.put = 0; + chan->dma.cur = chan->dma.put; + chan->dma.free = chan->dma.max - chan->dma.cur; +} + int nouveau_dma_init(struct nouveau_channel *chan) { @@ -74,12 +83,6 @@ nouveau_dma_init(struct nouveau_channel *chan) return ret; } - /* Initialise DMA vars */ - chan->dma.max = (chan->pushbuf_bo->bo.mem.size >> 2) - 2; - chan->dma.put = 0; - chan->dma.cur = chan->dma.put; - chan->dma.free = chan->dma.max - chan->dma.cur; - /* Insert NOPS for NOUVEAU_DMA_SKIPS */ ret = RING_SPACE(chan, NOUVEAU_DMA_SKIPS); if (ret) diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 4087a9a..026419f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -837,6 +837,7 @@ nouveau_debugfs_channel_fini(struct nouveau_channel *chan) #endif /* nouveau_dma.c */ +extern void nouveau_dma_pre_init(struct nouveau_channel *); extern int nouveau_dma_init(struct nouveau_channel *); extern int nouveau_dma_wait(struct nouveau_channel *, int size); -- cgit v0.10.2 From 40c2298bdcc8b766a39964c44e9a74d16aa95d53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Ko=C5=9Bcielnicki?= Date: Sun, 10 Jan 2010 17:09:14 +0000 Subject: drm/nv04: Fix set_operation software method. Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nv04_graph.c b/drivers/gpu/drm/nouveau/nv04_graph.c index 98f3b40..e260986 100644 --- a/drivers/gpu/drm/nouveau/nv04_graph.c +++ b/drivers/gpu/drm/nouveau/nv04_graph.c @@ -537,7 +537,7 @@ nv04_graph_mthd_set_operation(struct nouveau_channel *chan, int grclass, int mthd, uint32_t data) { struct drm_device *dev = chan->dev; - uint32_t instance = nv_rd32(dev, NV04_PGRAPH_CTX_SWITCH4) & 0xffff; + uint32_t instance = (nv_rd32(dev, NV04_PGRAPH_CTX_SWITCH4) & 0xffff) << 4; int subc = (nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR) >> 13) & 0x7; uint32_t tmp; -- cgit v0.10.2 From 3f50b0222e4c6ac59a5c4819f8be0fa500970381 Mon Sep 17 00:00:00 2001 From: Kevin Winchester Date: Tue, 17 Nov 2009 14:38:45 -0800 Subject: agp: correct missing cleanup on error in agp_add_bridge While investigating a kmemleak detected leak, I encountered the agp_add_bridge function. It appears to be responsible for freeing the agp_bridge_data in the case of a failure, but it is only doing so for some errors. Fix it to always free the bridge data if a failure condition is encountered. Signed-off-by: Kevin Winchester Signed-off-by: Andrew Morton Signed-off-by: Dave Airlie diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c index a56ca08..c3ab46d 100644 --- a/drivers/char/agp/backend.c +++ b/drivers/char/agp/backend.c @@ -285,18 +285,22 @@ int agp_add_bridge(struct agp_bridge_data *bridge) { int error; - if (agp_off) - return -ENODEV; + if (agp_off) { + error = -ENODEV; + goto err_put_bridge; + } if (!bridge->dev) { printk (KERN_DEBUG PFX "Erk, registering with no pci_dev!\n"); - return -EINVAL; + error = -EINVAL; + goto err_put_bridge; } /* Grab reference on the chipset driver. */ if (!try_module_get(bridge->driver->owner)) { dev_info(&bridge->dev->dev, "can't lock chipset driver\n"); - return -EINVAL; + error = -EINVAL; + goto err_put_bridge; } error = agp_backend_initialize(bridge); @@ -326,6 +330,7 @@ frontend_err: agp_backend_cleanup(bridge); err_out: module_put(bridge->driver->owner); +err_put_bridge: agp_put_bridge(bridge); return error; } -- cgit v0.10.2 From 67fe63b0715ccfaefa0af8a6e705c5470ee5cada Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Thu, 7 Jan 2010 12:58:51 -0700 Subject: agp/hp: fixup hp agp after ACPI changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 15b8dd53f5ffa changed the string in info->hardware_id from a static array to a pointer and added a length field. But instead of changing "sizeof(array)" to "length", we changed it to "sizeof(length)" (== 4), which corrupts the string we're trying to null-terminate. We no longer even need to null-terminate the string, but we *do* need to check whether we found a HID. If there's no HID, we used to have an empty array, but now we have a null pointer. The combination of these defects causes this oops: Unable to handle kernel NULL pointer dereference (address 0000000000000003) modprobe[895]: Oops 8804682956800 [1] ip is at zx1_gart_probe+0xd0/0xcc0 [hp_agp] http://marc.info/?l=linux-ia64&m=126264484923647&w=2 Signed-off-by: Bjorn Helgaas Reported-by: Émeric Maschino Signed-off-by: Dave Airlie diff --git a/drivers/char/agp/hp-agp.c b/drivers/char/agp/hp-agp.c index 9047b27..dc8a6f7 100644 --- a/drivers/char/agp/hp-agp.c +++ b/drivers/char/agp/hp-agp.c @@ -488,9 +488,8 @@ zx1_gart_probe (acpi_handle obj, u32 depth, void *context, void **ret) handle = obj; do { status = acpi_get_object_info(handle, &info); - if (ACPI_SUCCESS(status)) { + if (ACPI_SUCCESS(status) && (info->valid & ACPI_VALID_HID)) { /* TBD check _CID also */ - info->hardware_id.string[sizeof(info->hardware_id.length)-1] = '\0'; match = (strcmp(info->hardware_id.string, "HWP0001") == 0); kfree(info); if (match) { -- cgit v0.10.2 From 3d4a7882b11299104a0e74425dece2e26ac98024 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Thu, 7 Jan 2010 12:58:56 -0700 Subject: agp/hp: fail gracefully if we don't find an IOC Bail out if we don't find an enclosing IOC. Previously, if we didn't find one, we tried to set things up using garbage for the SBA/IOC register address, which causes a crash. This crash only happens if firmware supplies a defective ACPI namespace, so it doesn't fix any problems in the field. Signed-off-by: Bjorn Helgaas Signed-off-by: Dave Airlie diff --git a/drivers/char/agp/hp-agp.c b/drivers/char/agp/hp-agp.c index dc8a6f7..58752b7 100644 --- a/drivers/char/agp/hp-agp.c +++ b/drivers/char/agp/hp-agp.c @@ -508,6 +508,9 @@ zx1_gart_probe (acpi_handle obj, u32 depth, void *context, void **ret) handle = parent; } while (ACPI_SUCCESS(status)); + if (ACPI_FAILURE(status)) + return AE_OK; /* found no enclosing IOC */ + if (hp_zx1_setup(sba_hpa + HP_ZX1_IOC_OFFSET, lba_hpa)) return AE_OK; -- cgit v0.10.2 From ba198098a21a5dc8885fddfb308135bc2f138003 Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Fri, 8 Jan 2010 13:44:49 +0000 Subject: GFS2: Use MAX_LFS_FILESIZE for meta inode size Using ~0ULL was cauing sign issues in filemap_fdatawrite_range, so use MAX_LFS_FILESIZE instead. Signed-off-by: Steven Whitehouse diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c index cb8d7a9..6f68a5f 100644 --- a/fs/gfs2/meta_io.c +++ b/fs/gfs2/meta_io.c @@ -121,7 +121,7 @@ struct inode *gfs2_aspace_get(struct gfs2_sbd *sdp) if (aspace) { mapping_set_gfp_mask(aspace->i_mapping, GFP_NOFS); aspace->i_mapping->a_ops = &aspace_aops; - aspace->i_size = ~0ULL; + aspace->i_size = MAX_LFS_FILESIZE; ip = GFS2_I(aspace); clear_bit(GIF_USER, &ip->i_flags); insert_inode_hash(aspace); -- cgit v0.10.2 From fc248a497d83f5aba9d46d7ff114c070fb2a2fa2 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Mon, 4 Jan 2010 15:23:50 +0200 Subject: OMAP: DSS2: RFBI: convert to new kfifo API Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c index d0b3006..b936495 100644 --- a/drivers/video/omap2/dss/rfbi.c +++ b/drivers/video/omap2/dss/rfbi.c @@ -120,7 +120,7 @@ static struct { struct omap_dss_device *dssdev[2]; - struct kfifo *cmd_fifo; + struct kfifo cmd_fifo; spinlock_t cmd_lock; struct completion cmd_done; atomic_t cmd_fifo_full; @@ -1011,20 +1011,20 @@ static void process_cmd_fifo(void) return; while (true) { - spin_lock_irqsave(rfbi.cmd_fifo->lock, flags); + spin_lock_irqsave(&rfbi.cmd_lock, flags); - len = __kfifo_get(rfbi.cmd_fifo, (unsigned char *)&p, + len = kfifo_out(&rfbi.cmd_fifo, (unsigned char *)&p, sizeof(struct update_param)); if (len == 0) { DSSDBG("nothing more in fifo\n"); atomic_set(&rfbi.cmd_pending, 0); - spin_unlock_irqrestore(rfbi.cmd_fifo->lock, flags); + spin_unlock_irqrestore(&rfbi.cmd_lock, flags); break; } /* DSSDBG("fifo full %d\n", rfbi.cmd_fifo_full.counter);*/ - spin_unlock_irqrestore(rfbi.cmd_fifo->lock, flags); + spin_unlock_irqrestore(&rfbi.cmd_lock, flags); BUG_ON(len != sizeof(struct update_param)); BUG_ON(p.rfbi_module > 1); @@ -1052,25 +1052,25 @@ static void rfbi_push_cmd(struct update_param *p) unsigned long flags; int available; - spin_lock_irqsave(rfbi.cmd_fifo->lock, flags); + spin_lock_irqsave(&rfbi.cmd_lock, flags); available = RFBI_CMD_FIFO_LEN_BYTES - - __kfifo_len(rfbi.cmd_fifo); + kfifo_len(&rfbi.cmd_fifo); /* DSSDBG("%d bytes left in fifo\n", available); */ if (available < sizeof(struct update_param)) { DSSDBG("Going to wait because FIFO FULL..\n"); - spin_unlock_irqrestore(rfbi.cmd_fifo->lock, flags); + spin_unlock_irqrestore(&rfbi.cmd_lock, flags); atomic_inc(&rfbi.cmd_fifo_full); wait_for_completion(&rfbi.cmd_done); /*DSSDBG("Woke up because fifo not full anymore\n");*/ continue; } - ret = __kfifo_put(rfbi.cmd_fifo, (unsigned char *)p, + ret = kfifo_in(&rfbi.cmd_fifo, (unsigned char *)p, sizeof(struct update_param)); /* DSSDBG("pushed %d bytes\n", ret);*/ - spin_unlock_irqrestore(rfbi.cmd_fifo->lock, flags); + spin_unlock_irqrestore(&rfbi.cmd_lock, flags); BUG_ON(ret != sizeof(struct update_param)); @@ -1155,12 +1155,12 @@ int rfbi_init(void) { u32 rev; u32 l; + int r; spin_lock_init(&rfbi.cmd_lock); - rfbi.cmd_fifo = kfifo_alloc(RFBI_CMD_FIFO_LEN_BYTES, GFP_KERNEL, - &rfbi.cmd_lock); - if (IS_ERR(rfbi.cmd_fifo)) - return -ENOMEM; + r = kfifo_alloc(&rfbi.cmd_fifo, RFBI_CMD_FIFO_LEN_BYTES, GFP_KERNEL); + if (r) + return r; init_completion(&rfbi.cmd_done); atomic_set(&rfbi.cmd_fifo_full, 0); @@ -1196,7 +1196,7 @@ void rfbi_exit(void) { DSSDBG("rfbi_exit\n"); - kfifo_free(rfbi.cmd_fifo); + kfifo_free(&rfbi.cmd_fifo); iounmap(rfbi.base); } -- cgit v0.10.2 From f778a12dd33200513596a0d4d3ba4d5f09e79c09 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 16 Dec 2009 13:18:07 +0200 Subject: OMAP: OMAPFB: fix clk_get for RFBI omapfb platform device was still used to get clocks inside rfbi.c Signed-off-by: Tomi Valkeinen Tested-by: Sergey Lapin diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c index c7c6455..e192b05 100644 --- a/drivers/video/omap/dispc.c +++ b/drivers/video/omap/dispc.c @@ -189,11 +189,6 @@ static struct { struct omapfb_color_key color_key; } dispc; -static struct platform_device omapdss_device = { - .name = "omapdss", - .id = -1, -}; - static void enable_lcd_clocks(int enable); static void inline dispc_write_reg(int idx, u32 val) @@ -920,20 +915,20 @@ static irqreturn_t omap_dispc_irq_handler(int irq, void *dev) static int get_dss_clocks(void) { - dispc.dss_ick = clk_get(&omapdss_device.dev, "ick"); + dispc.dss_ick = clk_get(&dispc.fbdev->dssdev->dev, "ick"); if (IS_ERR(dispc.dss_ick)) { dev_err(dispc.fbdev->dev, "can't get ick\n"); return PTR_ERR(dispc.dss_ick); } - dispc.dss1_fck = clk_get(&omapdss_device.dev, "dss1_fck"); + dispc.dss1_fck = clk_get(&dispc.fbdev->dssdev->dev, "dss1_fck"); if (IS_ERR(dispc.dss1_fck)) { dev_err(dispc.fbdev->dev, "can't get dss1_fck\n"); clk_put(dispc.dss_ick); return PTR_ERR(dispc.dss1_fck); } - dispc.dss_54m_fck = clk_get(&omapdss_device.dev, "tv_fck"); + dispc.dss_54m_fck = clk_get(&dispc.fbdev->dssdev->dev, "tv_fck"); if (IS_ERR(dispc.dss_54m_fck)) { dev_err(dispc.fbdev->dev, "can't get tv_fck\n"); clk_put(dispc.dss_ick); @@ -1385,12 +1380,6 @@ static int omap_dispc_init(struct omapfb_device *fbdev, int ext_mode, int skip_init = 0; int i; - r = platform_device_register(&omapdss_device); - if (r) { - dev_err(fbdev->dev, "can't register omapdss device\n"); - return r; - } - memset(&dispc, 0, sizeof(dispc)); dispc.base = ioremap(DISPC_BASE, SZ_1K); @@ -1534,7 +1523,6 @@ static void omap_dispc_cleanup(void) free_irq(INT_24XX_DSS_IRQ, dispc.fbdev); put_dss_clocks(); iounmap(dispc.base); - platform_device_unregister(&omapdss_device); } const struct lcd_ctrl omap2_int_ctrl = { diff --git a/drivers/video/omap/omapfb.h b/drivers/video/omap/omapfb.h index 46e4714..af3c9e5 100644 --- a/drivers/video/omap/omapfb.h +++ b/drivers/video/omap/omapfb.h @@ -203,6 +203,8 @@ struct omapfb_device { struct omapfb_mem_desc mem_desc; struct fb_info *fb_info[OMAPFB_PLANE_NUM]; + + struct platform_device *dssdev; /* dummy dev for clocks */ }; #ifdef CONFIG_ARCH_OMAP1 diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c index c7f59a5..f74aec9 100644 --- a/drivers/video/omap/omapfb_main.c +++ b/drivers/video/omap/omapfb_main.c @@ -83,6 +83,12 @@ static struct caps_table_struct color_caps[] = { { 1 << OMAPFB_COLOR_YUY422, "YUY422", }, }; +/* dummy device for clocks */ +static struct platform_device omapdss_device = { + .name = "omapdss", + .id = -1, +}; + /* * --------------------------------------------------------------------------- * LCD panel @@ -1700,6 +1706,7 @@ static int omapfb_do_probe(struct platform_device *pdev, fbdev->dev = &pdev->dev; fbdev->panel = panel; + fbdev->dssdev = &omapdss_device; platform_set_drvdata(pdev, fbdev); mutex_init(&fbdev->rqueue_mutex); @@ -1814,8 +1821,16 @@ cleanup: static int omapfb_probe(struct platform_device *pdev) { + int r; + BUG_ON(fbdev_pdev != NULL); + r = platform_device_register(&omapdss_device); + if (r) { + dev_err(&pdev->dev, "can't register omapdss device\n"); + return r; + } + /* Delay actual initialization until the LCD is registered */ fbdev_pdev = pdev; if (fbdev_panel != NULL) @@ -1843,6 +1858,9 @@ static int omapfb_remove(struct platform_device *pdev) fbdev->state = OMAPFB_DISABLED; omapfb_free_resources(fbdev, saved_state); + platform_device_unregister(&omapdss_device); + fbdev->dssdev = NULL; + return 0; } diff --git a/drivers/video/omap/rfbi.c b/drivers/video/omap/rfbi.c index fed7b1b..1162603 100644 --- a/drivers/video/omap/rfbi.c +++ b/drivers/video/omap/rfbi.c @@ -83,13 +83,13 @@ static inline u32 rfbi_read_reg(int idx) static int rfbi_get_clocks(void) { - rfbi.dss_ick = clk_get(rfbi.fbdev->dev, "ick"); + rfbi.dss_ick = clk_get(&dispc.fbdev->dssdev->dev, "ick"); if (IS_ERR(rfbi.dss_ick)) { dev_err(rfbi.fbdev->dev, "can't get ick\n"); return PTR_ERR(rfbi.dss_ick); } - rfbi.dss1_fck = clk_get(rfbi.fbdev->dev, "dss1_fck"); + rfbi.dss1_fck = clk_get(&dispc.fbdev->dssdev->dev, "dss1_fck"); if (IS_ERR(rfbi.dss1_fck)) { dev_err(rfbi.fbdev->dev, "can't get dss1_fck\n"); clk_put(rfbi.dss_ick); -- cgit v0.10.2 From b64a5a1200e7ac91ac0dff71b0cfbc3ae19de944 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 7 Jan 2010 11:56:14 +0200 Subject: OMAP: OMAPFB: add dummy release function for omapdss This should fix: WARNING: at drivers/base/core.c:131 device_release+0x68/0x7c() Device 'omapdss' does not have a release() function, it is broken and must be fixed. Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c index f74aec9..2c4f470 100644 --- a/drivers/video/omap/omapfb_main.c +++ b/drivers/video/omap/omapfb_main.c @@ -83,10 +83,17 @@ static struct caps_table_struct color_caps[] = { { 1 << OMAPFB_COLOR_YUY422, "YUY422", }, }; +static void omapdss_release(struct device *dev) +{ +} + /* dummy device for clocks */ static struct platform_device omapdss_device = { .name = "omapdss", .id = -1, + .dev = { + .release = omapdss_release, + }, }; /* -- cgit v0.10.2 From 3043c10a7e6a133dd79636d6ec4f650a6b2848ae Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 7 Jan 2010 13:06:51 +0200 Subject: MAINTAINERS: change omapfb maintainer Signed-off-by: Tomi Valkeinen Acked-by: Imre Deak diff --git a/MAINTAINERS b/MAINTAINERS index 66f5f7d..8d2fcee 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3949,7 +3949,7 @@ S: Maintained F: sound/soc/omap/ OMAP FRAMEBUFFER SUPPORT -M: Imre Deak +M: Tomi Valkeinen L: linux-fbdev@vger.kernel.org L: linux-omap@vger.kernel.org S: Maintained -- cgit v0.10.2 From 05b5d898235401c489c68e1f3bc5706a29ad5713 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Wed, 6 Jan 2010 18:03:36 +0100 Subject: quota: Fix dquot_transfer for filesystems different from ext4 Commit fd8fbfc1 modified the way we find amount of reserved space belonging to an inode. The amount of reserved space is checked from dquot_transfer and thus inode_reserved_space gets called even for filesystems that don't provide get_reserved_space callback which results in a BUG. Fix the problem by checking get_reserved_space callback and return 0 if the filesystem does not provide it. CC: Dmitry Monakhov Signed-off-by: Jan Kara diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index dea86ab..3fc62b0 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c @@ -1377,6 +1377,9 @@ static void inode_sub_rsv_space(struct inode *inode, qsize_t number) static qsize_t inode_get_rsv_space(struct inode *inode) { qsize_t ret; + + if (!inode->i_sb->dq_op->get_reserved_space) + return 0; spin_lock(&inode->i_lock); ret = *inode_reserved_space(inode); spin_unlock(&inode->i_lock); -- cgit v0.10.2 From 676eec0daf87614eadbcd82d3876b09b65e1ddf9 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 7 Jan 2010 13:18:04 +0200 Subject: MAINTAINERS: Combine DSS2 and OMAPFB2 into one entry There isn't really any reason to divide those. Signed-off-by: Tomi Valkeinen diff --git a/MAINTAINERS b/MAINTAINERS index 8d2fcee..b888cd6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3955,23 +3955,14 @@ L: linux-omap@vger.kernel.org S: Maintained F: drivers/video/omap/ -OMAP DISPLAY SUBSYSTEM SUPPORT (DSS2) +OMAP DISPLAY SUBSYSTEM and FRAMEBUFFER SUPPORT (DSS2) M: Tomi Valkeinen L: linux-omap@vger.kernel.org -L: linux-fbdev@vger.kernel.org (moderated for non-subscribers) +L: linux-fbdev@vger.kernel.org S: Maintained -F: drivers/video/omap2/dss/ -F: drivers/video/omap2/vrfb.c -F: drivers/video/omap2/vram.c +F: drivers/video/omap2/ F: Documentation/arm/OMAP/DSS -OMAP FRAMEBUFFER SUPPORT (FOR DSS2) -M: Tomi Valkeinen -L: linux-omap@vger.kernel.org -L: linux-fbdev@vger.kernel.org (moderated for non-subscribers) -S: Maintained -F: drivers/video/omap2/omapfb/ - OMAP MMC SUPPORT M: Jarkko Lavinen L: linux-omap@vger.kernel.org -- cgit v0.10.2 From 5c18df85d731196f40784492d36d0baefdedf15a Mon Sep 17 00:00:00 2001 From: Vaibhav Hiremath Date: Mon, 4 Jan 2010 15:34:14 +0100 Subject: OMAP: DSS2: Fix compile warning Signed-off-by: Vaibhav Hiremath Acked-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index dbb0ce2..82918ee 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c @@ -124,6 +124,7 @@ static void restore_all_ctx(void) dss_clk_disable_all_no_ctx(); } +#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) /* CLOCKS */ static void core_dump_clocks(struct seq_file *s) { @@ -149,6 +150,7 @@ static void core_dump_clocks(struct seq_file *s) clocks[i]->usecount); } } +#endif /* defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) */ static int dss_get_clock(struct clk **clock, const char *clk_name) { -- cgit v0.10.2 From 7f000dd4542fcc1a69b429c0af6c6d961d7fb912 Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Tue, 22 Dec 2009 09:34:49 +0100 Subject: video/omap: add __init/__exit macros to drivers/video/omap/lcd_htcherald.c Trivial patch which adds the __init/__exit macros to the module_init/ module_exit functions of drivers/video/omap/lcd_htcherald.c Please have a look at the small patch and either pull it through your tree, or please ack' it so Jiri can pull it through the trivial tree. Patch against linux-next-tree, 22. Dez 08:38:18 CET 2009 but also present in linus tree. Signed-off-by: Peter Huewe Acked-by: Tony Lindgren diff --git a/drivers/video/omap/lcd_htcherald.c b/drivers/video/omap/lcd_htcherald.c index a9007c5..4802419 100644 --- a/drivers/video/omap/lcd_htcherald.c +++ b/drivers/video/omap/lcd_htcherald.c @@ -115,12 +115,12 @@ struct platform_driver htcherald_panel_driver = { }, }; -static int htcherald_panel_drv_init(void) +static int __init htcherald_panel_drv_init(void) { return platform_driver_register(&htcherald_panel_driver); } -static void htcherald_panel_drv_cleanup(void) +static void __exit htcherald_panel_drv_cleanup(void) { platform_driver_unregister(&htcherald_panel_driver); } -- cgit v0.10.2 From f3a82d11d478a9eb5ff0cfa83796f0ba8149d841 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 7 Jan 2010 13:37:30 +0200 Subject: OMAP: DSS2: OMAPFB: fix omapfb_free_fbmem() Fixes bug causing VRFB memory area to be released twice. Signed-off-by: Tomi Valkeinen Reported-by: Eino-Ville Talvala diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c index ef29983..e61a75c 100644 --- a/drivers/video/omap2/omapfb/omapfb-main.c +++ b/drivers/video/omap2/omapfb/omapfb-main.c @@ -1311,6 +1311,7 @@ static void omapfb_free_fbmem(struct fb_info *fbi) if (rg->vrfb.vaddr[0]) { iounmap(rg->vrfb.vaddr[0]); omap_vrfb_release_ctx(&rg->vrfb); + rg->vrfb.vaddr[0] = NULL; } } -- cgit v0.10.2 From 24be78b32f0a6e14aead3eac89d768a361b091b3 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 7 Jan 2010 14:19:48 +0200 Subject: OMAP: DSS2: Make check-delay-loops consistent Loops checking for certain condition were rather inconsistent. Signed-off-by: Tomi Valkeinen Reported-by: Juha Leppanen diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index e32a53c..6122178 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -828,12 +828,12 @@ static int dsi_pll_power(enum dsi_pll_power_state state) /* PLL_PWR_STATUS */ while (FLD_GET(dsi_read_reg(DSI_CLK_CTRL), 29, 28) != state) { - udelay(1); - if (t++ > 1000) { + if (++t > 1000) { DSSERR("Failed to set DSI PLL power mode to %d\n", state); return -ENODEV; } + udelay(1); } return 0; @@ -1441,12 +1441,12 @@ static int dsi_complexio_power(enum dsi_complexio_power_state state) /* PWR_STATUS */ while (FLD_GET(dsi_read_reg(DSI_COMPLEXIO_CFG1), 26, 25) != state) { - udelay(1); - if (t++ > 1000) { + if (++t > 1000) { DSSERR("failed to set complexio power state to " "%d\n", state); return -ENODEV; } + udelay(1); } return 0; @@ -1646,10 +1646,10 @@ static void dsi_complexio_uninit(void) static int _dsi_wait_reset(void) { - int i = 0; + int t = 0; while (REG_GET(DSI_SYSSTATUS, 0, 0) == 0) { - if (i++ > 5) { + if (++t > 5) { DSSERR("soft reset failed\n"); return -ENODEV; } @@ -2706,7 +2706,6 @@ static int dsi_update_screen_l4(struct omap_dss_device *dssdev, /* using fifo not empty */ /* TX_FIFO_NOT_EMPTY */ while (FLD_GET(dsi_read_reg(DSI_VC_CTRL(0)), 5, 5)) { - udelay(1); fifo_stalls++; if (fifo_stalls > 0xfffff) { DSSERR("fifo stalls overflow, pixels left %d\n", @@ -2714,6 +2713,7 @@ static int dsi_update_screen_l4(struct omap_dss_device *dssdev, dsi_if_enable(0); return -EIO; } + udelay(1); } #elif 1 /* using fifo emptiness */ diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index 9b05ee6..0a26b7d 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c @@ -467,14 +467,14 @@ static irqreturn_t dss_irq_handler_omap3(int irq, void *arg) static int _omap_dss_wait_reset(void) { - unsigned timeout = 1000; + int t = 0; while (REG_GET(DSS_SYSSTATUS, 0, 0) == 0) { - udelay(1); - if (!--timeout) { + if (++t > 1000) { DSSERR("soft reset failed\n"); return -ENODEV; } + udelay(1); } return 0; -- cgit v0.10.2 From 4c9f8be7dab831c78b5f491739fc5cd01f2efb03 Mon Sep 17 00:00:00 2001 From: Colin Tuckley Date: Mon, 11 Jan 2010 11:09:15 +0100 Subject: ARM: 5873/1: ARM: Fix the reset logic for ARM RealView boards Extend the patch from Philby John to the other "RealView" boards. Rename the constants and offsets to reflect their actual functions. Cc: Philby John Signed-off-by: Colin Tuckley Acked-by: Catalin Marinas Signed-off-by: Russell King diff --git a/arch/arm/mach-realview/include/mach/board-pb1176.h b/arch/arm/mach-realview/include/mach/board-pb1176.h index 34b80b7..2f5ccb2 100644 --- a/arch/arm/mach-realview/include/mach/board-pb1176.h +++ b/arch/arm/mach-realview/include/mach/board-pb1176.h @@ -74,8 +74,8 @@ #define REALVIEW_PB1176_L220_BASE 0x10110000 /* L220 registers */ /* - * Control register SYS_RESETCTL is set to 1 to force a soft reset + * Control register SYS_RESETCTL Bit 8 is set to 1 to force a soft reset */ -#define REALVIEW_PB1176_SYS_LOCKVAL_RSTCTL 0x0100 +#define REALVIEW_PB1176_SYS_SOFT_RESET 0x0100 #endif /* __ASM_ARCH_BOARD_PB1176_H */ diff --git a/arch/arm/mach-realview/include/mach/platform.h b/arch/arm/mach-realview/include/mach/platform.h index 4f46bf7..86c0c44 100644 --- a/arch/arm/mach-realview/include/mach/platform.h +++ b/arch/arm/mach-realview/include/mach/platform.h @@ -140,7 +140,7 @@ * SYS_CLD, SYS_BOOTCS */ #define REALVIEW_SYS_LOCK_LOCKED (1 << 16) -#define REALVIEW_SYS_LOCKVAL_MASK 0xA05F /* Enable write access */ +#define REALVIEW_SYS_LOCK_VAL 0xA05F /* Enable write access */ /* * REALVIEW_SYS_FLASH diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c index 917f8ca..7d857d3 100644 --- a/arch/arm/mach-realview/realview_eb.c +++ b/arch/arm/mach-realview/realview_eb.c @@ -381,6 +381,20 @@ static struct sys_timer realview_eb_timer = { .init = realview_eb_timer_init, }; +static void realview_eb_reset(char mode) +{ + void __iomem *reset_ctrl = __io_address(REALVIEW_SYS_RESETCTL); + void __iomem *lock_ctrl = __io_address(REALVIEW_SYS_LOCK); + + /* + * To reset, we hit the on-board reset register + * in the system FPGA + */ + __raw_writel(REALVIEW_SYS_LOCK_VAL, lock_ctrl); + if (core_tile_eb11mp()) + __raw_writel(0x0008, reset_ctrl); +} + static void __init realview_eb_init(void) { int i; @@ -408,6 +422,7 @@ static void __init realview_eb_init(void) #ifdef CONFIG_LEDS leds_event = realview_leds_event; #endif + realview_reset = realview_eb_reset; } MACHINE_START(REALVIEW_EB, "ARM-RealView EB") diff --git a/arch/arm/mach-realview/realview_pb1176.c b/arch/arm/mach-realview/realview_pb1176.c index 7fb726d..44392e5 100644 --- a/arch/arm/mach-realview/realview_pb1176.c +++ b/arch/arm/mach-realview/realview_pb1176.c @@ -292,12 +292,10 @@ static struct sys_timer realview_pb1176_timer = { static void realview_pb1176_reset(char mode) { - void __iomem *hdr_ctrl = __io_address(REALVIEW_SYS_BASE) + - REALVIEW_SYS_RESETCTL_OFFSET; - void __iomem *rst_hdr_ctrl = __io_address(REALVIEW_SYS_BASE) + - REALVIEW_SYS_LOCK_OFFSET; - __raw_writel(REALVIEW_SYS_LOCKVAL_MASK, rst_hdr_ctrl); - __raw_writel(REALVIEW_PB1176_SYS_LOCKVAL_RSTCTL, hdr_ctrl); + void __iomem *reset_ctrl = __io_address(REALVIEW_SYS_RESETCTL); + void __iomem *lock_ctrl = __io_address(REALVIEW_SYS_LOCK); + __raw_writel(REALVIEW_SYS_LOCK_VAL, lock_ctrl); + __raw_writel(REALVIEW_PB1176_SYS_SOFT_RESET, reset_ctrl); } static void realview_pb1176_fixup(struct machine_desc *mdesc, diff --git a/arch/arm/mach-realview/realview_pb11mp.c b/arch/arm/mach-realview/realview_pb11mp.c index 9bbbfc0..3e02731 100644 --- a/arch/arm/mach-realview/realview_pb11mp.c +++ b/arch/arm/mach-realview/realview_pb11mp.c @@ -301,17 +301,16 @@ static struct sys_timer realview_pb11mp_timer = { static void realview_pb11mp_reset(char mode) { - void __iomem *hdr_ctrl = __io_address(REALVIEW_SYS_BASE) + - REALVIEW_SYS_RESETCTL_OFFSET; - unsigned int val; + void __iomem *reset_ctrl = __io_address(REALVIEW_SYS_RESETCTL); + void __iomem *lock_ctrl = __io_address(REALVIEW_SYS_LOCK); /* * To reset, we hit the on-board reset register * in the system FPGA */ - val = __raw_readl(hdr_ctrl); - val |= REALVIEW_PB11MP_SYS_CTRL_RESET_CONFIGCLR; - __raw_writel(val, hdr_ctrl); + __raw_writel(REALVIEW_SYS_LOCK_VAL, lock_ctrl); + __raw_writel(0x0000, reset_ctrl); + __raw_writel(0x0004, reset_ctrl); } static void __init realview_pb11mp_init(void) diff --git a/arch/arm/mach-realview/realview_pba8.c b/arch/arm/mach-realview/realview_pba8.c index fe861e9..fe4e25c 100644 --- a/arch/arm/mach-realview/realview_pba8.c +++ b/arch/arm/mach-realview/realview_pba8.c @@ -272,6 +272,20 @@ static struct sys_timer realview_pba8_timer = { .init = realview_pba8_timer_init, }; +static void realview_pba8_reset(char mode) +{ + void __iomem *reset_ctrl = __io_address(REALVIEW_SYS_RESETCTL); + void __iomem *lock_ctrl = __io_address(REALVIEW_SYS_LOCK); + + /* + * To reset, we hit the on-board reset register + * in the system FPGA + */ + __raw_writel(REALVIEW_SYS_LOCK_VAL, lock_ctrl); + __raw_writel(0x0000, reset_ctrl); + __raw_writel(0x0004, reset_ctrl); +} + static void __init realview_pba8_init(void) { int i; @@ -291,6 +305,7 @@ static void __init realview_pba8_init(void) #ifdef CONFIG_LEDS leds_event = realview_leds_event; #endif + realview_reset = realview_pba8_reset; } MACHINE_START(REALVIEW_PBA8, "ARM-RealView PB-A8") diff --git a/arch/arm/mach-realview/realview_pbx.c b/arch/arm/mach-realview/realview_pbx.c index ec39488..a21a4b3 100644 --- a/arch/arm/mach-realview/realview_pbx.c +++ b/arch/arm/mach-realview/realview_pbx.c @@ -324,6 +324,20 @@ static void realview_pbx_fixup(struct machine_desc *mdesc, struct tag *tags, #endif } +static void realview_pbx_reset(char mode) +{ + void __iomem *reset_ctrl = __io_address(REALVIEW_SYS_RESETCTL); + void __iomem *lock_ctrl = __io_address(REALVIEW_SYS_LOCK); + + /* + * To reset, we hit the on-board reset register + * in the system FPGA + */ + __raw_writel(REALVIEW_SYS_LOCK_VAL, lock_ctrl); + __raw_writel(0x0000, reset_ctrl); + __raw_writel(0x0004, reset_ctrl); +} + static void __init realview_pbx_init(void) { int i; @@ -358,6 +372,7 @@ static void __init realview_pbx_init(void) #ifdef CONFIG_LEDS leds_event = realview_leds_event; #endif + realview_reset = realview_pbx_reset; } MACHINE_START(REALVIEW_PBX, "ARM-RealView PBX") -- cgit v0.10.2 From cc20b900be7aa8e456aff82dfcb55fb15c508962 Mon Sep 17 00:00:00 2001 From: Simon Kagstrom Date: Mon, 11 Jan 2010 15:57:24 +0100 Subject: ARM: 5874/1: serial21285: fix disable_irq-from-interrupt-handler deadlock The console hangs during bootup when disable_irq is called from the transmit interrupt handler (it will wait forever for it's "own" interrupt in synchronize_irq). Fix by using disable_irq_nosync() instead. Signed-off-by: Simon Kagstrom Signed-off-by: Russell King diff --git a/drivers/serial/21285.c b/drivers/serial/21285.c index 1e3d193..8681f13 100644 --- a/drivers/serial/21285.c +++ b/drivers/serial/21285.c @@ -58,7 +58,7 @@ static const char serial21285_name[] = "Footbridge UART"; static void serial21285_stop_tx(struct uart_port *port) { if (tx_enabled(port)) { - disable_irq(IRQ_CONTX); + disable_irq_nosync(IRQ_CONTX); tx_enabled(port) = 0; } } @@ -74,7 +74,7 @@ static void serial21285_start_tx(struct uart_port *port) static void serial21285_stop_rx(struct uart_port *port) { if (rx_enabled(port)) { - disable_irq(IRQ_CONRX); + disable_irq_nosync(IRQ_CONRX); rx_enabled(port) = 0; } } -- cgit v0.10.2 From 4b529401c5089cf33f7165607cbc2fde43357bfb Mon Sep 17 00:00:00 2001 From: Andreas Fenkart Date: Fri, 8 Jan 2010 14:42:31 -0800 Subject: mm: make totalhigh_pages unsigned long Makes it consistent with the extern declaration, used when CONFIG_HIGHMEM is set Removes redundant casts in printout messages Signed-off-by: Andreas Fenkart Acked-by: Russell King Cc: Ralf Baechle Cc: David Howells Cc: Ingo Molnar Cc: Thomas Gleixner Cc: "H. Peter Anvin" Cc: Chen Liqin Cc: Lennox Wu Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 52c40d1..a04ffbb 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -616,7 +616,7 @@ void __init mem_init(void) "%dK data, %dK init, %luK highmem)\n", nr_free_pages() << (PAGE_SHIFT-10), codesize >> 10, datasize >> 10, initsize >> 10, - (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10))); + totalhigh_pages << (PAGE_SHIFT-10)); if (PAGE_SIZE >= 16384 && num_physpages <= 128) { extern int sysctl_overcommit_memory; diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index 9e8d003..1651942 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c @@ -424,7 +424,7 @@ void __init mem_init(void) reservedpages << (PAGE_SHIFT-10), datasize >> 10, initsize >> 10, - (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10))); + totalhigh_pages << (PAGE_SHIFT-10)); } #endif /* !CONFIG_NEED_MULTIPLE_NODES */ diff --git a/arch/mips/sgi-ip27/ip27-memory.c b/arch/mips/sgi-ip27/ip27-memory.c index f61c164..bc12971 100644 --- a/arch/mips/sgi-ip27/ip27-memory.c +++ b/arch/mips/sgi-ip27/ip27-memory.c @@ -505,5 +505,5 @@ void __init mem_init(void) (num_physpages - tmp) << (PAGE_SHIFT-10), datasize >> 10, initsize >> 10, - (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10))); + totalhigh_pages << (PAGE_SHIFT-10)); } diff --git a/arch/mn10300/mm/init.c b/arch/mn10300/mm/init.c index ec14205..dd27a9a 100644 --- a/arch/mn10300/mm/init.c +++ b/arch/mn10300/mm/init.c @@ -118,8 +118,7 @@ void __init mem_init(void) reservedpages << (PAGE_SHIFT - 10), datasize >> 10, initsize >> 10, - (unsigned long) (totalhigh_pages << (PAGE_SHIFT - 10)) - ); + totalhigh_pages << (PAGE_SHIFT - 10)); } /* diff --git a/arch/score/mm/init.c b/arch/score/mm/init.c index 8c15b2c..dfaf458 100644 --- a/arch/score/mm/init.c +++ b/arch/score/mm/init.c @@ -106,7 +106,7 @@ void __init mem_init(void) ram << (PAGE_SHIFT-10), codesize >> 10, reservedpages << (PAGE_SHIFT-10), datasize >> 10, initsize >> 10, - (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10))); + totalhigh_pages << (PAGE_SHIFT-10)); } #endif /* !CONFIG_NEED_MULTIPLE_NODES */ diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c index c973f8e..9a0c258 100644 --- a/arch/x86/mm/init_32.c +++ b/arch/x86/mm/init_32.c @@ -892,8 +892,7 @@ void __init mem_init(void) reservedpages << (PAGE_SHIFT-10), datasize >> 10, initsize >> 10, - (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10)) - ); + totalhigh_pages << (PAGE_SHIFT-10)); printk(KERN_INFO "virtual kernel memory layout:\n" " fixmap : 0x%08lx - 0x%08lx (%4ld kB)\n" diff --git a/include/linux/highmem.h b/include/linux/highmem.h index 211ff44..ab2cc20 100644 --- a/include/linux/highmem.h +++ b/include/linux/highmem.h @@ -46,7 +46,7 @@ void kmap_flush_unused(void); static inline unsigned int nr_free_highpages(void) { return 0; } -#define totalhigh_pages 0 +#define totalhigh_pages 0UL #ifndef ARCH_HAS_KMAP static inline void *kmap(struct page *page) -- cgit v0.10.2 From cb5a8b2c92febbed57126e1b8416dfd7607ff03d Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 8 Jan 2010 14:42:34 -0800 Subject: docs: large update to ioctl-number.txt Add many ioctl definitions to ioctl-number.txt. Fix some whitespace/formatting. Correct some filenames/paths. Signed-off-by: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/Documentation/ioctl/ioctl-number.txt b/Documentation/ioctl/ioctl-number.txt index 9473749..35cf64d 100644 --- a/Documentation/ioctl/ioctl-number.txt +++ b/Documentation/ioctl/ioctl-number.txt @@ -56,10 +56,11 @@ Following this convention is good because: (5) When following the convention, the driver code can use generic code to copy the parameters between user and kernel space. -This table lists ioctls visible from user land for Linux/i386. It contains -most drivers up to 2.3.14, but I know I am missing some. +This table lists ioctls visible from user land for Linux/x86. It contains +most drivers up to 2.6.31, but I know I am missing some. There has been +no attempt to list non-X86 architectures or ioctls from drivers/staging/. -Code Seq# Include File Comments +Code Seq#(hex) Include File Comments ======================================================== 0x00 00-1F linux/fs.h conflict! 0x00 00-1F scsi/scsi_ioctl.h conflict! @@ -69,119 +70,228 @@ Code Seq# Include File Comments 0x03 all linux/hdreg.h 0x04 D2-DC linux/umsdos_fs.h Dead since 2.6.11, but don't reuse these. 0x06 all linux/lp.h -0x09 all linux/md.h +0x09 all linux/raid/md_u.h +0x10 00-0F drivers/char/s390/vmcp.h 0x12 all linux/fs.h linux/blkpg.h 0x1b all InfiniBand Subsystem 0x20 all drivers/cdrom/cm206.h 0x22 all scsi/sg.h '#' 00-3F IEEE 1394 Subsystem Block for the entire subsystem +'$' 00-0F linux/perf_counter.h, linux/perf_event.h '1' 00-1F PPS kit from Ulrich Windl +'2' 01-04 linux/i2o.h +'3' 00-0F drivers/s390/char/raw3270.h conflict! +'3' 00-1F linux/suspend_ioctls.h conflict! + and kernel/power/user.c '8' all SNP8023 advanced NIC card -'A' 00-1F linux/apm_bios.h +'@' 00-0F linux/radeonfb.h conflict! +'@' 00-0F drivers/video/aty/aty128fb.c conflict! +'A' 00-1F linux/apm_bios.h conflict! +'A' 00-0F linux/agpgart.h conflict! + and drivers/char/agp/compat_ioctl.h +'A' 00-7F sound/asound.h conflict! +'B' 00-1F linux/cciss_ioctl.h conflict! +'B' 00-0F include/linux/pmu.h conflict! 'B' C0-FF advanced bbus -'C' all linux/soundcard.h +'C' all linux/soundcard.h conflict! +'C' 01-2F linux/capi.h conflict! +'C' F0-FF drivers/net/wan/cosa.h conflict! 'D' all arch/s390/include/asm/dasd.h -'E' all linux/input.h -'F' all linux/fb.h -'H' all linux/hiddev.h -'I' all linux/isdn.h +'D' 40-5F drivers/scsi/dpt/dtpi_ioctl.h +'D' 05 drivers/scsi/pmcraid.h +'E' all linux/input.h conflict! +'E' 00-0F xen/evtchn.h conflict! +'F' all linux/fb.h conflict! +'F' 01-02 drivers/scsi/pmcraid.h conflict! +'F' 20 drivers/video/fsl-diu-fb.h conflict! +'F' 20 drivers/video/intelfb/intelfb.h conflict! +'F' 20 linux/ivtvfb.h conflict! +'F' 20 linux/matroxfb.h conflict! +'F' 20 drivers/video/aty/atyfb_base.c conflict! +'F' 00-0F video/da8xx-fb.h conflict! +'F' 80-8F linux/arcfb.h conflict! +'F' DD video/sstfb.h conflict! +'G' 00-3F drivers/misc/sgi-gru/grulib.h conflict! +'G' 00-0F linux/gigaset_dev.h conflict! +'H' 00-7F linux/hiddev.h conflict! +'H' 00-0F linux/hidraw.h conflict! +'H' 00-0F sound/asound.h conflict! +'H' 20-40 sound/asound_fm.h conflict! +'H' 80-8F sound/sfnt_info.h conflict! +'H' 10-8F sound/emu10k1.h conflict! +'H' 10-1F sound/sb16_csp.h conflict! +'H' 10-1F sound/hda_hwdep.h conflict! +'H' 40-4F sound/hdspm.h conflict! +'H' 40-4F sound/hdsp.h conflict! +'H' 90 sound/usb/usx2y/usb_stream.h +'H' C0-F0 net/bluetooth/hci.h conflict! +'H' C0-DF net/bluetooth/hidp/hidp.h conflict! +'H' C0-DF net/bluetooth/cmtp/cmtp.h conflict! +'H' C0-DF net/bluetooth/bnep/bnep.h conflict! +'I' all linux/isdn.h conflict! +'I' 00-0F drivers/isdn/divert/isdn_divert.h conflict! +'I' 40-4F linux/mISDNif.h conflict! 'J' 00-1F drivers/scsi/gdth_ioctl.h 'K' all linux/kd.h -'L' 00-1F linux/loop.h -'L' 20-2F driver/usb/misc/vstusb.h +'L' 00-1F linux/loop.h conflict! +'L' 10-1F drivers/scsi/mpt2sas/mpt2sas_ctl.h conflict! +'L' 20-2F linux/usb/vstusb.h 'L' E0-FF linux/ppdd.h encrypted disk device driver -'M' all linux/soundcard.h +'M' all linux/soundcard.h conflict! +'M' 01-16 mtd/mtd-abi.h conflict! + and drivers/mtd/mtdchar.c +'M' 01-03 drivers/scsi/megaraid/megaraid_sas.h +'M' 00-0F drivers/video/fsl-diu-fb.h conflict! 'N' 00-1F drivers/usb/scanner.h -'O' 00-02 include/mtd/ubi-user.h UBI -'P' all linux/soundcard.h +'O' 00-06 mtd/ubi-user.h UBI +'P' all linux/soundcard.h conflict! +'P' 60-6F sound/sscape_ioctl.h conflict! +'P' 00-0F drivers/usb/class/usblp.c conflict! 'Q' all linux/soundcard.h -'R' 00-1F linux/random.h +'R' 00-1F linux/random.h conflict! +'R' 01 linux/rfkill.h conflict! +'R' 01-0F media/rds.h conflict! +'R' C0-DF net/bluetooth/rfcomm.h 'S' all linux/cdrom.h conflict! 'S' 80-81 scsi/scsi_ioctl.h conflict! 'S' 82-FF scsi/scsi.h conflict! +'S' 00-7F sound/asequencer.h conflict! 'T' all linux/soundcard.h conflict! +'T' 00-AF sound/asound.h conflict! 'T' all arch/x86/include/asm/ioctls.h conflict! -'U' 00-EF linux/drivers/usb/usb.h -'V' all linux/vt.h +'T' C0-DF linux/if_tun.h conflict! +'U' all sound/asound.h conflict! +'U' 00-0F drivers/media/video/uvc/uvcvideo.h conflict! +'U' 00-CF linux/uinput.h conflict! +'U' 00-EF linux/usbdevice_fs.h +'U' C0-CF drivers/bluetooth/hci_uart.h +'V' all linux/vt.h conflict! +'V' all linux/videodev2.h conflict! +'V' C0 linux/ivtvfb.h conflict! +'V' C0 linux/ivtv.h conflict! +'V' C0 media/davinci/vpfe_capture.h conflict! +'V' C0 media/si4713.h conflict! +'V' C0-CF drivers/media/video/mxb.h conflict! 'W' 00-1F linux/watchdog.h conflict! 'W' 00-1F linux/wanrouter.h conflict! -'X' all linux/xfs_fs.h +'W' 00-3F sound/asound.h conflict! +'X' all fs/xfs/xfs_fs.h conflict! + and fs/xfs/linux-2.6/xfs_ioctl32.h + and include/linux/falloc.h + and linux/fs.h +'X' all fs/ocfs2/ocfs_fs.h conflict! +'X' 01 linux/pktcdvd.h conflict! 'Y' all linux/cyclades.h -'[' 00-07 linux/usb/usbtmc.h USB Test and Measurement Devices +'Z' 14-15 drivers/message/fusion/mptctl.h +'[' 00-07 linux/usb/tmc.h USB Test and Measurement Devices -'a' all ATM on linux +'a' all linux/atm*.h, linux/sonet.h ATM on linux -'b' 00-FF bit3 vme host bridge +'b' 00-FF conflict! bit3 vme host bridge +'b' 00-0F media/bt819.h conflict! +'c' all linux/cm4000_cs.h conflict! 'c' 00-7F linux/comstats.h conflict! 'c' 00-7F linux/coda.h conflict! -'c' 80-9F arch/s390/include/asm/chsc.h -'c' A0-AF arch/x86/include/asm/msr.h +'c' 00-1F linux/chio.h conflict! +'c' 80-9F arch/s390/include/asm/chsc.h conflict! +'c' A0-AF arch/x86/include/asm/msr.h conflict! 'd' 00-FF linux/char/drm/drm/h conflict! +'d' 02-40 pcmcia/ds.h conflict! +'d' 10-3F drivers/media/video/dabusb.h conflict! +'d' C0-CF drivers/media/video/saa7191.h conflict! 'd' F0-FF linux/digi1.h 'e' all linux/digi1.h conflict! -'e' 00-1F net/irda/irtty.h conflict! -'f' 00-1F linux/ext2_fs.h -'h' 00-7F Charon filesystem +'e' 00-1F drivers/net/irda/irtty-sir.h conflict! +'f' 00-1F linux/ext2_fs.h conflict! +'f' 00-1F linux/ext3_fs.h conflict! +'f' 00-0F fs/jfs/jfs_dinode.h conflict! +'f' 00-0F fs/ext4/ext4.h conflict! +'f' 00-0F linux/fs.h conflict! +'f' 00-0F fs/ocfs2/ocfs2_fs.h conflict! +'g' 00-0F linux/usb/gadgetfs.h +'g' 20-2F linux/usb/g_printer.h +'h' 00-7F conflict! Charon filesystem -'i' 00-3F linux/i2o.h +'h' 00-1F linux/hpet.h conflict! +'i' 00-3F linux/i2o-dev.h conflict! +'i' 0B-1F linux/ipmi.h conflict! +'i' 80-8F linux/i8k.h 'j' 00-3F linux/joystick.h +'k' 00-0F linux/spi/spidev.h conflict! +'k' 00-05 video/kyro.h conflict! 'l' 00-3F linux/tcfs_fs.h transparent cryptographic file system 'l' 40-7F linux/udf_fs_i.h in development: -'m' 00-09 linux/mmtimer.h +'m' 00-09 linux/mmtimer.h conflict! 'm' all linux/mtio.h conflict! 'm' all linux/soundcard.h conflict! 'm' all linux/synclink.h conflict! +'m' 00-19 drivers/message/fusion/mptctl.h conflict! +'m' 00 drivers/scsi/megaraid/megaraid_ioctl.h conflict! 'm' 00-1F net/irda/irmod.h conflict! -'n' 00-7F linux/ncp_fs.h +'n' 00-7F linux/ncp_fs.h and fs/ncpfs/ioctl.c 'n' 80-8F linux/nilfs2_fs.h NILFS2 -'n' E0-FF video/matrox.h matroxfb +'n' E0-FF linux/matroxfb.h matroxfb 'o' 00-1F fs/ocfs2/ocfs2_fs.h OCFS2 -'o' 00-03 include/mtd/ubi-user.h conflict! (OCFS2 and UBI overlaps) -'o' 40-41 include/mtd/ubi-user.h UBI -'o' 01-A1 include/linux/dvb/*.h DVB +'o' 00-03 mtd/ubi-user.h conflict! (OCFS2 and UBI overlaps) +'o' 40-41 mtd/ubi-user.h UBI +'o' 01-A1 linux/dvb/*.h DVB 'p' 00-0F linux/phantom.h conflict! (OpenHaptics needs this) +'p' 00-1F linux/rtc.h conflict! 'p' 00-3F linux/mc146818rtc.h conflict! 'p' 40-7F linux/nvram.h -'p' 80-9F user-space parport +'p' 80-9F linux/ppdev.h user-space parport -'p' a1-a4 linux/pps.h LinuxPPS +'p' A1-A4 linux/pps.h LinuxPPS 'q' 00-1F linux/serio.h -'q' 80-FF Internet PhoneJACK, Internet LineJACK - -'r' 00-1F linux/msdos_fs.h +'q' 80-FF linux/telephony.h Internet PhoneJACK, Internet LineJACK + linux/ixjuser.h +'r' 00-1F linux/msdos_fs.h and fs/fat/dir.c 's' all linux/cdk.h 't' 00-7F linux/if_ppp.h 't' 80-8F linux/isdn_ppp.h +'t' 90 linux/toshiba.h 'u' 00-1F linux/smb_fs.h -'v' 00-1F linux/ext2_fs.h conflict! 'v' all linux/videodev.h conflict! +'v' 00-1F linux/ext2_fs.h conflict! +'v' 00-1F linux/fs.h conflict! +'v' 00-0F linux/sonypi.h conflict! +'v' C0-CF drivers/media/video/ov511.h conflict! +'v' C0-DF media/pwc-ioctl.h conflict! +'v' C0-FF linux/meye.h conflict! +'v' C0-CF drivers/media/video/zoran/zoran.h conflict! +'v' D0-DF drivers/media/video/cpia2/cpia2dev.h conflict! 'w' all CERN SCI driver 'y' 00-1F packet based user level communications -'z' 00-3F CAN bus card +'z' 00-3F CAN bus card conflict! -'z' 40-7F CAN bus card +'z' 40-7F CAN bus card conflict! +'z' 10-4F drivers/s390/crypto/zcrypt_api.h conflict! 0x80 00-1F linux/fb.h 0x81 00-1F linux/videotext.h +0x88 00-3F media/ovcamchip.h 0x89 00-06 arch/x86/include/asm/sockios.h 0x89 0B-DF linux/sockios.h 0x89 E0-EF linux/sockios.h SIOCPROTOPRIVATE range +0x89 E0-EF linux/dn.h PROTOPRIVATE range 0x89 F0-FF linux/sockios.h SIOCDEVPRIVATE range 0x8B all linux/wireless.h 0x8C 00-3F WiNRADiO driver 0x90 00 drivers/cdrom/sbpcd.h +0x92 00-0F drivers/usb/mon/mon_bin.c 0x93 60-7F linux/auto_fs.h +0x94 all fs/btrfs/ioctl.h 0x99 00-0F 537-Addinboard driver 0xA0 all linux/sdp/sdp.h Industrial Device Project @@ -192,17 +302,22 @@ Code Seq# Include File Comments 0xAB 00-1F linux/nbd.h 0xAC 00-1F linux/raw.h 0xAD 00 Netfilter device in development: - + 0xAE all linux/kvm.h Kernel-based Virtual Machine 0xB0 all RATIO devices in development: 0xB1 00-1F PPPoX +0xC0 00-0F linux/usb/iowarrior.h 0xCB 00-1F CBM serial IEC bus in development: +0xCD 01 linux/reiserfs_fs.h +0xCF 02 fs/cifs/ioctl.c +0xDB 00-0F drivers/char/mwave/mwavepub.h 0xDD 00-3F ZFCP device driver see drivers/s390/scsi/ -0xF3 00-3F video/sisfb.h sisfb (in development) +0xF3 00-3F drivers/usb/misc/sisusbvga/sisusb.h sisfb (in development) 0xF4 00-1F video/mbxfb.h mbxfb +0xFD all linux/dm-ioctl.h -- cgit v0.10.2 From e992cd9b72a18122bd5c958715623057f110793f Mon Sep 17 00:00:00 2001 From: Vegard Nossum Date: Fri, 8 Jan 2010 14:42:35 -0800 Subject: kmemcheck: make bitfield annotations truly no-ops when disabled It turns out that even zero-sized struct members (int foo[0];) will affect the struct layout, causing us in particular to lose 4 bytes in struct sock. This patch fixes the regression in CONFIG_KMEMCHECK=n case. Reported-by: Eric Dumazet Signed-off-by: Vegard Nossum Acked-by: Pekka Enberg Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/include/linux/kmemcheck.h b/include/linux/kmemcheck.h index e880d4cf9..08d7dc4 100644 --- a/include/linux/kmemcheck.h +++ b/include/linux/kmemcheck.h @@ -36,6 +36,56 @@ int kmemcheck_hide_addr(unsigned long address); bool kmemcheck_is_obj_initialized(unsigned long addr, size_t size); +/* + * 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); + */ +#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 { \ + int _n; \ + \ + if (!ptr) \ + break; \ + \ + _n = (long) &((ptr)->name##_end) \ + - (long) &((ptr)->name##_begin); \ + MAYBE_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) \ + #else #define kmemcheck_enabled 0 @@ -106,60 +156,16 @@ static inline bool kmemcheck_is_obj_initialized(unsigned long addr, size_t size) return true; } -#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_bitfield_begin(name) +#define kmemcheck_bitfield_end(name) +#define kmemcheck_annotate_bitfield(ptr, name) \ + do { \ + } while (0) -#define kmemcheck_annotate_bitfield(ptr, name) \ - do { \ - int _n; \ - \ - if (!ptr) \ - break; \ - \ - _n = (long) &((ptr)->name##_end) \ - - (long) &((ptr)->name##_begin); \ - MAYBE_BUILD_BUG_ON(_n < 0); \ - \ - kmemcheck_mark_initialized(&((ptr)->name##_begin), _n); \ +#define kmemcheck_annotate_variable(var) \ + do { \ } while (0) -#define kmemcheck_annotate_variable(var) \ - do { \ - kmemcheck_mark_initialized(&(var), sizeof(var)); \ - } while (0) \ +#endif /* CONFIG_KMEMCHECK */ #endif /* LINUX_KMEMCHECK_H */ -- cgit v0.10.2 From 42d53b4ff7d61487d18274ebdf1f70c1aef6f122 Mon Sep 17 00:00:00 2001 From: Krzysztof Halasa Date: Fri, 8 Jan 2010 14:42:36 -0800 Subject: dma-debug: allow DMA_BIDIRECTIONAL mappings to be synced with DMA_FROM_DEVICE and There is no need to perform full BIDIR sync (copying the buffers in case of swiotlb and similar schemes) if we know that the owner (CPU or device) hasn't altered the data. Addresses the false-positive reported at http://bugzilla.kernel.org/show_bug.cgi?id=14169 Signed-off-by: Krzysztof Halasa Cc: David Miller Cc: Joerg Roedel Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/lib/dma-debug.c b/lib/dma-debug.c index cf90620..7d2f0b3 100644 --- a/lib/dma-debug.c +++ b/lib/dma-debug.c @@ -913,6 +913,9 @@ static void check_sync(struct device *dev, ref->size); } + if (entry->direction == DMA_BIDIRECTIONAL) + goto out; + if (ref->direction != entry->direction) { err_printk(dev, entry, "DMA-API: device driver syncs " "DMA memory with different direction " @@ -923,9 +926,6 @@ static void check_sync(struct device *dev, dir2name[ref->direction]); } - if (entry->direction == DMA_BIDIRECTIONAL) - goto out; - if (to_cpu && !(entry->direction == DMA_FROM_DEVICE) && !(ref->direction == DMA_TO_DEVICE)) err_printk(dev, entry, "DMA-API: device driver syncs " @@ -948,7 +948,6 @@ static void check_sync(struct device *dev, out: put_hash_bucket(bucket, &flags); - } void debug_dma_map_page(struct device *dev, struct page *page, size_t offset, -- cgit v0.10.2 From 8767ba2796a1c894e6d9524584a26a8224f0543d Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Fri, 8 Jan 2010 14:42:38 -0800 Subject: kmod: fix resource leak in call_usermodehelper_pipe() Fix resource (write-pipe file) leak in call_usermodehelper_pipe(). When call_usermodehelper_exec() fails, write-pipe file is opened and call_usermodehelper_pipe() just returns an error. Since it is hard for caller to determine whether the error occured when opening the pipe or executing the helper, the caller cannot close the pipe by themselves. I've found this resoruce leak when testing coredump. You can check how the resource leaks as below; $ echo "|nocommand" > /proc/sys/kernel/core_pattern $ ulimit -c unlimited $ while [ 1 ]; do ./segv; done &> /dev/null & $ cat /proc/meminfo (<- repeat it) where segv.c is; //----- int main () { char *p = 0; *p = 1; } //----- This patch closes write-pipe file if call_usermodehelper_exec() failed. Signed-off-by: Masami Hiramatsu Cc: Rusty Russell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/kernel/kmod.c b/kernel/kmod.c index 25b1031..bf0e231 100644 --- a/kernel/kmod.c +++ b/kernel/kmod.c @@ -520,13 +520,15 @@ int call_usermodehelper_pipe(char *path, char **argv, char **envp, return -ENOMEM; ret = call_usermodehelper_stdinpipe(sub_info, filp); - if (ret < 0) - goto out; + if (ret < 0) { + call_usermodehelper_freeinfo(sub_info); + return ret; + } - return call_usermodehelper_exec(sub_info, UMH_WAIT_EXEC); + ret = call_usermodehelper_exec(sub_info, UMH_WAIT_EXEC); + if (ret < 0) /* Failed to execute helper, close pipe */ + filp_close(*filp, NULL); - out: - call_usermodehelper_freeinfo(sub_info); return ret; } EXPORT_SYMBOL(call_usermodehelper_pipe); -- cgit v0.10.2 From 129182e5626972ac0df85d43a36dd46ad61c64e1 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Fri, 8 Jan 2010 14:42:39 -0800 Subject: percpu: avoid calling __pcpu_ptr_to_addr(NULL) __pcpu_ptr_to_addr() can be overridden by the architecture and might not behave well if passed a NULL pointer. So avoid calling it until we have verified that its arg is not NULL. Cc: Rusty Russell Cc: Kamalesh Babulal Acked-by: Tejun Heo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/mm/percpu.c b/mm/percpu.c index 442010c..083e7c9 100644 --- a/mm/percpu.c +++ b/mm/percpu.c @@ -1271,7 +1271,7 @@ static void pcpu_reclaim(struct work_struct *work) */ void free_percpu(void *ptr) { - void *addr = __pcpu_ptr_to_addr(ptr); + void *addr; struct pcpu_chunk *chunk; unsigned long flags; int off; @@ -1279,6 +1279,8 @@ void free_percpu(void *ptr) if (!ptr) return; + addr = __pcpu_ptr_to_addr(ptr); + spin_lock_irqsave(&pcpu_lock, flags); chunk = pcpu_chunk_addr_search(addr); -- cgit v0.10.2 From ac4c2a3bbe5db5fc570b1d0ee1e474db7cb22585 Mon Sep 17 00:00:00 2001 From: Joakim Tjernlund Date: Fri, 8 Jan 2010 14:42:40 -0800 Subject: zlib: optimize inffast when copying direct from output JFFS2 uses lesser compression ratio and inflate always ends up in "copy direct from output" case. This patch tries to optimize the direct copy procedure. Uses get_unaligned() but only in one place. The copy loop just above this one can also use this optimization, but I havn't done so as I have not tested if it is a win there too. On my MPC8321 this is about 17% faster on my JFFS2 root FS than the original. [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Joakim Tjernlund Cc: Roel Kluin Cc: Richard Purdie Cc: David Woodhouse Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index bb2465b..826a30a 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -20,7 +20,7 @@ all: $(obj)/zImage BOOTCFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ - -fno-strict-aliasing -Os -msoft-float -pipe \ + -fno-strict-aliasing -Os -msoft-float -pipe -D__KERNEL__\ -fomit-frame-pointer -fno-builtin -fPIC -nostdinc \ -isystem $(shell $(CROSS32CC) -print-file-name=include) BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional -nostdinc @@ -34,6 +34,8 @@ BOOTCFLAGS += -fno-stack-protector endif BOOTCFLAGS += -I$(obj) -I$(srctree)/$(obj) +BOOTCFLAGS += -include include/linux/autoconf.h -Iarch/powerpc/include +BOOTCFLAGS += -Iinclude DTS_FLAGS ?= -p 1024 diff --git a/lib/zlib_inflate/inffast.c b/lib/zlib_inflate/inffast.c index 8550b0c..05e1559 100644 --- a/lib/zlib_inflate/inffast.c +++ b/lib/zlib_inflate/inffast.c @@ -4,6 +4,8 @@ */ #include +#include +#include #include "inftrees.h" #include "inflate.h" #include "inffast.h" @@ -24,9 +26,11 @@ #ifdef POSTINC # define OFF 0 # define PUP(a) *(a)++ +# define UP_UNALIGNED(a) get_unaligned((a)++) #else # define OFF 1 # define PUP(a) *++(a) +# define UP_UNALIGNED(a) get_unaligned(++(a)) #endif /* @@ -239,18 +243,47 @@ void inflate_fast(z_streamp strm, unsigned start) } } else { + unsigned short *sout; + unsigned long loops; + from = out - dist; /* copy direct from output */ - do { /* minimum length is three */ - PUP(out) = PUP(from); - PUP(out) = PUP(from); - PUP(out) = PUP(from); - len -= 3; - } while (len > 2); - if (len) { - PUP(out) = PUP(from); - if (len > 1) - PUP(out) = PUP(from); - } + /* minimum length is three */ + /* Align out addr */ + if (!((long)(out - 1 + OFF) & 1)) { + PUP(out) = PUP(from); + len--; + } + sout = (unsigned short *)(out - OFF); + if (dist > 2) { + unsigned short *sfrom; + + sfrom = (unsigned short *)(from - OFF); + loops = len >> 1; + do + PUP(sout) = UP_UNALIGNED(sfrom); + while (--loops); + out = (unsigned char *)sout + OFF; + from = (unsigned char *)sfrom + OFF; + } else { /* dist == 1 or dist == 2 */ + unsigned short pat16; + + pat16 = *(sout-2+2*OFF); + if (dist == 1) +#if defined(__BIG_ENDIAN) + pat16 = (pat16 & 0xff) | ((pat16 & 0xff) << 8); +#elif defined(__LITTLE_ENDIAN) + pat16 = (pat16 & 0xff00) | ((pat16 & 0xff00) >> 8); +#else +#error __BIG_ENDIAN nor __LITTLE_ENDIAN is defined +#endif + loops = len >> 1; + do + PUP(sout) = pat16; + while (--loops); + out = (unsigned char *)sout + OFF; + } + if (len & 1) + PUP(out) = PUP(from); } } else if ((op & 64) == 0) { /* 2nd level distance code */ -- cgit v0.10.2 From 7dd65feb6c603e13eba501c34c662259ab38e70e Mon Sep 17 00:00:00 2001 From: Albin Tonnerre Date: Fri, 8 Jan 2010 14:42:42 -0800 Subject: lib: add support for LZO-compressed kernels This patch series adds generic support for creating and extracting LZO-compressed kernel images, as well as support for using such images on the x86 and ARM architectures, and support for creating and using LZO-compressed initrd and initramfs images. Russell King said: : Testing on a Cortex A9 model: : - lzo decompressor is 65% of the time gzip takes to decompress a kernel : - lzo kernel is 9% larger than a gzip kernel : : which I'm happy to say confirms your figures when comparing the two. : : However, when comparing your new gzip code to the old gzip code: : - new is 99% of the size of the old code : - new takes 42% of the time to decompress than the old code : : What this means is that for a proper comparison, the results get even better: : - lzo is 7.5% larger than the old gzip'd kernel image : - lzo takes 28% of the time that the old gzip code took : : So the expense seems definitely worth the effort. The only reason I : can think of ever using gzip would be if you needed the additional : compression (eg, because you have limited flash to store the image.) : : I would argue that the default for ARM should therefore be LZO. This patch: The lzo compressor is worse than gzip at compression, but faster at extraction. Here are some figures for an ARM board I'm working on: Uncompressed size: 3.24Mo gzip 1.61Mo 0.72s lzo 1.75Mo 0.48s So for a compression ratio that is still relatively close to gzip, it's much faster to extract, at least in that case. This part contains: - Makefile routine to support lzo compression - Fixes to the existing lzo compressor so that it can be used in compressed kernels - wrapper around the existing lzo1x_decompress, as it only extracts one block at a time, while we need to extract a whole file here - config dialog for kernel compression [akpm@linux-foundation.org: coding-style fixes] [akpm@linux-foundation.org: cleanup] Signed-off-by: Albin Tonnerre Tested-by: Wu Zhangjin Acked-by: "H. Peter Anvin" Cc: Ingo Molnar Cc: Thomas Gleixner Tested-by: Russell King Acked-by: Russell King Cc: Ralf Baechle Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/include/linux/decompress/unlzo.h b/include/linux/decompress/unlzo.h new file mode 100644 index 0000000..9872297 --- /dev/null +++ b/include/linux/decompress/unlzo.h @@ -0,0 +1,10 @@ +#ifndef DECOMPRESS_UNLZO_H +#define DECOMPRESS_UNLZO_H + +int unlzo(unsigned char *inbuf, int len, + int(*fill)(void*, unsigned int), + int(*flush)(void*, unsigned int), + unsigned char *output, + int *pos, + void(*error)(char *x)); +#endif diff --git a/init/Kconfig b/init/Kconfig index a23da9f..d95ca7c 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -115,10 +115,13 @@ config HAVE_KERNEL_BZIP2 config HAVE_KERNEL_LZMA bool +config HAVE_KERNEL_LZO + bool + choice prompt "Kernel compression mode" default KERNEL_GZIP - depends on HAVE_KERNEL_GZIP || HAVE_KERNEL_BZIP2 || HAVE_KERNEL_LZMA + depends on HAVE_KERNEL_GZIP || HAVE_KERNEL_BZIP2 || HAVE_KERNEL_LZMA || HAVE_KERNEL_LZO help The linux kernel is a kind of self-extracting executable. Several compression algorithms are available, which differ @@ -141,9 +144,8 @@ config KERNEL_GZIP bool "Gzip" depends on HAVE_KERNEL_GZIP help - The old and tried gzip compression. Its compression ratio is - the poorest among the 3 choices; however its speed (both - compression and decompression) is the fastest. + The old and tried gzip compression. It provides a good balance + between compression ratio and decompression speed. config KERNEL_BZIP2 bool "Bzip2" @@ -164,6 +166,14 @@ config KERNEL_LZMA two. Compression is slowest. The kernel size is about 33% smaller with LZMA in comparison to gzip. +config KERNEL_LZO + bool "LZO" + depends on HAVE_KERNEL_LZO + help + Its compression ratio is the poorest among the 4. The kernel + size is about about 10% bigger than gzip; however its speed + (both compression and decompression) is the fastest. + endchoice config SWAP diff --git a/lib/decompress_unlzo.c b/lib/decompress_unlzo.c new file mode 100644 index 0000000..db521f4 --- /dev/null +++ b/lib/decompress_unlzo.c @@ -0,0 +1,209 @@ +/* + * LZO decompressor for the Linux kernel. Code borrowed from the lzo + * implementation by Markus Franz Xaver Johannes Oberhumer. + * + * Linux kernel adaptation: + * Copyright (C) 2009 + * Albin Tonnerre, Free Electrons + * + * Original code: + * Copyright (C) 1996-2005 Markus Franz Xaver Johannes Oberhumer + * All Rights Reserved. + * + * lzop and the LZO library are free software; you can redistribute them + * and/or modify them 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; see the file COPYING. + * If not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Markus F.X.J. Oberhumer + * + * http://www.oberhumer.com/opensource/lzop/ + */ + +#ifdef STATIC +#include "lzo/lzo1x_decompress.c" +#else +#include +#include +#endif + +#include +#include +#include + +#include +#include + +static const unsigned char lzop_magic[] = { + 0x89, 0x4c, 0x5a, 0x4f, 0x00, 0x0d, 0x0a, 0x1a, 0x0a }; + +#define LZO_BLOCK_SIZE (256*1024l) +#define HEADER_HAS_FILTER 0x00000800L + +STATIC inline int INIT parse_header(u8 *input, u8 *skip) +{ + int l; + u8 *parse = input; + u8 level = 0; + u16 version; + + /* read magic: 9 first bits */ + for (l = 0; l < 9; l++) { + if (*parse++ != lzop_magic[l]) + return 0; + } + /* get version (2bytes), skip library version (2), + * 'need to be extracted' version (2) and + * method (1) */ + version = get_unaligned_be16(parse); + parse += 7; + if (version >= 0x0940) + level = *parse++; + if (get_unaligned_be32(parse) & HEADER_HAS_FILTER) + parse += 8; /* flags + filter info */ + else + parse += 4; /* flags */ + + /* skip mode and mtime_low */ + parse += 8; + if (version >= 0x0940) + parse += 4; /* skip mtime_high */ + + l = *parse++; + /* don't care about the file name, and skip checksum */ + parse += l + 4; + + *skip = parse - input; + return 1; +} + +STATIC inline int INIT unlzo(u8 *input, int in_len, + int (*fill) (void *, unsigned int), + int (*flush) (void *, unsigned int), + u8 *output, int *posp, + void (*error_fn) (char *x)) +{ + u8 skip = 0, r = 0; + u32 src_len, dst_len; + size_t tmp; + u8 *in_buf, *in_buf_save, *out_buf; + int obytes_processed = 0; + + set_error_fn(error_fn); + + if (output) { + out_buf = output; + } else if (!flush) { + error("NULL output pointer and no flush function provided"); + goto exit; + } else { + out_buf = malloc(LZO_BLOCK_SIZE); + if (!out_buf) { + error("Could not allocate output buffer"); + goto exit; + } + } + + if (input && fill) { + error("Both input pointer and fill function provided, don't know what to do"); + goto exit_1; + } else if (input) { + in_buf = input; + } else if (!fill || !posp) { + error("NULL input pointer and missing position pointer or fill function"); + goto exit_1; + } else { + in_buf = malloc(lzo1x_worst_compress(LZO_BLOCK_SIZE)); + if (!in_buf) { + error("Could not allocate input buffer"); + goto exit_1; + } + } + in_buf_save = in_buf; + + if (posp) + *posp = 0; + + if (fill) + fill(in_buf, lzo1x_worst_compress(LZO_BLOCK_SIZE)); + + if (!parse_header(input, &skip)) { + error("invalid header"); + goto exit_2; + } + in_buf += skip; + + if (posp) + *posp = skip; + + for (;;) { + /* read uncompressed block size */ + dst_len = get_unaligned_be32(in_buf); + in_buf += 4; + + /* exit if last block */ + if (dst_len == 0) { + if (posp) + *posp += 4; + break; + } + + if (dst_len > LZO_BLOCK_SIZE) { + error("dest len longer than block size"); + goto exit_2; + } + + /* read compressed block size, and skip block checksum info */ + src_len = get_unaligned_be32(in_buf); + in_buf += 8; + + if (src_len <= 0 || src_len > dst_len) { + error("file corrupted"); + goto exit_2; + } + + /* decompress */ + tmp = dst_len; + r = lzo1x_decompress_safe((u8 *) in_buf, src_len, + out_buf, &tmp); + + if (r != LZO_E_OK || dst_len != tmp) { + error("Compressed data violation"); + goto exit_2; + } + + obytes_processed += dst_len; + if (flush) + flush(out_buf, dst_len); + if (output) + out_buf += dst_len; + if (posp) + *posp += src_len + 12; + if (fill) { + in_buf = in_buf_save; + fill(in_buf, lzo1x_worst_compress(LZO_BLOCK_SIZE)); + } else + in_buf += src_len; + } + +exit_2: + if (!input) + free(in_buf); +exit_1: + if (!output) + free(out_buf); +exit: + return obytes_processed; +} + +#define decompress unlzo diff --git a/lib/lzo/lzo1x_decompress.c b/lib/lzo/lzo1x_decompress.c index 5dc6b29..f2fd098 100644 --- a/lib/lzo/lzo1x_decompress.c +++ b/lib/lzo/lzo1x_decompress.c @@ -11,11 +11,13 @@ * Richard Purdie */ +#ifndef STATIC #include #include -#include -#include +#endif + #include +#include #include "lzodefs.h" #define HAVE_IP(x, ip_end, ip) ((size_t)(ip_end - ip) < (x)) @@ -244,9 +246,10 @@ lookbehind_overrun: *out_len = op - out; return LZO_E_LOOKBEHIND_OVERRUN; } - +#ifndef STATIC EXPORT_SYMBOL_GPL(lzo1x_decompress_safe); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("LZO1X Decompressor"); +#endif diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index cd815ac..0fe48cd 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -235,3 +235,8 @@ quiet_cmd_lzma = LZMA $@ cmd_lzma = (cat $(filter-out FORCE,$^) | \ lzma -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \ (rm -f $@ ; false) + +quiet_cmd_lzo = LZO $@ +cmd_lzo = (cat $(filter-out FORCE,$^) | \ + lzop -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \ + (rm -f $@ ; false) -- cgit v0.10.2 From e7db7b4270ed2a606b8c0b5f944a5f92ade0e84c Mon Sep 17 00:00:00 2001 From: Albin Tonnerre Date: Fri, 8 Jan 2010 14:42:43 -0800 Subject: arm: add support for LZO-compressed kernels - changes to ach/arch/boot/Makefile to make it easier to add new compression types - new piggy.lzo.S necessary for lzo compression - changes in arch/arm/boot/compressed/misc.c to allow the use of lzo or gzip, depending on the config - Kconfig support Signed-off-by: Albin Tonnerre Tested-by: Wu Zhangjin Acked-by: "H. Peter Anvin" Cc: Ingo Molnar Cc: Thomas Gleixner Tested-by: Russell King Acked-by: Russell King Cc: Ralf Baechle Cc: Martin Michlmayr Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 4f8760d..c2238cd 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -18,6 +18,8 @@ config ARM select HAVE_KRETPROBES if (HAVE_KPROBES) select HAVE_FUNCTION_TRACER if (!XIP_KERNEL) select HAVE_GENERIC_DMA_COHERENT + select HAVE_KERNEL_GZIP + select HAVE_KERNEL_LZO help The ARM series is a line of low-power-consumption RISC chip designs licensed by ARM Ltd and targeted at embedded applications and diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index ce39dc5..2d4d88b 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile @@ -63,8 +63,12 @@ endif SEDFLAGS = s/TEXT_START/$(ZTEXTADDR)/;s/BSS_START/$(ZBSSADDR)/ -targets := vmlinux vmlinux.lds piggy.gz piggy.o font.o font.c \ - head.o misc.o $(OBJS) +suffix_$(CONFIG_KERNEL_GZIP) = gzip +suffix_$(CONFIG_KERNEL_LZO) = lzo + +targets := vmlinux vmlinux.lds \ + piggy.$(suffix_y) piggy.$(suffix_y).o \ + font.o font.c head.o misc.o $(OBJS) ifeq ($(CONFIG_FUNCTION_TRACER),y) ORIG_CFLAGS := $(KBUILD_CFLAGS) @@ -87,22 +91,34 @@ endif ifneq ($(PARAMS_PHYS),) LDFLAGS_vmlinux += --defsym params_phys=$(PARAMS_PHYS) endif -LDFLAGS_vmlinux += -p --no-undefined -X \ - $(shell $(CC) $(KBUILD_CFLAGS) --print-libgcc-file-name) -T +# ? +LDFLAGS_vmlinux += -p +# Report unresolved symbol references +LDFLAGS_vmlinux += --no-undefined +# Delete all temporary local symbols +LDFLAGS_vmlinux += -X +# Next argument is a linker script +LDFLAGS_vmlinux += -T + +# For __aeabi_uidivmod +lib1funcs = $(obj)/lib1funcs.o + +$(obj)/lib1funcs.S: $(srctree)/arch/$(SRCARCH)/lib/lib1funcs.S FORCE + $(call cmd,shipped) # Don't allow any static data in misc.o, which # would otherwise mess up our GOT table CFLAGS_misc.o := -Dstatic= -$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.o \ - $(addprefix $(obj)/, $(OBJS)) FORCE +$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.$(suffix_y).o \ + $(addprefix $(obj)/, $(OBJS)) $(lib1funcs) FORCE $(call if_changed,ld) @: -$(obj)/piggy.gz: $(obj)/../Image FORCE - $(call if_changed,gzip) +$(obj)/piggy.$(suffix_y): $(obj)/../Image FORCE + $(call if_changed,$(suffix_y)) -$(obj)/piggy.o: $(obj)/piggy.gz FORCE +$(obj)/piggy.$(suffix_y).o: $(obj)/piggy.$(suffix_y) FORCE CFLAGS_font.o := -Dstatic= diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c index 17153b5..7e0fe4d 100644 --- a/arch/arm/boot/compressed/misc.c +++ b/arch/arm/boot/compressed/misc.c @@ -18,10 +18,15 @@ unsigned int __machine_arch_type; +#define _LINUX_STRING_H_ + #include /* for inline */ #include /* for size_t */ #include /* for NULL */ #include +#include + +#include #ifdef STANDALONE_DEBUG #define putstr printf @@ -188,34 +193,8 @@ static inline __ptr_t memcpy(__ptr_t __dest, __const __ptr_t __src, /* * gzip delarations */ -#define OF(args) args #define STATIC static -typedef unsigned char uch; -typedef unsigned short ush; -typedef unsigned long ulg; - -#define WSIZE 0x8000 /* Window size must be at least 32k, */ - /* and a power of two */ - -static uch *inbuf; /* input buffer */ -static uch window[WSIZE]; /* Sliding window buffer */ - -static unsigned insize; /* valid bytes in inbuf */ -static unsigned inptr; /* index of next byte to be processed in inbuf */ -static unsigned outcnt; /* bytes in output buffer */ - -/* gzip flag byte */ -#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ -#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */ -#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ -#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ -#define COMMENT 0x10 /* bit 4 set: file comment present */ -#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ -#define RESERVED 0xC0 /* bit 6,7: reserved */ - -#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf()) - /* Diagnostic functions */ #ifdef DEBUG # define Assert(cond,msg) {if(!(cond)) error(msg);} @@ -233,24 +212,20 @@ static unsigned outcnt; /* bytes in output buffer */ # define Tracecv(c,x) #endif -static int fill_inbuf(void); -static void flush_window(void); static void error(char *m); extern char input_data[]; extern char input_data_end[]; -static uch *output_data; -static ulg output_ptr; -static ulg bytes_out; +static unsigned char *output_data; +static unsigned long output_ptr; static void error(char *m); static void putstr(const char *); -extern int end; -static ulg free_mem_ptr; -static ulg free_mem_end_ptr; +static unsigned long free_mem_ptr; +static unsigned long free_mem_end_ptr; #ifdef STANDALONE_DEBUG #define NO_INFLATE_MALLOC @@ -258,46 +233,13 @@ static ulg free_mem_end_ptr; #define ARCH_HAS_DECOMP_WDOG -#include "../../../../lib/inflate.c" - -/* =========================================================================== - * Fill the input buffer. This is called only when the buffer is empty - * and at least one byte is really needed. - */ -int fill_inbuf(void) -{ - if (insize != 0) - error("ran out of input data"); - - inbuf = input_data; - insize = &input_data_end[0] - &input_data[0]; - - inptr = 1; - return inbuf[0]; -} +#ifdef CONFIG_KERNEL_GZIP +#include "../../../../lib/decompress_inflate.c" +#endif -/* =========================================================================== - * Write the output window window[0..outcnt-1] and update crc and bytes_out. - * (Used for the decompressed data only.) - */ -void flush_window(void) -{ - ulg c = crc; - unsigned n; - uch *in, *out, ch; - - in = window; - out = &output_data[output_ptr]; - for (n = 0; n < outcnt; n++) { - ch = *out++ = *in++; - c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); - } - crc = c; - bytes_out += (ulg)outcnt; - output_ptr += (ulg)outcnt; - outcnt = 0; - putstr("."); -} +#ifdef CONFIG_KERNEL_LZO +#include "../../../../lib/decompress_unlzo.c" +#endif #ifndef arch_error #define arch_error(x) @@ -314,22 +256,33 @@ static void error(char *x) while(1); /* Halt */ } +asmlinkage void __div0(void) +{ + error("Attempting division by 0!"); +} + #ifndef STANDALONE_DEBUG -ulg -decompress_kernel(ulg output_start, ulg free_mem_ptr_p, ulg free_mem_ptr_end_p, - int arch_id) +unsigned long +decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p, + unsigned long free_mem_ptr_end_p, + int arch_id) { - output_data = (uch *)output_start; /* Points to kernel start */ + unsigned char *tmp; + + output_data = (unsigned char *)output_start; free_mem_ptr = free_mem_ptr_p; free_mem_end_ptr = free_mem_ptr_end_p; __machine_arch_type = arch_id; arch_decomp_setup(); - makecrc(); + tmp = (unsigned char *) (((unsigned long)input_data_end) - 4); + output_ptr = get_unaligned_le32(tmp); + putstr("Uncompressing Linux..."); - gunzip(); + decompress(input_data, input_data_end - input_data, + NULL, NULL, output_data, NULL, error); putstr(" done, booting the kernel.\n"); return output_ptr; } @@ -341,11 +294,10 @@ int main() { output_data = output_buffer; - makecrc(); putstr("Uncompressing Linux..."); - gunzip(); + decompress(input_data, input_data_end - input_data, + NULL, NULL, output_data, NULL, error); putstr("done.\n"); return 0; } #endif - diff --git a/arch/arm/boot/compressed/piggy.S b/arch/arm/boot/compressed/piggy.S deleted file mode 100644 index 54c9518..0000000 --- a/arch/arm/boot/compressed/piggy.S +++ /dev/null @@ -1,6 +0,0 @@ - .section .piggydata,#alloc - .globl input_data -input_data: - .incbin "arch/arm/boot/compressed/piggy.gz" - .globl input_data_end -input_data_end: diff --git a/arch/arm/boot/compressed/piggy.gzip.S b/arch/arm/boot/compressed/piggy.gzip.S new file mode 100644 index 0000000..a68adf9 --- /dev/null +++ b/arch/arm/boot/compressed/piggy.gzip.S @@ -0,0 +1,6 @@ + .section .piggydata,#alloc + .globl input_data +input_data: + .incbin "arch/arm/boot/compressed/piggy.gzip" + .globl input_data_end +input_data_end: diff --git a/arch/arm/boot/compressed/piggy.lzo.S b/arch/arm/boot/compressed/piggy.lzo.S new file mode 100644 index 0000000..a425ad9 --- /dev/null +++ b/arch/arm/boot/compressed/piggy.lzo.S @@ -0,0 +1,6 @@ + .section .piggydata,#alloc + .globl input_data +input_data: + .incbin "arch/arm/boot/compressed/piggy.lzo" + .globl input_data_end +input_data_end: -- cgit v0.10.2 From 13510997d600a076e064f10587a8f6d20f8fff41 Mon Sep 17 00:00:00 2001 From: Albin Tonnerre Date: Fri, 8 Jan 2010 14:42:45 -0800 Subject: x86: add support for LZO-compressed kernels The necessary changes to the x86 Kconfig and boot/compressed to allow the use of this new compression method Signed-off-by: Albin Tonnerre Acked-by: H. Peter Anvin Tested-by: Wu Zhangjin Cc: Ingo Molnar Cc: Thomas Gleixner Tested-by: Russell King Acked-by: Russell King Cc: Ralf Baechle Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 55298e8..6bf1f1a 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -49,6 +49,7 @@ config X86 select HAVE_KERNEL_GZIP select HAVE_KERNEL_BZIP2 select HAVE_KERNEL_LZMA + select HAVE_KERNEL_LZO select HAVE_HW_BREAKPOINT select PERF_EVENTS select ANON_INODES diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile index f25bbd3..fbb47da 100644 --- a/arch/x86/boot/compressed/Makefile +++ b/arch/x86/boot/compressed/Makefile @@ -4,7 +4,7 @@ # create a compressed vmlinux image from the original vmlinux # -targets := vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma head_$(BITS).o misc.o piggy.o +targets := vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma vmlinux.bin.lzo head_$(BITS).o misc.o piggy.o KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2 KBUILD_CFLAGS += -fno-strict-aliasing -fPIC @@ -49,10 +49,13 @@ $(obj)/vmlinux.bin.bz2: $(vmlinux.bin.all-y) FORCE $(call if_changed,bzip2) $(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y) FORCE $(call if_changed,lzma) +$(obj)/vmlinux.bin.lzo: $(vmlinux.bin.all-y) FORCE + $(call if_changed,lzo) suffix-$(CONFIG_KERNEL_GZIP) := gz suffix-$(CONFIG_KERNEL_BZIP2) := bz2 suffix-$(CONFIG_KERNEL_LZMA) := lzma +suffix-$(CONFIG_KERNEL_LZO) := lzo quiet_cmd_mkpiggy = MKPIGGY $@ cmd_mkpiggy = $(obj)/mkpiggy $< > $@ || ( rm -f $@ ; false ) diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c index 842b2a3..3b22fe8 100644 --- a/arch/x86/boot/compressed/misc.c +++ b/arch/x86/boot/compressed/misc.c @@ -162,6 +162,10 @@ static int lines, cols; #include "../../../../lib/decompress_unlzma.c" #endif +#ifdef CONFIG_KERNEL_LZO +#include "../../../../lib/decompress_unlzo.c" +#endif + static void scroll(void) { int i; -- cgit v0.10.2 From cacb246f8db2b9eba89d44a0f0dd4f6ed93bc113 Mon Sep 17 00:00:00 2001 From: Albin Tonnerre Date: Fri, 8 Jan 2010 14:42:46 -0800 Subject: Add LZO compression support for initramfs and old-style initrd Signed-off-by: Albin Tonnerre Tested-by: Wu Zhangjin Acked-by: "H. Peter Anvin" Cc: Ingo Molnar Cc: Thomas Gleixner Tested-by: Russell King Acked-by: Russell King Cc: Ralf Baechle Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/lib/Kconfig b/lib/Kconfig index 1cfe516..97b136f 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -117,6 +117,10 @@ config DECOMPRESS_BZIP2 config DECOMPRESS_LZMA tristate +config DECOMPRESS_LZO + select LZO_DECOMPRESS + tristate + # # Generic allocator support is selected if needed # diff --git a/lib/Makefile b/lib/Makefile index 347ad8d..911b25a 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -69,6 +69,7 @@ obj-$(CONFIG_LZO_DECOMPRESS) += lzo/ lib-$(CONFIG_DECOMPRESS_GZIP) += decompress_inflate.o lib-$(CONFIG_DECOMPRESS_BZIP2) += decompress_bunzip2.o lib-$(CONFIG_DECOMPRESS_LZMA) += decompress_unlzma.o +lib-$(CONFIG_DECOMPRESS_LZO) += decompress_unlzo.o obj-$(CONFIG_TEXTSEARCH) += textsearch.o obj-$(CONFIG_TEXTSEARCH_KMP) += ts_kmp.o diff --git a/lib/decompress.c b/lib/decompress.c index d2842f5..a760681 100644 --- a/lib/decompress.c +++ b/lib/decompress.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -22,6 +23,9 @@ #ifndef CONFIG_DECOMPRESS_LZMA # define unlzma NULL #endif +#ifndef CONFIG_DECOMPRESS_LZO +# define unlzo NULL +#endif static const struct compress_format { unsigned char magic[2]; @@ -32,6 +36,7 @@ static const struct compress_format { { {037, 0236}, "gzip", gunzip }, { {0x42, 0x5a}, "bzip2", bunzip2 }, { {0x5d, 0x00}, "lzma", unlzma }, + { {0x89, 0x4c}, "lzo", unlzo }, { {0, 0}, NULL, NULL } }; diff --git a/usr/Kconfig b/usr/Kconfig index 1c3039f..e2721f5 100644 --- a/usr/Kconfig +++ b/usr/Kconfig @@ -72,6 +72,15 @@ config RD_LZMA Support loading of a LZMA encoded initial ramdisk or cpio buffer If unsure, say N. +config RD_LZO + bool "Support initial ramdisks compressed using LZO" if EMBEDDED + default !EMBEDDED + depends on BLK_DEV_INITRD + select DECOMPRESS_LZO + help + Support loading of a LZO encoded initial ramdisk or cpio buffer + If unsure, say N. + choice prompt "Built-in initramfs compression mode" if INITRAMFS_SOURCE!="" help @@ -108,16 +117,15 @@ config INITRAMFS_COMPRESSION_GZIP bool "Gzip" depends on RD_GZIP help - The old and tried gzip compression. Its compression ratio is - the poorest among the 3 choices; however its speed (both - compression and decompression) is the fastest. + The old and tried gzip compression. It provides a good balance + between compression ratio and decompression speed. config INITRAMFS_COMPRESSION_BZIP2 bool "Bzip2" depends on RD_BZIP2 help Its compression ratio and speed is intermediate. - Decompression speed is slowest among the three. The initramfs + Decompression speed is slowest among the four. The initramfs size is about 10% smaller with bzip2, in comparison to gzip. Bzip2 uses a large amount of memory. For modern kernels you will need at least 8MB RAM or more for booting. @@ -128,7 +136,15 @@ config INITRAMFS_COMPRESSION_LZMA help The most recent compression algorithm. Its ratio is best, decompression speed is between the other - two. Compression is slowest. The initramfs size is about 33% + three. Compression is slowest. The initramfs size is about 33% smaller with LZMA in comparison to gzip. +config INITRAMFS_COMPRESSION_LZO + bool "LZO" + depends on RD_LZO + help + Its compression ratio is the poorest among the four. The kernel + size is about about 10% bigger than gzip; however its speed + (both compression and decompression) is the fastest. + endchoice -- cgit v0.10.2 From 7ee3aebe31d2cb22c84e1c8f48182947b13a3607 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 8 Jan 2010 14:42:47 -0800 Subject: lib/rational.c needs module.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit lib/rational.c:62: warning: data definition has no type or storage class lib/rational.c:62: warning: type defaults to 'int' in declaration of 'EXPORT_SYMBOL' lib/rational.c:62: warning: parameter names (without types) in function declaration Signed-off-by: Sascha Hauer Signed-off-by: Uwe Kleine-König Acked-by: WANG Cong Cc: Oskar Schirmer Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/lib/rational.c b/lib/rational.c index b3c099b..3ed247b 100644 --- a/lib/rational.c +++ b/lib/rational.c @@ -7,6 +7,7 @@ */ #include +#include /* * calculate best rational approximation for a given fraction -- cgit v0.10.2 From 272a897904b9a067550f5b8e812036b65180418f Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Fri, 8 Jan 2010 14:42:48 -0800 Subject: scripts/get_maintainer.pl: fix file exclusion X: logic The following command doesn't generate any output. `./scripts/get_maintainer.pl --no-git -f drivers/net/wireless/wl12xx/wl1271_acx.c` An excluded "X:" pattern match in any section would cause a file not to match any other section. Signed-off-by: Joe Perches Reported-by: Dan Carpenter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index 445e884..090f248 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl @@ -296,46 +296,56 @@ my @status = (); foreach my $file (@files) { -#Do not match excluded file patterns - - my $exclude = 0; - foreach my $line (@typevalue) { - if ($line =~ m/^(\C):\s*(.*)/) { - my $type = $1; - my $value = $2; - if ($type eq 'X') { - if (file_match_pattern($file, $value)) { - $exclude = 1; - last; - } - } - } - } + my %hash; + my $tvi = find_first_section(); + while ($tvi < @typevalue) { + my $start = find_starting_index($tvi); + my $end = find_ending_index($tvi); + my $exclude = 0; + my $i; + + #Do not match excluded file patterns - if (!$exclude) { - my $tvi = 0; - my %hash; - foreach my $line (@typevalue) { + for ($i = $start; $i < $end; $i++) { + my $line = $typevalue[$i]; if ($line =~ m/^(\C):\s*(.*)/) { my $type = $1; my $value = $2; - if ($type eq 'F') { + if ($type eq 'X') { if (file_match_pattern($file, $value)) { - my $value_pd = ($value =~ tr@/@@); - my $file_pd = ($file =~ tr@/@@); - $value_pd++ if (substr($value,-1,1) ne "/"); - if ($pattern_depth == 0 || - (($file_pd - $value_pd) < $pattern_depth)) { - $hash{$tvi} = $value_pd; - } + $exclude = 1; } } } - $tvi++; } - foreach my $line (sort {$hash{$b} <=> $hash{$a}} keys %hash) { - add_categories($line); + + if (!$exclude) { + for ($i = $start; $i < $end; $i++) { + my $line = $typevalue[$i]; + if ($line =~ m/^(\C):\s*(.*)/) { + my $type = $1; + my $value = $2; + if ($type eq 'F') { + if (file_match_pattern($file, $value)) { + my $value_pd = ($value =~ tr@/@@); + my $file_pd = ($file =~ tr@/@@); + $value_pd++ if (substr($value,-1,1) ne "/"); + if ($pattern_depth == 0 || + (($file_pd - $value_pd) < $pattern_depth)) { + $hash{$tvi} = $value_pd; + } + } + } + } + } } + + $tvi += ($end - $start); + + } + + foreach my $line (sort {$hash{$b} <=> $hash{$a}} keys %hash) { + add_categories($line); } if ($email && $email_git) { @@ -570,6 +580,20 @@ sub format_email { return $formatted_email; } +sub find_first_section { + my $index = 0; + + while ($index < @typevalue) { + my $tv = $typevalue[$index]; + if (($tv =~ m/^(\C):\s*(.*)/)) { + last; + } + $index++; + } + + return $index; +} + sub find_starting_index { my ($index) = @_; -- cgit v0.10.2 From bd4f490a079730aadfaf9a728303ea0135c01945 Mon Sep 17 00:00:00 2001 From: Dave Anderson Date: Fri, 8 Jan 2010 14:42:50 -0800 Subject: cgroups: fix 2.6.32 regression causing BUG_ON() in cgroup_diput() The LTP cgroup test suite generates a "kernel BUG at kernel/cgroup.c:790!" here in cgroup_diput(): /* * if we're getting rid of the cgroup, refcount should ensure * that there are no pidlists left. */ BUG_ON(!list_empty(&cgrp->pidlists)); The cgroup pidlist rework in 2.6.32 generates the BUG_ON, which is caused when pidlist_array_load() calls cgroup_pidlist_find(): (1) if a matching cgroup_pidlist is found, it down_write's the mutex of the pre-existing cgroup_pidlist, and increments its use_count. (2) if no matching cgroup_pidlist is found, then a new one is allocated, it down_write's its mutex, and the use_count is set to 0. (3) the matching, or new, cgroup_pidlist gets returned back to pidlist_array_load(), which increments its use_count -- regardless whether new or pre-existing -- and up_write's the mutex. So if a matching list is ever encountered by cgroup_pidlist_find() during the life of a cgroup directory, it results in an inflated use_count value, preventing it from ever getting released by cgroup_release_pid_array(). Then if the directory is subsequently removed, cgroup_diput() hits the BUG_ON() when it finds that the directory's cgroup is still populated with a pidlist. The patch simply removes the use_count increment when a matching pidlist is found by cgroup_pidlist_find(), because it gets bumped by the calling pidlist_array_load() function while still protected by the list's mutex. Signed-off-by: Dave Anderson Reviewed-by: Li Zefan Acked-by: Ben Blum Cc: Paul Menage Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 0249f4b..1fbcc74 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -2468,7 +2468,6 @@ static struct cgroup_pidlist *cgroup_pidlist_find(struct cgroup *cgrp, /* make sure l doesn't vanish out from under us */ down_write(&l->mutex); mutex_unlock(&cgrp->pidlist_mutex); - l->use_count++; return l; } } -- cgit v0.10.2 From b45c6e76bc2c72f6426c14bed64fdcbc9bf37cb0 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Fri, 8 Jan 2010 14:42:52 -0800 Subject: kernel/signal.c: fix kernel information leak with print-fatal-signals=1 When print-fatal-signals is enabled it's possible to dump any memory reachable by the kernel to the log by simply jumping to that address from user space. Or crash the system if there's some hardware with read side effects. The fatal signals handler will dump 16 bytes at the execution address, which is fully controlled by ring 3. In addition when something jumps to a unmapped address there will be up to 16 additional useless page faults, which might be potentially slow (and at least is not very efficient) Fortunately this option is off by default and only there on i386. But fix it by checking for kernel addresses and also stopping when there's a page fault. Signed-off-by: Andi Kleen Cc: Ingo Molnar Cc: Oleg Nesterov Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/kernel/signal.c b/kernel/signal.c index d09692b..934ae5e 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -979,7 +979,8 @@ static void print_fatal_signal(struct pt_regs *regs, int signr) for (i = 0; i < 16; i++) { unsigned char insn; - __get_user(insn, (unsigned char *)(regs->ip + i)); + if (get_user(insn, (unsigned char *)(regs->ip + i))) + break; printk("%02x ", insn); } } -- cgit v0.10.2 From f146aabfe921006b98dfa4a78506763aedfd3206 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Fri, 8 Jan 2010 14:42:54 -0800 Subject: .gitignore: ignore vmlinuz MIPS compressed kernels output a vmlinuz file in the top-level directory (maybe others do). Add vmlinuz to the list of files to ignore by git. Signed-off-by: Florian Fainelli Cc: Ralf Baechle Cc: Maxime Bizon Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/.gitignore b/.gitignore index fb2190c..de6344e 100644 --- a/.gitignore +++ b/.gitignore @@ -37,6 +37,7 @@ modules.builtin tags TAGS vmlinux +vmlinuz System.map Module.markers Module.symvers -- cgit v0.10.2 From 1306d603fcf1f6682f8575d1ff23631a24184b21 Mon Sep 17 00:00:00 2001 From: KOSAKI Motohiro Date: Fri, 8 Jan 2010 14:42:56 -0800 Subject: proc: partially revert "procfs: provide stack information for threads" Commit d899bf7b (procfs: provide stack information for threads) introduced to show stack information in /proc/{pid}/status. But it cause large performance regression. Unfortunately /proc/{pid}/status is used ps command too and ps is one of most important component. Because both to take mmap_sem and page table walk are heavily operation. If many process run, the ps performance is, [before d899bf7b] % perf stat ps >/dev/null Performance counter stats for 'ps': 4090.435806 task-clock-msecs # 0.032 CPUs 229 context-switches # 0.000 M/sec 0 CPU-migrations # 0.000 M/sec 234 page-faults # 0.000 M/sec 8587565207 cycles # 2099.425 M/sec 9866662403 instructions # 1.149 IPC 3789415411 cache-references # 926.409 M/sec 30419509 cache-misses # 7.437 M/sec 128.859521955 seconds time elapsed [after d899bf7b] % perf stat ps > /dev/null Performance counter stats for 'ps': 4305.081146 task-clock-msecs # 0.028 CPUs 480 context-switches # 0.000 M/sec 2 CPU-migrations # 0.000 M/sec 237 page-faults # 0.000 M/sec 9021211334 cycles # 2095.480 M/sec 10605887536 instructions # 1.176 IPC 3612650999 cache-references # 839.160 M/sec 23917502 cache-misses # 5.556 M/sec 152.277819582 seconds time elapsed Thus, this patch revert it. Fortunately /proc/{pid}/task/{tid}/smaps provide almost same information. we can use it. Commit d899bf7b introduced two features: 1) Add the annotattion of [thread stack: xxxx] mark to /proc/{pid}/task/{tid}/maps. 2) Add StackUsage field to /proc/{pid}/status. I only revert (2), because I haven't seen (1) cause regression. Signed-off-by: KOSAKI Motohiro Cc: Stefani Seibold Cc: Ingo Molnar Cc: Peter Zijlstra Cc: Alexey Dobriyan Cc: "Eric W. Biederman" Cc: Randy Dunlap Cc: Andrew Morton Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt index 220cc63..0d07513 100644 --- a/Documentation/filesystems/proc.txt +++ b/Documentation/filesystems/proc.txt @@ -177,7 +177,6 @@ read the file /proc/PID/status: CapBnd: ffffffffffffffff voluntary_ctxt_switches: 0 nonvoluntary_ctxt_switches: 1 - Stack usage: 12 kB This shows you nearly the same information you would get if you viewed it with the ps command. In fact, ps uses the proc file system to obtain its @@ -231,7 +230,6 @@ Table 1-2: Contents of the statm files (as of 2.6.30-rc7) Mems_allowed_list Same as previous, but in "list format" voluntary_ctxt_switches number of voluntary context switches nonvoluntary_ctxt_switches number of non voluntary context switches - Stack usage: stack usage high water mark (round up to page size) .............................................................................. Table 1-3: Contents of the statm files (as of 2.6.8-rc3) diff --git a/fs/proc/array.c b/fs/proc/array.c index f560325..13b5d07 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c @@ -327,94 +327,6 @@ static inline void task_context_switch_counts(struct seq_file *m, p->nivcsw); } -#ifdef CONFIG_MMU - -struct stack_stats { - struct vm_area_struct *vma; - unsigned long startpage; - unsigned long usage; -}; - -static int stack_usage_pte_range(pmd_t *pmd, unsigned long addr, - unsigned long end, struct mm_walk *walk) -{ - struct stack_stats *ss = walk->private; - struct vm_area_struct *vma = ss->vma; - pte_t *pte, ptent; - spinlock_t *ptl; - int ret = 0; - - pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl); - for (; addr != end; pte++, addr += PAGE_SIZE) { - ptent = *pte; - -#ifdef CONFIG_STACK_GROWSUP - if (pte_present(ptent) || is_swap_pte(ptent)) - ss->usage = addr - ss->startpage + PAGE_SIZE; -#else - if (pte_present(ptent) || is_swap_pte(ptent)) { - ss->usage = ss->startpage - addr + PAGE_SIZE; - pte++; - ret = 1; - break; - } -#endif - } - pte_unmap_unlock(pte - 1, ptl); - cond_resched(); - return ret; -} - -static inline unsigned long get_stack_usage_in_bytes(struct vm_area_struct *vma, - struct task_struct *task) -{ - struct stack_stats ss; - struct mm_walk stack_walk = { - .pmd_entry = stack_usage_pte_range, - .mm = vma->vm_mm, - .private = &ss, - }; - - if (!vma->vm_mm || is_vm_hugetlb_page(vma)) - return 0; - - ss.vma = vma; - ss.startpage = task->stack_start & PAGE_MASK; - ss.usage = 0; - -#ifdef CONFIG_STACK_GROWSUP - walk_page_range(KSTK_ESP(task) & PAGE_MASK, vma->vm_end, - &stack_walk); -#else - walk_page_range(vma->vm_start, (KSTK_ESP(task) & PAGE_MASK) + PAGE_SIZE, - &stack_walk); -#endif - return ss.usage; -} - -static inline void task_show_stack_usage(struct seq_file *m, - struct task_struct *task) -{ - struct vm_area_struct *vma; - struct mm_struct *mm = get_task_mm(task); - - if (mm) { - down_read(&mm->mmap_sem); - vma = find_vma(mm, task->stack_start); - if (vma) - seq_printf(m, "Stack usage:\t%lu kB\n", - get_stack_usage_in_bytes(vma, task) >> 10); - - up_read(&mm->mmap_sem); - mmput(mm); - } -} -#else -static void task_show_stack_usage(struct seq_file *m, struct task_struct *task) -{ -} -#endif /* CONFIG_MMU */ - static void task_cpus_allowed(struct seq_file *m, struct task_struct *task) { seq_printf(m, "Cpus_allowed:\t"); @@ -445,7 +357,6 @@ int proc_pid_status(struct seq_file *m, struct pid_namespace *ns, task_show_regs(m, task); #endif task_context_switch_counts(m, task); - task_show_stack_usage(m, task); return 0; } -- cgit v0.10.2 From 0a88422312f5bf7b9e3450e27d8ddc385af38789 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 8 Jan 2010 14:42:57 -0800 Subject: power: fix kernel-doc notation Warning(drivers/base/power/main.c:453): No description found for parameter 'dev' Warning(drivers/base/power/main.c:453): No description found for parameter 'cb' Warning(drivers/base/power/main.c:719): No description found for parameter 'dev' Warning(drivers/base/power/main.c:719): No description found for parameter 'state' Warning(drivers/base/power/main.c:719): No description found for parameter 'cb' Signed-off-by: Randy Dunlap Cc: Rafael J. Wysocki Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 48adf80..a5142bd 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -446,8 +446,8 @@ EXPORT_SYMBOL_GPL(dpm_resume_noirq); /** * legacy_resume - Execute a legacy (bus or class) resume callback for device. - * dev: Device to resume. - * cb: Resume callback to execute. + * @dev: Device to resume. + * @cb: Resume callback to execute. */ static int legacy_resume(struct device *dev, int (*cb)(struct device *dev)) { @@ -711,8 +711,9 @@ EXPORT_SYMBOL_GPL(dpm_suspend_noirq); /** * legacy_suspend - Execute a legacy (bus or class) suspend callback for device. - * dev: Device to suspend. - * cb: Suspend callback to execute. + * @dev: Device to suspend. + * @state: PM transition of the system being carried out. + * @cb: Suspend callback to execute. */ static int legacy_suspend(struct device *dev, pm_message_t state, int (*cb)(struct device *dev, pm_message_t state)) -- cgit v0.10.2 From 7d92df692994472cab6045bbd9d0e2c4afa4365f Mon Sep 17 00:00:00 2001 From: Anna Lemehova Date: Fri, 8 Jan 2010 14:42:58 -0800 Subject: mmc_block: add dev_t initialization check When a card is removed before mmc_blk_probe() has called add_disk(), then the minor field is uninitialized and has value 0. This caused mmc_blk_put() to always release devidx 0 even if 0 was still in use. Then the next mmc_blk_probe() used the first free idx of 0, which oopses in sysfs, since it is used by another card. Signed-off-by: Anna Lemehova Signed-off-by: Adrian Hunter Cc: Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 85f0e8c..5988573 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -85,7 +85,12 @@ static void mmc_blk_put(struct mmc_blk_data *md) mutex_lock(&open_lock); md->usage--; if (md->usage == 0) { + int devmaj = MAJOR(disk_devt(md->disk)); int devidx = MINOR(disk_devt(md->disk)) >> MMC_SHIFT; + + if (!devmaj) + devidx = md->disk->first_minor >> MMC_SHIFT; + __clear_bit(devidx, dev_use); put_disk(md->disk); -- cgit v0.10.2 From 0a74ff29b8dd8b748f8856352f9a9b5c6cc362cc Mon Sep 17 00:00:00 2001 From: Jarkko Lavinen Date: Fri, 8 Jan 2010 14:42:59 -0800 Subject: mmc_block: fix probe error cleanup bug If mmc_blk_set_blksize() fails mmc_blk_probe() the request queue and its thread have been set up and they need to be shut down properly before putting the disk. Signed-off-by: Jarkko Lavinen Signed-off-by: Adrian Hunter Cc: Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 5988573..ee879117 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -618,6 +618,7 @@ static int mmc_blk_probe(struct mmc_card *card) return 0; out: + mmc_cleanup_queue(&md->queue); mmc_blk_put(md); return err; -- cgit v0.10.2 From 5fa83ce284a4b7cd9dcfadd01500b0ed4ab9b740 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Fri, 8 Jan 2010 14:43:00 -0800 Subject: mmc_block: fix queue cleanup The main bug was that 'blk_cleanup_queue()' was called while the block device could still be in use, for example, because the card was removed while files were still open. In addition, to be sure that 'mmc_request()' will get called for all new requests (so it can error them out), the queue is emptied during cleanup. This is done after the worker thread is stopped to avoid racing with it. Finally, it is not a device error for this to be happening, so quiet the (sometimes very many) error messages. Signed-off-by: Adrian Hunter Cc: Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index ee879117..1f552c6 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -91,6 +91,8 @@ static void mmc_blk_put(struct mmc_blk_data *md) if (!devmaj) devidx = md->disk->first_minor >> MMC_SHIFT; + blk_cleanup_queue(md->queue.queue); + __clear_bit(devidx, dev_use); put_disk(md->disk); diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index 49e5823..c5a7a85 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c @@ -90,9 +90,10 @@ static void mmc_request(struct request_queue *q) struct request *req; if (!mq) { - printk(KERN_ERR "MMC: killing requests for dead queue\n"); - while ((req = blk_fetch_request(q)) != NULL) + while ((req = blk_fetch_request(q)) != NULL) { + req->cmd_flags |= REQ_QUIET; __blk_end_request_all(req, -EIO); + } return; } @@ -223,17 +224,18 @@ void mmc_cleanup_queue(struct mmc_queue *mq) struct request_queue *q = mq->queue; unsigned long flags; - /* Mark that we should start throwing out stragglers */ - spin_lock_irqsave(q->queue_lock, flags); - q->queuedata = NULL; - spin_unlock_irqrestore(q->queue_lock, flags); - /* Make sure the queue isn't suspended, as that will deadlock */ mmc_queue_resume(mq); /* Then terminate our worker thread */ kthread_stop(mq->thread); + /* Empty the queue */ + spin_lock_irqsave(q->queue_lock, flags); + q->queuedata = NULL; + blk_start_queue(q); + spin_unlock_irqrestore(q->queue_lock, flags); + if (mq->bounce_sg) kfree(mq->bounce_sg); mq->bounce_sg = NULL; @@ -245,8 +247,6 @@ void mmc_cleanup_queue(struct mmc_queue *mq) kfree(mq->bounce_buf); mq->bounce_buf = NULL; - blk_cleanup_queue(mq->queue); - mq->card = NULL; } EXPORT_SYMBOL(mmc_cleanup_queue); -- cgit v0.10.2 From 11723ab15d28e71dd118a8a92f98493f5a5907da Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Fri, 8 Jan 2010 14:43:01 -0800 Subject: mmc: allow for MMC v4.4 JEDEC eMMC specification version 4.4 (MMCA 4.4) defines Extended CSD structure versions up to 5. Signed-off-by: Adrian Hunter Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index c111894..0eac6c8 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -207,7 +207,7 @@ static int mmc_read_ext_csd(struct mmc_card *card) } card->ext_csd.rev = ext_csd[EXT_CSD_REV]; - if (card->ext_csd.rev > 3) { + if (card->ext_csd.rev > 5) { printk(KERN_ERR "%s: unrecognised EXT_CSD structure " "version %d\n", mmc_hostname(card->host), card->ext_csd.rev); -- cgit v0.10.2 From 3f4724027bfe38644146252f7aa979dea7f80720 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 8 Jan 2010 14:43:02 -0800 Subject: vsnprintf: fix reference for compressed ipv6 addresses MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Uwe Kleine-König Reported-by: Josip Rodin Cc: Joe Perches Cc: David S. Miller Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/lib/vsprintf.c b/lib/vsprintf.c index d4996cf..3b8aeec 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -903,7 +903,7 @@ static char *uuid_string(char *buf, char *end, const u8 *addr, * IPv6 omits the colons (01020304...0f) * IPv4 uses dot-separated decimal with leading 0's (010.123.045.006) * - 'I6c' for IPv6 addresses printed as specified by - * http://www.ietf.org/id/draft-kawamura-ipv6-text-representation-03.txt + * http://tools.ietf.org/html/draft-ietf-6man-text-addr-representation-00 * - 'U' For a 16 byte UUID/GUID, it prints the UUID/GUID in the form * "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" * Options for %pU are: @@ -1188,7 +1188,7 @@ qualifier: * %pI6 print an IPv6 address with colons * %pi6 print an IPv6 address without colons * %pI6c print an IPv6 address as specified by - * http://www.ietf.org/id/draft-kawamura-ipv6-text-representation-03.txt + * http://tools.ietf.org/html/draft-ietf-6man-text-addr-representation-00 * %pU[bBlL] print a UUID/GUID in big or little endian using lower or upper * case. * %n is ignored -- cgit v0.10.2 From 24f3c59e1781435835083eab587399c8bdc235b4 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 8 Jan 2010 14:43:03 -0800 Subject: gpiolib: fix poll(2) support reconfigure on sysfs polarity change Previously enabled poll(2) support on one edge was never reconfigured when sysfs polarity change was triggered from kernel, because 'struct device *dev' shadowed an earlier definition. Found by sparse, which I should've run much earlier. Signed-off-by: Jani Nikula Cc: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index a25ad28..350842a 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -858,8 +858,6 @@ int gpio_sysfs_set_active_low(unsigned gpio, int value) desc = &gpio_desc[gpio]; if (test_bit(FLAG_EXPORT, &desc->flags)) { - struct device *dev; - dev = class_find_device(&gpio_class, NULL, desc, match_export); if (dev == NULL) { status = -ENODEV; -- cgit v0.10.2 From b5430a04e995081a308b4419bd0940f2badc6e6b Mon Sep 17 00:00:00 2001 From: Tomaz Mertelj Date: Fri, 8 Jan 2010 14:43:04 -0800 Subject: hwmon: driver for Texas Instruments amc6821 chip Signed-off-by: Cc: Jean Delvare Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/Documentation/hwmon/amc6821 b/Documentation/hwmon/amc6821 new file mode 100644 index 0000000..ced8359 --- /dev/null +++ b/Documentation/hwmon/amc6821 @@ -0,0 +1,102 @@ +Kernel driver amc6821 +===================== + +Supported chips: + Texas Instruments AMC6821 + Prefix: 'amc6821' + Addresses scanned: 0x18, 0x19, 0x1a, 0x2c, 0x2d, 0x2e, 0x4c, 0x4d, 0x4e + Datasheet: http://focus.ti.com/docs/prod/folders/print/amc6821.html + +Authors: + Tomaz Mertelj + + +Description +----------- + +This driver implements support for the Texas Instruments amc6821 chip. +The chip has one on-chip and one remote temperature sensor and one pwm fan +regulator. +The pwm can be controlled either from software or automatically. + +The driver provides the following sensor accesses in sysfs: + +temp1_input ro on-chip temperature +temp1_min rw " +temp1_max rw " +temp1_crit rw " +temp1_min_alarm ro " +temp1_max_alarm ro " +temp1_crit_alarm ro " + +temp2_input ro remote temperature +temp2_min rw " +temp2_max rw " +temp2_crit rw " +temp2_min_alarm ro " +temp2_max_alarm ro " +temp2_crit_alarm ro " +temp2_fault ro " + +fan1_input ro tachometer speed +fan1_min rw " +fan1_max rw " +fan1_fault ro " +fan1_div rw Fan divisor can be either 2 or 4. + +pwm1 rw pwm1 +pwm1_enable rw regulator mode, 1=open loop, 2=fan controlled + by remote temperature, 3=fan controlled by + combination of the on-chip temperature and + remote-sensor temperature, +pwm1_auto_channels_temp ro 1 if pwm_enable==2, 3 if pwm_enable==3 +pwm1_auto_point1_pwm ro Hardwired to 0, shared for both + temperature channels. +pwm1_auto_point2_pwm rw This value is shared for both temperature + channels. +pwm1_auto_point3_pwm rw Hardwired to 255, shared for both + temperature channels. + +temp1_auto_point1_temp ro Hardwired to temp2_auto_point1_temp + which is rw. Below this temperature fan stops. +temp1_auto_point2_temp rw The low-temperature limit of the proportional + range. Below this temperature + pwm1 = pwm1_auto_point2_pwm. It can go from + 0 degree C to 124 degree C in steps of + 4 degree C. Read it out after writing to get + the actual value. +temp1_auto_point3_temp rw Above this temperature fan runs at maximum + speed. It can go from temp1_auto_point2_temp. + It can only have certain discrete values + which depend on temp1_auto_point2_temp and + pwm1_auto_point2_pwm. Read it out after + writing to get the actual value. + +temp2_auto_point1_temp rw Must be between 0 degree C and 63 degree C and + it defines the passive cooling temperature. + Below this temperature the fan stops in + the closed loop mode. +temp2_auto_point2_temp rw The low-temperature limit of the proportional + range. Below this temperature + pwm1 = pwm1_auto_point2_pwm. It can go from + 0 degree C to 124 degree C in steps + of 4 degree C. + +temp2_auto_point3_temp rw Above this temperature fan runs at maximum + speed. It can only have certain discrete + values which depend on temp2_auto_point2_temp + and pwm1_auto_point2_pwm. Read it out after + writing to get actual value. + + +Module parameters +----------------- + +If your board has a BIOS that initializes the amc6821 correctly, you should +load the module with: init=0. + +If your board BIOS doesn't initialize the chip, or you want +different settings, you can set the following parameters: +init=1, +pwminv: 0 default pwm output, 1 inverts pwm output. + diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 46c3c56..07a0f03 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -792,6 +792,16 @@ config SENSORS_ADS7828 This driver can also be built as a module. If so, the module will be called ads7828. +config SENSORS_AMC6821 + tristate "Texas Instruments AMC6821" + depends on I2C && EXPERIMENTAL + help + If you say yes here you get support for the Texas Instruments + AMC6821 hardware monitoring chips. + + This driver can also be build as a module. If so, the module + will be called amc6821. + config SENSORS_THMC50 tristate "Texas Instruments THMC50 / Analog Devices ADM1022" depends on I2C && EXPERIMENTAL diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 450c8e8..4bc215c 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -86,6 +86,7 @@ obj-$(CONFIG_SENSORS_SIS5595) += sis5595.o obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o +obj-$(CONFIG_SENSORS_AMC6821) += amc6821.o obj-$(CONFIG_SENSORS_THMC50) += thmc50.o obj-$(CONFIG_SENSORS_TMP401) += tmp401.o obj-$(CONFIG_SENSORS_TMP421) += tmp421.o diff --git a/drivers/hwmon/amc6821.c b/drivers/hwmon/amc6821.c new file mode 100644 index 0000000..1c89d92 --- /dev/null +++ b/drivers/hwmon/amc6821.c @@ -0,0 +1,1116 @@ +/* + amc6821.c - Part of lm_sensors, Linux kernel modules for hardware + monitoring + Copyright (C) 2009 T. Mertelj + + Based on max6650.c: + Copyright (C) 2007 Hans J. Koch + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#include /* Needed for KERN_INFO */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/* + * Addresses to scan. + */ + +static const unsigned short normal_i2c[] = {0x18, 0x19, 0x1a, 0x2c, 0x2d, 0x2e, + 0x4c, 0x4d, 0x4e, I2C_CLIENT_END}; + + + +/* + * Insmod parameters + */ + +static int pwminv = 0; /*Inverted PWM output. */ +module_param(pwminv, int, S_IRUGO); + +static int init = 1; /*Power-on initialization.*/ +module_param(init, int, S_IRUGO); + + +enum chips { amc6821 }; + +#define AMC6821_REG_DEV_ID 0x3D +#define AMC6821_REG_COMP_ID 0x3E +#define AMC6821_REG_CONF1 0x00 +#define AMC6821_REG_CONF2 0x01 +#define AMC6821_REG_CONF3 0x3F +#define AMC6821_REG_CONF4 0x04 +#define AMC6821_REG_STAT1 0x02 +#define AMC6821_REG_STAT2 0x03 +#define AMC6821_REG_TDATA_LOW 0x08 +#define AMC6821_REG_TDATA_HI 0x09 +#define AMC6821_REG_LTEMP_HI 0x0A +#define AMC6821_REG_RTEMP_HI 0x0B +#define AMC6821_REG_LTEMP_LIMIT_MIN 0x15 +#define AMC6821_REG_LTEMP_LIMIT_MAX 0x14 +#define AMC6821_REG_RTEMP_LIMIT_MIN 0x19 +#define AMC6821_REG_RTEMP_LIMIT_MAX 0x18 +#define AMC6821_REG_LTEMP_CRIT 0x1B +#define AMC6821_REG_RTEMP_CRIT 0x1D +#define AMC6821_REG_PSV_TEMP 0x1C +#define AMC6821_REG_DCY 0x22 +#define AMC6821_REG_LTEMP_FAN_CTRL 0x24 +#define AMC6821_REG_RTEMP_FAN_CTRL 0x25 +#define AMC6821_REG_DCY_LOW_TEMP 0x21 + +#define AMC6821_REG_TACH_LLIMITL 0x10 +#define AMC6821_REG_TACH_LLIMITH 0x11 +#define AMC6821_REG_TACH_HLIMITL 0x12 +#define AMC6821_REG_TACH_HLIMITH 0x13 + +#define AMC6821_CONF1_START 0x01 +#define AMC6821_CONF1_FAN_INT_EN 0x02 +#define AMC6821_CONF1_FANIE 0x04 +#define AMC6821_CONF1_PWMINV 0x08 +#define AMC6821_CONF1_FAN_FAULT_EN 0x10 +#define AMC6821_CONF1_FDRC0 0x20 +#define AMC6821_CONF1_FDRC1 0x40 +#define AMC6821_CONF1_THERMOVIE 0x80 + +#define AMC6821_CONF2_PWM_EN 0x01 +#define AMC6821_CONF2_TACH_MODE 0x02 +#define AMC6821_CONF2_TACH_EN 0x04 +#define AMC6821_CONF2_RTFIE 0x08 +#define AMC6821_CONF2_LTOIE 0x10 +#define AMC6821_CONF2_RTOIE 0x20 +#define AMC6821_CONF2_PSVIE 0x40 +#define AMC6821_CONF2_RST 0x80 + +#define AMC6821_CONF3_THERM_FAN_EN 0x80 +#define AMC6821_CONF3_REV_MASK 0x0F + +#define AMC6821_CONF4_OVREN 0x10 +#define AMC6821_CONF4_TACH_FAST 0x20 +#define AMC6821_CONF4_PSPR 0x40 +#define AMC6821_CONF4_MODE 0x80 + +#define AMC6821_STAT1_RPM_ALARM 0x01 +#define AMC6821_STAT1_FANS 0x02 +#define AMC6821_STAT1_RTH 0x04 +#define AMC6821_STAT1_RTL 0x08 +#define AMC6821_STAT1_R_THERM 0x10 +#define AMC6821_STAT1_RTF 0x20 +#define AMC6821_STAT1_LTH 0x40 +#define AMC6821_STAT1_LTL 0x80 + +#define AMC6821_STAT2_RTC 0x08 +#define AMC6821_STAT2_LTC 0x10 +#define AMC6821_STAT2_LPSV 0x20 +#define AMC6821_STAT2_L_THERM 0x40 +#define AMC6821_STAT2_THERM_IN 0x80 + +enum {IDX_TEMP1_INPUT = 0, IDX_TEMP1_MIN, IDX_TEMP1_MAX, + IDX_TEMP1_CRIT, IDX_TEMP2_INPUT, IDX_TEMP2_MIN, + IDX_TEMP2_MAX, IDX_TEMP2_CRIT, + TEMP_IDX_LEN, }; + +static const u8 temp_reg[] = {AMC6821_REG_LTEMP_HI, + AMC6821_REG_LTEMP_LIMIT_MIN, + AMC6821_REG_LTEMP_LIMIT_MAX, + AMC6821_REG_LTEMP_CRIT, + AMC6821_REG_RTEMP_HI, + AMC6821_REG_RTEMP_LIMIT_MIN, + AMC6821_REG_RTEMP_LIMIT_MAX, + AMC6821_REG_RTEMP_CRIT, }; + +enum {IDX_FAN1_INPUT = 0, IDX_FAN1_MIN, IDX_FAN1_MAX, + FAN1_IDX_LEN, }; + +static const u8 fan_reg_low[] = {AMC6821_REG_TDATA_LOW, + AMC6821_REG_TACH_LLIMITL, + AMC6821_REG_TACH_HLIMITL, }; + + +static const u8 fan_reg_hi[] = {AMC6821_REG_TDATA_HI, + AMC6821_REG_TACH_LLIMITH, + AMC6821_REG_TACH_HLIMITH, }; + +static int amc6821_probe( + struct i2c_client *client, + const struct i2c_device_id *id); +static int amc6821_detect( + struct i2c_client *client, + struct i2c_board_info *info); +static int amc6821_init_client(struct i2c_client *client); +static int amc6821_remove(struct i2c_client *client); +static struct amc6821_data *amc6821_update_device(struct device *dev); + +/* + * Driver data (common to all clients) + */ + +static const struct i2c_device_id amc6821_id[] = { + { "amc6821", amc6821 }, + { } +}; + +MODULE_DEVICE_TABLE(i2c, amc6821_id); + +static struct i2c_driver amc6821_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "amc6821", + }, + .probe = amc6821_probe, + .remove = amc6821_remove, + .id_table = amc6821_id, + .detect = amc6821_detect, + .address_list = normal_i2c, +}; + + +/* + * Client data (each client gets its own) + */ + +struct amc6821_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* zero until following fields are valid */ + unsigned long last_updated; /* in jiffies */ + + /* register values */ + int temp[TEMP_IDX_LEN]; + + u16 fan[FAN1_IDX_LEN]; + u8 fan1_div; + + u8 pwm1; + u8 temp1_auto_point_temp[3]; + u8 temp2_auto_point_temp[3]; + u8 pwm1_auto_point_pwm[3]; + u8 pwm1_enable; + u8 pwm1_auto_channels_temp; + + u8 stat1; + u8 stat2; +}; + + +static ssize_t get_temp( + struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct amc6821_data *data = amc6821_update_device(dev); + int ix = to_sensor_dev_attr(devattr)->index; + + return sprintf(buf, "%d\n", data->temp[ix] * 1000); +} + + + +static ssize_t set_temp( + struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct amc6821_data *data = i2c_get_clientdata(client); + int ix = to_sensor_dev_attr(attr)->index; + long val; + + int ret = strict_strtol(buf, 10, &val); + if (ret) + return ret; + val = SENSORS_LIMIT(val / 1000, -128, 127); + + mutex_lock(&data->update_lock); + data->temp[ix] = val; + if (i2c_smbus_write_byte_data(client, temp_reg[ix], data->temp[ix])) { + dev_err(&client->dev, "Register write error, aborting.\n"); + count = -EIO; + } + mutex_unlock(&data->update_lock); + return count; +} + + + + +static ssize_t get_temp_alarm( + struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct amc6821_data *data = amc6821_update_device(dev); + int ix = to_sensor_dev_attr(devattr)->index; + u8 flag; + + switch (ix) { + case IDX_TEMP1_MIN: + flag = data->stat1 & AMC6821_STAT1_LTL; + break; + case IDX_TEMP1_MAX: + flag = data->stat1 & AMC6821_STAT1_LTH; + break; + case IDX_TEMP1_CRIT: + flag = data->stat2 & AMC6821_STAT2_LTC; + break; + case IDX_TEMP2_MIN: + flag = data->stat1 & AMC6821_STAT1_RTL; + break; + case IDX_TEMP2_MAX: + flag = data->stat1 & AMC6821_STAT1_RTH; + break; + case IDX_TEMP2_CRIT: + flag = data->stat2 & AMC6821_STAT2_RTC; + break; + default: + dev_dbg(dev, "Unknown attr->index (%d).\n", ix); + return -EINVAL; + } + if (flag) + return sprintf(buf, "1"); + else + return sprintf(buf, "0"); +} + + + + +static ssize_t get_temp2_fault( + struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct amc6821_data *data = amc6821_update_device(dev); + if (data->stat1 & AMC6821_STAT1_RTF) + return sprintf(buf, "1"); + else + return sprintf(buf, "0"); +} + +static ssize_t get_pwm1( + struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct amc6821_data *data = amc6821_update_device(dev); + return sprintf(buf, "%d\n", data->pwm1); +} + +static ssize_t set_pwm1( + struct device *dev, + struct device_attribute *devattr, + const char *buf, + size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct amc6821_data *data = i2c_get_clientdata(client); + long val; + int ret = strict_strtol(buf, 10, &val); + if (ret) + return ret; + + mutex_lock(&data->update_lock); + data->pwm1 = SENSORS_LIMIT(val , 0, 255); + i2c_smbus_write_byte_data(client, AMC6821_REG_DCY, data->pwm1); + mutex_unlock(&data->update_lock); + return count; +} + +static ssize_t get_pwm1_enable( + struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct amc6821_data *data = amc6821_update_device(dev); + return sprintf(buf, "%d\n", data->pwm1_enable); +} + +static ssize_t set_pwm1_enable( + struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct amc6821_data *data = i2c_get_clientdata(client); + long val; + int config = strict_strtol(buf, 10, &val); + if (config) + return config; + + config = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF1); + if (config < 0) { + dev_err(&client->dev, + "Error reading configuration register, aborting.\n"); + return -EIO; + } + + switch (val) { + case 1: + config &= ~AMC6821_CONF1_FDRC0; + config &= ~AMC6821_CONF1_FDRC1; + break; + case 2: + config &= ~AMC6821_CONF1_FDRC0; + config |= AMC6821_CONF1_FDRC1; + break; + case 3: + config |= AMC6821_CONF1_FDRC0; + config |= AMC6821_CONF1_FDRC1; + break; + default: + return -EINVAL; + } + mutex_lock(&data->update_lock); + if (i2c_smbus_write_byte_data(client, AMC6821_REG_CONF1, config)) { + dev_err(&client->dev, + "Configuration register write error, aborting.\n"); + count = -EIO; + } + mutex_unlock(&data->update_lock); + return count; +} + + +static ssize_t get_pwm1_auto_channels_temp( + struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct amc6821_data *data = amc6821_update_device(dev); + return sprintf(buf, "%d\n", data->pwm1_auto_channels_temp); +} + + +static ssize_t get_temp_auto_point_temp( + struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + int ix = to_sensor_dev_attr_2(devattr)->index; + int nr = to_sensor_dev_attr_2(devattr)->nr; + struct amc6821_data *data = amc6821_update_device(dev); + switch (nr) { + case 1: + return sprintf(buf, "%d\n", + data->temp1_auto_point_temp[ix] * 1000); + break; + case 2: + return sprintf(buf, "%d\n", + data->temp2_auto_point_temp[ix] * 1000); + break; + default: + dev_dbg(dev, "Unknown attr->nr (%d).\n", nr); + return -EINVAL; + } +} + + +static ssize_t get_pwm1_auto_point_pwm( + struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + int ix = to_sensor_dev_attr(devattr)->index; + struct amc6821_data *data = amc6821_update_device(dev); + return sprintf(buf, "%d\n", data->pwm1_auto_point_pwm[ix]); +} + + +static inline ssize_t set_slope_register(struct i2c_client *client, + u8 reg, + u8 dpwm, + u8 *ptemp) +{ + int dt; + u8 tmp; + + dt = ptemp[2]-ptemp[1]; + for (tmp = 4; tmp > 0; tmp--) { + if (dt * (0x20 >> tmp) >= dpwm) + break; + } + tmp |= (ptemp[1] & 0x7C) << 1; + if (i2c_smbus_write_byte_data(client, + reg, tmp)) { + dev_err(&client->dev, "Register write error, aborting.\n"); + return -EIO; + } + return 0; +} + + + +static ssize_t set_temp_auto_point_temp( + struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct amc6821_data *data = amc6821_update_device(dev); + int ix = to_sensor_dev_attr_2(attr)->index; + int nr = to_sensor_dev_attr_2(attr)->nr; + u8 *ptemp; + u8 reg; + int dpwm; + long val; + int ret = strict_strtol(buf, 10, &val); + if (ret) + return ret; + + switch (nr) { + case 1: + ptemp = data->temp1_auto_point_temp; + reg = AMC6821_REG_LTEMP_FAN_CTRL; + break; + case 2: + ptemp = data->temp2_auto_point_temp; + reg = AMC6821_REG_RTEMP_FAN_CTRL; + break; + default: + dev_dbg(dev, "Unknown attr->nr (%d).\n", nr); + return -EINVAL; + } + + data->valid = 0; + mutex_lock(&data->update_lock); + switch (ix) { + case 0: + ptemp[0] = SENSORS_LIMIT(val / 1000, 0, + data->temp1_auto_point_temp[1]); + ptemp[0] = SENSORS_LIMIT(ptemp[0], 0, + data->temp2_auto_point_temp[1]); + ptemp[0] = SENSORS_LIMIT(ptemp[0], 0, 63); + if (i2c_smbus_write_byte_data( + client, + AMC6821_REG_PSV_TEMP, + ptemp[0])) { + dev_err(&client->dev, + "Register write error, aborting.\n"); + count = -EIO; + } + goto EXIT; + break; + case 1: + ptemp[1] = SENSORS_LIMIT( + val / 1000, + (ptemp[0] & 0x7C) + 4, + 124); + ptemp[1] &= 0x7C; + ptemp[2] = SENSORS_LIMIT( + ptemp[2], ptemp[1] + 1, + 255); + break; + case 2: + ptemp[2] = SENSORS_LIMIT( + val / 1000, + ptemp[1]+1, + 255); + break; + default: + dev_dbg(dev, "Unknown attr->index (%d).\n", ix); + count = -EINVAL; + goto EXIT; + } + dpwm = data->pwm1_auto_point_pwm[2] - data->pwm1_auto_point_pwm[1]; + if (set_slope_register(client, reg, dpwm, ptemp)) + count = -EIO; + +EXIT: + mutex_unlock(&data->update_lock); + return count; +} + + + +static ssize_t set_pwm1_auto_point_pwm( + struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct amc6821_data *data = i2c_get_clientdata(client); + int dpwm; + long val; + int ret = strict_strtol(buf, 10, &val); + if (ret) + return ret; + + mutex_lock(&data->update_lock); + data->pwm1_auto_point_pwm[1] = SENSORS_LIMIT(val, 0, 254); + if (i2c_smbus_write_byte_data(client, AMC6821_REG_DCY_LOW_TEMP, + data->pwm1_auto_point_pwm[1])) { + dev_err(&client->dev, "Register write error, aborting.\n"); + count = -EIO; + goto EXIT; + } + dpwm = data->pwm1_auto_point_pwm[2] - data->pwm1_auto_point_pwm[1]; + if (set_slope_register(client, AMC6821_REG_LTEMP_FAN_CTRL, dpwm, + data->temp1_auto_point_temp)) { + count = -EIO; + goto EXIT; + } + if (set_slope_register(client, AMC6821_REG_RTEMP_FAN_CTRL, dpwm, + data->temp2_auto_point_temp)) { + count = -EIO; + goto EXIT; + } + +EXIT: + data->valid = 0; + mutex_unlock(&data->update_lock); + return count; +} + +static ssize_t get_fan( + struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct amc6821_data *data = amc6821_update_device(dev); + int ix = to_sensor_dev_attr(devattr)->index; + if (0 == data->fan[ix]) + return sprintf(buf, "0"); + return sprintf(buf, "%d\n", (int)(6000000 / data->fan[ix])); +} + + + +static ssize_t get_fan1_fault( + struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct amc6821_data *data = amc6821_update_device(dev); + if (data->stat1 & AMC6821_STAT1_FANS) + return sprintf(buf, "1"); + else + return sprintf(buf, "0"); +} + + + +static ssize_t set_fan( + struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct amc6821_data *data = i2c_get_clientdata(client); + long val; + int ix = to_sensor_dev_attr(attr)->index; + int ret = strict_strtol(buf, 10, &val); + if (ret) + return ret; + val = 1 > val ? 0xFFFF : 6000000/val; + + mutex_lock(&data->update_lock); + data->fan[ix] = (u16) SENSORS_LIMIT(val, 1, 0xFFFF); + if (i2c_smbus_write_byte_data(client, fan_reg_low[ix], + data->fan[ix] & 0xFF)) { + dev_err(&client->dev, "Register write error, aborting.\n"); + count = -EIO; + goto EXIT; + } + if (i2c_smbus_write_byte_data(client, + fan_reg_hi[ix], data->fan[ix] >> 8)) { + dev_err(&client->dev, "Register write error, aborting.\n"); + count = -EIO; + } +EXIT: + mutex_unlock(&data->update_lock); + return count; +} + + + +static ssize_t get_fan1_div( + struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct amc6821_data *data = amc6821_update_device(dev); + return sprintf(buf, "%d\n", data->fan1_div); +} + +static ssize_t set_fan1_div( + struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct amc6821_data *data = i2c_get_clientdata(client); + long val; + int config = strict_strtol(buf, 10, &val); + if (config) + return config; + + config = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF4); + if (config < 0) { + dev_err(&client->dev, + "Error reading configuration register, aborting.\n"); + return -EIO; + } + mutex_lock(&data->update_lock); + switch (val) { + case 2: + config &= ~AMC6821_CONF4_PSPR; + data->fan1_div = 2; + break; + case 4: + config |= AMC6821_CONF4_PSPR; + data->fan1_div = 4; + break; + default: + mutex_unlock(&data->update_lock); + count = -EINVAL; + goto EXIT; + } + if (i2c_smbus_write_byte_data(client, AMC6821_REG_CONF4, config)) { + dev_err(&client->dev, + "Configuration register write error, aborting.\n"); + count = -EIO; + } +EXIT: + mutex_unlock(&data->update_lock); + return count; +} + + + +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, + get_temp, NULL, IDX_TEMP1_INPUT); +static SENSOR_DEVICE_ATTR(temp1_min, S_IRUGO | S_IWUSR, get_temp, + set_temp, IDX_TEMP1_MIN); +static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR, get_temp, + set_temp, IDX_TEMP1_MAX); +static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO | S_IWUSR, get_temp, + set_temp, IDX_TEMP1_CRIT); +static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, + get_temp_alarm, NULL, IDX_TEMP1_MIN); +static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, + get_temp_alarm, NULL, IDX_TEMP1_MAX); +static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, + get_temp_alarm, NULL, IDX_TEMP1_CRIT); +static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO | S_IWUSR, + get_temp, NULL, IDX_TEMP2_INPUT); +static SENSOR_DEVICE_ATTR(temp2_min, S_IRUGO | S_IWUSR, get_temp, + set_temp, IDX_TEMP2_MIN); +static SENSOR_DEVICE_ATTR(temp2_max, S_IRUGO | S_IWUSR, get_temp, + set_temp, IDX_TEMP2_MAX); +static SENSOR_DEVICE_ATTR(temp2_crit, S_IRUGO | S_IWUSR, get_temp, + set_temp, IDX_TEMP2_CRIT); +static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, + get_temp2_fault, NULL, 0); +static SENSOR_DEVICE_ATTR(temp2_min_alarm, S_IRUGO, + get_temp_alarm, NULL, IDX_TEMP2_MIN); +static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, + get_temp_alarm, NULL, IDX_TEMP2_MAX); +static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, + get_temp_alarm, NULL, IDX_TEMP2_CRIT); +static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, get_fan, NULL, IDX_FAN1_INPUT); +static SENSOR_DEVICE_ATTR(fan1_min, S_IRUGO | S_IWUSR, + get_fan, set_fan, IDX_FAN1_MIN); +static SENSOR_DEVICE_ATTR(fan1_max, S_IRUGO | S_IWUSR, + get_fan, set_fan, IDX_FAN1_MAX); +static SENSOR_DEVICE_ATTR(fan1_fault, S_IRUGO, get_fan1_fault, NULL, 0); +static SENSOR_DEVICE_ATTR(fan1_div, S_IRUGO | S_IWUSR, + get_fan1_div, set_fan1_div, 0); + +static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, get_pwm1, set_pwm1, 0); +static SENSOR_DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, + get_pwm1_enable, set_pwm1_enable, 0); +static SENSOR_DEVICE_ATTR(pwm1_auto_point1_pwm, S_IRUGO, + get_pwm1_auto_point_pwm, NULL, 0); +static SENSOR_DEVICE_ATTR(pwm1_auto_point2_pwm, S_IWUSR | S_IRUGO, + get_pwm1_auto_point_pwm, set_pwm1_auto_point_pwm, 1); +static SENSOR_DEVICE_ATTR(pwm1_auto_point3_pwm, S_IRUGO, + get_pwm1_auto_point_pwm, NULL, 2); +static SENSOR_DEVICE_ATTR(pwm1_auto_channels_temp, S_IRUGO, + get_pwm1_auto_channels_temp, NULL, 0); +static SENSOR_DEVICE_ATTR_2(temp1_auto_point1_temp, S_IRUGO, + get_temp_auto_point_temp, NULL, 1, 0); +static SENSOR_DEVICE_ATTR_2(temp1_auto_point2_temp, S_IWUSR | S_IRUGO, + get_temp_auto_point_temp, set_temp_auto_point_temp, 1, 1); +static SENSOR_DEVICE_ATTR_2(temp1_auto_point3_temp, S_IWUSR | S_IRUGO, + get_temp_auto_point_temp, set_temp_auto_point_temp, 1, 2); + +static SENSOR_DEVICE_ATTR_2(temp2_auto_point1_temp, S_IWUSR | S_IRUGO, + get_temp_auto_point_temp, set_temp_auto_point_temp, 2, 0); +static SENSOR_DEVICE_ATTR_2(temp2_auto_point2_temp, S_IWUSR | S_IRUGO, + get_temp_auto_point_temp, set_temp_auto_point_temp, 2, 1); +static SENSOR_DEVICE_ATTR_2(temp2_auto_point3_temp, S_IWUSR | S_IRUGO, + get_temp_auto_point_temp, set_temp_auto_point_temp, 2, 2); + + + +static struct attribute *amc6821_attrs[] = { + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_temp1_min.dev_attr.attr, + &sensor_dev_attr_temp1_max.dev_attr.attr, + &sensor_dev_attr_temp1_crit.dev_attr.attr, + &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_input.dev_attr.attr, + &sensor_dev_attr_temp2_min.dev_attr.attr, + &sensor_dev_attr_temp2_max.dev_attr.attr, + &sensor_dev_attr_temp2_crit.dev_attr.attr, + &sensor_dev_attr_temp2_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_fault.dev_attr.attr, + &sensor_dev_attr_fan1_input.dev_attr.attr, + &sensor_dev_attr_fan1_min.dev_attr.attr, + &sensor_dev_attr_fan1_max.dev_attr.attr, + &sensor_dev_attr_fan1_fault.dev_attr.attr, + &sensor_dev_attr_fan1_div.dev_attr.attr, + &sensor_dev_attr_pwm1.dev_attr.attr, + &sensor_dev_attr_pwm1_enable.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_channels_temp.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point3_pwm.dev_attr.attr, + &sensor_dev_attr_temp1_auto_point1_temp.dev_attr.attr, + &sensor_dev_attr_temp1_auto_point2_temp.dev_attr.attr, + &sensor_dev_attr_temp1_auto_point3_temp.dev_attr.attr, + &sensor_dev_attr_temp2_auto_point1_temp.dev_attr.attr, + &sensor_dev_attr_temp2_auto_point2_temp.dev_attr.attr, + &sensor_dev_attr_temp2_auto_point3_temp.dev_attr.attr, + NULL +}; + +static struct attribute_group amc6821_attr_grp = { + .attrs = amc6821_attrs, +}; + + + +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int amc6821_detect( + struct i2c_client *client, + struct i2c_board_info *info) +{ + struct i2c_adapter *adapter = client->adapter; + int address = client->addr; + int dev_id, comp_id; + + dev_dbg(&adapter->dev, "amc6821_detect called.\n"); + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { + dev_dbg(&adapter->dev, + "amc6821: I2C bus doesn't support byte mode, " + "skipping.\n"); + return -ENODEV; + } + + dev_id = i2c_smbus_read_byte_data(client, AMC6821_REG_DEV_ID); + comp_id = i2c_smbus_read_byte_data(client, AMC6821_REG_COMP_ID); + if (dev_id != 0x21 || comp_id != 0x49) { + dev_dbg(&adapter->dev, + "amc6821: detection failed at 0x%02x.\n", + address); + return -ENODEV; + } + + /* Bit 7 of the address register is ignored, so we can check the + ID registers again */ + dev_id = i2c_smbus_read_byte_data(client, 0x80 | AMC6821_REG_DEV_ID); + comp_id = i2c_smbus_read_byte_data(client, 0x80 | AMC6821_REG_COMP_ID); + if (dev_id != 0x21 || comp_id != 0x49) { + dev_dbg(&adapter->dev, + "amc6821: detection failed at 0x%02x.\n", + address); + return -ENODEV; + } + + dev_info(&adapter->dev, "amc6821: chip found at 0x%02x.\n", address); + strlcpy(info->type, "amc6821", I2C_NAME_SIZE); + + return 0; +} + +static int amc6821_probe( + struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct amc6821_data *data; + int err; + + data = kzalloc(sizeof(struct amc6821_data), GFP_KERNEL); + if (!data) { + dev_err(&client->dev, "out of memory.\n"); + return -ENOMEM; + } + + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + + /* + * Initialize the amc6821 chip + */ + err = amc6821_init_client(client); + if (err) + goto err_free; + + err = sysfs_create_group(&client->dev.kobj, &amc6821_attr_grp); + if (err) + goto err_free; + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (!IS_ERR(data->hwmon_dev)) + return 0; + + err = PTR_ERR(data->hwmon_dev); + dev_err(&client->dev, "error registering hwmon device.\n"); + sysfs_remove_group(&client->dev.kobj, &amc6821_attr_grp); +err_free: + kfree(data); + return err; +} + +static int amc6821_remove(struct i2c_client *client) +{ + struct amc6821_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &amc6821_attr_grp); + + kfree(data); + + return 0; +} + + +static int amc6821_init_client(struct i2c_client *client) +{ + int config; + int err = -EIO; + + if (init) { + config = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF4); + + if (config < 0) { + dev_err(&client->dev, + "Error reading configuration register, aborting.\n"); + return err; + } + + config |= AMC6821_CONF4_MODE; + + if (i2c_smbus_write_byte_data(client, AMC6821_REG_CONF4, + config)) { + dev_err(&client->dev, + "Configuration register write error, aborting.\n"); + return err; + } + + config = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF3); + + if (config < 0) { + dev_err(&client->dev, + "Error reading configuration register, aborting.\n"); + return err; + } + + dev_info(&client->dev, "Revision %d\n", config & 0x0f); + + config &= ~AMC6821_CONF3_THERM_FAN_EN; + + if (i2c_smbus_write_byte_data(client, AMC6821_REG_CONF3, + config)) { + dev_err(&client->dev, + "Configuration register write error, aborting.\n"); + return err; + } + + config = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF2); + + if (config < 0) { + dev_err(&client->dev, + "Error reading configuration register, aborting.\n"); + return err; + } + + config &= ~AMC6821_CONF2_RTFIE; + config &= ~AMC6821_CONF2_LTOIE; + config &= ~AMC6821_CONF2_RTOIE; + if (i2c_smbus_write_byte_data(client, + AMC6821_REG_CONF2, config)) { + dev_err(&client->dev, + "Configuration register write error, aborting.\n"); + return err; + } + + config = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF1); + + if (config < 0) { + dev_err(&client->dev, + "Error reading configuration register, aborting.\n"); + return err; + } + + config &= ~AMC6821_CONF1_THERMOVIE; + config &= ~AMC6821_CONF1_FANIE; + config |= AMC6821_CONF1_START; + if (pwminv) + config |= AMC6821_CONF1_PWMINV; + else + config &= ~AMC6821_CONF1_PWMINV; + + if (i2c_smbus_write_byte_data( + client, AMC6821_REG_CONF1, config)) { + dev_err(&client->dev, + "Configuration register write error, aborting.\n"); + return err; + } + } + return 0; +} + + +static struct amc6821_data *amc6821_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct amc6821_data *data = i2c_get_clientdata(client); + int timeout = HZ; + u8 reg; + int i; + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + timeout) || + !data->valid) { + + for (i = 0; i < TEMP_IDX_LEN; i++) + data->temp[i] = i2c_smbus_read_byte_data(client, + temp_reg[i]); + + data->stat1 = i2c_smbus_read_byte_data(client, + AMC6821_REG_STAT1); + data->stat2 = i2c_smbus_read_byte_data(client, + AMC6821_REG_STAT2); + + data->pwm1 = i2c_smbus_read_byte_data(client, + AMC6821_REG_DCY); + for (i = 0; i < FAN1_IDX_LEN; i++) { + data->fan[i] = i2c_smbus_read_byte_data( + client, + fan_reg_low[i]); + data->fan[i] += i2c_smbus_read_byte_data( + client, + fan_reg_hi[i]) << 8; + } + data->fan1_div = i2c_smbus_read_byte_data(client, + AMC6821_REG_CONF4); + data->fan1_div = data->fan1_div & AMC6821_CONF4_PSPR ? 4 : 2; + + data->pwm1_auto_point_pwm[0] = 0; + data->pwm1_auto_point_pwm[2] = 255; + data->pwm1_auto_point_pwm[1] = i2c_smbus_read_byte_data(client, + AMC6821_REG_DCY_LOW_TEMP); + + data->temp1_auto_point_temp[0] = + i2c_smbus_read_byte_data(client, + AMC6821_REG_PSV_TEMP); + data->temp2_auto_point_temp[0] = + data->temp1_auto_point_temp[0]; + reg = i2c_smbus_read_byte_data(client, + AMC6821_REG_LTEMP_FAN_CTRL); + data->temp1_auto_point_temp[1] = (reg & 0xF8) >> 1; + reg &= 0x07; + reg = 0x20 >> reg; + if (reg > 0) + data->temp1_auto_point_temp[2] = + data->temp1_auto_point_temp[1] + + (data->pwm1_auto_point_pwm[2] - + data->pwm1_auto_point_pwm[1]) / reg; + else + data->temp1_auto_point_temp[2] = 255; + + reg = i2c_smbus_read_byte_data(client, + AMC6821_REG_RTEMP_FAN_CTRL); + data->temp2_auto_point_temp[1] = (reg & 0xF8) >> 1; + reg &= 0x07; + reg = 0x20 >> reg; + if (reg > 0) + data->temp2_auto_point_temp[2] = + data->temp2_auto_point_temp[1] + + (data->pwm1_auto_point_pwm[2] - + data->pwm1_auto_point_pwm[1]) / reg; + else + data->temp2_auto_point_temp[2] = 255; + + reg = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF1); + reg = (reg >> 5) & 0x3; + switch (reg) { + case 0: /*open loop: software sets pwm1*/ + data->pwm1_auto_channels_temp = 0; + data->pwm1_enable = 1; + break; + case 2: /*closed loop: remote T (temp2)*/ + data->pwm1_auto_channels_temp = 2; + data->pwm1_enable = 2; + break; + case 3: /*closed loop: local and remote T (temp2)*/ + data->pwm1_auto_channels_temp = 3; + data->pwm1_enable = 3; + break; + case 1: /*semi-open loop: software sets rpm, chip controls pwm1, + *currently not implemented + */ + data->pwm1_auto_channels_temp = 0; + data->pwm1_enable = 0; + break; + } + + data->last_updated = jiffies; + data->valid = 1; + } + mutex_unlock(&data->update_lock); + return data; +} + + +static int __init amc6821_init(void) +{ + return i2c_add_driver(&amc6821_driver); +} + +static void __exit amc6821_exit(void) +{ + i2c_del_driver(&amc6821_driver); +} + +module_init(amc6821_init); +module_exit(amc6821_exit); + + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("T. Mertelj "); +MODULE_DESCRIPTION("Texas Instruments amc6821 hwmon driver"); -- cgit v0.10.2 From 74dbdd239bb1348ad86d28b18574d9c1f28b62ca Mon Sep 17 00:00:00 2001 From: Andrea Arcangeli Date: Fri, 8 Jan 2010 14:43:05 -0800 Subject: mm: hugetlb: fix clear_huge_page() sz is in bytes, MAX_ORDER_NR_PAGES is in pages. Signed-off-by: Andrea Arcangeli Acked-by: David Gibson Cc: Mel Gorman Cc: David Rientjes Cc: Lee Schermerhorn Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 65f38c2..e91b81b 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -402,7 +402,7 @@ static void clear_huge_page(struct page *page, { int i; - if (unlikely(sz > MAX_ORDER_NR_PAGES)) { + if (unlikely(sz/PAGE_SIZE > MAX_ORDER_NR_PAGES)) { clear_gigantic_page(page, addr, sz); return; } -- cgit v0.10.2 From 006b4298f26984d514546fe4e53371761f66b643 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 8 Jan 2010 14:43:07 -0800 Subject: Documentation: update ring-buffer-design.txt Fix typos, grammos, spellos, hyphenation. Signed-off-by: Randy Dunlap Acked-by: Steven Rostedt Cc: Mel Gorman Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/Documentation/trace/ring-buffer-design.txt b/Documentation/trace/ring-buffer-design.txt index 5b1d23d..d299ff3 100644 --- a/Documentation/trace/ring-buffer-design.txt +++ b/Documentation/trace/ring-buffer-design.txt @@ -33,9 +33,9 @@ head_page - a pointer to the page that the reader will use next tail_page - a pointer to the page that will be written to next -commit_page - a pointer to the page with the last finished non nested write. +commit_page - a pointer to the page with the last finished non-nested write. -cmpxchg - hardware assisted atomic transaction that performs the following: +cmpxchg - hardware-assisted atomic transaction that performs the following: A = B iff previous A == C @@ -52,15 +52,15 @@ The Generic Ring Buffer The ring buffer can be used in either an overwrite mode or in producer/consumer mode. -Producer/consumer mode is where the producer were to fill up the +Producer/consumer mode is where if the producer were to fill up the buffer before the consumer could free up anything, the producer will stop writing to the buffer. This will lose most recent events. -Overwrite mode is where the produce were to fill up the buffer +Overwrite mode is where if the producer were to fill up the buffer before the consumer could free up anything, the producer will overwrite the older data. This will lose the oldest events. -No two writers can write at the same time (on the same per cpu buffer), +No two writers can write at the same time (on the same per-cpu buffer), but a writer may interrupt another writer, but it must finish writing before the previous writer may continue. This is very important to the algorithm. The writers act like a "stack". The way interrupts works @@ -79,16 +79,16 @@ the interrupt doing a write as well. Readers can happen at any time. But no two readers may run at the same time, nor can a reader preempt/interrupt another reader. A reader -can not preempt/interrupt a writer, but it may read/consume from the +cannot preempt/interrupt a writer, but it may read/consume from the buffer at the same time as a writer is writing, but the reader must be on another processor to do so. A reader may read on its own processor and can be preempted by a writer. -A writer can preempt a reader, but a reader can not preempt a writer. +A writer can preempt a reader, but a reader cannot preempt a writer. But a reader can read the buffer at the same time (on another processor) as a writer. -The ring buffer is made up of a list of pages held together by a link list. +The ring buffer is made up of a list of pages held together by a linked list. At initialization a reader page is allocated for the reader that is not part of the ring buffer. @@ -102,7 +102,7 @@ the head page. The reader has its own page to use. At start up time, this page is allocated but is not attached to the list. When the reader wants -to read from the buffer, if its page is empty (like it is on start up) +to read from the buffer, if its page is empty (like it is on start-up), it will swap its page with the head_page. The old reader page will become part of the ring buffer and the head_page will be removed. The page after the inserted page (old reader_page) will become the @@ -206,7 +206,7 @@ The main pointers: commit page - the page that last finished a write. -The commit page only is updated by the outer most writer in the +The commit page only is updated by the outermost writer in the writer stack. A writer that preempts another writer will not move the commit page. @@ -281,7 +281,7 @@ with the previous write. The commit pointer points to the last write location that was committed without preempting another write. When a write that preempted another write is committed, it only becomes a pending commit -and will not be a full commit till all writes have been committed. +and will not be a full commit until all writes have been committed. The commit page points to the page that has the last full commit. The tail page points to the page with the last write (before @@ -292,7 +292,7 @@ be several pages ahead. If the tail page catches up to the commit page then no more writes may take place (regardless of the mode of the ring buffer: overwrite and produce/consumer). -The order of pages are: +The order of pages is: head page commit page @@ -311,7 +311,7 @@ Possible scenario: There is a special case that the head page is after either the commit page and possibly the tail page. That is when the commit (and tail) page has been swapped with the reader page. This is because the head page is always -part of the ring buffer, but the reader page is not. When ever there +part of the ring buffer, but the reader page is not. Whenever there has been less than a full page that has been committed inside the ring buffer, and a reader swaps out a page, it will be swapping out the commit page. @@ -338,7 +338,7 @@ and a reader swaps out a page, it will be swapping out the commit page. In this case, the head page will not move when the tail and commit move back into the ring buffer. -The reader can not swap a page into the ring buffer if the commit page +The reader cannot swap a page into the ring buffer if the commit page is still on that page. If the read meets the last commit (real commit not pending or reserved), then there is nothing more to read. The buffer is considered empty until another full commit finishes. @@ -395,7 +395,7 @@ The main idea behind the lockless algorithm is to combine the moving of the head_page pointer with the swapping of pages with the reader. State flags are placed inside the pointer to the page. To do this, each page must be aligned in memory by 4 bytes. This will allow the 2 -least significant bits of the address to be used as flags. Since +least significant bits of the address to be used as flags, since they will always be zero for the address. To get the address, simply mask out the flags. @@ -460,7 +460,7 @@ When the reader tries to swap the page with the ring buffer, it will also use cmpxchg. If the flag bit in the pointer to the head page does not have the HEADER flag set, the compare will fail and the reader will need to look for the new head page and try again. -Note, the flag UPDATE and HEADER are never set at the same time. +Note, the flags UPDATE and HEADER are never set at the same time. The reader swaps the reader page as follows: @@ -539,7 +539,7 @@ updated to the reader page. | +-----------------------------+ | +------------------------------------+ -Another important point. The page that the reader page points back to +Another important point: The page that the reader page points back to by its previous pointer (the one that now points to the new head page) never points back to the reader page. That is because the reader page is not part of the ring buffer. Traversing the ring buffer via the next pointers @@ -572,7 +572,7 @@ not be able to swap the head page from the buffer, nor will it be able to move the head page, until the writer is finished with the move. This eliminates any races that the reader can have on the writer. The reader -must spin, and this is why the reader can not preempt the writer. +must spin, and this is why the reader cannot preempt the writer. tail page | @@ -659,9 +659,9 @@ before pushing the head page. If it is, then it can be assumed that the tail page wrapped the buffer, and we must drop new writes. This is not a race condition, because the commit page can only be moved -by the outter most writer (the writer that was preempted). +by the outermost writer (the writer that was preempted). This means that the commit will not move while a writer is moving the -tail page. The reader can not swap the reader page if it is also being +tail page. The reader cannot swap the reader page if it is also being used as the commit page. The reader can simply check that the commit is off the reader page. Once the commit page leaves the reader page it will never go back on it unless a reader does another swap with the @@ -733,7 +733,7 @@ The write converts the head page pointer to UPDATE. --->| |<---| |<---| |<---| |<--- +---+ +---+ +---+ +---+ -But if a nested writer preempts here. It will see that the next +But if a nested writer preempts here, it will see that the next page is a head page, but it is also nested. It will detect that it is nested and will save that information. The detection is the fact that it sees the UPDATE flag instead of a HEADER or NORMAL @@ -761,7 +761,7 @@ to NORMAL. --->| |<---| |<---| |<---| |<--- +---+ +---+ +---+ +---+ -After the nested writer finishes, the outer most writer will convert +After the nested writer finishes, the outermost writer will convert the UPDATE pointer to NORMAL. @@ -812,7 +812,7 @@ head page. +---+ +---+ +---+ +---+ The nested writer moves the tail page forward. But does not set the old -update page to NORMAL because it is not the outer most writer. +update page to NORMAL because it is not the outermost writer. tail page | @@ -892,7 +892,7 @@ It will return to the first writer. --->| |<---| |<---| |<---| |<--- +---+ +---+ +---+ +---+ -The first writer can not know atomically test if the tail page moved +The first writer cannot know atomically if the tail page moved while it updates the HEAD page. It will then update the head page to what it thinks is the new head page. @@ -923,9 +923,9 @@ if the tail page is either where it use to be or on the next page: --->| |<---| |<---| |<---| |<--- +---+ +---+ +---+ +---+ -If tail page != A and tail page does not equal B, then it must reset the -pointer back to NORMAL. The fact that it only needs to worry about -nested writers, it only needs to check this after setting the HEAD page. +If tail page != A and tail page != B, then it must reset the pointer +back to NORMAL. The fact that it only needs to worry about nested +writers means that it only needs to check this after setting the HEAD page. (first writer) @@ -939,7 +939,7 @@ nested writers, it only needs to check this after setting the HEAD page. +---+ +---+ +---+ +---+ Now the writer can update the head page. This is also why the head page must -remain in UPDATE and only reset by the outer most writer. This prevents +remain in UPDATE and only reset by the outermost writer. This prevents the reader from seeing the incorrect head page. -- cgit v0.10.2 From 5787536edf18e33d06e2bf038bfd0910f4def213 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Fri, 8 Jan 2010 14:43:08 -0800 Subject: drivers/cpuidle/governors/menu.c: fix undefined reference to `__udivdi3' menu: use proper 64 bit math The new menu governor is incorrectly doing a 64 bit divide. Compile tested only Signed-off-by: Stephen Hemminger Cc: Arjan van de Ven Cc: Len Brown Cc: Venkatesh Pallipadi Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c index 6810443..73655ae 100644 --- a/drivers/cpuidle/governors/menu.c +++ b/drivers/cpuidle/governors/menu.c @@ -18,6 +18,7 @@ #include #include #include +#include #define BUCKETS 12 #define RESOLUTION 1024 @@ -169,6 +170,12 @@ static DEFINE_PER_CPU(struct menu_device, menu_devices); static void menu_update(struct cpuidle_device *dev); +/* This implements DIV_ROUND_CLOSEST but avoids 64 bit division */ +static u64 div_round64(u64 dividend, u32 divisor) +{ + return div_u64(dividend + (divisor / 2), divisor); +} + /** * menu_select - selects the next idle state to enter * @dev: the CPU @@ -209,9 +216,8 @@ static int menu_select(struct cpuidle_device *dev) data->correction_factor[data->bucket] = RESOLUTION * DECAY; /* Make sure to round up for half microseconds */ - data->predicted_us = DIV_ROUND_CLOSEST( - data->expected_us * data->correction_factor[data->bucket], - RESOLUTION * DECAY); + data->predicted_us = div_round64(data->expected_us * data->correction_factor[data->bucket], + RESOLUTION * DECAY); /* * We want to default to C1 (hlt), not to busy polling -- cgit v0.10.2 From 80884094e34456887ecdbd107d40e72c4a40f9c9 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Fri, 8 Jan 2010 14:43:08 -0800 Subject: gpio: adp5588-gpio: new driver for ADP5588 GPIO expanders Signed-off-by: Michael Hennerich Signed-off-by: Mike Frysinger Cc: Jean Delvare Cc: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index a019b49..1f1d88a 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -172,6 +172,15 @@ config GPIO_ADP5520 To compile this driver as a module, choose M here: the module will be called adp5520-gpio. +config GPIO_ADP5588 + tristate "ADP5588 I2C GPIO expander" + depends on I2C + help + This option enables support for 18 GPIOs found + on Analog Devices ADP5588 GPIO Expanders. + To compile this driver as a module, choose M here: the module will be + called adp5588-gpio. + comment "PCI GPIO expanders:" config GPIO_CS5535 diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 52fe4cf..4868723 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -5,6 +5,7 @@ ccflags-$(CONFIG_DEBUG_GPIO) += -DDEBUG obj-$(CONFIG_GPIOLIB) += gpiolib.o obj-$(CONFIG_GPIO_ADP5520) += adp5520-gpio.o +obj-$(CONFIG_GPIO_ADP5588) += adp5588-gpio.o obj-$(CONFIG_GPIO_LANGWELL) += langwell_gpio.o obj-$(CONFIG_GPIO_MAX7301) += max7301.o obj-$(CONFIG_GPIO_MAX732X) += max732x.o diff --git a/drivers/gpio/adp5588-gpio.c b/drivers/gpio/adp5588-gpio.c new file mode 100644 index 0000000..afc097a --- /dev/null +++ b/drivers/gpio/adp5588-gpio.c @@ -0,0 +1,266 @@ +/* + * GPIO Chip driver for Analog Devices + * ADP5588 I/O Expander and QWERTY Keypad Controller + * + * Copyright 2009 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include + +#include + +#define DRV_NAME "adp5588-gpio" +#define MAXGPIO 18 +#define ADP_BANK(offs) ((offs) >> 3) +#define ADP_BIT(offs) (1u << ((offs) & 0x7)) + +struct adp5588_gpio { + struct i2c_client *client; + struct gpio_chip gpio_chip; + struct mutex lock; /* protect cached dir, dat_out */ + unsigned gpio_start; + uint8_t dat_out[3]; + uint8_t dir[3]; +}; + +static int adp5588_gpio_read(struct i2c_client *client, u8 reg) +{ + int ret = i2c_smbus_read_byte_data(client, reg); + + if (ret < 0) + dev_err(&client->dev, "Read Error\n"); + + return ret; +} + +static int adp5588_gpio_write(struct i2c_client *client, u8 reg, u8 val) +{ + int ret = i2c_smbus_write_byte_data(client, reg, val); + + if (ret < 0) + dev_err(&client->dev, "Write Error\n"); + + return ret; +} + +static int adp5588_gpio_get_value(struct gpio_chip *chip, unsigned off) +{ + struct adp5588_gpio *dev = + container_of(chip, struct adp5588_gpio, gpio_chip); + + return !!(adp5588_gpio_read(dev->client, GPIO_DAT_STAT1 + ADP_BANK(off)) + & ADP_BIT(off)); +} + +static void adp5588_gpio_set_value(struct gpio_chip *chip, + unsigned off, int val) +{ + unsigned bank, bit; + struct adp5588_gpio *dev = + container_of(chip, struct adp5588_gpio, gpio_chip); + + bank = ADP_BANK(off); + bit = ADP_BIT(off); + + mutex_lock(&dev->lock); + if (val) + dev->dat_out[bank] |= bit; + else + dev->dat_out[bank] &= ~bit; + + adp5588_gpio_write(dev->client, GPIO_DAT_OUT1 + bank, + dev->dat_out[bank]); + mutex_unlock(&dev->lock); +} + +static int adp5588_gpio_direction_input(struct gpio_chip *chip, unsigned off) +{ + int ret; + unsigned bank; + struct adp5588_gpio *dev = + container_of(chip, struct adp5588_gpio, gpio_chip); + + bank = ADP_BANK(off); + + mutex_lock(&dev->lock); + dev->dir[bank] &= ~ADP_BIT(off); + ret = adp5588_gpio_write(dev->client, GPIO_DIR1 + bank, dev->dir[bank]); + mutex_unlock(&dev->lock); + + return ret; +} + +static int adp5588_gpio_direction_output(struct gpio_chip *chip, + unsigned off, int val) +{ + int ret; + unsigned bank, bit; + struct adp5588_gpio *dev = + container_of(chip, struct adp5588_gpio, gpio_chip); + + bank = ADP_BANK(off); + bit = ADP_BIT(off); + + mutex_lock(&dev->lock); + dev->dir[bank] |= bit; + + if (val) + dev->dat_out[bank] |= bit; + else + dev->dat_out[bank] &= ~bit; + + ret = adp5588_gpio_write(dev->client, GPIO_DAT_OUT1 + bank, + dev->dat_out[bank]); + ret |= adp5588_gpio_write(dev->client, GPIO_DIR1 + bank, + dev->dir[bank]); + mutex_unlock(&dev->lock); + + return ret; +} + +static int __devinit adp5588_gpio_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct adp5588_gpio_platform_data *pdata = client->dev.platform_data; + struct adp5588_gpio *dev; + struct gpio_chip *gc; + int ret, i, revid; + + if (pdata == NULL) { + dev_err(&client->dev, "missing platform data\n"); + return -ENODEV; + } + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA)) { + dev_err(&client->dev, "SMBUS Byte Data not Supported\n"); + return -EIO; + } + + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (dev == NULL) { + dev_err(&client->dev, "failed to alloc memory\n"); + return -ENOMEM; + } + + dev->client = client; + + gc = &dev->gpio_chip; + gc->direction_input = adp5588_gpio_direction_input; + gc->direction_output = adp5588_gpio_direction_output; + gc->get = adp5588_gpio_get_value; + gc->set = adp5588_gpio_set_value; + gc->can_sleep = 1; + + gc->base = pdata->gpio_start; + gc->ngpio = MAXGPIO; + gc->label = client->name; + gc->owner = THIS_MODULE; + + mutex_init(&dev->lock); + + + ret = adp5588_gpio_read(dev->client, DEV_ID); + if (ret < 0) + goto err; + + revid = ret & ADP5588_DEVICE_ID_MASK; + + for (i = 0, ret = 0; i <= ADP_BANK(MAXGPIO); i++) { + dev->dat_out[i] = adp5588_gpio_read(client, GPIO_DAT_OUT1 + i); + dev->dir[i] = adp5588_gpio_read(client, GPIO_DIR1 + i); + ret |= adp5588_gpio_write(client, KP_GPIO1 + i, 0); + ret |= adp5588_gpio_write(client, GPIO_PULL1 + i, + (pdata->pullup_dis_mask >> (8 * i)) & 0xFF); + + if (ret) + goto err; + } + + ret = gpiochip_add(&dev->gpio_chip); + if (ret) + goto err; + + dev_info(&client->dev, "gpios %d..%d on a %s Rev. %d\n", + gc->base, gc->base + gc->ngpio - 1, + client->name, revid); + + if (pdata->setup) { + ret = pdata->setup(client, gc->base, gc->ngpio, pdata->context); + if (ret < 0) + dev_warn(&client->dev, "setup failed, %d\n", ret); + } + + i2c_set_clientdata(client, dev); + return 0; + +err: + kfree(dev); + return ret; +} + +static int __devexit adp5588_gpio_remove(struct i2c_client *client) +{ + struct adp5588_gpio_platform_data *pdata = client->dev.platform_data; + struct adp5588_gpio *dev = i2c_get_clientdata(client); + int ret; + + if (pdata->teardown) { + ret = pdata->teardown(client, + dev->gpio_chip.base, dev->gpio_chip.ngpio, + pdata->context); + if (ret < 0) { + dev_err(&client->dev, "teardown failed %d\n", ret); + return ret; + } + } + + ret = gpiochip_remove(&dev->gpio_chip); + if (ret) { + dev_err(&client->dev, "gpiochip_remove failed %d\n", ret); + return ret; + } + + kfree(dev); + return 0; +} + +static const struct i2c_device_id adp5588_gpio_id[] = { + {DRV_NAME, 0}, + {} +}; + +MODULE_DEVICE_TABLE(i2c, adp5588_gpio_id); + +static struct i2c_driver adp5588_gpio_driver = { + .driver = { + .name = DRV_NAME, + }, + .probe = adp5588_gpio_probe, + .remove = __devexit_p(adp5588_gpio_remove), + .id_table = adp5588_gpio_id, +}; + +static int __init adp5588_gpio_init(void) +{ + return i2c_add_driver(&adp5588_gpio_driver); +} + +module_init(adp5588_gpio_init); + +static void __exit adp5588_gpio_exit(void) +{ + i2c_del_driver(&adp5588_gpio_driver); +} + +module_exit(adp5588_gpio_exit); + +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("GPIO ADP5588 Driver"); +MODULE_LICENSE("GPL"); diff --git a/include/linux/i2c/adp5588.h b/include/linux/i2c/adp5588.h index fc5db82..02c9af3 100644 --- a/include/linux/i2c/adp5588.h +++ b/include/linux/i2c/adp5588.h @@ -89,4 +89,16 @@ struct adp5588_kpad_platform_data { unsigned short unlock_key2; /* Unlock Key 2 */ }; +struct adp5588_gpio_platform_data { + unsigned gpio_start; /* GPIO Chip base # */ + unsigned pullup_dis_mask; /* Pull-Up Disable Mask */ + int (*setup)(struct i2c_client *client, + int gpio, unsigned ngpio, + void *context); + int (*teardown)(struct i2c_client *client, + int gpio, unsigned ngpio, + void *context); + void *context; +}; + #endif -- cgit v0.10.2 From d2b34e20c1f431604e0dde910c3ff271c84ed706 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 8 Jan 2010 14:43:09 -0800 Subject: documentation: update kernel-doc-nano-HOWTO information Remove comments about function short descriptions not allowed to be on multiple lines (that was fixed/changed recently). Add comments that function "section header:" names need to be unique per function/struct/union/typedef/enum. Signed-off-by: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/Documentation/kernel-doc-nano-HOWTO.txt b/Documentation/kernel-doc-nano-HOWTO.txt index 348b9e5..27a52b3 100644 --- a/Documentation/kernel-doc-nano-HOWTO.txt +++ b/Documentation/kernel-doc-nano-HOWTO.txt @@ -214,11 +214,13 @@ The format of the block comment is like this: * (section header: (section description)? )* (*)?*/ -The short function description ***cannot be multiline***, but the other -descriptions can be (and they can contain blank lines). If you continue -that initial short description onto a second line, that second line will -appear further down at the beginning of the description section, which is -almost certainly not what you had in mind. +All "description" text can span multiple lines, although the +function_name & its short description are traditionally on a single line. +Description text may also contain blank lines (i.e., lines that contain +only a "*"). + +"section header:" names must be unique per function (or struct, +union, typedef, enum). Avoid putting a spurious blank line after the function name, or else the description will be repeated! -- cgit v0.10.2 From 7f53a09ed40f08416b3029ada8f02252e7596c18 Mon Sep 17 00:00:00 2001 From: Minchan Kim Date: Fri, 8 Jan 2010 14:43:10 -0800 Subject: smaps: fix wrong rss count A long time ago we regarded zero page as file_rss and vm_normal_page doesn't return NULL. But now, we reinstated ZERO_PAGE and vm_normal_page's implementation can return NULL in case of zero page. Also we don't count it with file_rss any more. Then, RSS and PSS can't be matched. For consistency, Let's ignore zero page in smaps_pte_range. Signed-off-by: Minchan Kim Acked-by: KAMEZAWA Hiroyuki Acked-by: Hugh Dickins Acked-by: Matt Mackall Reviewed-by: KOSAKI Motohiro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 47c03f4..f277c4a 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -361,12 +361,11 @@ static int smaps_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end, if (!pte_present(ptent)) continue; - mss->resident += PAGE_SIZE; - page = vm_normal_page(vma, addr, ptent); if (!page) continue; + mss->resident += PAGE_SIZE; /* Accumulate the size in pages that have been accessed. */ if (pte_young(ptent) || PageReferenced(page)) mss->referenced += PAGE_SIZE; -- cgit v0.10.2 From 004731b2c7c658d36bee167cb1e1a399c2cbccc9 Mon Sep 17 00:00:00 2001 From: OGAWA Hirofumi Date: Fri, 8 Jan 2010 14:43:11 -0800 Subject: rtc_cmos: convert shutdown to new pnp_driver->shutdown MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit abd6633c67925f90775bb74755f9c547e30f1f20 ("pnp: add a shutdown method to pnp drivers") adds shutdown method to bus driver blindly. With it, driver->shutdown is no longer valid. Use pnp_driver->shutdown instead. Addresses http://bugzilla.kernel.org/show_bug.cgi?id=14889 Signed-off-by: OGAWA Hirofumi Reported-by: Malte Schröder Cc: "Rafael J. Wysocki" Cc: Bjorn Helgaas Cc: David Hardeman Cc: Dmitry Torokhov Cc: Alessandro Zummo Cc: Paul Gortmaker Cc: [2.6.32.x] Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index c8c1232..e9aa814 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -1096,9 +1096,9 @@ static int cmos_pnp_resume(struct pnp_dev *pnp) #define cmos_pnp_resume NULL #endif -static void cmos_pnp_shutdown(struct device *pdev) +static void cmos_pnp_shutdown(struct pnp_dev *pnp) { - if (system_state == SYSTEM_POWER_OFF && !cmos_poweroff(pdev)) + if (system_state == SYSTEM_POWER_OFF && !cmos_poweroff(&pnp->dev)) return; cmos_do_shutdown(); @@ -1117,15 +1117,12 @@ static struct pnp_driver cmos_pnp_driver = { .id_table = rtc_ids, .probe = cmos_pnp_probe, .remove = __exit_p(cmos_pnp_remove), + .shutdown = cmos_pnp_shutdown, /* flag ensures resume() gets called, and stops syslog spam */ .flags = PNP_DRIVER_RES_DO_NOT_CHANGE, .suspend = cmos_pnp_suspend, .resume = cmos_pnp_resume, - .driver = { - .name = (char *)driver_name, - .shutdown = cmos_pnp_shutdown, - } }; #endif /* CONFIG_PNP */ -- cgit v0.10.2 From 4c03ee7352f2f0ee393c7190ce0b758dd1217f57 Mon Sep 17 00:00:00 2001 From: Mark Salter Date: Fri, 8 Jan 2010 14:43:14 -0800 Subject: mn10300: signal stack fix This fixes a signal stack handling problem in the MN10300 arch. When new threads are cloned with CLONE_VM, they don't inherit the alternate signal stack. They do share the signal flags, though. When deciding whether to use an alternate stack, the arch code needs to check to make sure the task struct contains a valid alternate stack. This patch fixes the MN10300 arch by using the sas_ss_flags() test provided by sched.h rather than the on_sig_stack() test which is insufficient by itself. Signed-off-by: Mark Salter Signed-off-by: David Howells Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/arch/mn10300/kernel/signal.c b/arch/mn10300/kernel/signal.c index a21f43b..717db14 100644 --- a/arch/mn10300/kernel/signal.c +++ b/arch/mn10300/kernel/signal.c @@ -264,7 +264,7 @@ static inline void __user *get_sigframe(struct k_sigaction *ka, /* this is the X/Open sanctioned signal stack switching. */ if (ka->sa.sa_flags & SA_ONSTACK) { - if (!on_sig_stack(sp)) + if (sas_ss_flags(sp) == 0) sp = current->sas_ss_sp + current->sas_ss_size; } -- cgit v0.10.2 From b0641e86fbc722906e323b2c2a069e65f44ff484 Mon Sep 17 00:00:00 2001 From: Mark Salter Date: Fri, 8 Jan 2010 14:43:15 -0800 Subject: mn10300: objcopy flags fix The gcc-4.2.1 based toolchain for MN10300 adds some new note sections which need to be stripped from the binary image. This patch takes care of that. Signed-off-by: Mark Salter Signed-off-by: David Howells Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/arch/mn10300/Makefile b/arch/mn10300/Makefile index dd0c8ff..ac5c6bd 100644 --- a/arch/mn10300/Makefile +++ b/arch/mn10300/Makefile @@ -19,7 +19,7 @@ CCDIR := $(strip $(patsubst %/specs,%,$(CCSPECS))) KBUILD_CPPFLAGS += -nostdinc -I$(CCDIR)/include LDFLAGS := -OBJCOPYFLAGS := -O binary -R .note -R .comment -S +OBJCOPYFLAGS := -O binary -R .note -R .comment -R .GCC-command-line -R .note.gnu.build-id -S #LDFLAGS_vmlinux := -Map linkmap.txt CHECKFLAGS += -- cgit v0.10.2 From d6bb7a1ad326f56f0793353c59348554f84b513c Mon Sep 17 00:00:00 2001 From: Mark Salter Date: Fri, 8 Jan 2010 14:43:16 -0800 Subject: mn10300: add cc clobbers to asm statements gcc 4.2.1 for MN10300 is more agressive than the older gcc in reordering/moving other insns between an insn that sets flags and an insn that uses those flags. This leads to trouble with asm statements which are missing an explicit "cc" clobber. This patch adds the explicit "cc" clobber to asm statements which do indeed clobber the condition flags. Signed-off-by: Mark Salter Signed-off-by: David Howells Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/arch/mn10300/include/asm/bitops.h b/arch/mn10300/include/asm/bitops.h index 0b610f4..f49ac49 100644 --- a/arch/mn10300/include/asm/bitops.h +++ b/arch/mn10300/include/asm/bitops.h @@ -165,7 +165,7 @@ static inline __attribute__((const)) unsigned long __ffs(unsigned long x) { int bit; - asm("bsch %2,%0" : "=r"(bit) : "0"(0), "r"(x & -x)); + asm("bsch %2,%0" : "=r"(bit) : "0"(0), "r"(x & -x) : "cc"); return bit; } @@ -177,7 +177,7 @@ static inline __attribute__((const)) int __ilog2_u32(u32 n) { int bit; - asm("bsch %2,%0" : "=r"(bit) : "0"(0), "r"(n)); + asm("bsch %2,%0" : "=r"(bit) : "0"(0), "r"(n) : "cc"); return bit; } diff --git a/arch/mn10300/include/asm/div64.h b/arch/mn10300/include/asm/div64.h index 3a8329b..34dcb8e 100644 --- a/arch/mn10300/include/asm/div64.h +++ b/arch/mn10300/include/asm/div64.h @@ -72,6 +72,7 @@ unsigned __muldiv64u(unsigned val, unsigned mult, unsigned div) * MDR = MDR:val%div */ : "=r"(result) : "0"(val), "ir"(mult), "r"(div) + : "cc" ); return result; @@ -92,6 +93,7 @@ signed __muldiv64s(signed val, signed mult, signed div) * MDR = MDR:val%div */ : "=r"(result) : "0"(val), "ir"(mult), "r"(div) + : "cc" ); return result; diff --git a/arch/mn10300/include/asm/system.h b/arch/mn10300/include/asm/system.h index 8214fb7..3636c05 100644 --- a/arch/mn10300/include/asm/system.h +++ b/arch/mn10300/include/asm/system.h @@ -143,6 +143,7 @@ do { \ " mov %0,epsw \n" \ : "=&d"(tmp) \ : "i"(~EPSW_IM), "r"(__mn10300_irq_enabled_epsw) \ + : "cc" \ ); \ } while (0) diff --git a/arch/mn10300/include/asm/tlbflush.h b/arch/mn10300/include/asm/tlbflush.h index e023986..1a7e292 100644 --- a/arch/mn10300/include/asm/tlbflush.h +++ b/arch/mn10300/include/asm/tlbflush.h @@ -22,7 +22,7 @@ do { \ " mov %0,%1 \n" \ : "=d"(w) \ : "m"(MMUCTR), "i"(MMUCTR_IIV|MMUCTR_DIV) \ - : "memory" \ + : "cc", "memory" \ ); \ } while (0) diff --git a/arch/mn10300/include/asm/uaccess.h b/arch/mn10300/include/asm/uaccess.h index 167e10f..197a7af 100644 --- a/arch/mn10300/include/asm/uaccess.h +++ b/arch/mn10300/include/asm/uaccess.h @@ -316,7 +316,7 @@ do { \ " .previous\n" \ : "=a"(__from), "=a"(__to), "=r"(size), "=&r"(w)\ : "0"(__from), "1"(__to), "2"(size) \ - : "memory"); \ + : "cc", "memory"); \ } \ } while (0) @@ -352,7 +352,7 @@ do { \ " .previous\n" \ : "=a"(__from), "=a"(__to), "=r"(size), "=&r"(w)\ : "0"(__from), "1"(__to), "2"(size) \ - : "memory"); \ + : "cc", "memory"); \ } \ } while (0) diff --git a/arch/mn10300/kernel/mn10300-serial.c b/arch/mn10300/kernel/mn10300-serial.c index 229b710..ef34d5a 100644 --- a/arch/mn10300/kernel/mn10300-serial.c +++ b/arch/mn10300/kernel/mn10300-serial.c @@ -380,7 +380,8 @@ static int mask_test_and_clear(volatile u8 *ptr, u8 mask) u32 epsw; asm volatile(" bclr %1,(%2) \n" " mov epsw,%0 \n" - : "=d"(epsw) : "d"(mask), "a"(ptr)); + : "=d"(epsw) : "d"(mask), "a"(ptr) + : "cc", "memory"); return !(epsw & EPSW_FLAG_Z); } diff --git a/arch/mn10300/lib/checksum.c b/arch/mn10300/lib/checksum.c index 274f29e..b6580f5 100644 --- a/arch/mn10300/lib/checksum.c +++ b/arch/mn10300/lib/checksum.c @@ -22,6 +22,7 @@ static inline unsigned short from32to16(__wsum sum) " addc 0xffff,%0 \n" : "=r" (sum) : "r" (sum << 16), "0" (sum & 0xffff0000) + : "cc" ); return sum >> 16; } diff --git a/arch/mn10300/lib/delay.c b/arch/mn10300/lib/delay.c index cce66bc..fdf6f71 100644 --- a/arch/mn10300/lib/delay.c +++ b/arch/mn10300/lib/delay.c @@ -28,7 +28,8 @@ void __delay(unsigned long loops) "2: add -1,%0 \n" " bne 2b \n" : "=&d" (d0) - : "0" (loops)); + : "0" (loops) + : "cc"); } EXPORT_SYMBOL(__delay); diff --git a/arch/mn10300/lib/usercopy.c b/arch/mn10300/lib/usercopy.c index a75b203..7826e6c 100644 --- a/arch/mn10300/lib/usercopy.c +++ b/arch/mn10300/lib/usercopy.c @@ -62,7 +62,7 @@ do { \ " .previous" \ :"=&r"(res), "=r"(count), "=&r"(w) \ :"i"(-EFAULT), "1"(count), "a"(src), "a"(dst) \ - :"memory"); \ + : "memory", "cc"); \ } while (0) long @@ -109,7 +109,7 @@ do { \ ".previous\n" \ : "+r"(size), "=&r"(w) \ : "a"(addr), "d"(0) \ - : "memory"); \ + : "memory", "cc"); \ } while (0) unsigned long @@ -161,6 +161,6 @@ long strnlen_user(const char *s, long n) ".previous\n" :"=d"(res), "=&r"(w) :"0"(0), "a"(s), "r"(n) - :"memory"); + : "memory", "cc"); return res; } diff --git a/arch/mn10300/mm/misalignment.c b/arch/mn10300/mm/misalignment.c index 3001625..6dffbf9 100644 --- a/arch/mn10300/mm/misalignment.c +++ b/arch/mn10300/mm/misalignment.c @@ -633,13 +633,13 @@ static int misalignment_addr(unsigned long *registers, unsigned long sp, goto displace_or_inc; case SD24: tmp = disp << 8; - asm("asr 8,%0" : "=r"(tmp) : "0"(tmp)); + asm("asr 8,%0" : "=r"(tmp) : "0"(tmp) : "cc"); disp = (long) tmp; goto displace_or_inc; case SIMM4_2: tmp = opcode >> 4 & 0x0f; tmp <<= 28; - asm("asr 28,%0" : "=r"(tmp) : "0"(tmp)); + asm("asr 28,%0" : "=r"(tmp) : "0"(tmp) : "cc"); disp = (long) tmp; goto displace_or_inc; case IMM8: -- cgit v0.10.2 From e5d20d01023e76f3c1289cfca2e3305de7ff9e69 Mon Sep 17 00:00:00 2001 From: David Howells Date: Fri, 8 Jan 2010 14:43:17 -0800 Subject: mn10300: wire up missing new syscalls Wire up missing new system calls for MN10300. Signed-off-by: David Howells Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/arch/mn10300/include/asm/unistd.h b/arch/mn10300/include/asm/unistd.h index 2a98393..c05acb9 100644 --- a/arch/mn10300/include/asm/unistd.h +++ b/arch/mn10300/include/asm/unistd.h @@ -348,10 +348,11 @@ #define __NR_pwritev 335 #define __NR_rt_tgsigqueueinfo 336 #define __NR_perf_event_open 337 +#define __NR_recvmmsg 338 #ifdef __KERNEL__ -#define NR_syscalls 338 +#define NR_syscalls 339 /* * specify the deprecated syscalls we want to support on this arch diff --git a/arch/mn10300/kernel/entry.S b/arch/mn10300/kernel/entry.S index c9ee6c0..88e3e1c 100644 --- a/arch/mn10300/kernel/entry.S +++ b/arch/mn10300/kernel/entry.S @@ -724,6 +724,7 @@ ENTRY(sys_call_table) .long sys_pwritev /* 335 */ .long sys_rt_tgsigqueueinfo .long sys_perf_event_open + .long sys_recvmmsg nr_syscalls=(.-sys_call_table)/4 -- cgit v0.10.2 From 07c706a6226ea7556a41fced300248d1daac90db Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 8 Jan 2010 14:43:17 -0800 Subject: mn10300: fix several bogus includes on abs2305 asm/cpu never existed for mn10300; the files they are looking for are in asm. Signed-off-by: Al Viro Signed-off-by: David Howells Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/arch/mn10300/unit-asb2305/include/unit/serial.h b/arch/mn10300/unit-asb2305/include/unit/serial.h index 3bfc9093..8086cc0 100644 --- a/arch/mn10300/unit-asb2305/include/unit/serial.h +++ b/arch/mn10300/unit-asb2305/include/unit/serial.h @@ -11,7 +11,7 @@ #ifndef _ASM_UNIT_SERIAL_H #define _ASM_UNIT_SERIAL_H -#include +#include #include #include diff --git a/arch/mn10300/unit-asb2305/include/unit/timex.h b/arch/mn10300/unit-asb2305/include/unit/timex.h index a71c49a..d1c72d5 100644 --- a/arch/mn10300/unit-asb2305/include/unit/timex.h +++ b/arch/mn10300/unit-asb2305/include/unit/timex.h @@ -15,7 +15,7 @@ #include #endif /* __ASSEMBLY__ */ -#include +#include #include /* diff --git a/arch/mn10300/unit-asb2305/leds.c b/arch/mn10300/unit-asb2305/leds.c index d345ff9..6f8de99 100644 --- a/arch/mn10300/unit-asb2305/leds.c +++ b/arch/mn10300/unit-asb2305/leds.c @@ -13,8 +13,8 @@ #include #include #include -#include -#include +#include +#include #include static const u8 asb2305_led_hex_tbl[16] = { diff --git a/arch/mn10300/unit-asb2305/unit-init.c b/arch/mn10300/unit-asb2305/unit-init.c index 1c452cc..a76c8e0 100644 --- a/arch/mn10300/unit-asb2305/unit-init.c +++ b/arch/mn10300/unit-asb2305/unit-init.c @@ -15,9 +15,8 @@ #include #include #include -#include -#include -#include +#include +#include #include /* -- cgit v0.10.2 From e716381f9f4ea65df2e2a911275b47ed6ae53d4b Mon Sep 17 00:00:00 2001 From: David Howells Date: Fri, 8 Jan 2010 14:43:18 -0800 Subject: mn10300: use KERN_ERR not KERN_ERROR Use KERN_ERR not KERN_ERROR in the ASB2305 platform code. Signed-off-by: David Howells Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/arch/mn10300/unit-asb2305/pci.c b/arch/mn10300/unit-asb2305/pci.c index 07dbbcd..082590f 100644 --- a/arch/mn10300/unit-asb2305/pci.c +++ b/arch/mn10300/unit-asb2305/pci.c @@ -279,7 +279,7 @@ static int __init pci_sanity_check(struct pci_ops *o) (x == PCI_VENDOR_ID_INTEL || x == PCI_VENDOR_ID_COMPAQ))) return 1; - printk(KERN_ERROR "PCI: Sanity check failed\n"); + printk(KERN_ERR "PCI: Sanity check failed\n"); return 0; } -- cgit v0.10.2 From 126cda50468d26c4c67f20c51a800685d42d1c61 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 8 Jan 2010 14:43:19 -0800 Subject: mn10300: use generic pci_enable_resources() Use the generic pci_enable_resources() instead of the arch-specific code. Unlike this arch-specific code, the generic version: - checks PCI_NUM_RESOURCES (11), not 6, resources - skips resources that have neither IORESOURCE_IO nor IORESOURCE_MEM set - skips ROM resources unless IORESOURCE_ROM_ENABLE is set - checks for resource collisions with "!r->parent" Signed-off-by: Bjorn Helgaas Signed-off-by: David Howells Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/arch/mn10300/unit-asb2305/pci-asb2305.c b/arch/mn10300/unit-asb2305/pci-asb2305.c index d100ca7..78cd134 100644 --- a/arch/mn10300/unit-asb2305/pci-asb2305.c +++ b/arch/mn10300/unit-asb2305/pci-asb2305.c @@ -218,45 +218,6 @@ void __init pcibios_resource_survey(void) pcibios_allocate_resources(1); } -int pcibios_enable_resources(struct pci_dev *dev, int mask) -{ - u16 cmd, old_cmd; - int idx; - struct resource *r; - - pci_read_config_word(dev, PCI_COMMAND, &cmd); - old_cmd = cmd; - - for (idx = 0; idx < 6; idx++) { - /* Only set up the requested stuff */ - if (!(mask & (1 << idx))) - continue; - - r = &dev->resource[idx]; - - if (!r->start && r->end) { - printk(KERN_ERR - "PCI: Device %s not available because of" - " resource collisions\n", - pci_name(dev)); - return -EINVAL; - } - - if (r->flags & IORESOURCE_IO) - cmd |= PCI_COMMAND_IO; - if (r->flags & IORESOURCE_MEM) - cmd |= PCI_COMMAND_MEMORY; - } - - if (dev->resource[PCI_ROM_RESOURCE].start) - cmd |= PCI_COMMAND_MEMORY; - - if (cmd != old_cmd) - pci_write_config_word(dev, PCI_COMMAND, cmd); - - return 0; -} - /* * If we set up a device for bus mastering, we need to check the latency * timer as certain crappy BIOSes forget to set it properly. diff --git a/arch/mn10300/unit-asb2305/pci-asb2305.h b/arch/mn10300/unit-asb2305/pci-asb2305.h index 9763d1c..c3fa294 100644 --- a/arch/mn10300/unit-asb2305/pci-asb2305.h +++ b/arch/mn10300/unit-asb2305/pci-asb2305.h @@ -34,7 +34,6 @@ extern unsigned int pci_probe; extern unsigned int pcibios_max_latency; extern void pcibios_resource_survey(void); -extern int pcibios_enable_resources(struct pci_dev *dev, int mask); /* pci.c */ diff --git a/arch/mn10300/unit-asb2305/pci.c b/arch/mn10300/unit-asb2305/pci.c index 082590f..02527ce 100644 --- a/arch/mn10300/unit-asb2305/pci.c +++ b/arch/mn10300/unit-asb2305/pci.c @@ -440,7 +440,7 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) { int err; - err = pcibios_enable_resources(dev, mask); + err = pci_enable_resources(dev, mask); if (err == 0) pcibios_enable_irq(dev); return err; @@ -455,6 +455,7 @@ static void __init unit_disable_pcnet(struct pci_bus *bus, struct pci_ops *o) bus->number = 0; + o->read (bus, PCI_DEVFN(2, 0), PCI_VENDOR_ID, 4, &x); o->read (bus, PCI_DEVFN(2, 0), PCI_COMMAND, 2, &x); x |= PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY | -- cgit v0.10.2 From 112b4a0bf1080b3d40a2d3b3982361229b25e72d Mon Sep 17 00:00:00 2001 From: David Howells Date: Fri, 8 Jan 2010 14:43:20 -0800 Subject: mn10300: insert PCI root bus resources for the ASB2305 devel motherboard Insert PCI root bus resources for the MN10300-based ASB2305 development kit motherboard. This is required because the CPU's window onto the PCI bus address space is considerably smaller than the CPU's full address space and non-PCI devices lie outside of the PCI window that we might want to access. Without this patch, the PCI root bus uses the platform-level bus resources, and these are then confined to the PCI window, thus making platform_device_add() reject devices outside of this window. We also add a reservation for the PCI SRAM region. Signed-off-by: David Howells Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/arch/mn10300/unit-asb2305/pci.c b/arch/mn10300/unit-asb2305/pci.c index 02527ce..2cb7e75 100644 --- a/arch/mn10300/unit-asb2305/pci.c +++ b/arch/mn10300/unit-asb2305/pci.c @@ -27,6 +27,29 @@ struct pci_bus *pci_root_bus; struct pci_ops *pci_root_ops; /* + * The accessible PCI window does not cover the entire CPU address space, but + * there are devices we want to access outside of that window, so we need to + * insert specific PCI bus resources instead of using the platform-level bus + * resources directly for the PCI root bus. + * + * These are configured and inserted by pcibios_init() and are attached to the + * root bus by pcibios_fixup_bus(). + */ +static struct resource pci_ioport_resource = { + .name = "PCI IO", + .start = 0xbe000000, + .end = 0xbe03ffff, + .flags = IORESOURCE_IO, +}; + +static struct resource pci_iomem_resource = { + .name = "PCI mem", + .start = 0xb8000000, + .end = 0xbbffffff, + .flags = IORESOURCE_MEM, +}; + +/* * Functions for accessing PCI configuration space */ @@ -297,6 +320,7 @@ static int __init pci_check_direct(void) printk(KERN_INFO "PCI: Using configuration ampci\n"); request_mem_region(0xBE040000, 256, "AMPCI bridge"); request_mem_region(0xBFFFFFF4, 12, "PCI ampci"); + request_mem_region(0xBC000000, 32 * 1024 * 1024, "PCI SRAM"); return 0; } @@ -358,6 +382,11 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus) { struct pci_dev *dev; + if (bus->number == 0) { + bus->resource[0] = &pci_ioport_resource; + bus->resource[1] = &pci_iomem_resource; + } + if (bus->self) { pci_read_bridge_bases(bus); pcibios_fixup_device_resources(bus->self); @@ -380,6 +409,11 @@ static int __init pcibios_init(void) iomem_resource.start = 0xA0000000; iomem_resource.end = 0xDFFFFFFF; + if (insert_resource(&iomem_resource, &pci_iomem_resource) < 0) + panic("Unable to insert PCI IOMEM resource\n"); + if (insert_resource(&ioport_resource, &pci_ioport_resource) < 0) + panic("Unable to insert PCI IOPORT resource\n"); + if (!pci_probe) return 0; @@ -391,32 +425,11 @@ static int __init pcibios_init(void) printk(KERN_INFO "PCI: Probing PCI hardware [mempage %08x]\n", MEM_PAGING_REG); - { -#if 0 - static struct pci_bus am33_root_bus = { - .children = LIST_HEAD_INIT(am33_root_bus.children), - .devices = LIST_HEAD_INIT(am33_root_bus.devices), - .number = 0, - .secondary = 0, - .resource = { &ioport_resource, &iomem_resource }, - }; - - am33_root_bus.ops = pci_root_ops; - list_add_tail(&am33_root_bus.node, &pci_root_buses); - - am33_root_bus.subordinate = pci_do_scan_bus(0); - - pci_root_bus = &am33_root_bus; -#else - pci_root_bus = pci_scan_bus(0, &pci_direct_ampci, NULL); -#endif - } + pci_root_bus = pci_scan_bus(0, &pci_direct_ampci, NULL); pcibios_irq_init(); pcibios_fixup_irqs(); -#if 0 pcibios_resource_survey(); -#endif return 0; } -- cgit v0.10.2 From 012c79bad50469d964fda126102080d4b93a5946 Mon Sep 17 00:00:00 2001 From: David Howells Date: Fri, 8 Jan 2010 14:43:21 -0800 Subject: mn10300: make the ASB2305's PCnet32 NIC work by using the PCI bridge's SRAM Access to the ASB2305's PCnet32 NIC doesn't work correctly because when the NIC attempts to update the ring buffer flags by DMA, the change to RAM crops up about 17uS after the interrupt line is asserted. This is almost certainly due to a bug in the PCI bridge FPGA on that board. We can get around this by making dma_alloc_coherent() put the ring buffer in the SRAM attached to the PCI bridge rather than in the SDRAM. Signed-off-by: David Howells Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/arch/mn10300/mm/dma-alloc.c b/arch/mn10300/mm/dma-alloc.c index f3649d8..ee82d62 100644 --- a/arch/mn10300/mm/dma-alloc.c +++ b/arch/mn10300/mm/dma-alloc.c @@ -16,12 +16,24 @@ #include #include +static unsigned long pci_sram_allocated = 0xbc000000; + void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, int gfp) { unsigned long addr; void *ret; + printk("dma_alloc_coherent(%s,%zu,,%x)\n", dev_name(dev), size, gfp); + + if (0xbe000000 - pci_sram_allocated >= size) { + size = (size + 255) & ~255; + addr = pci_sram_allocated; + pci_sram_allocated += size; + ret = (void *) addr; + goto done; + } + /* ignore region specifiers */ gfp &= ~(__GFP_DMA | __GFP_HIGHMEM); @@ -41,7 +53,9 @@ void *dma_alloc_coherent(struct device *dev, size_t size, /* write back and evict all cache lines covering this region */ mn10300_dcache_flush_inv_range2(virt_to_phys((void *) addr), PAGE_SIZE); +done: *dma_handle = virt_to_bus((void *) addr); + printk("dma_alloc_coherent() = %p [%x]\n", ret, *dma_handle); return ret; } EXPORT_SYMBOL(dma_alloc_coherent); @@ -51,6 +65,9 @@ void dma_free_coherent(struct device *dev, size_t size, void *vaddr, { unsigned long addr = (unsigned long) vaddr & ~0x20000000; + if (addr >= 0x9c000000) + return; + free_pages(addr, get_order(size)); } EXPORT_SYMBOL(dma_free_coherent); -- cgit v0.10.2 From 598cace09645fc10f8150e4adc982922cbd214ed Mon Sep 17 00:00:00 2001 From: David Howells Date: Fri, 8 Jan 2010 14:43:21 -0800 Subject: mn10300: update the ASB2303 defconfig Update the defconfig for the ASB2303 platform. Signed-off-by: David Howells Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/arch/mn10300/configs/asb2303_defconfig b/arch/mn10300/configs/asb2303_defconfig index 3acce23..441920d 100644 --- a/arch/mn10300/configs/asb2303_defconfig +++ b/arch/mn10300/configs/asb2303_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.30-rc2 -# Sat Apr 18 11:13:22 2009 +# Linux kernel version: 2.6.33-rc1 +# Tue Dec 22 19:26:25 2009 # CONFIG_MN10300=y CONFIG_AM33=y @@ -22,6 +22,7 @@ CONFIG_GENERIC_HARDIRQS=y # CONFIG_HOTPLUG_CPU is not set CONFIG_HZ=1000 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y # # General setup @@ -43,11 +44,10 @@ CONFIG_BSD_PROCESS_ACCT=y # # RCU Subsystem # -CONFIG_CLASSIC_RCU=y # CONFIG_TREE_RCU is not set -# CONFIG_PREEMPT_RCU is not set +# CONFIG_TREE_PREEMPT_RCU is not set +CONFIG_TINY_RCU=y # CONFIG_TREE_RCU_TRACE is not set -# CONFIG_PREEMPT_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_GROUP_SCHED is not set @@ -62,7 +62,6 @@ CONFIG_ANON_INODES=y CONFIG_EMBEDDED=y CONFIG_SYSCTL_SYSCALL=y # CONFIG_KALLSYMS is not set -CONFIG_STRIP_ASM_SYMS=y # CONFIG_HOTPLUG is not set CONFIG_PRINTK=y CONFIG_BUG=y @@ -75,14 +74,22 @@ CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y + +# +# Kernel Performance Events And Counters +# # CONFIG_VM_EVENT_COUNTERS is not set CONFIG_COMPAT_BRK=y CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set CONFIG_PROFILING=y -# CONFIG_MARKERS is not set CONFIG_HAVE_OPROFILE=y +CONFIG_HAVE_ARCH_TRACEHOOK=y + +# +# GCOV-based kernel profiling +# # CONFIG_SLOW_WORK is not set # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set CONFIG_SLABINFO=y @@ -90,6 +97,35 @@ CONFIG_RT_MUTEXES=y CONFIG_BASE_SMALL=0 # CONFIG_MODULES is not set # CONFIG_BLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +# CONFIG_INLINE_SPIN_UNLOCK is not set +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +# CONFIG_INLINE_READ_UNLOCK is not set +# CONFIG_INLINE_READ_UNLOCK_BH is not set +# CONFIG_INLINE_READ_UNLOCK_IRQ is not set +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +# CONFIG_INLINE_WRITE_UNLOCK is not set +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set # CONFIG_FREEZER is not set # @@ -145,9 +181,8 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=1 CONFIG_VIRT_TO_BUS=y -CONFIG_UNEVICTABLE_LRU=y -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 # # Power management options @@ -202,6 +237,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_NETFILTER is not set # CONFIG_IP_DCCP is not set # CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set @@ -216,6 +252,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set # CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set # CONFIG_NET_SCHED is not set # CONFIG_DCB is not set @@ -341,7 +378,6 @@ CONFIG_MISC_DEVICES=y # CONFIG_SCSI_DMA is not set # CONFIG_SCSI_NETLINK is not set CONFIG_NETDEVICES=y -CONFIG_COMPAT_NET_DEV_OPS=y # CONFIG_DUMMY is not set # CONFIG_BONDING is not set # CONFIG_MACVLAN is not set @@ -362,14 +398,11 @@ CONFIG_SMC91X=y # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set # CONFIG_B44 is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set - -# -# Wireless LAN -# -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +# CONFIG_WLAN is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers @@ -430,11 +463,15 @@ CONFIG_RTC=y # CONFIG_TCG_TPM is not set # CONFIG_I2C is not set # CONFIG_SPI is not set + +# +# PPS support +# +# CONFIG_PPS is not set # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set # CONFIG_THERMAL is not set -# CONFIG_THERMAL_HWMON is not set # CONFIG_WATCHDOG is not set CONFIG_SSB_POSSIBLE=y @@ -451,22 +488,7 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set # CONFIG_REGULATOR is not set - -# -# Multimedia devices -# - -# -# Multimedia core support -# -# CONFIG_VIDEO_DEV is not set -# CONFIG_DVB_CORE is not set -# CONFIG_VIDEO_MEDIA is not set - -# -# Multimedia drivers -# -# CONFIG_DAB is not set +# CONFIG_MEDIA_SUPPORT is not set # # Graphics support @@ -490,11 +512,17 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_DMADEVICES is not set # CONFIG_AUXDISPLAY is not set # CONFIG_UIO is not set + +# +# TI VLYNQ +# # CONFIG_STAGING is not set # # File systems # +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y CONFIG_DNOTIFY=y CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y @@ -539,6 +567,7 @@ CONFIG_NFS_V3=y # CONFIG_NFS_V3_ACL is not set # CONFIG_NFS_V4 is not set CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set CONFIG_LOCKD=y CONFIG_LOCKD_V4=y CONFIG_NFS_COMMON=y @@ -561,13 +590,13 @@ CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y CONFIG_FRAME_WARN=1024 CONFIG_MAGIC_SYSRQ=y +CONFIG_STRIP_ASM_SYMS=y # CONFIG_UNUSED_SYMBOLS is not set # CONFIG_DEBUG_FS is not set # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set -# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_SYSCTL_SYSCALL_CHECK is not set # CONFIG_SAMPLES is not set @@ -577,7 +606,11 @@ CONFIG_MAGIC_SYSRQ=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" # CONFIG_CRYPTO is not set # CONFIG_BINARY_PRINTF is not set -- cgit v0.10.2 From a29815a333c6c6e677294bbe5958e771d0aad3fd Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Sun, 10 Jan 2010 16:28:09 +0200 Subject: core, x86: make LIST_POISON less deadly The list macros use LIST_POISON1 and LIST_POISON2 as undereferencable pointers in order to trap erronous use of freed list_heads. Unfortunately userspace can arrange for those pointers to actually be dereferencable, potentially turning an oops to an expolit. To avoid this allow architectures (currently x86_64 only) to override the default values for these pointers with truly-undereferencable values. This is easy on x86_64 as the virtual address space is large and contains areas that cannot be mapped. Other 64-bit architectures will likely find similar unmapped ranges. [ingo: switch to 0xdead000000000000 as the unmapped area] [ingo: add comments, cleanup] [jaswinder: eliminate sparse warnings] Acked-by: Linus Torvalds Signed-off-by: Jaswinder Singh Rajput Signed-off-by: Ingo Molnar Signed-off-by: Avi Kivity Signed-off-by: Linus Torvalds diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 6bf1f1a..cbcbfde 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -1247,6 +1247,11 @@ config ARCH_MEMORY_PROBE def_bool X86_64 depends on MEMORY_HOTPLUG +config ILLEGAL_POINTER_VALUE + hex + default 0 if X86_32 + default 0xdead000000000000 if X86_64 + source "mm/Kconfig" config HIGHPTE diff --git a/include/linux/poison.h b/include/linux/poison.h index 7fc194a..2110a81 100644 --- a/include/linux/poison.h +++ b/include/linux/poison.h @@ -2,13 +2,25 @@ #define _LINUX_POISON_H /********** include/linux/list.h **********/ + +/* + * Architectures might want to move the poison pointer offset + * into some well-recognized area such as 0xdead000000000000, + * that is also not mappable by user-space exploits: + */ +#ifdef CONFIG_ILLEGAL_POINTER_VALUE +# define POISON_POINTER_DELTA _AC(CONFIG_ILLEGAL_POINTER_VALUE, UL) +#else +# define POISON_POINTER_DELTA 0 +#endif + /* * These are non-NULL pointers that will result in page faults * under normal circumstances, used to verify that nobody uses * non-initialized list entries. */ -#define LIST_POISON1 ((void *) 0x00100100) -#define LIST_POISON2 ((void *) 0x00200200) +#define LIST_POISON1 ((void *) 0x00100100 + POISON_POINTER_DELTA) +#define LIST_POISON2 ((void *) 0x00200200 + POISON_POINTER_DELTA) /********** include/linux/timer.h **********/ /* -- cgit v0.10.2 From eb70df13ee52dbc0f2c0ffd8ed34a8cd27440baf Mon Sep 17 00:00:00 2001 From: Jarek Poplawski Date: Sun, 10 Jan 2010 22:04:19 +0000 Subject: af_packet: Don't use skb after dev_queue_xmit() tpacket_snd() can change and kfree an skb after dev_queue_xmit(), which is illegal. With debugging by: Stephen Hemminger Reported-by: Michael Breuer With help from: David S. Miller Signed-off-by: Jarek Poplawski Tested-by: Michael Breuer Signed-off-by: David S. Miller diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index e0516a2..f126d18 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -1021,8 +1021,20 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) status = TP_STATUS_SEND_REQUEST; err = dev_queue_xmit(skb); - if (unlikely(err > 0 && (err = net_xmit_errno(err)) != 0)) - goto out_xmit; + if (unlikely(err > 0)) { + err = net_xmit_errno(err); + if (err && __packet_get_status(po, ph) == + TP_STATUS_AVAILABLE) { + /* skb was destructed already */ + skb = NULL; + goto out_status; + } + /* + * skb was dropped but not destructed yet; + * let's treat it like congestion or err < 0 + */ + err = 0; + } packet_increment_head(&po->tx_ring); len_sum += tp_len; } while (likely((ph != NULL) || @@ -1033,9 +1045,6 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) err = len_sum; goto out_put; -out_xmit: - skb->destructor = sock_wfree; - atomic_dec(&po->tx_ring.pending); out_status: __packet_set_status(po, ph, status); kfree_skb(skb); -- cgit v0.10.2 From aa4e2e171385bb77b4da8b760d26dea2aa291587 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 11 Jan 2010 15:53:45 -0800 Subject: Documentation/3c509: document ethtool support 3c509 was changed to support ethtool in 2002, making the 'xcvr' module parameter obsolete in most cases. More recently 3c509 was converted to the modern driver model and this parameter was removed. Fix the documentation to refer to ethtool rather than the module parameter. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller diff --git a/Documentation/networking/3c509.txt b/Documentation/networking/3c509.txt index 0643e3b..3c45d5d 100644 --- a/Documentation/networking/3c509.txt +++ b/Documentation/networking/3c509.txt @@ -48,11 +48,11 @@ for LILO parameters for doing this: This configures the first found 3c509 card for IRQ 10, base I/O 0x310, and transceiver type 3 (10base2). The flag "0x3c509" must be set to avoid conflicts with other card types when overriding the I/O address. When the driver is -loaded as a module, only the IRQ and transceiver setting may be overridden. -For example, setting two cards to 10base2/IRQ10 and AUI/IRQ11 is done by using -the xcvr and irq module options: +loaded as a module, only the IRQ may be overridden. For example, +setting two cards to IRQ10 and IRQ11 is done by using the irq module +option: - options 3c509 xcvr=3,1 irq=10,11 + options 3c509 irq=10,11 (2) Full-duplex mode @@ -77,6 +77,8 @@ operation. itself full-duplex capable. This is almost certainly one of two things: a full- duplex-capable Ethernet switch (*not* a hub), or a full-duplex-capable NIC on another system that's connected directly to the 3c509B via a crossover cable. + +Full-duplex mode can be enabled using 'ethtool'. /////Extremely important caution concerning full-duplex mode///// Understand that the 3c509B's hardware's full-duplex support is much more @@ -113,6 +115,8 @@ This insured that merely upgrading the driver from an earlier version would never automatically enable full-duplex mode in an existing installation; it must always be explicitly enabled via one of these code in order to be activated. + +The transceiver type can be changed using 'ethtool'. (4a) Interpretation of error messages and common problems -- cgit v0.10.2 From 066000dd856709b6980123eb39b957fe26993f7b Mon Sep 17 00:00:00 2001 From: Ananth N Mavinakayanahalli Date: Mon, 11 Jan 2010 15:51:04 -0800 Subject: Revert "x86, apic: Use logical flat on intel with <= 8 logical cpus" Revert commit 2fbd07a5f5d1295fa9b0c0564ec27da7c276a75a, as this commit breaks an IBM platform with quad-core Xeon cpu's. According to Suresh, this might be an IBM platform issue, as on other Intel platforms with <= 8 logical cpu's, logical flat mode works fine irespective of physical apic id values (inline with the xapic architecture). Revert this for now because of the IBM platform breakage. Another version will be re-submitted after the complete analysis. Signed-off-by: Ananth N Mavinakayanahalli Acked-by: Suresh Siddha Signed-off-by: Linus Torvalds diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index aa57c07..e80f291 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -62,7 +62,7 @@ unsigned int boot_cpu_physical_apicid = -1U; /* * The highest APIC ID seen during enumeration. * - * On AMD, this determines the messaging protocol we can use: if all APIC IDs + * This determines the messaging protocol we can use: if all APIC IDs * are in the 0 ... 7 range, then we can use logical addressing which * has some performance advantages (better broadcasting). * @@ -1898,14 +1898,24 @@ void __cpuinit generic_processor_info(int apicid, int version) max_physical_apicid = apicid; #ifdef CONFIG_X86_32 - switch (boot_cpu_data.x86_vendor) { - case X86_VENDOR_INTEL: - if (num_processors > 8) - def_to_bigsmp = 1; - break; - case X86_VENDOR_AMD: - if (max_physical_apicid >= 8) + /* + * Would be preferable to switch to bigsmp when CONFIG_HOTPLUG_CPU=y + * but we need to work other dependencies like SMP_SUSPEND etc + * before this can be done without some confusion. + * if (CPU_HOTPLUG_ENABLED || num_processors > 8) + * - Ashok Raj + */ + if (max_physical_apicid >= 8) { + switch (boot_cpu_data.x86_vendor) { + case X86_VENDOR_INTEL: + if (!APIC_XAPIC(version)) { + def_to_bigsmp = 0; + break; + } + /* If P4 and above fall through */ + case X86_VENDOR_AMD: def_to_bigsmp = 1; + } } #endif diff --git a/arch/x86/kernel/apic/probe_64.c b/arch/x86/kernel/apic/probe_64.c index c4cbd308..65edc18 100644 --- a/arch/x86/kernel/apic/probe_64.c +++ b/arch/x86/kernel/apic/probe_64.c @@ -64,23 +64,16 @@ void __init default_setup_apic_routing(void) apic = &apic_x2apic_phys; else apic = &apic_x2apic_cluster; + printk(KERN_INFO "Setting APIC routing to %s\n", apic->name); } #endif if (apic == &apic_flat) { - switch (boot_cpu_data.x86_vendor) { - case X86_VENDOR_INTEL: - if (num_processors > 8) - apic = &apic_physflat; - break; - case X86_VENDOR_AMD: - if (max_physical_apicid >= 8) - apic = &apic_physflat; - } + if (max_physical_apicid >= 8) + apic = &apic_physflat; + printk(KERN_INFO "Setting APIC routing to %s\n", apic->name); } - printk(KERN_INFO "Setting APIC routing to %s\n", apic->name); - if (is_vsmp_box()) { /* need to update phys_pkg_id */ apic->phys_pkg_id = apicid_phys_pkg_id; -- cgit v0.10.2 From 2d9c5597ad1408885fdef5838aa27a8a0ee9e915 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 8 Jan 2010 11:56:41 +0200 Subject: OMAP: DSS2: Reject scaling settings when they cannot be supported MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the scaling ratio is below 0.5 video output width can't be identical to the display width. Reject such settings. Signed-off-by: Ville Syrjälä Acked-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index e2e0f9a..de8bfba 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -1454,7 +1454,10 @@ static unsigned long calc_fclk_five_taps(u16 width, u16 height, do_div(tmp, 2 * out_height * ppl); fclk = tmp; - if (height > 2 * out_height && ppl != out_width) { + if (height > 2 * out_height) { + if (ppl == out_width) + return 0; + tmp = pclk * (height - 2 * out_height) * out_width; do_div(tmp, 2 * out_height * (ppl - out_width)); fclk = max(fclk, (u32) tmp); @@ -1634,7 +1637,7 @@ static int _dispc_setup_plane(enum omap_plane plane, DSSDBG("required fclk rate = %lu Hz\n", fclk); DSSDBG("current fclk rate = %lu Hz\n", dispc_fclk_rate()); - if (fclk > dispc_fclk_rate()) { + if (!fclk || fclk > dispc_fclk_rate()) { DSSERR("failed to set up scaling, " "required fclk rate = %lu Hz, " "current fclk rate = %lu Hz\n", -- cgit v0.10.2 From 807a7515aea421f2b340140482ed4c8811c523c6 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 7 Jan 2010 17:45:03 +0200 Subject: OMAP: DSS2: OMAPFB: fix crash when panel driver was not loaded If the panel's probe had failed, omapfb would still go on, eventually crashing. A better fix would be to handle each display properly, and leaving just the failed display out. But that is a bigger change. Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c index e61a75c..d17caef 100644 --- a/drivers/video/omap2/omapfb/omapfb-main.c +++ b/drivers/video/omap2/omapfb/omapfb-main.c @@ -2115,6 +2115,11 @@ static int omapfb_probe(struct platform_device *pdev) dssdev = NULL; for_each_dss_dev(dssdev) { omap_dss_get_device(dssdev); + if (!dssdev->driver) { + dev_err(&pdev->dev, "no driver for display\n"); + r = -EINVAL; + goto cleanup; + } fbdev->displays[fbdev->num_displays++] = dssdev; } -- cgit v0.10.2 From 9db2f1bec36805e57a003f7bb90e003815d96de8 Mon Sep 17 00:00:00 2001 From: Jarek Poplawski Date: Mon, 4 Jan 2010 08:48:41 +0000 Subject: sky2: Fix oops in sky2_xmit_frame() after TX timeout During TX timeout procedure dev could be awoken too early, e.g. by sky2_complete_tx() called from sky2_down(). Then sky2_xmit_frame() can run while buffers are freed causing an oops. This patch fixes it by adding netif_device_present() test in sky2_tx_complete(). Fixes: http://bugzilla.kernel.org/show_bug.cgi?id=14925 With debugging by: Mike McCormack Reported-by: Berck E. Nash Tested-by: Berck E. Nash Signed-off-by: Jarek Poplawski Signed-off-by: David S. Miller diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 1c01b96..7650f73 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -1844,7 +1844,8 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done) sky2->tx_cons = idx; smp_mb(); - if (tx_avail(sky2) > MAX_SKB_TX_LE + 4) + /* Wake unless it's detached, and called e.g. from sky2_down() */ + if (tx_avail(sky2) > MAX_SKB_TX_LE + 4 && netif_device_present(dev)) netif_wake_queue(dev); } -- cgit v0.10.2 From 9c0afc861a7228f718cb6a79fa7f9d46bf9ff300 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 12 Jan 2010 14:00:11 +0100 Subject: ALSA: hda - Fix ALC861-VD capture source mixer The capture source or input source mixer element wasn't created properly for ALC861-VD codec due to the wrong NID passed to alc_auto_create_input_ctls(). References: Novell bnc#568305 http://bugzilla.novell.com/show_bug.cgi?id=568305 Signed-off-by: Takashi Iwai Cc: diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index c746505..e3caa78 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -15493,7 +15493,7 @@ static struct alc_config_preset alc861vd_presets[] = { static int alc861vd_auto_create_input_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg) { - return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x09, 0); + return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x22, 0); } -- cgit v0.10.2 From abbdc3d88aa2d5c937b21044c336bcd056c1732f Mon Sep 17 00:00:00 2001 From: David Daney Date: Thu, 3 Dec 2009 17:43:54 -0800 Subject: MIPS: Cleanup forgotten label_module_alloc in tlbex.c commit c8af165342e83a4eb078c9607d29a7c399d30a53 (lmo) rsp. e0cc87f59490d7d62a8ab2a76498dc8a2b64927a (kernel.org) left label_module_alloc unused. Remove it now. Signed-off-by: David Daney Cc: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/752/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index 3d0baa4..badcf5e 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c @@ -73,9 +73,6 @@ static int __cpuinit m4kc_tlbp_war(void) enum label_id { label_second_part = 1, label_leave, -#ifdef MODULE_START - label_module_alloc, -#endif label_vmalloc, label_vmalloc_done, label_tlbw_hazard, @@ -92,9 +89,6 @@ enum label_id { UASM_L_LA(_second_part) UASM_L_LA(_leave) -#ifdef MODULE_START -UASM_L_LA(_module_alloc) -#endif UASM_L_LA(_vmalloc) UASM_L_LA(_vmalloc_done) UASM_L_LA(_tlbw_hazard) @@ -818,8 +812,6 @@ static void __cpuinit build_r4000_tlb_refill_handler(void) } else { #if defined(CONFIG_HUGETLB_PAGE) const enum label_id ls = label_tlb_huge_update; -#elif defined(MODULE_START) - const enum label_id ls = label_module_alloc; #else const enum label_id ls = label_vmalloc; #endif -- cgit v0.10.2 From d4d9a553d7b96e18fcfbd0b8fb5f803b3a27e4e6 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Thu, 10 Dec 2009 22:55:13 +0800 Subject: MIPS: Cleanup and Fixup of compressed kernel support o Remove the .initrd section. The initrd section was already handled when vmlinux was linked. o Discard .MIPS.options, .options, .pdr, .reginfo, .comment and .note sections. If .MIPS.options is not removed, kernels compiled with gcc 3.4.6 will not boot. o Clean up the file format. o Remove several other unneeded sections. Tested with GCC 3.4.6 and 4.4.1 with and without initrd. Signed-off-by: Wu Zhangjin Cc: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/785/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/boot/compressed/Makefile b/arch/mips/boot/compressed/Makefile index e27f40b..671d344 100644 --- a/arch/mips/boot/compressed/Makefile +++ b/arch/mips/boot/compressed/Makefile @@ -56,7 +56,7 @@ $(obj)/piggy.o: $(obj)/vmlinux.$(suffix_y) $(obj)/dummy.o LDFLAGS_vmlinuz := $(LDFLAGS) -Ttext $(VMLINUZ_LOAD_ADDRESS) -T vmlinuz: $(src)/ld.script $(obj-y) $(obj)/piggy.o $(call if_changed,ld) - $(Q)$(OBJCOPY) $(OBJCOPYFLAGS) -R .comment -R .stab -R .stabstr -R .initrd -R .sysmap $@ + $(Q)$(OBJCOPY) $(OBJCOPYFLAGS) $@ # # Some DECstations need all possible sections of an ECOFF executable @@ -84,14 +84,11 @@ vmlinuz.ecoff: $(obj)/../elf2ecoff $(VMLINUZ) $(obj)/../elf2ecoff: $(src)/../elf2ecoff.c $(Q)$(HOSTCC) -o $@ $^ -drop-sections = .reginfo .mdebug .comment .note .pdr .options .MIPS.options -strip-flags = $(addprefix --remove-section=,$(drop-sections)) - -OBJCOPYFLAGS_vmlinuz.bin := $(OBJCOPYFLAGS) -O binary $(strip-flags) +OBJCOPYFLAGS_vmlinuz.bin := $(OBJCOPYFLAGS) -O binary vmlinuz.bin: vmlinuz $(call if_changed,objcopy) -OBJCOPYFLAGS_vmlinuz.srec := $(OBJCOPYFLAGS) -S -O srec $(strip-flags) +OBJCOPYFLAGS_vmlinuz.srec := $(OBJCOPYFLAGS) -S -O srec vmlinuz.srec: vmlinuz $(call if_changed,objcopy) diff --git a/arch/mips/boot/compressed/decompress.c b/arch/mips/boot/compressed/decompress.c index 67330c2..e48fd72 100644 --- a/arch/mips/boot/compressed/decompress.c +++ b/arch/mips/boot/compressed/decompress.c @@ -28,8 +28,6 @@ char *zimage_start; /* The linker tells us where the image is. */ extern unsigned char __image_begin, __image_end; -extern unsigned char __ramdisk_begin, __ramdisk_end; -unsigned long initrd_size; /* debug interfaces */ extern void puts(const char *s); @@ -102,14 +100,6 @@ void decompress_kernel(unsigned long boot_heap_start) puthex((unsigned long)(zimage_size + zimage_start)); puts("\n"); - if (initrd_size) { - puts("initrd at: "); - puthex((unsigned long)(&__ramdisk_begin)); - puts(" "); - puthex((unsigned long)(&__ramdisk_end)); - puts("\n"); - } - /* this area are prepared for mallocing when decompressing */ free_mem_ptr = boot_heap_start; free_mem_end_ptr = boot_heap_start + BOOT_HEAP_SIZE; diff --git a/arch/mips/boot/compressed/ld.script b/arch/mips/boot/compressed/ld.script index 29e9f4c..613a35b 100644 --- a/arch/mips/boot/compressed/ld.script +++ b/arch/mips/boot/compressed/ld.script @@ -1,150 +1,67 @@ +/* + * ld.script for compressed kernel support of MIPS + * + * Copyright (C) 2009 Lemote Inc. + * Author: Wu Zhangjin + */ + OUTPUT_ARCH(mips) ENTRY(start) SECTIONS { - /* Read-only sections, merged into text segment: */ - .init : { *(.init) } =0 - .text : - { - _ftext = . ; - *(.text) - *(.rodata) - *(.rodata1) - /* .gnu.warning sections are handled specially by elf32.em. */ - *(.gnu.warning) - } =0 - .kstrtab : { *(.kstrtab) } - - . = ALIGN(16); /* Exception table */ - __start___ex_table = .; - __ex_table : { *(__ex_table) } - __stop___ex_table = .; - - __start___dbe_table = .; /* Exception table for data bus errors */ - __dbe_table : { *(__dbe_table) } - __stop___dbe_table = .; - - __start___ksymtab = .; /* Kernel symbol table */ - __ksymtab : { *(__ksymtab) } - __stop___ksymtab = .; - - _etext = .; - - . = ALIGN(8192); - .data.init_task : { *(.data.init_task) } - - /* Startup code */ - . = ALIGN(4096); - __init_begin = .; - .text.init : { *(.text.init) } - .data.init : { *(.data.init) } - . = ALIGN(16); - __setup_start = .; - .setup.init : { *(.setup.init) } - __setup_end = .; - __initcall_start = .; - .initcall.init : { *(.initcall.init) } - __initcall_end = .; - . = ALIGN(4096); /* Align double page for init_task_union */ - __init_end = .; - - . = ALIGN(4096); - .data.page_aligned : { *(.data.idt) } - - . = ALIGN(32); - .data.cacheline_aligned : { *(.data.cacheline_aligned) } + /* . = VMLINUZ_LOAD_ADDRESS */ + /* read-only */ + _text = .; /* Text and read-only data */ + .text : { + _ftext = . ; + *(.text) + *(.rodata) + } = 0 + _etext = .; /* End of text section */ - .fini : { *(.fini) } =0 - .reginfo : { *(.reginfo) } - /* Adjust the address for the data segment. We want to adjust up to - the same address within the page on the next page up. It would - be more correct to do this: - . = .; - The current expression does not correctly handle the case of a - text segment ending precisely at the end of a page; it causes the - data segment to skip a page. The above expression does not have - this problem, but it will currently (2/95) cause BFD to allocate - a single segment, combining both text and data, for this case. - This will prevent the text segment from being shared among - multiple executions of the program; I think that is more - important than losing a page of the virtual address space (note - that no actual memory is lost; the page which is skipped can not - be referenced). */ - . = .; - .data : - { - _fdata = . ; - *(.data) + /* writable */ + .data : { /* Data */ + _fdata = . ; + *(.data) + /* Put the compressed image here, so bss is on the end. */ + __image_begin = .; + *(.image) + __image_end = .; + CONSTRUCTORS + } + .sdata : { *(.sdata) } + . = ALIGN(4); + _edata = .; /* End of data section */ - /* Put the compressed image here, so bss is on the end. */ - __image_begin = .; - *(.image) - __image_end = .; - /* Align the initial ramdisk image (INITRD) on page boundaries. */ - . = ALIGN(4096); - __ramdisk_begin = .; - *(.initrd) - __ramdisk_end = .; - . = ALIGN(4096); + /* BSS */ + __bss_start = .; + _fbss = .; + .sbss : { *(.sbss) *(.scommon) } + .bss : { + *(.dynbss) + *(.bss) + *(COMMON) + } + . = ALIGN(4); + _end = . ; - CONSTRUCTORS - } - .data1 : { *(.data1) } - _gp = . + 0x8000; - .lit8 : { *(.lit8) } - .lit4 : { *(.lit4) } - .ctors : { *(.ctors) } - .dtors : { *(.dtors) } - .got : { *(.got.plt) *(.got) } - .dynamic : { *(.dynamic) } - /* We want the small data sections together, so single-instruction offsets - can access them all, and initialized data all before uninitialized, so - we can shorten the on-disk segment size. */ - .sdata : { *(.sdata) } - . = ALIGN(4); - _edata = .; - PROVIDE (edata = .); + /* These are needed for ELF backends which have not yet been converted + * to the new style linker. */ - __bss_start = .; - _fbss = .; - .sbss : { *(.sbss) *(.scommon) } - .bss : - { - *(.dynbss) - *(.bss) - *(COMMON) - . = ALIGN(4); - _end = . ; - PROVIDE (end = .); - } + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } - /* Sections to be discarded */ - /DISCARD/ : - { - *(.text.exit) - *(.data.exit) - *(.exitcall.exit) - } + /* These must appear regardless of . */ + .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) } + .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) } - /* This is the MIPS specific mdebug section. */ - .mdebug : { *(.mdebug) } - /* These are needed for ELF backends which have not yet been - converted to the new style linker. */ - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } - /* DWARF debug sections. - Symbols in the .debug DWARF section are relative to the beginning of the - section so we begin .debug at 0. It's not clear yet what needs to happen - for the others. */ - .debug 0 : { *(.debug) } - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - .debug_sfnames 0 : { *(.debug_sfnames) } - .line 0 : { *(.line) } - /* These must appear regardless of . */ - .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) } - .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) } - .comment : { *(.comment) } - .note : { *(.note) } + /* Sections to be discarded */ + /DISCARD/ : { + *(.MIPS.options) + *(.options) + *(.pdr) + *(.reginfo) + *(.comment) + *(.note) + } } -- cgit v0.10.2 From 66a0f0f2a20a8df2cdf22e911839c29c462836f3 Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Thu, 10 Dec 2009 14:00:39 +0900 Subject: MIPS: VR41xx: Use strlcat() for the command line arguments Signed-off-by: Yoichi Yuasa Cc: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/784/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/vr41xx/common/init.c b/arch/mips/vr41xx/common/init.c index 1386e6f..2391632 100644 --- a/arch/mips/vr41xx/common/init.c +++ b/arch/mips/vr41xx/common/init.c @@ -1,7 +1,7 @@ /* * init.c, Common initialization routines for NEC VR4100 series. * - * Copyright (C) 2003-2008 Yoichi Yuasa + * Copyright (C) 2003-2009 Yoichi Yuasa * * 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 @@ -66,9 +66,9 @@ void __init prom_init(void) argv = (char **)fw_arg1; for (i = 1; i < argc; i++) { - strcat(arcs_cmdline, argv[i]); + strlcat(arcs_cmdline, argv[i], COMMAND_LINE_SIZE); if (i < (argc - 1)) - strcat(arcs_cmdline, " "); + strlcat(arcs_cmdline, " ", COMMAND_LINE_SIZE); } } -- cgit v0.10.2 From 05c694681e059b9e99449bb239367ab486cd1fca Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Sat, 12 Dec 2009 17:57:39 +0100 Subject: MIPS: BCM63xx: Fix whitespace damaged board_bcm963xx.c Signed-off-by: Florian Fainelli Signed-off-by: Ralf Baechle diff --git a/arch/mips/bcm63xx/boards/board_bcm963xx.c b/arch/mips/bcm63xx/boards/board_bcm963xx.c index 05a35cf..1fe412c 100644 --- a/arch/mips/bcm63xx/boards/board_bcm963xx.c +++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c @@ -346,27 +346,26 @@ static struct board_info __initdata board_96348gw = { }; static struct board_info __initdata board_FAST2404 = { - .name = "F@ST2404", - .expected_cpu_id = 0x6348, - - .has_enet0 = 1, - .has_enet1 = 1, - .has_pci = 1, + .name = "F@ST2404", + .expected_cpu_id = 0x6348, - .enet0 = { - .has_phy = 1, - .use_internal_phy = 1, - }, + .has_enet0 = 1, + .has_enet1 = 1, + .has_pci = 1, - .enet1 = { - .force_speed_100 = 1, - .force_duplex_full = 1, - }, + .enet0 = { + .has_phy = 1, + .use_internal_phy = 1, + }, + .enet1 = { + .force_speed_100 = 1, + .force_duplex_full = 1, + }, - .has_ohci0 = 1, - .has_pccard = 1, - .has_ehci0 = 1, + .has_ohci0 = 1, + .has_pccard = 1, + .has_ehci0 = 1, }; static struct board_info __initdata board_DV201AMR = { -- cgit v0.10.2 From 42ecda1ae80b4b19c3c7ba36e3141c4c19e1fe70 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 13 Dec 2009 12:40:39 +0100 Subject: MIPS: Alchemy: Correct code taking the size of a pointer sizeof(dp) is just the size of the pointer. Change it to the size of the referenced structure. A simplified version of the semantic patch that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @@ expression *x; expression f; type T; @@ *f(...,(T)x,...) // Signed-off-by: Julia Lawall Patchwork: http://patchwork.linux-mips.org/patch/789/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/alchemy/common/dbdma.c b/arch/mips/alchemy/common/dbdma.c index 19c1c82..5c68569 100644 --- a/arch/mips/alchemy/common/dbdma.c +++ b/arch/mips/alchemy/common/dbdma.c @@ -613,7 +613,7 @@ u32 _au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes, u32 flags) dma_cache_wback_inv((unsigned long)buf, nbytes); dp->dscr_cmd0 |= DSCR_CMD0_V; /* Let it rip */ au_sync(); - dma_cache_wback_inv((unsigned long)dp, sizeof(dp)); + dma_cache_wback_inv((unsigned long)dp, sizeof(*dp)); ctp->chan_ptr->ddma_dbell = 0; /* Get next descriptor pointer. */ @@ -676,7 +676,7 @@ _au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes, u32 flags) dma_cache_inv((unsigned long)buf, nbytes); dp->dscr_cmd0 |= DSCR_CMD0_V; /* Let it rip */ au_sync(); - dma_cache_wback_inv((unsigned long)dp, sizeof(dp)); + dma_cache_wback_inv((unsigned long)dp, sizeof(*dp)); ctp->chan_ptr->ddma_dbell = 0; /* Get next descriptor pointer. */ -- cgit v0.10.2 From 57699407faf009f2abc33e381bc82b4c81bb0585 Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Fri, 18 Dec 2009 21:20:24 +0900 Subject: MIPS: AR7: Remove kgdb_enabled An unused leftover from the old KGDB implementation. Signed-off-by: Yoichi Yuasa Patchwork: http://patchwork.linux-mips.org/patch/794/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/ar7/prom.c b/arch/mips/ar7/prom.c index 5ad6f1d..453dd22 100644 --- a/arch/mips/ar7/prom.c +++ b/arch/mips/ar7/prom.c @@ -219,14 +219,6 @@ static void __init console_config(void) if (strstr(prom_getcmdline(), "console=")) return; -#ifdef CONFIG_KGDB - if (!strstr(prom_getcmdline(), "nokgdb")) { - strcat(prom_getcmdline(), " console=kgdb"); - kgdb_enabled = 1; - return; - } -#endif - s = prom_getenv("modetty0"); if (s) { baud = simple_strtoul(s, &p, 10); -- cgit v0.10.2 From 99d2b173e5e14d10d2179d342d91c5bed0e8832d Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Fri, 18 Dec 2009 21:29:17 +0900 Subject: MIPS: PowerTV: Remove unused prom_getcmdline() Signed-off-by: Yoichi Yuasa Patchwork: http://patchwork.linux-mips.org/patch/797/ Reviewed-by: David VomLehn Signed-off-by: Ralf Baechle diff --git a/arch/mips/powertv/cmdline.c b/arch/mips/powertv/cmdline.c index 98d73cb..ee7ab47 100644 --- a/arch/mips/powertv/cmdline.c +++ b/arch/mips/powertv/cmdline.c @@ -31,11 +31,6 @@ */ #define prom_argv(index) ((char *)(long)_prom_argv[(index)]) -char * __init prom_getcmdline(void) -{ - return &(arcs_cmdline[0]); -} - void __init prom_init_cmdline(void) { int len; -- cgit v0.10.2 From 09b7c9f24d8e9b772da682b52b83c88f426a849d Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Fri, 18 Dec 2009 21:30:18 +0900 Subject: MIPS: PowerTV: Remove unused ptv_memsize Signed-off-by: Yoichi Yuasa Patchwork: http://patchwork.linux-mips.org/patch/799/ Reviewed-by: David VomLehn Signed-off-by: Ralf Baechle diff --git a/arch/mips/powertv/memory.c b/arch/mips/powertv/memory.c index 28d0660..f49eb3d 100644 --- a/arch/mips/powertv/memory.c +++ b/arch/mips/powertv/memory.c @@ -42,8 +42,6 @@ #define BOOT_MEM_SIZE KIBIBYTE(256) /* Memory reserved for bldr */ #define PHYS_MEM_START 0x10000000 /* Start of physical memory */ -unsigned long ptv_memsize; - char __initdata cmdline[COMMAND_LINE_SIZE]; void __init prom_meminit(void) @@ -87,9 +85,6 @@ void __init prom_meminit(void) } } - /* Store memsize for diagnostic purposes */ - ptv_memsize = memsize; - physend = PFN_ALIGN(&_end) - 0x80000000; if (memsize > LOW_MEM_MAX) { low_mem = LOW_MEM_MAX; -- cgit v0.10.2 From 2620c3570f748647afb17e095507099a309ed8f6 Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Fri, 18 Dec 2009 21:33:46 +0900 Subject: MIPS: PowerTV: Remove mips_machine_halt() mips_machine_halt() is same as mips_machine_restart(). Also delete the registration of _machine_halt and pm_power_off because mips_machine_halt() is the restart function. Signed-off-by: Yoichi Yuasa Patchwork: http://patchwork.linux-mips.org/patch/798/ Reviewed-by: David VomLehn Signed-off-by: Ralf Baechle diff --git a/arch/mips/powertv/reset.c b/arch/mips/powertv/reset.c index 494c652..0007652 100644 --- a/arch/mips/powertv/reset.c +++ b/arch/mips/powertv/reset.c @@ -28,9 +28,6 @@ #include #include "reset.h" -static void mips_machine_restart(char *command); -static void mips_machine_halt(void); - static void mips_machine_restart(char *command) { #ifdef CONFIG_BOOTLOADER_DRIVER @@ -44,22 +41,7 @@ static void mips_machine_restart(char *command) #endif } -static void mips_machine_halt(void) -{ -#ifdef CONFIG_BOOTLOADER_DRIVER - /* - * Call the bootloader's reset function to ensure - * that persistent data is flushed before hard reset - */ - kbldr_SetCauseAndReset(); -#else - writel(0x1, asic_reg_addr(watchdog)); -#endif -} - void mips_reboot_setup(void) { _machine_restart = mips_machine_restart; - _machine_halt = mips_machine_halt; - pm_power_off = mips_machine_halt; } -- cgit v0.10.2 From 0eb99a9354cfe73dfa76ef81c917f7655b1b306c Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Fri, 18 Dec 2009 21:36:32 +0900 Subject: MIPS: PowerTV: Remove unused platform_die() Signed-off-by: Yoichi Yuasa Patchwork: http://patchwork.linux-mips.org/patch/800/ Reviewed-by: David VomLehn Signed-off-by: Ralf Baechle diff --git a/arch/mips/powertv/powertv_setup.c b/arch/mips/powertv/powertv_setup.c index bd8ebf1..698b1ea 100644 --- a/arch/mips/powertv/powertv_setup.c +++ b/arch/mips/powertv/powertv_setup.c @@ -64,9 +64,6 @@ #define REG_SIZE "4" /* In bytes */ #endif -static struct pt_regs die_regs; -static bool have_die_regs; - static void register_panic_notifier(void); static int panic_handler(struct notifier_block *notifier_block, unsigned long event, void *cause_string); @@ -218,24 +215,6 @@ static int panic_handler(struct notifier_block *notifier_block, return NOTIFY_DONE; } -/** - * Platform-specific handling of oops - * @str: Pointer to the oops string - * @regs: Pointer to the oops registers - * All we do here is to save the registers for subsequent printing through - * the panic notifier. - */ -void platform_die(const char *str, const struct pt_regs *regs) -{ - /* If we already have saved registers, don't overwrite them as they - * they apply to the initial fault */ - - if (!have_die_regs) { - have_die_regs = true; - die_regs = *regs; - } -} - /* Information about the RF MAC address, if one was supplied on the * command line. */ static bool have_rfmac; -- cgit v0.10.2 From 7e326d687d182e45447c24daccaa9b60bae130d5 Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Fri, 18 Dec 2009 21:38:37 +0900 Subject: MIPS: PowerTV: simplify prom_init_cmdline() and merge into prom_init() Signed-off-by: Yoichi Yuasa Patchwork: http://patchwork.linux-mips.org/patch/801/ Reviewed-by: David VomLehn Signed-off-by: Ralf Baechle diff --git a/arch/mips/powertv/Makefile b/arch/mips/powertv/Makefile index 2c51671..0a0d73c 100644 --- a/arch/mips/powertv/Makefile +++ b/arch/mips/powertv/Makefile @@ -23,6 +23,6 @@ # under Linux. # -obj-y += cmdline.o init.o memory.o reset.o time.o powertv_setup.o asic/ pci/ +obj-y += init.o memory.o reset.o time.o powertv_setup.o asic/ pci/ EXTRA_CFLAGS += -Wall -Werror diff --git a/arch/mips/powertv/cmdline.c b/arch/mips/powertv/cmdline.c deleted file mode 100644 index ee7ab47..0000000 --- a/arch/mips/powertv/cmdline.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. - * Portions copyright (C) 2009 Cisco Systems, Inc. - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * Kernel command line creation using the prom monitor (YAMON) argc/argv. - */ -#include -#include - -#include - -#include "init.h" - -/* - * YAMON (32-bit PROM) pass arguments and environment as 32-bit pointer. - * This macro take care of sign extension. - */ -#define prom_argv(index) ((char *)(long)_prom_argv[(index)]) - -void __init prom_init_cmdline(void) -{ - int len; - - if (prom_argc != 1) - return; - - len = strlen(arcs_cmdline); - - arcs_cmdline[len] = ' '; - - strlcpy(arcs_cmdline + len + 1, (char *)_prom_argv, - COMMAND_LINE_SIZE - len - 1); -} diff --git a/arch/mips/powertv/init.c b/arch/mips/powertv/init.c index 5f4e4c3..de0e46a 100644 --- a/arch/mips/powertv/init.c +++ b/arch/mips/powertv/init.c @@ -34,10 +34,7 @@ #include #include -#include "init.h" - -int prom_argc; -int *_prom_argv, *_prom_envp; +static int *_prom_envp; unsigned long _prom_memsize; /* @@ -109,8 +106,11 @@ static void __init mips_ejtag_setup(void) void __init prom_init(void) { + int prom_argc; + char *prom_argv; + prom_argc = fw_arg0; - _prom_argv = (int *) fw_arg1; + prom_argv = (char *) fw_arg1; _prom_envp = (int *) fw_arg2; _prom_memsize = (unsigned long) fw_arg3; @@ -118,7 +118,10 @@ void __init prom_init(void) board_ejtag_handler_setup = mips_ejtag_setup; pr_info("\nLINUX started...\n"); - prom_init_cmdline(); + + if (prom_argc == 1) + strlcat(arcs_cmdline, prom_argv, COMMAND_LINE_SIZE); + configure_platform(); prom_meminit(); diff --git a/arch/mips/powertv/init.h b/arch/mips/powertv/init.h index 7af6bf2..b194c34 100644 --- a/arch/mips/powertv/init.h +++ b/arch/mips/powertv/init.h @@ -22,7 +22,5 @@ #ifndef _POWERTV_INIT_H #define _POWERTV_INIT_H -extern int prom_argc; -extern int *_prom_argv; extern unsigned long _prom_memsize; #endif -- cgit v0.10.2 From 98bea6fc87390b6a12f595ad06fc686712435f94 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Tue, 22 Dec 2009 00:48:57 +0900 Subject: MIPS: TXx9: Cleanup builtin-cmdline processing Since commit 898d357b5262f9e26bc2418e01f8676e80d9867e (lmo) / 6acc7d485c24c00e111c61b2e6dff9180faebcae (kernel.org) ("Fix and enhance built-in kernel command line") arcs_cmdline[] does not contain built-in command line. The commit introduce CONFIG_CMDLINE_BOOL and CONFIG_CMDLINE_OVERRIDE to control built-in command line, and now we can use them instead of platform-specific built-in command line processing. Signed-off-by: Atsushi Nemoto Patchwork: http://patchwork.linux-mips.org/patch/802/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c index 06e801c..e27809b 100644 --- a/arch/mips/txx9/generic/setup.c +++ b/arch/mips/txx9/generic/setup.c @@ -160,7 +160,6 @@ static void __init prom_init_cmdline(void) int argc; int *argv32; int i; /* Always ignore the "-c" at argv[0] */ - static char builtin[COMMAND_LINE_SIZE] __initdata; if (fw_arg0 >= CKSEG0 || fw_arg1 < CKSEG0) { /* @@ -174,20 +173,6 @@ static void __init prom_init_cmdline(void) argv32 = (int *)fw_arg1; } - /* ignore all built-in args if any f/w args given */ - /* - * But if built-in strings was started with '+', append them - * to command line args. If built-in was started with '-', - * ignore all f/w args. - */ - builtin[0] = '\0'; - if (arcs_cmdline[0] == '+') - strcpy(builtin, arcs_cmdline + 1); - else if (arcs_cmdline[0] == '-') { - strcpy(builtin, arcs_cmdline + 1); - argc = 0; - } else if (argc <= 1) - strcpy(builtin, arcs_cmdline); arcs_cmdline[0] = '\0'; for (i = 1; i < argc; i++) { @@ -201,12 +186,6 @@ static void __init prom_init_cmdline(void) } else strcat(arcs_cmdline, str); } - /* append saved builtin args */ - if (builtin[0]) { - if (arcs_cmdline[0]) - strcat(arcs_cmdline, " "); - strcat(arcs_cmdline, builtin); - } } static int txx9_ic_disable __initdata; -- cgit v0.10.2 From c6a3c851a287980e47b45bf191a3b78d9d8508e2 Mon Sep 17 00:00:00 2001 From: David Daney Date: Wed, 23 Dec 2009 13:18:54 -0800 Subject: MIPS: Octeon: Add sched_clock() to csrc-octeon.c With the advent of function graph tracing on MIPS, Octeon needs a high precision sched_clock() implementation. Without it, most timing numbers are reported as 0.000. This new sched_clock just uses the 64-bit cycle counter appropriately scaled. Signed-off-by: David Daney Patchwork: http://patchwork.linux-mips.org/patch/805/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/cavium-octeon/csrc-octeon.c b/arch/mips/cavium-octeon/csrc-octeon.c index 96110f2..96df821 100644 --- a/arch/mips/cavium-octeon/csrc-octeon.c +++ b/arch/mips/cavium-octeon/csrc-octeon.c @@ -50,6 +50,13 @@ static struct clocksource clocksource_mips = { .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; +unsigned long long notrace sched_clock(void) +{ + return clocksource_cyc2ns(read_c0_cvmcount(), + clocksource_mips.mult, + clocksource_mips.shift); +} + void __init plat_time_init(void) { clocksource_mips.rating = 300; -- cgit v0.10.2 From 0833c76bd894b797f353e32c5eadfe16855bcf69 Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Thu, 24 Dec 2009 17:06:34 +0900 Subject: MIPS: Cobalt use strlcat() for the command line arguments Tested with CoLo v1.22 Signed-off-by: Yoichi Yuasa Patchwork: http://patchwork.linux-mips.org/patch/807/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/cobalt/setup.c b/arch/mips/cobalt/setup.c index b516442..ec3b2c4 100644 --- a/arch/mips/cobalt/setup.c +++ b/arch/mips/cobalt/setup.c @@ -97,26 +97,18 @@ void __init plat_mem_setup(void) void __init prom_init(void) { - int narg, indx, posn, nchr; unsigned long memsz; + int argc, i; char **argv; memsz = fw_arg0 & 0x7fff0000; - narg = fw_arg0 & 0x0000ffff; - - if (narg) { - arcs_cmdline[0] = '\0'; - argv = (char **) fw_arg1; - posn = 0; - for (indx = 1; indx < narg; ++indx) { - nchr = strlen(argv[indx]); - if (posn + 1 + nchr + 1 > sizeof(arcs_cmdline)) - break; - if (posn) - arcs_cmdline[posn++] = ' '; - strcpy(arcs_cmdline + posn, argv[indx]); - posn += nchr; - } + argc = fw_arg0 & 0x0000ffff; + argv = (char **)fw_arg1; + + for (i = 1; i < argc; i++) { + strlcat(arcs_cmdline, argv[i], COMMAND_LINE_SIZE); + if (i < (argc - 1)) + strlcat(arcs_cmdline, " ", COMMAND_LINE_SIZE); } add_memory_region(0x0, memsz, BOOT_MEM_RAM); -- cgit v0.10.2 From 1dc238632bbb4283ba2c789b2aeadb1a2743eb4f Mon Sep 17 00:00:00 2001 From: David VomLehn Date: Mon, 21 Dec 2009 17:43:42 -0800 Subject: MIPS: PowerTV: Remove extra r4k_clockevent_init() call A call to r4k_clocksource_init() was added to plat_time_init(), but when init_mips_clock_source() calls the same function, boot fails in clockevents_register_device(). This patch removes the extraneous call. Signed-off-by: David VomLehn Patchwork: http://patchwork.linux-mips.org/patch/803/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/powertv/time.c b/arch/mips/powertv/time.c index 1e0a5ef..9fd7b67 100644 --- a/arch/mips/powertv/time.c +++ b/arch/mips/powertv/time.c @@ -33,5 +33,4 @@ unsigned int __cpuinit get_c0_compare_int(void) void __init plat_time_init(void) { powertv_clocksource_init(); - r4k_clockevent_init(); } -- cgit v0.10.2 From 70b5c8194f1ecfab5f7e8db3590e7ef7996d893e Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Sun, 3 Jan 2010 14:13:04 +0900 Subject: MIPS: AR7: Remove unused prom_getchar() Signed-off-by: Yoichi Yuasa Cc: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/811/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/ar7/prom.c b/arch/mips/ar7/prom.c index 453dd22..c1fdd36 100644 --- a/arch/mips/ar7/prom.c +++ b/arch/mips/ar7/prom.c @@ -272,13 +272,6 @@ static inline void serial_out(int offset, int value) writel(value, (void *)PORT(offset)); } -char prom_getchar(void) -{ - while (!(serial_in(UART_LSR) & UART_LSR_DR)) - ; - return serial_in(UART_RX); -} - int prom_putchar(char c) { while ((serial_in(UART_LSR) & UART_LSR_TEMT) == 0) -- cgit v0.10.2 From 0622870a641f17f9ea10be82d5a8770d0e16c19b Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Sun, 3 Jan 2010 14:39:11 +0900 Subject: MIPS: BCM63xx: Remove duplicate CONFIG_CMDLINE. Builtin cmdline is copied by arch_mem_init(). Signed-off-by: Yoichi Yuasa Cc: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/812/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/bcm63xx/prom.c b/arch/mips/bcm63xx/prom.c index fb284fb..be252ef 100644 --- a/arch/mips/bcm63xx/prom.c +++ b/arch/mips/bcm63xx/prom.c @@ -40,9 +40,6 @@ void __init prom_init(void) reg &= ~mask; bcm_perf_writel(reg, PERF_CKCTL_REG); - /* assign command line from kernel config */ - strcpy(arcs_cmdline, CONFIG_CMDLINE); - /* register gpiochip */ bcm63xx_gpio_init(); -- cgit v0.10.2 From 9b54dc5869c3989077e456c57e51810f0a1bdbcb Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Sun, 3 Jan 2010 14:47:34 +0900 Subject: MIPS: Malta, PowerTV: Remove unnecessary "Linux started" Signed-off-by: Yoichi Yuasa Cc: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/813/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/mipssim/sim_setup.c b/arch/mips/mipssim/sim_setup.c index 0824f6a..55f22a3 100644 --- a/arch/mips/mipssim/sim_setup.c +++ b/arch/mips/mipssim/sim_setup.c @@ -49,9 +49,6 @@ void __init plat_mem_setup(void) set_io_port_base(0xbfd00000); serial_init(); - - pr_info("Linux started...\n"); - } extern struct plat_smp_ops ssmtc_smp_ops; @@ -60,7 +57,6 @@ void __init prom_init(void) { set_io_port_base(0xbfd00000); - pr_info("\nLINUX started...\n"); prom_meminit(); #ifdef CONFIG_MIPS_MT_SMP diff --git a/arch/mips/mti-malta/malta-init.c b/arch/mips/mti-malta/malta-init.c index f1b14c8..414f0c9 100644 --- a/arch/mips/mti-malta/malta-init.c +++ b/arch/mips/mti-malta/malta-init.c @@ -355,7 +355,6 @@ void __init prom_init(void) board_nmi_handler_setup = mips_nmi_setup; board_ejtag_handler_setup = mips_ejtag_setup; - pr_info("\nLINUX started...\n"); prom_init_cmdline(); prom_meminit(); #ifdef CONFIG_SERIAL_8250_CONSOLE diff --git a/arch/mips/powertv/init.c b/arch/mips/powertv/init.c index de0e46a..0afe227 100644 --- a/arch/mips/powertv/init.c +++ b/arch/mips/powertv/init.c @@ -117,8 +117,6 @@ void __init prom_init(void) board_nmi_handler_setup = mips_nmi_setup; board_ejtag_handler_setup = mips_ejtag_setup; - pr_info("\nLINUX started...\n"); - if (prom_argc == 1) strlcat(arcs_cmdline, prom_argv, COMMAND_LINE_SIZE); -- cgit v0.10.2 From 0e8a1d8262f41d6e8c1d736a408882bbb7a5c0a6 Mon Sep 17 00:00:00 2001 From: David Daney Date: Fri, 8 Jan 2010 14:47:36 -0800 Subject: MIPS: Octeon: Use non-overflowing arithmetic in sched_clock With typical mult and shift values, the calculation for Octeon's sched_clock overflows when using 64-bit arithmetic. Use 128-bit calculations instead. Signed-off-by: David Daney To: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/849/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/cavium-octeon/csrc-octeon.c b/arch/mips/cavium-octeon/csrc-octeon.c index 96df821..0bf4bbe 100644 --- a/arch/mips/cavium-octeon/csrc-octeon.c +++ b/arch/mips/cavium-octeon/csrc-octeon.c @@ -52,9 +52,34 @@ static struct clocksource clocksource_mips = { unsigned long long notrace sched_clock(void) { - return clocksource_cyc2ns(read_c0_cvmcount(), - clocksource_mips.mult, - clocksource_mips.shift); + /* 64-bit arithmatic can overflow, so use 128-bit. */ +#if (__GNUC__ < 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ <= 3)) + u64 t1, t2, t3; + unsigned long long rv; + u64 mult = clocksource_mips.mult; + u64 shift = clocksource_mips.shift; + u64 cnt = read_c0_cvmcount(); + + asm ( + "dmultu\t%[cnt],%[mult]\n\t" + "nor\t%[t1],$0,%[shift]\n\t" + "mfhi\t%[t2]\n\t" + "mflo\t%[t3]\n\t" + "dsll\t%[t2],%[t2],1\n\t" + "dsrlv\t%[rv],%[t3],%[shift]\n\t" + "dsllv\t%[t1],%[t2],%[t1]\n\t" + "or\t%[rv],%[t1],%[rv]\n\t" + : [rv] "=&r" (rv), [t1] "=&r" (t1), [t2] "=&r" (t2), [t3] "=&r" (t3) + : [cnt] "r" (cnt), [mult] "r" (mult), [shift] "r" (shift) + : "hi", "lo"); + return rv; +#else + /* GCC > 4.3 do it the easy way. */ + unsigned int __attribute__((mode(TI))) t; + t = read_c0_cvmcount(); + t = t * clocksource_mips.mult; + return (unsigned long long)(t >> clocksource_mips.shift); +#endif } void __init plat_time_init(void) -- cgit v0.10.2 From d797396f3387c5be8f63fcc8e9be98bb884ea86a Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Wed, 6 Jan 2010 15:55:13 +1100 Subject: MIPS: cpumask_of_node() should handle -1 as a node pcibus_to_node can return -1 if we cannot determine which node a pci bus is on. If passed -1, cpumask_of_node will negatively index the lookup array and pull in random data: # cat /sys/devices/pci0000:00/0000:00:01.0/local_cpus 00000000,00000003,00000000,00000000 # cat /sys/devices/pci0000:00/0000:00:01.0/local_cpulist 64-65 Change cpumask_of_node to check for -1 and return cpu_all_mask in this case: # cat /sys/devices/pci0000:00/0000:00:01.0/local_cpus ffffffff,ffffffff,ffffffff,ffffffff # cat /sys/devices/pci0000:00/0000:00:01.0/local_cpulist 0-127 Signed-off-by: Anton Blanchard Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Cc: Rusty Russell Cc: Andrew Morton Patchwork: http://patchwork.linux-mips.org/patch/831/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/include/asm/mach-ip27/topology.h b/arch/mips/include/asm/mach-ip27/topology.h index 09a59bc..1b1a7d1 100644 --- a/arch/mips/include/asm/mach-ip27/topology.h +++ b/arch/mips/include/asm/mach-ip27/topology.h @@ -24,7 +24,9 @@ extern struct cpuinfo_ip27 sn_cpu_info[NR_CPUS]; #define cpu_to_node(cpu) (sn_cpu_info[(cpu)].p_nodeid) #define parent_node(node) (node) -#define cpumask_of_node(node) (&hub_data(node)->h_cpus) +#define cpumask_of_node(node) ((node) == -1 ? \ + cpu_all_mask : \ + &hub_data(node)->h_cpus) struct pci_bus; extern int pcibus_to_node(struct pci_bus *); -- cgit v0.10.2 From 17f964e881e125917cbeea8eb82271cc68485a22 Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Fri, 18 Dec 2009 21:13:17 +0900 Subject: MIPS: Move vmlinux.ecoff to arch/mips/boot It moves to the same directory as the boot files in other formats. Signed-off-by: Yoichi Yuasa Cc: linux-mips Patchwork: http://patchwork.linux-mips.org/patch/796/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/boot/Makefile b/arch/mips/boot/Makefile index 094bc84..e39a08e 100644 --- a/arch/mips/boot/Makefile +++ b/arch/mips/boot/Makefile @@ -28,7 +28,7 @@ VMLINUX = vmlinux all: vmlinux.ecoff vmlinux.srec vmlinux.ecoff: $(obj)/elf2ecoff $(VMLINUX) - $(obj)/elf2ecoff $(VMLINUX) vmlinux.ecoff $(E2EFLAGS) + $(obj)/elf2ecoff $(VMLINUX) $(obj)/vmlinux.ecoff $(E2EFLAGS) $(obj)/elf2ecoff: $(obj)/elf2ecoff.c $(HOSTCC) -o $@ $^ -- cgit v0.10.2 From 9a3065c942d59afcc1b71bb75743d9f37fcc2954 Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Fri, 18 Dec 2009 21:14:19 +0900 Subject: MIPS: Ignore vmlinux.* Signed-off-by: Yoichi Yuasa Cc: linux-mips Patchwork: http://patchwork.linux-mips.org/patch/795/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/boot/.gitignore b/arch/mips/boot/.gitignore index ba63401..4667a5f 100644 --- a/arch/mips/boot/.gitignore +++ b/arch/mips/boot/.gitignore @@ -1,4 +1,5 @@ mkboot elf2ecoff +vmlinux.* zImage zImage.tmp -- cgit v0.10.2 From 7511bce4069de39ea04b14c1e1d55c249f9ce808 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 12 Jan 2010 18:59:16 +0000 Subject: ARM: Fix wrong dmb The __kuser_cmpxchg code uses an ARMv6 dmb instruction, rather than one based upon the architecture being built for. Switch to using the macro provided for this purpose, which also eliminates the need for an ifdef. Acked-by: Nicolas Pitre Signed-off-by: Russell King diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index d2903e3..6c5cf36 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -957,9 +957,7 @@ kuser_cmpxchg_fixup: #else -#ifdef CONFIG_SMP - mcr p15, 0, r0, c7, c10, 5 @ dmb -#endif + smp_dmb 1: ldrex r3, [r2] subs r3, r3, r0 strexeq r3, r1, [r2] -- cgit v0.10.2 From aff7b4f86737f1ae364bf5ece9a9b8586ddb2db4 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 12 Jan 2010 19:02:05 +0000 Subject: ARM: Ensure ARMv6/7 mm files are built using appropriate assembler options A kernel with both ARMv6 and ARMv7 selected results in build errors. Fix this by specifying the proper architectures for these assembly files. Signed-off-by: Russell King diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile index 827e238..e8d34a80 100644 --- a/arch/arm/mm/Makefile +++ b/arch/arm/mm/Makefile @@ -27,6 +27,9 @@ obj-$(CONFIG_CPU_ABRT_EV5TJ) += abort-ev5tj.o obj-$(CONFIG_CPU_ABRT_EV6) += abort-ev6.o obj-$(CONFIG_CPU_ABRT_EV7) += abort-ev7.o +AFLAGS_abort-ev6.o :=-Wa,-march=armv6k +AFLAGS_abort-ev7.o :=-Wa,-march=armv7-a + obj-$(CONFIG_CPU_PABRT_LEGACY) += pabort-legacy.o obj-$(CONFIG_CPU_PABRT_V6) += pabort-v6.o obj-$(CONFIG_CPU_PABRT_V7) += pabort-v7.o @@ -39,6 +42,9 @@ obj-$(CONFIG_CPU_CACHE_V6) += cache-v6.o obj-$(CONFIG_CPU_CACHE_V7) += cache-v7.o obj-$(CONFIG_CPU_CACHE_FA) += cache-fa.o +AFLAGS_cache-v6.o :=-Wa,-march=armv6 +AFLAGS_cache-v7.o :=-Wa,-march=armv7-a + obj-$(CONFIG_CPU_COPY_V3) += copypage-v3.o obj-$(CONFIG_CPU_COPY_V4WT) += copypage-v4wt.o obj-$(CONFIG_CPU_COPY_V4WB) += copypage-v4wb.o @@ -58,6 +64,9 @@ obj-$(CONFIG_CPU_TLB_V6) += tlb-v6.o obj-$(CONFIG_CPU_TLB_V7) += tlb-v7.o obj-$(CONFIG_CPU_TLB_FA) += tlb-fa.o +AFLAGS_tlb-v6.o :=-Wa,-march=armv6 +AFLAGS_tlb-v7.o :=-Wa,-march=armv7-a + obj-$(CONFIG_CPU_ARM610) += proc-arm6_7.o obj-$(CONFIG_CPU_ARM710) += proc-arm6_7.o obj-$(CONFIG_CPU_ARM7TDMI) += proc-arm7tdmi.o @@ -84,6 +93,9 @@ obj-$(CONFIG_CPU_FEROCEON) += proc-feroceon.o obj-$(CONFIG_CPU_V6) += proc-v6.o obj-$(CONFIG_CPU_V7) += proc-v7.o +AFLAGS_proc-v6.o :=-Wa,-march=armv6 +AFLAGS_proc-v7.o :=-Wa,-march=armv7-a + obj-$(CONFIG_CACHE_FEROCEON_L2) += cache-feroceon-l2.o obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o obj-$(CONFIG_CACHE_XSC3L2) += cache-xsc3l2.o -- cgit v0.10.2 From a2342f46437cde56803a36fdf94da635a74ad41c Mon Sep 17 00:00:00 2001 From: Mikael Pettersson Date: Sat, 9 Jan 2010 23:32:06 +0100 Subject: sata_promise: don't classify overruns as HSM errors When sata_promise encounters an overrun or underrun error it translates that to a libata AC_ERR_HSM, causing a hard reset. Since over/under-runs were thought to be rare and transient, this action seemed reasonable. Unfortunately it turns out that the controller throws overrun errors when e.g. hal polls a CD or DVD writer containing blank media, causing long sequences of hard resets and retries before EH finally gives up. This patch updates sata_promise to classify over/under-runs as AC_ERR_OTHER instead. This allows libata EH and upper layers to retry or fail the operation as they see fit without the disruption caused by repeated hard resets. This fixes a problem using a DVD-RAM drive with sata_promise, reported by Thomas Schorpp. I also tested it on a DVD-RW drive. Signed-off-by: Mikael Pettersson Tested-by: thomas schorpp Signed-off-by: Jeff Garzik diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c index 07d8d00..6330628 100644 --- a/drivers/ata/sata_promise.c +++ b/drivers/ata/sata_promise.c @@ -862,7 +862,7 @@ static void pdc_error_intr(struct ata_port *ap, struct ata_queued_cmd *qc, if (port_status & PDC_DRIVE_ERR) ac_err_mask |= AC_ERR_DEV; if (port_status & (PDC_OVERRUN_ERR | PDC_UNDERRUN_ERR)) - ac_err_mask |= AC_ERR_HSM; + ac_err_mask |= AC_ERR_OTHER; if (port_status & (PDC2_ATA_HBA_ERR | PDC2_ATA_DMA_CNT_ERR)) ac_err_mask |= AC_ERR_ATA_BUS; if (port_status & (PDC_PH_ERR | PDC_SH_ERR | PDC_DH_ERR | PDC2_HTO_ERR -- cgit v0.10.2 From 0b67c7439fe2a5d76602de36854c88e2beab00b0 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 11 Jan 2010 17:03:11 +0900 Subject: ata_piix: enable 32bit PIO on SATA piix Commit 871af1210f13966ab911ed2166e4ab2ce775b99d enabled 32bit PIO for PATA piix but didn't for SATA. There's no reason not to use 32bit PIO on SATA piix. Enable it. Signed-off-by: Tejun Heo Cc: Alan Cox Signed-off-by: Jeff Garzik diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 19136a7..6f3f225 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -329,7 +329,7 @@ static struct ata_port_operations ich_pata_ops = { }; static struct ata_port_operations piix_sata_ops = { - .inherits = &ata_bmdma_port_ops, + .inherits = &ata_bmdma32_port_ops, }; static struct ata_port_operations piix_sidpr_sata_ops = { -- cgit v0.10.2 From 5040ab67a2c6d5710ba497dc52a8f7035729d7b0 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 11 Jan 2010 11:14:44 +0900 Subject: libata: retry link resume if necessary Interestingly, when SIDPR is used in ata_piix, writes to DET in SControl sometimes get ignored leading to detection failure. Update sata_link_resume() such that it reads back SControl after clearing DET and retry if it's not clear. Signed-off-by: Tejun Heo Reported-by: fengxiangjun Reported-by: Jim Faulkner Cc: stable@kernel.org Signed-off-by: Jeff Garzik diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 22ff51b..6728328 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -3790,21 +3790,45 @@ int sata_link_debounce(struct ata_link *link, const unsigned long *params, int sata_link_resume(struct ata_link *link, const unsigned long *params, unsigned long deadline) { + int tries = ATA_LINK_RESUME_TRIES; u32 scontrol, serror; int rc; if ((rc = sata_scr_read(link, SCR_CONTROL, &scontrol))) return rc; - scontrol = (scontrol & 0x0f0) | 0x300; + /* + * Writes to SControl sometimes get ignored under certain + * controllers (ata_piix SIDPR). Make sure DET actually is + * cleared. + */ + do { + scontrol = (scontrol & 0x0f0) | 0x300; + if ((rc = sata_scr_write(link, SCR_CONTROL, scontrol))) + return rc; + /* + * Some PHYs react badly if SStatus is pounded + * immediately after resuming. Delay 200ms before + * debouncing. + */ + msleep(200); - if ((rc = sata_scr_write(link, SCR_CONTROL, scontrol))) - return rc; + /* is SControl restored correctly? */ + if ((rc = sata_scr_read(link, SCR_CONTROL, &scontrol))) + return rc; + } while ((scontrol & 0xf0f) != 0x300 && --tries); - /* Some PHYs react badly if SStatus is pounded immediately - * after resuming. Delay 200ms before debouncing. - */ - msleep(200); + if ((scontrol & 0xf0f) != 0x300) { + ata_link_printk(link, KERN_ERR, + "failed to resume link (SControl %X)\n", + scontrol); + return 0; + } + + if (tries < ATA_LINK_RESUME_TRIES) + ata_link_printk(link, KERN_WARNING, + "link resume succeeded after %d retries\n", + ATA_LINK_RESUME_TRIES - tries); if ((rc = sata_link_debounce(link, params, deadline))) return rc; diff --git a/include/linux/libata.h b/include/linux/libata.h index 6a9c4dd..7311225 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -354,6 +354,9 @@ enum { /* max tries if error condition is still set after ->error_handler */ ATA_EH_MAX_TRIES = 5, + /* sometimes resuming a link requires several retries */ + ATA_LINK_RESUME_TRIES = 5, + /* how hard are we gonna try to probe/recover devices */ ATA_PROBE_MAX_TRIES = 3, ATA_EH_DEV_TRIES = 3, -- cgit v0.10.2 From 682137f7e6bc78e3c324874c0c213123ddc5e261 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Wed, 13 Jan 2010 10:42:05 +1000 Subject: m68knommu: fix definitions of __pa() and __va() Fix compilation breakage of all m68knommu targets: CC arch/m68knommu/kernel/asm-offsets.s In file included from include/linux/sched.h:77, from arch/m68knommu/kernel/asm-offsets.c:12: include/linux/percpu.h: In function 'per_cpu_ptr_to_phys': include/linux/percpu.h:161: error: implicit declaration of function 'virt_to_phy This is broken in linux-2.6.33-rc3. Change the definitions of __pa() and __va() to not use virt_to_phys() and phys_to_virt(). Trivial 1:1 conversion required for the non-MMU case. A side effect if this is that the m68knommu can now use asm/virtconvert.h for the definition of virt_to_phys() and phys_to_virt(). Also cleaned up the definition of page_to_phys() when moving into virtconvert.h. Signed-off-by: Greg Ungerer Signed-off-by: Linus Torvalds diff --git a/arch/m68k/include/asm/io_no.h b/arch/m68k/include/asm/io_no.h index 7f57436..359065d5 100644 --- a/arch/m68k/include/asm/io_no.h +++ b/arch/m68k/include/asm/io_no.h @@ -3,6 +3,7 @@ #ifdef __KERNEL__ +#include /* * These are for ISA/PCI shared memory _only_ and should never be used @@ -165,19 +166,6 @@ static inline void *ioremap_fullcache(unsigned long physaddr, unsigned long size extern void iounmap(void *addr); -/* Pages to physical address... */ -#define page_to_phys(page) ((page - mem_map) << PAGE_SHIFT) -#define page_to_bus(page) ((page - mem_map) << PAGE_SHIFT) - -/* - * Macros used for converting between virtual and physical mappings. - */ -#define phys_to_virt(vaddr) ((void *) (vaddr)) -#define virt_to_phys(vaddr) ((unsigned long) (vaddr)) - -#define virt_to_bus virt_to_phys -#define bus_to_virt phys_to_virt - /* * Convert a physical pointer to a virtual kernel pointer for /dev/mem * access diff --git a/arch/m68k/include/asm/page_no.h b/arch/m68k/include/asm/page_no.h index 1f31b06..8029a33 100644 --- a/arch/m68k/include/asm/page_no.h +++ b/arch/m68k/include/asm/page_no.h @@ -56,8 +56,8 @@ extern unsigned long memory_end; #ifndef __ASSEMBLY__ -#define __pa(vaddr) virt_to_phys((void *)(vaddr)) -#define __va(paddr) phys_to_virt((unsigned long)(paddr)) +#define __pa(vaddr) ((unsigned long)(vaddr)) +#define __va(paddr) ((void *)(paddr)) #define virt_to_pfn(kaddr) (__pa(kaddr) >> PAGE_SHIFT) #define pfn_to_virt(pfn) __va((pfn) << PAGE_SHIFT) diff --git a/arch/m68k/include/asm/virtconvert.h b/arch/m68k/include/asm/virtconvert.h index 22ab05c..3f834b3 100644 --- a/arch/m68k/include/asm/virtconvert.h +++ b/arch/m68k/include/asm/virtconvert.h @@ -26,6 +26,7 @@ static inline void *phys_to_virt(unsigned long address) } /* Permanent address of a page. */ +#ifdef CONFIG_MMU #ifdef CONFIG_SINGLE_MEMORY_CHUNK #define page_to_phys(page) \ __pa(PAGE_OFFSET + (((page) - pg_data_map[0].node_mem_map) << PAGE_SHIFT)) @@ -37,6 +38,9 @@ static inline void *phys_to_virt(unsigned long address) page_to_pfn(__page) << PAGE_SHIFT; \ }) #endif +#else +#define page_to_phys(page) (((page) - mem_map) << PAGE_SHIFT) +#endif /* * IO bus memory addresses are 1:1 with the physical address, -- cgit v0.10.2 From dbf004d7883b3adb058c0c1a5635bc4ec27651c0 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Tue, 12 Jan 2010 16:59:52 -0500 Subject: remove my email address from checkpatch. Maybe this will stop people emailing me about it. Signed-off-by: Dave Jones Signed-off-by: Linus Torvalds diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index bc4114f..3257d3d 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1,5 +1,5 @@ #!/usr/bin/perl -w -# (c) 2001, Dave Jones. (the file handling bit) +# (c) 2001, Dave Jones. (the file handling bit) # (c) 2005, Joel Schopp (the ugly bit) # (c) 2007,2008, Andy Whitcroft (new conditions, test suite) # (c) 2008,2009, Andy Whitcroft -- cgit v0.10.2 From 2c761270d5520dd84ab0b4e47c24d99ff8503c38 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Tue, 12 Jan 2010 17:39:16 +1100 Subject: lib: Introduce generic list_sort function There are two copies of list_sort() in the tree already, one in the DRM code, another in ubifs. Now XFS needs this as well. Create a generic list_sort() function from the ubifs version and convert existing users to it so we don't end up with yet another copy in the tree. Signed-off-by: Dave Chinner Acked-by: Dave Airlie Acked-by: Artem Bityutskiy Signed-off-by: Linus Torvalds diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index 6d81a02..76d6339 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c @@ -1,9 +1,4 @@ /* - * The list_sort function is (presumably) licensed under the GPL (see the - * top level "COPYING" file for details). - * - * The remainder of this file is: - * * Copyright © 1997-2003 by The XFree86 Project, Inc. * Copyright © 2007 Dave Airlie * Copyright © 2007-2008 Intel Corporation @@ -36,6 +31,7 @@ */ #include +#include #include "drmP.h" #include "drm.h" #include "drm_crtc.h" @@ -855,6 +851,7 @@ EXPORT_SYMBOL(drm_mode_prune_invalid); /** * drm_mode_compare - compare modes for favorability + * @priv: unused * @lh_a: list_head for first mode * @lh_b: list_head for second mode * @@ -868,7 +865,7 @@ EXPORT_SYMBOL(drm_mode_prune_invalid); * Negative if @lh_a is better than @lh_b, zero if they're equivalent, or * positive if @lh_b is better than @lh_a. */ -static int drm_mode_compare(struct list_head *lh_a, struct list_head *lh_b) +static int drm_mode_compare(void *priv, struct list_head *lh_a, struct list_head *lh_b) { struct drm_display_mode *a = list_entry(lh_a, struct drm_display_mode, head); struct drm_display_mode *b = list_entry(lh_b, struct drm_display_mode, head); @@ -885,85 +882,6 @@ static int drm_mode_compare(struct list_head *lh_a, struct list_head *lh_b) return diff; } -/* FIXME: what we don't have a list sort function? */ -/* list sort from Mark J Roberts (mjr@znex.org) */ -void list_sort(struct list_head *head, - int (*cmp)(struct list_head *a, struct list_head *b)) -{ - struct list_head *p, *q, *e, *list, *tail, *oldhead; - int insize, nmerges, psize, qsize, i; - - list = head->next; - list_del(head); - insize = 1; - for (;;) { - p = oldhead = list; - list = tail = NULL; - nmerges = 0; - - while (p) { - nmerges++; - q = p; - psize = 0; - for (i = 0; i < insize; i++) { - psize++; - q = q->next == oldhead ? NULL : q->next; - if (!q) - break; - } - - qsize = insize; - while (psize > 0 || (qsize > 0 && q)) { - if (!psize) { - e = q; - q = q->next; - qsize--; - if (q == oldhead) - q = NULL; - } else if (!qsize || !q) { - e = p; - p = p->next; - psize--; - if (p == oldhead) - p = NULL; - } else if (cmp(p, q) <= 0) { - e = p; - p = p->next; - psize--; - if (p == oldhead) - p = NULL; - } else { - e = q; - q = q->next; - qsize--; - if (q == oldhead) - q = NULL; - } - if (tail) - tail->next = e; - else - list = e; - e->prev = tail; - tail = e; - } - p = q; - } - - tail->next = list; - list->prev = tail; - - if (nmerges <= 1) - break; - - insize *= 2; - } - - head->next = list; - head->prev = list->prev; - list->prev->next = head; - list->prev = head; -} - /** * drm_mode_sort - sort mode list * @mode_list: list to sort @@ -975,7 +893,7 @@ void list_sort(struct list_head *head, */ void drm_mode_sort(struct list_head *mode_list) { - list_sort(mode_list, drm_mode_compare); + list_sort(NULL, mode_list, drm_mode_compare); } EXPORT_SYMBOL(drm_mode_sort); diff --git a/fs/ubifs/gc.c b/fs/ubifs/gc.c index 618c270..e5a3d8e 100644 --- a/fs/ubifs/gc.c +++ b/fs/ubifs/gc.c @@ -54,6 +54,7 @@ */ #include +#include #include "ubifs.h" /* @@ -108,101 +109,6 @@ static int switch_gc_head(struct ubifs_info *c) } /** - * list_sort - sort a list. - * @priv: private data, passed to @cmp - * @head: the list to sort - * @cmp: the elements comparison function - * - * This function has been implemented by Mark J Roberts . It - * implements "merge sort" which has O(nlog(n)) complexity. The list is sorted - * in ascending order. - * - * The comparison function @cmp is supposed to return a negative value if @a is - * than @b, and a positive value if @a is greater than @b. If @a and @b are - * equivalent, then it does not matter what this function returns. - */ -static void list_sort(void *priv, struct list_head *head, - int (*cmp)(void *priv, struct list_head *a, - struct list_head *b)) -{ - struct list_head *p, *q, *e, *list, *tail, *oldhead; - int insize, nmerges, psize, qsize, i; - - if (list_empty(head)) - return; - - list = head->next; - list_del(head); - insize = 1; - for (;;) { - p = oldhead = list; - list = tail = NULL; - nmerges = 0; - - while (p) { - nmerges++; - q = p; - psize = 0; - for (i = 0; i < insize; i++) { - psize++; - q = q->next == oldhead ? NULL : q->next; - if (!q) - break; - } - - qsize = insize; - while (psize > 0 || (qsize > 0 && q)) { - if (!psize) { - e = q; - q = q->next; - qsize--; - if (q == oldhead) - q = NULL; - } else if (!qsize || !q) { - e = p; - p = p->next; - psize--; - if (p == oldhead) - p = NULL; - } else if (cmp(priv, p, q) <= 0) { - e = p; - p = p->next; - psize--; - if (p == oldhead) - p = NULL; - } else { - e = q; - q = q->next; - qsize--; - if (q == oldhead) - q = NULL; - } - if (tail) - tail->next = e; - else - list = e; - e->prev = tail; - tail = e; - } - p = q; - } - - tail->next = list; - list->prev = tail; - - if (nmerges <= 1) - break; - - insize *= 2; - } - - head->next = list; - head->prev = list->prev; - list->prev->next = head; - list->prev = head; -} - -/** * data_nodes_cmp - compare 2 data nodes. * @priv: UBIFS file-system description object * @a: first data node diff --git a/include/linux/list_sort.h b/include/linux/list_sort.h new file mode 100644 index 0000000..1a2df2e --- /dev/null +++ b/include/linux/list_sort.h @@ -0,0 +1,11 @@ +#ifndef _LINUX_LIST_SORT_H +#define _LINUX_LIST_SORT_H + +#include + +struct list_head; + +void list_sort(void *priv, struct list_head *head, + int (*cmp)(void *priv, struct list_head *a, + struct list_head *b)); +#endif diff --git a/lib/Makefile b/lib/Makefile index 911b25a..3b0b4a6 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -21,7 +21,7 @@ lib-y += kobject.o kref.o klist.o obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \ bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o \ - string_helpers.o gcd.o + string_helpers.o gcd.o list_sort.o ifeq ($(CONFIG_DEBUG_KOBJECT),y) CFLAGS_kobject.o += -DDEBUG diff --git a/lib/list_sort.c b/lib/list_sort.c new file mode 100644 index 0000000..19d11e0 --- /dev/null +++ b/lib/list_sort.c @@ -0,0 +1,102 @@ +#include +#include +#include +#include +#include + +/** + * list_sort - sort a list. + * @priv: private data, passed to @cmp + * @head: the list to sort + * @cmp: the elements comparison function + * + * This function has been implemented by Mark J Roberts . It + * implements "merge sort" which has O(nlog(n)) complexity. The list is sorted + * in ascending order. + * + * The comparison function @cmp is supposed to return a negative value if @a is + * less than @b, and a positive value if @a is greater than @b. If @a and @b + * are equivalent, then it does not matter what this function returns. + */ +void list_sort(void *priv, struct list_head *head, + int (*cmp)(void *priv, struct list_head *a, + struct list_head *b)) +{ + struct list_head *p, *q, *e, *list, *tail, *oldhead; + int insize, nmerges, psize, qsize, i; + + if (list_empty(head)) + return; + + list = head->next; + list_del(head); + insize = 1; + for (;;) { + p = oldhead = list; + list = tail = NULL; + nmerges = 0; + + while (p) { + nmerges++; + q = p; + psize = 0; + for (i = 0; i < insize; i++) { + psize++; + q = q->next == oldhead ? NULL : q->next; + if (!q) + break; + } + + qsize = insize; + while (psize > 0 || (qsize > 0 && q)) { + if (!psize) { + e = q; + q = q->next; + qsize--; + if (q == oldhead) + q = NULL; + } else if (!qsize || !q) { + e = p; + p = p->next; + psize--; + if (p == oldhead) + p = NULL; + } else if (cmp(priv, p, q) <= 0) { + e = p; + p = p->next; + psize--; + if (p == oldhead) + p = NULL; + } else { + e = q; + q = q->next; + qsize--; + if (q == oldhead) + q = NULL; + } + if (tail) + tail->next = e; + else + list = e; + e->prev = tail; + tail = e; + } + p = q; + } + + tail->next = list; + list->prev = tail; + + if (nmerges <= 1) + break; + + insize *= 2; + } + + head->next = list; + head->prev = list->prev; + list->prev->next = head; + list->prev = head; +} + +EXPORT_SYMBOL(list_sort); -- cgit v0.10.2 From bb7d3f24c71e528989501617651b669fbed798cb Mon Sep 17 00:00:00 2001 From: "Bryn M. Reeves" Date: Thu, 12 Nov 2009 18:31:54 +0000 Subject: [SCSI] megaraid_sas: remove sysfs poll_mode_io world writeable permissions /sys/bus/pci/drivers/megaraid_sas/poll_mode_io defaults to being world-writable, which seems bad (letting any user affect kernel driver behavior). This turns off group and user write permissions, so that on typical production systems only root can write to it. Signed-off-by: Bryn M. Reeves Signed-off-by: Linus Torvalds diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c index 99ff99e..708ea31 100644 --- a/drivers/scsi/megaraid/megaraid_sas.c +++ b/drivers/scsi/megaraid/megaraid_sas.c @@ -4046,7 +4046,7 @@ megasas_aen_polling(struct work_struct *work) } -static DRIVER_ATTR(poll_mode_io, S_IRUGO|S_IWUGO, +static DRIVER_ATTR(poll_mode_io, S_IRUGO|S_IWUSR, megasas_sysfs_show_poll_mode_io, megasas_sysfs_set_poll_mode_io); -- cgit v0.10.2 From 7284ce6c9f6153d1777df5f310c959724d1bd446 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 12 Jan 2010 21:15:00 -0800 Subject: Linux 2.6.33-rc4 diff --git a/Makefile b/Makefile index 1231094..9f64552 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 33 -EXTRAVERSION = -rc3 +EXTRAVERSION = -rc4 NAME = Man-Eating Seals of Antiquity # *DOCUMENTATION* -- cgit v0.10.2 From c2c5d45d46c8c0fd34291dec958670ad4816796f Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Thu, 31 Dec 2009 03:52:25 +0100 Subject: perf: Stop stack frame walking off kernel addresses boundaries While processing kernel perf callchains, an bad entry can be considered as a valid stack pointer but not as a kernel address. In this case, we hang in an endless loop. This can happen in an x86-32 kernel after processing the last entry in a kernel stacktrace. Just stop the stack frame walking after we encounter an invalid kernel address. This fixes a hard lockup in x86-32. Signed-off-by: Frederic Weisbecker Cc: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: Paul Mackerras LKML-Reference: <1262227945-27014-1-git-send-regression-fweisbec@gmail.com> Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c index c56bc28..6d81755 100644 --- a/arch/x86/kernel/dumpstack.c +++ b/arch/x86/kernel/dumpstack.c @@ -123,13 +123,15 @@ print_context_stack_bp(struct thread_info *tinfo, while (valid_stack_ptr(tinfo, ret_addr, sizeof(*ret_addr), end)) { unsigned long addr = *ret_addr; - if (__kernel_text_address(addr)) { - ops->address(data, addr, 1); - frame = frame->next_frame; - ret_addr = &frame->return_address; - print_ftrace_graph_addr(addr, data, ops, tinfo, graph); - } + if (!__kernel_text_address(addr)) + break; + + ops->address(data, addr, 1); + frame = frame->next_frame; + ret_addr = &frame->return_address; + print_ftrace_graph_addr(addr, data, ops, tinfo, graph); } + return (unsigned long)frame; } EXPORT_SYMBOL_GPL(print_context_stack_bp); -- cgit v0.10.2 From 830395188fae5f4028fa3c38ab1b031aae18a64c Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 12 Jan 2010 08:58:29 -0200 Subject: perf tools: Move QUIET_STDERR def to before first use MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QUIET_STDERR is used when detecting if -fstack-protector-all can be used. Noticed while building the perf tools on a Debian PARISC64 machine. Signed-off-by: Arnaldo Carvalho de Melo Cc: Frédéric Weisbecker Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Paul Mackerras LKML-Reference: <1263293910-8484-1-git-send-email-acme@infradead.org> Signed-off-by: Ingo Molnar diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 652a470..07f596d 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -250,6 +250,12 @@ PTHREAD_LIBS = -lpthread # explicitly what architecture to check for. Fix this up for yours.. SPARSE_FLAGS = -D__BIG_ENDIAN__ -D__powerpc__ +ifeq ($(V), 2) + QUIET_STDERR = ">/dev/null" +else + QUIET_STDERR = ">/dev/null 2>&1" +endif + ifeq ($(shell sh -c "echo 'int foo(void) {char X[2]; return 3;}' | $(CC) -x c -c -Werror -fstack-protector-all - -o /dev/null "$(QUIET_STDERR)" && echo y"), y) CFLAGS := $(CFLAGS) -fstack-protector-all endif @@ -451,11 +457,6 @@ BUILTIN_OBJS += builtin-kmem.o PERFLIBS = $(LIB_FILE) -ifeq ($(V), 2) - QUIET_STDERR = ">/dev/null" -else - QUIET_STDERR = ">/dev/null 2>&1" -endif # # Platform specific tweaks # -- cgit v0.10.2 From 1703f2c321a8a531c393e137a82602e16c6061cb Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 12 Jan 2010 08:58:30 -0200 Subject: perf tools: Check if /dev/null can be used as the -o gcc argument MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit At least on Debian PARISC64, using: acme@parisc:~/git/linux-2.6-tip$ gcc -v Using built-in specs. Target: hppa-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Debian 4.3.4-6' --with-bugurl=file:///usr/share/doc/gcc-4.3/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --with-gxx-include-dir=/usr/include/c++/4.3 --program-suffix=-4.3 --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-mpfr --disable-libssp --enable-checking=release --build=hppa-linux-gnu --host=hppa-linux-gnu --target=hppa-linux-gnu Thread model: posix gcc version 4.3.4 (Debian 4.3.4-6) there are issues about using 'gcc -o /dev/null': /usr/bin/ld: final link failed: File truncated collect2: ld returned 1 exit status So we test that and use /dev/null in environments where it works, while using an .INTERMEDIATE file on those where it can't be used, so that the .perf.dev.null file can be used instead and then deleted when make exits. Researched-with: Kyle McMartin Researched-with: Mauro Carvalho Chehab Signed-off-by: Arnaldo Carvalho de Melo Cc: Frédéric Weisbecker Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Paul Mackerras LKML-Reference: <1263293910-8484-2-git-send-email-acme@infradead.org> Signed-off-by: Ingo Molnar diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 07f596d..2e7fa3a 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -256,7 +256,13 @@ else QUIET_STDERR = ">/dev/null 2>&1" endif -ifeq ($(shell sh -c "echo 'int foo(void) {char X[2]; return 3;}' | $(CC) -x c -c -Werror -fstack-protector-all - -o /dev/null "$(QUIET_STDERR)" && echo y"), y) +BITBUCKET = "/dev/null" + +ifneq ($(shell sh -c "(echo '\#include '; echo 'int main(void) { return puts(\"hi\"); }') | $(CC) -x c - $(ALL_CFLAGS) -o $(BITBUCKET) "$(QUIET_STDERR)" && echo y"), y) + BITBUCKET = .perf.dev.null +endif + +ifeq ($(shell sh -c "echo 'int foo(void) {char X[2]; return 3;}' | $(CC) -x c -c -Werror -fstack-protector-all - -o $(BITBUCKET) "$(QUIET_STDERR)" && echo y"), y) CFLAGS := $(CFLAGS) -fstack-protector-all endif @@ -484,19 +490,19 @@ ifeq ($(uname_S),Darwin) PTHREAD_LIBS = endif -ifeq ($(shell sh -c "(echo '\#include '; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ, 0); return (long)elf; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o /dev/null $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y) -ifneq ($(shell sh -c "(echo '\#include '; echo 'int main(void) { const char * version = gnu_get_libc_version(); return (long)version; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o /dev/null $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y) +ifeq ($(shell sh -c "(echo '\#include '; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ, 0); return (long)elf; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y) +ifneq ($(shell sh -c "(echo '\#include '; echo 'int main(void) { const char * version = gnu_get_libc_version(); return (long)version; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y) msg := $(error No gnu/libc-version.h found, please install glibc-dev[el]/glibc-static); endif - ifneq ($(shell sh -c "(echo '\#include '; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ_MMAP, 0); return (long)elf; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o /dev/null $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y) + ifneq ($(shell sh -c "(echo '\#include '; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ_MMAP, 0); return (long)elf; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y) BASIC_CFLAGS += -DLIBELF_NO_MMAP endif else msg := $(error No libelf.h/libelf found, please install libelf-dev/elfutils-libelf-devel and glibc-dev[el]); endif -ifneq ($(shell sh -c "(echo '\#ifndef _MIPS_SZLONG'; echo '\#define _MIPS_SZLONG 0'; echo '\#endif'; echo '\#include '; echo '\#include '; echo 'int main(void) { Dwarf_Debug dbg; Dwarf_Error err; Dwarf_Ranges *rng; dwarf_init(0, DW_DLC_READ, 0, 0, &dbg, &err); dwarf_get_ranges(dbg, 0, &rng, 0, 0, &err); return (long)dbg; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/libdwarf -ldwarf -lelf -o /dev/null $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y) +ifneq ($(shell sh -c "(echo '\#ifndef _MIPS_SZLONG'; echo '\#define _MIPS_SZLONG 0'; echo '\#endif'; echo '\#include '; echo '\#include '; echo 'int main(void) { Dwarf_Debug dbg; Dwarf_Error err; Dwarf_Ranges *rng; dwarf_init(0, DW_DLC_READ, 0, 0, &dbg, &err); dwarf_get_ranges(dbg, 0, &rng, 0, 0, &err); return (long)dbg; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/libdwarf -ldwarf -lelf -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y) msg := $(warning No libdwarf.h found or old libdwarf.h found, disables dwarf support. Please install libdwarf-dev/libdwarf-devel >= 20081231); BASIC_CFLAGS += -DNO_LIBDWARF else @@ -510,7 +516,7 @@ PERL_EMBED_LDOPTS = `perl -MExtUtils::Embed -e ldopts 2>/dev/null` PERL_EMBED_CCOPTS = `perl -MExtUtils::Embed -e ccopts 2>/dev/null` endif -ifneq ($(shell sh -c "(echo '\#include '; echo '\#include '; echo 'int main(void) { perl_alloc(); return 0; }') | $(CC) -x c - $(PERL_EMBED_CCOPTS) -o /dev/null $(PERL_EMBED_LDOPTS) > /dev/null 2>&1 && echo y"), y) +ifneq ($(shell sh -c "(echo '\#include '; echo '\#include '; echo 'int main(void) { perl_alloc(); return 0; }') | $(CC) -x c - $(PERL_EMBED_CCOPTS) -o $(BITBUCKET) $(PERL_EMBED_LDOPTS) > /dev/null 2>&1 && echo y"), y) BASIC_CFLAGS += -DNO_LIBPERL else ALL_LDFLAGS += $(PERL_EMBED_LDOPTS) @@ -520,20 +526,20 @@ endif ifdef NO_DEMANGLE BASIC_CFLAGS += -DNO_DEMANGLE else - has_bfd := $(shell sh -c "(echo '\#include '; echo 'int main(void) { bfd_demangle(0, 0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o /dev/null $(ALL_LDFLAGS) $(EXTLIBS) -lbfd "$(QUIET_STDERR)" && echo y") + has_bfd := $(shell sh -c "(echo '\#include '; echo 'int main(void) { bfd_demangle(0, 0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) -lbfd "$(QUIET_STDERR)" && echo y") ifeq ($(has_bfd),y) EXTLIBS += -lbfd else - has_bfd_iberty := $(shell sh -c "(echo '\#include '; echo 'int main(void) { bfd_demangle(0, 0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o /dev/null $(ALL_LDFLAGS) $(EXTLIBS) -lbfd -liberty "$(QUIET_STDERR)" && echo y") + has_bfd_iberty := $(shell sh -c "(echo '\#include '; echo 'int main(void) { bfd_demangle(0, 0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) -lbfd -liberty "$(QUIET_STDERR)" && echo y") ifeq ($(has_bfd_iberty),y) EXTLIBS += -lbfd -liberty else - has_bfd_iberty_z := $(shell sh -c "(echo '\#include '; echo 'int main(void) { bfd_demangle(0, 0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o /dev/null $(ALL_LDFLAGS) $(EXTLIBS) -lbfd -liberty -lz "$(QUIET_STDERR)" && echo y") + has_bfd_iberty_z := $(shell sh -c "(echo '\#include '; echo 'int main(void) { bfd_demangle(0, 0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) -lbfd -liberty -lz "$(QUIET_STDERR)" && echo y") ifeq ($(has_bfd_iberty_z),y) EXTLIBS += -lbfd -liberty -lz else - has_cplus_demangle := $(shell sh -c "(echo 'extern char *cplus_demangle(const char *, int);'; echo 'int main(void) { cplus_demangle(0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o /dev/null $(ALL_LDFLAGS) $(EXTLIBS) -liberty "$(QUIET_STDERR)" && echo y") + has_cplus_demangle := $(shell sh -c "(echo 'extern char *cplus_demangle(const char *, int);'; echo 'int main(void) { cplus_demangle(0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) -liberty "$(QUIET_STDERR)" && echo y") ifeq ($(has_cplus_demangle),y) EXTLIBS += -liberty BASIC_CFLAGS += -DHAVE_CPLUS_DEMANGLE @@ -781,7 +787,7 @@ export TAR INSTALL DESTDIR SHELL_PATH SHELL = $(SHELL_PATH) -all:: shell_compatibility_test $(ALL_PROGRAMS) $(BUILT_INS) $(OTHER_PROGRAMS) PERF-BUILD-OPTIONS +all:: .perf.dev.null shell_compatibility_test $(ALL_PROGRAMS) $(BUILT_INS) $(OTHER_PROGRAMS) PERF-BUILD-OPTIONS ifneq (,$X) $(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) perf$X)), test '$p' -ef '$p$X' || $(RM) '$p';) endif @@ -1108,6 +1114,11 @@ clean: .PHONY: .FORCE-PERF-VERSION-FILE TAGS tags cscope .FORCE-PERF-CFLAGS .PHONY: .FORCE-PERF-BUILD-OPTIONS +.perf.dev.null: + touch .perf.dev.null + +.INTERMEDIATE: .perf.dev.null + ### Make sure built-ins do not have dups and listed in perf.c # check-builtins:: -- cgit v0.10.2