linux-moblin: Drop old versions (2.6.31.5 and 2.6.29.1)

Signed-off-by: Richard Purdie <rpurdie@linux.intel.com>
This commit is contained in:
Richard Purdie 2010-06-08 21:04:38 +01:00
parent 3a8ee5864d
commit fa64e20621
75 changed files with 0 additions and 131218 deletions

View File

@ -1,486 +0,0 @@
From 84e7ccff650b8f124585ba7d5b9a1544f53457e7 Mon Sep 17 00:00:00 2001
From: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
Date: Fri, 27 Feb 2009 16:53:11 +0100
Subject: [PATCH 1/8] drm: Split out the mm declarations in a separate header. Add atomic operations.
Signed-off-by: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
---
drivers/gpu/drm/drm_mm.c | 173 ++++++++++++++++++++++++++++++++++++++--------
include/drm/drmP.h | 37 +----------
include/drm/drm_mm.h | 90 ++++++++++++++++++++++++
3 files changed, 235 insertions(+), 65 deletions(-)
create mode 100644 include/drm/drm_mm.h
Index: linux-2.6.28/drivers/gpu/drm/drm_mm.c
===================================================================
--- linux-2.6.28.orig/drivers/gpu/drm/drm_mm.c 2009-03-09 19:19:52.000000000 +0000
+++ linux-2.6.28/drivers/gpu/drm/drm_mm.c 2009-03-12 13:15:05.000000000 +0000
@@ -42,8 +43,11 @@
*/
#include "drmP.h"
+#include "drm_mm.h"
#include <linux/slab.h>
+#define MM_UNUSED_TARGET 4
+
unsigned long drm_mm_tail_space(struct drm_mm *mm)
{
struct list_head *tail_node;
@@ -74,16 +78,66 @@
return 0;
}
+static struct drm_mm_node *drm_mm_kmalloc(struct drm_mm *mm, int atomic)
+{
+ struct drm_mm_node *child;
+
+ if (atomic) {
+ child =
+ (struct drm_mm_node *)kmalloc(sizeof(*child), GFP_ATOMIC);
+ } else {
+ child =
+ (struct drm_mm_node *)kmalloc(sizeof(*child), GFP_KERNEL);
+ }
+
+ if (unlikely(child == NULL)) {
+ spin_lock(&mm->unused_lock);
+ if (list_empty(&mm->unused_nodes))
+ child = NULL;
+ else {
+ child =
+ list_entry(mm->unused_nodes.next,
+ struct drm_mm_node, fl_entry);
+ list_del(&child->fl_entry);
+ --mm->num_unused;
+ }
+ spin_unlock(&mm->unused_lock);
+ }
+ return child;
+}
+
+int drm_mm_pre_get(struct drm_mm *mm)
+{
+ struct drm_mm_node *node;
+
+ spin_lock(&mm->unused_lock);
+ while (mm->num_unused < MM_UNUSED_TARGET) {
+ spin_unlock(&mm->unused_lock);
+ node = kmalloc(sizeof(*node), GFP_KERNEL);
+ spin_lock(&mm->unused_lock);
+
+ if (unlikely(node == NULL)) {
+ int ret = (mm->num_unused < 2) ? -ENOMEM : 0;
+ spin_unlock(&mm->unused_lock);
+ return ret;
+ }
+ ++mm->num_unused;
+ list_add_tail(&node->fl_entry, &mm->unused_nodes);
+ }
+ spin_unlock(&mm->unused_lock);
+ return 0;
+}
+
+EXPORT_SYMBOL(drm_mm_pre_get);
static int drm_mm_create_tail_node(struct drm_mm *mm,
- unsigned long start,
- unsigned long size)
+ unsigned long start,
+ unsigned long size, int atomic)
{
struct drm_mm_node *child;
- child = (struct drm_mm_node *)
- drm_alloc(sizeof(*child), DRM_MEM_MM);
- if (!child)
+ child = drm_mm_kmalloc(mm, atomic);
+ if (unlikely(child == NULL))
return -ENOMEM;
child->free = 1;
@@ -97,8 +151,7 @@
return 0;
}
-
-int drm_mm_add_space_to_tail(struct drm_mm *mm, unsigned long size)
+int drm_mm_add_space_to_tail(struct drm_mm *mm, unsigned long size, int atomic)
{
struct list_head *tail_node;
struct drm_mm_node *entry;
@@ -106,20 +159,21 @@
tail_node = mm->ml_entry.prev;
entry = list_entry(tail_node, struct drm_mm_node, ml_entry);
if (!entry->free) {
- return drm_mm_create_tail_node(mm, entry->start + entry->size, size);
+ return drm_mm_create_tail_node(mm, entry->start + entry->size,
+ size, atomic);
}
entry->size += size;
return 0;
}
static struct drm_mm_node *drm_mm_split_at_start(struct drm_mm_node *parent,
- unsigned long size)
+ unsigned long size,
+ int atomic)
{
struct drm_mm_node *child;
- child = (struct drm_mm_node *)
- drm_alloc(sizeof(*child), DRM_MEM_MM);
- if (!child)
+ child = drm_mm_kmalloc(parent->mm, atomic);
+ if (unlikely(child == NULL))
return NULL;
INIT_LIST_HEAD(&child->fl_entry);
@@ -151,8 +205,9 @@
tmp = parent->start % alignment;
if (tmp) {
- align_splitoff = drm_mm_split_at_start(parent, alignment - tmp);
- if (!align_splitoff)
+ align_splitoff =
+ drm_mm_split_at_start(parent, alignment - tmp, 0);
+ if (unlikely(align_splitoff == NULL))
return NULL;
}
@@ -161,7 +216,7 @@
parent->free = 0;
return parent;
} else {
- child = drm_mm_split_at_start(parent, size);
+ child = drm_mm_split_at_start(parent, size, 0);
}
if (align_splitoff)
@@ -169,14 +224,50 @@
return child;
}
+
EXPORT_SYMBOL(drm_mm_get_block);
+struct drm_mm_node *drm_mm_get_block_atomic(struct drm_mm_node *parent,
+ unsigned long size,
+ unsigned alignment)
+{
+
+ struct drm_mm_node *align_splitoff = NULL;
+ struct drm_mm_node *child;
+ unsigned tmp = 0;
+
+ if (alignment)
+ tmp = parent->start % alignment;
+
+ if (tmp) {
+ align_splitoff =
+ drm_mm_split_at_start(parent, alignment - tmp, 1);
+ if (unlikely(align_splitoff == NULL))
+ return NULL;
+ }
+
+ if (parent->size == size) {
+ list_del_init(&parent->fl_entry);
+ parent->free = 0;
+ return parent;
+ } else {
+ child = drm_mm_split_at_start(parent, size, 1);
+ }
+
+ if (align_splitoff)
+ drm_mm_put_block(align_splitoff);
+
+ return child;
+}
+
+EXPORT_SYMBOL(drm_mm_get_block_atomic);
+
/*
* Put a block. Merge with the previous and / or next block if they are free.
* Otherwise add to the free stack.
*/
-void drm_mm_put_block(struct drm_mm_node * cur)
+void drm_mm_put_block(struct drm_mm_node *cur)
{
struct drm_mm *mm = cur->mm;
@@ -188,21 +279,27 @@
int merged = 0;
if (cur_head->prev != root_head) {
- prev_node = list_entry(cur_head->prev, struct drm_mm_node, ml_entry);
+ prev_node =
+ list_entry(cur_head->prev, struct drm_mm_node, ml_entry);
if (prev_node->free) {
prev_node->size += cur->size;
merged = 1;
}
}
if (cur_head->next != root_head) {
- next_node = list_entry(cur_head->next, struct drm_mm_node, ml_entry);
+ next_node =
+ list_entry(cur_head->next, struct drm_mm_node, ml_entry);
if (next_node->free) {
if (merged) {
prev_node->size += next_node->size;
list_del(&next_node->ml_entry);
list_del(&next_node->fl_entry);
- drm_free(next_node, sizeof(*next_node),
- DRM_MEM_MM);
+ if (mm->num_unused < MM_UNUSED_TARGET) {
+ list_add(&next_node->fl_entry,
+ &mm->unused_nodes);
+ ++mm->num_unused;
+ } else
+ kfree(next_node);
} else {
next_node->size += cur->size;
next_node->start = cur->start;
@@ -215,14 +312,19 @@
list_add(&cur->fl_entry, &mm->fl_entry);
} else {
list_del(&cur->ml_entry);
- drm_free(cur, sizeof(*cur), DRM_MEM_MM);
+ if (mm->num_unused < MM_UNUSED_TARGET) {
+ list_add(&cur->fl_entry, &mm->unused_nodes);
+ ++mm->num_unused;
+ } else
+ kfree(cur);
}
}
+
EXPORT_SYMBOL(drm_mm_put_block);
-struct drm_mm_node *drm_mm_search_free(const struct drm_mm * mm,
- unsigned long size,
- unsigned alignment, int best_match)
+struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm,
+ unsigned long size,
+ unsigned alignment, int best_match)
{
struct list_head *list;
const struct list_head *free_stack = &mm->fl_entry;
@@ -247,7 +349,6 @@
wasted += alignment - tmp;
}
-
if (entry->size >= size + wasted) {
if (!best_match)
return entry;
@@ -260,6 +361,7 @@
return best;
}
+EXPORT_SYMBOL(drm_mm_search_free);
int drm_mm_clean(struct drm_mm * mm)
{
@@ -267,14 +369,17 @@
return (head->next->next == head);
}
-EXPORT_SYMBOL(drm_mm_search_free);
+EXPORT_SYMBOL(drm_mm_clean);
int drm_mm_init(struct drm_mm * mm, unsigned long start, unsigned long size)
{
INIT_LIST_HEAD(&mm->ml_entry);
INIT_LIST_HEAD(&mm->fl_entry);
+ INIT_LIST_HEAD(&mm->unused_nodes);
+ mm->num_unused = 0;
+ spin_lock_init(&mm->unused_lock);
- return drm_mm_create_tail_node(mm, start, size);
+ return drm_mm_create_tail_node(mm, start, size, 0);
}
EXPORT_SYMBOL(drm_mm_init);
@@ -282,6 +387,7 @@
{
struct list_head *bnode = mm->fl_entry.next;
struct drm_mm_node *entry;
+ struct drm_mm_node *next;
entry = list_entry(bnode, struct drm_mm_node, fl_entry);
@@ -293,7 +399,16 @@
list_del(&entry->fl_entry);
list_del(&entry->ml_entry);
+ kfree(entry);
+
+ spin_lock(&mm->unused_lock);
+ list_for_each_entry_safe(entry, next, &mm->unused_nodes, fl_entry) {
+ list_del(&entry->fl_entry);
+ kfree(entry);
+ --mm->num_unused;
+ }
+ spin_unlock(&mm->unused_lock);
- drm_free(entry, sizeof(*entry), DRM_MEM_MM);
+ BUG_ON(mm->num_unused != 0);
}
EXPORT_SYMBOL(drm_mm_takedown);
Index: linux-2.6.28/include/drm/drmP.h
===================================================================
--- linux-2.6.28.orig/include/drm/drmP.h 2009-03-12 13:13:54.000000000 +0000
+++ linux-2.6.28/include/drm/drmP.h 2009-03-12 13:37:59.000000000 +0000
@@ -86,6 +86,7 @@
#include "drm_os_linux.h"
#include "drm_hashtab.h"
+#include "drm_mm.h"
/***********************************************************************/
/** \name DRM template customization defaults */
@@ -502,26 +503,6 @@
};
-/*
- * Generic memory manager structs
- */
-
-struct drm_mm_node {
- struct list_head fl_entry;
- struct list_head ml_entry;
- int free;
- unsigned long start;
- unsigned long size;
- struct drm_mm *mm;
- void *private;
-};
-
-struct drm_mm {
- struct list_head fl_entry;
- struct list_head ml_entry;
-};
-
-
/**
* Mappings list
*/
@@ -1307,22 +1288,6 @@
extern int drm_sysfs_connector_add(struct drm_connector *connector);
extern void drm_sysfs_connector_remove(struct drm_connector *connector);
-/*
- * Basic memory manager support (drm_mm.c)
- */
-extern struct drm_mm_node *drm_mm_get_block(struct drm_mm_node * parent,
- unsigned long size,
- unsigned alignment);
-extern void drm_mm_put_block(struct drm_mm_node * cur);
-extern struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm, unsigned long size,
- unsigned alignment, int best_match);
-extern int drm_mm_init(struct drm_mm *mm, unsigned long start, unsigned long size);
-extern void drm_mm_takedown(struct drm_mm *mm);
-extern int drm_mm_clean(struct drm_mm *mm);
-extern unsigned long drm_mm_tail_space(struct drm_mm *mm);
-extern int drm_mm_remove_space_from_tail(struct drm_mm *mm, unsigned long size);
-extern int drm_mm_add_space_to_tail(struct drm_mm *mm, unsigned long size);
-
/* Graphics Execution Manager library functions (drm_gem.c) */
int drm_gem_init(struct drm_device *dev);
void drm_gem_destroy(struct drm_device *dev);
Index: linux-2.6.28/include/drm/drm_mm.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.28/include/drm/drm_mm.h 2009-03-12 13:15:05.000000000 +0000
@@ -0,0 +1,90 @@
+/**************************************************************************
+ *
+ * Copyright 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX. USA.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ **************************************************************************/
+/*
+ * Authors:
+ * Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
+ */
+
+#ifndef _DRM_MM_H_
+#define _DRM_MM_H_
+
+/*
+ * Generic range manager structs
+ */
+#include <linux/list.h>
+
+struct drm_mm_node {
+ struct list_head fl_entry;
+ struct list_head ml_entry;
+ int free;
+ unsigned long start;
+ unsigned long size;
+ struct drm_mm *mm;
+ void *private;
+};
+
+struct drm_mm {
+ struct list_head fl_entry;
+ struct list_head ml_entry;
+ struct list_head unused_nodes;
+ int num_unused;
+ spinlock_t unused_lock;
+};
+
+/*
+ * Basic range manager support (drm_mm.c)
+ */
+
+extern struct drm_mm_node *drm_mm_get_block(struct drm_mm_node *parent,
+ unsigned long size,
+ unsigned alignment);
+extern struct drm_mm_node *drm_mm_get_block_atomic(struct drm_mm_node *parent,
+ unsigned long size,
+ unsigned alignment);
+extern void drm_mm_put_block(struct drm_mm_node *cur);
+extern struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm,
+ unsigned long size,
+ unsigned alignment,
+ int best_match);
+extern int drm_mm_init(struct drm_mm *mm, unsigned long start,
+ unsigned long size);
+extern void drm_mm_takedown(struct drm_mm *mm);
+extern int drm_mm_clean(struct drm_mm *mm);
+extern unsigned long drm_mm_tail_space(struct drm_mm *mm);
+extern int drm_mm_remove_space_from_tail(struct drm_mm *mm,
+ unsigned long size);
+extern int drm_mm_add_space_to_tail(struct drm_mm *mm,
+ unsigned long size, int atomic);
+extern int drm_mm_pre_get(struct drm_mm *mm);
+
+static inline struct drm_mm *drm_get_mm(struct drm_mm_node *block)
+{
+ return block->mm;
+}
+
+#endif

View File

@ -1,191 +0,0 @@
From cd04a0500d70ea012089ec38183f20c0c30f8ba5 Mon Sep 17 00:00:00 2001
From: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
Date: Fri, 27 Feb 2009 12:31:58 +0100
Subject: [PATCH 2/8] drm: Add a tracker for global objects.
Signed-off-by: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
---
drivers/gpu/drm/Makefile | 3 +-
drivers/gpu/drm/drm_drv.c | 3 +
drivers/gpu/drm/drm_global.c | 107 ++++++++++++++++++++++++++++++++++++++++++
include/drm/drmP.h | 20 ++++++++
4 files changed, 132 insertions(+), 1 deletions(-)
create mode 100644 drivers/gpu/drm/drm_global.c
Index: linux-2.6.28/drivers/gpu/drm/Makefile
===================================================================
--- linux-2.6.28.orig/drivers/gpu/drm/Makefile 2009-03-12 13:13:54.000000000 +0000
+++ linux-2.6.28/drivers/gpu/drm/Makefile 2009-03-12 13:15:18.000000000 +0000
@@ -10,7 +10,8 @@
drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \
drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \
drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o \
- drm_crtc.o drm_crtc_helper.o drm_modes.o drm_edid.o
+ drm_crtc.o drm_crtc_helper.o drm_modes.o drm_edid.o \
+ drm_global.o
drm-$(CONFIG_COMPAT) += drm_ioc32.o
Index: linux-2.6.28/drivers/gpu/drm/drm_drv.c
===================================================================
--- linux-2.6.28.orig/drivers/gpu/drm/drm_drv.c 2009-03-12 13:13:54.000000000 +0000
+++ linux-2.6.28/drivers/gpu/drm/drm_drv.c 2009-03-12 13:37:56.000000000 +0000
@@ -382,6 +382,8 @@
DRM_INFO("Initialized %s %d.%d.%d %s\n",
CORE_NAME, CORE_MAJOR, CORE_MINOR, CORE_PATCHLEVEL, CORE_DATE);
+ drm_global_init();
+
return 0;
err_p3:
drm_sysfs_destroy();
@@ -395,6 +397,7 @@
static void __exit drm_core_exit(void)
{
+ drm_global_release();
remove_proc_entry("dri", NULL);
drm_sysfs_destroy();
Index: linux-2.6.28/drivers/gpu/drm/drm_global.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.28/drivers/gpu/drm/drm_global.c 2009-03-12 13:15:18.000000000 +0000
@@ -0,0 +1,107 @@
+/**************************************************************************
+ *
+ * Copyright 2008-2009 VMware, Inc., Palo Alto, CA., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+#include <drmP.h>
+struct drm_global_item {
+ struct mutex mutex;
+ void *object;
+ int refcount;
+};
+
+static struct drm_global_item glob[DRM_GLOBAL_NUM];
+
+void drm_global_init(void)
+{
+ int i;
+
+ for (i = 0; i < DRM_GLOBAL_NUM; ++i) {
+ struct drm_global_item *item = &glob[i];
+ mutex_init(&item->mutex);
+ item->object = NULL;
+ item->refcount = 0;
+ }
+}
+
+void drm_global_release(void)
+{
+ int i;
+ for (i = 0; i < DRM_GLOBAL_NUM; ++i) {
+ struct drm_global_item *item = &glob[i];
+ BUG_ON(item->object != NULL);
+ BUG_ON(item->refcount != 0);
+ }
+}
+
+int drm_global_item_ref(struct drm_global_reference *ref)
+{
+ int ret;
+ struct drm_global_item *item = &glob[ref->global_type];
+ void *object;
+
+ mutex_lock(&item->mutex);
+ if (item->refcount == 0) {
+ item->object = kmalloc(ref->size, GFP_KERNEL);
+ if (unlikely(item->object == NULL)) {
+ ret = -ENOMEM;
+ goto out_err;
+ }
+
+ ref->object = item->object;
+ ret = ref->init(ref);
+ if (unlikely(ret != 0))
+ goto out_err;
+
+ ++item->refcount;
+ }
+ ref->object = item->object;
+ object = item->object;
+ mutex_unlock(&item->mutex);
+ return 0;
+ out_err:
+ kfree(item->object);
+ mutex_unlock(&item->mutex);
+ item->object = NULL;
+ return ret;
+}
+
+EXPORT_SYMBOL(drm_global_item_ref);
+
+void drm_global_item_unref(struct drm_global_reference *ref)
+{
+ struct drm_global_item *item = &glob[ref->global_type];
+
+ mutex_lock(&item->mutex);
+ BUG_ON(item->refcount == 0);
+ BUG_ON(ref->object != item->object);
+ if (--item->refcount == 0) {
+ ref->release(ref);
+ kfree(item->object);
+ item->object = NULL;
+ }
+ mutex_unlock(&item->mutex);
+}
+
+EXPORT_SYMBOL(drm_global_item_unref);
Index: linux-2.6.28/include/drm/drmP.h
===================================================================
--- linux-2.6.28.orig/include/drm/drmP.h 2009-03-12 13:15:05.000000000 +0000
+++ linux-2.6.28/include/drm/drmP.h 2009-03-12 13:37:56.000000000 +0000
@@ -1412,5 +1412,25 @@
/*@}*/
+enum drm_global_types {
+ DRM_GLOBAL_TTM_MEM = 0,
+ DRM_GLOBAL_TTM_BO,
+ DRM_GLOBAL_TTM_OBJECT,
+ DRM_GLOBAL_NUM
+};
+
+struct drm_global_reference {
+ enum drm_global_types global_type;
+ size_t size;
+ void *object;
+ int (*init) (struct drm_global_reference *);
+ void (*release) (struct drm_global_reference *);
+};
+
+extern void drm_global_init(void);
+extern void drm_global_release(void);
+extern int drm_global_item_ref(struct drm_global_reference *ref);
+extern void drm_global_item_unref(struct drm_global_reference *ref);
+
#endif /* __KERNEL__ */
#endif

View File

@ -1,58 +0,0 @@
From 723cc597790fb648506a44e811415eb88b9dcdfa Mon Sep 17 00:00:00 2001
From: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
Date: Fri, 27 Feb 2009 17:18:37 +0100
Subject: [PATCH 3/8] drm: Export hash table functionality.
Also fix include file.
Signed-off-by: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
---
drivers/gpu/drm/drm_hashtab.c | 4 ++++
include/drm/drm_hashtab.h | 1 +
2 files changed, 5 insertions(+), 0 deletions(-)
Index: linux-2.6.28/drivers/gpu/drm/drm_hashtab.c
===================================================================
--- linux-2.6.28.orig/drivers/gpu/drm/drm_hashtab.c 2009-03-09 19:19:52.000000000 +0000
+++ linux-2.6.28/drivers/gpu/drm/drm_hashtab.c 2009-03-12 13:15:25.000000000 +0000
@@ -62,6 +62,7 @@
}
return 0;
}
+EXPORT_SYMBOL(drm_ht_create);
void drm_ht_verbose_list(struct drm_open_hash *ht, unsigned long key)
{
@@ -156,6 +157,7 @@
}
return 0;
}
+EXPORT_SYMBOL(drm_ht_just_insert_please);
int drm_ht_find_item(struct drm_open_hash *ht, unsigned long key,
struct drm_hash_item **item)
@@ -169,6 +171,7 @@
*item = hlist_entry(list, struct drm_hash_item, head);
return 0;
}
+EXPORT_SYMBOL(drm_ht_find_item);
int drm_ht_remove_key(struct drm_open_hash *ht, unsigned long key)
{
@@ -202,3 +205,4 @@
ht->table = NULL;
}
}
+EXPORT_SYMBOL(drm_ht_remove);
Index: linux-2.6.28/include/drm/drm_hashtab.h
===================================================================
--- linux-2.6.28.orig/include/drm/drm_hashtab.h 2008-12-24 23:26:37.000000000 +0000
+++ linux-2.6.28/include/drm/drm_hashtab.h 2009-03-12 13:15:25.000000000 +0000
@@ -34,6 +34,7 @@
#ifndef DRM_HASHTAB_H
#define DRM_HASHTAB_H
+#include <linux/list.h>
#define drm_hash_entry(_ptr, _type, _member) container_of(_ptr, _type, _member)

View File

@ -1,53 +0,0 @@
From a5fef5986c407d56f4e4cf618d6099e122a096ef Mon Sep 17 00:00:00 2001
From: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
Date: Fri, 27 Feb 2009 13:04:46 +0100
Subject: [PATCH 7/8] drm: Add unlocked IOCTL functionality from the drm repo.
---
drivers/gpu/drm/drm_drv.c | 11 ++++++++++-
include/drm/drmP.h | 2 ++
2 files changed, 12 insertions(+), 1 deletions(-)
Index: linux-2.6.28/drivers/gpu/drm/drm_drv.c
===================================================================
--- linux-2.6.28.orig/drivers/gpu/drm/drm_drv.c 2009-03-12 13:15:18.000000000 +0000
+++ linux-2.6.28/drivers/gpu/drm/drm_drv.c 2009-03-12 13:15:41.000000000 +0000
@@ -448,9 +450,16 @@
* 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,
unsigned int cmd, unsigned long arg)
{
+ return drm_unlocked_ioctl(filp, cmd, arg);
+}
+EXPORT_SYMBOL(drm_ioctl);
+
+long drm_unlocked_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_ioctl_desc *ioctl;
@@ -527,7 +536,7 @@
return retcode;
}
-EXPORT_SYMBOL(drm_ioctl);
+EXPORT_SYMBOL(drm_unlocked_ioctl);
drm_local_map_t *drm_getsarea(struct drm_device *dev)
{
Index: linux-2.6.28/include/drm/drmP.h
===================================================================
--- linux-2.6.28.orig/include/drm/drmP.h 2009-03-12 13:15:18.000000000 +0000
+++ linux-2.6.28/include/drm/drmP.h 2009-03-12 13:15:41.000000000 +0000
@@ -1025,6 +1025,8 @@
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_unlocked_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);

File diff suppressed because it is too large Load Diff

View File

@ -1,127 +0,0 @@
CONFIG_LOCALVERSION="-ivi"
CONFIG_INTEL_MENLOW=y
CONFIG_DRM_PSB=y
#
# Cgroups
#
CONFIG_CGROUPS=y
# CONFIG_CGROUP_DEBUG is not set
CONFIG_CGROUP_NS=y
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_DEVICE=y
# CONFIG_CPUSETS is not set
# CONFIG_CGROUP_CPUACCT is not set
# CONFIG_RESOURCE_COUNTERS is not set
CONFIG_4KSTACKS=y
CONFIG_ACER_WMI=y
CONFIG_ARCH_WANT_FRAME_POINTERS=y
# CONFIG_ATH5K_DEBUG is not set
CONFIG_ATH5K=y
CONFIG_ATL1E=y
# CONFIG_BNX2X is not set
CONFIG_CHELSIO_T3_DEPENDS=y
CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_CRYPTO_AEAD2=y
CONFIG_CRYPTO_AEAD=m
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_MANAGER2=y
CONFIG_CRYPTO_RNG2=y
CONFIG_CRYPTO_RNG=m
# CONFIG_DEBUG_NOTIFIERS is not set
# CONFIG_DEBUG_SPINLOCK is not set
CONFIG_EEEPC_LAPTOP=y
# CONFIG_EEPROM_AT25 is not set
# CONFIG_ENC28J60 is not set
# CONFIG_FB_BACKLIGHT is not set
# CONFIG_FB_BOOT_VESA_SUPPORT is not set
CONFIG_FB_CFB_COPYAREA=y
CONFIG_FB_CFB_FILLRECT=y
CONFIG_FB_CFB_IMAGEBLIT=y
# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
# CONFIG_FB_DDC is not set
# CONFIG_FB_MACMODES is not set
CONFIG_FB_MODE_HELPERS=y
# CONFIG_FB_SVGALIB is not set
# CONFIG_FB_SYS_COPYAREA is not set
# CONFIG_FB_SYS_FILLRECT is not set
# CONFIG_FB_SYS_FOPS is not set
# CONFIG_FB_SYS_IMAGEBLIT is not set
# CONFIG_FB_TMIO is not set
CONFIG_GENERIC_FIND_LAST_BIT=y
CONFIG_GENERIC_GPIO=y
CONFIG_GPIOLIB=y
# CONFIG_GPIO_MAX7301 is not set
# CONFIG_GPIO_MCP23S08 is not set
CONFIG_GPIO_SYSFS=y
CONFIG_GPIO_TIMBERDALE=y
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
CONFIG_HAVE_MMIOTRACE_SUPPORT=y
CONFIG_HID_NTRIG=y
CONFIG_HID_TOPSEED=y
CONFIG_I2C_ALGOBIT=y
CONFIG_I2C_CHARDEV=m
CONFIG_I2C_OCORES=m
# CONFIG_IOMMU_API is not set
# CONFIG_KS8842 is not set
CONFIG_LIBIPW=m
CONFIG_MAC80211_RC_DEFAULT="minstrel"
CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
# CONFIG_MAC80211_RC_DEFAULT_PID is not set
CONFIG_MAC80211_RC_MINSTREL=y
CONFIG_MFD_CORE=y
CONFIG_MFD_TIMBERDALE_DMA=m
CONFIG_MFD_TIMBERDALE_I2S=m
CONFIG_MFD_TIMBERDALE=y
CONFIG_MMC_SDHCI_PLTFM=m
# CONFIG_MOUSE_PS2_TOUCHKIT is not set
# CONFIG_PREEMPT is not set
# CONFIG_PREEMPT_RCU is not set
# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_PREEMPT_VOLUNTARY=y
CONFIG_R8169=y
# CONFIG_RT2860 is not set
# CONFIG_RT2870 is not set
# CONFIG_RTC_DRV_DS1305 is not set
# CONFIG_RTC_DRV_DS1390 is not set
# CONFIG_RTC_DRV_DS3234 is not set
# CONFIG_RTC_DRV_M41T94 is not set
# CONFIG_RTC_DRV_MAX6902 is not set
# CONFIG_RTC_DRV_R9701 is not set
# CONFIG_RTC_DRV_RS5C348 is not set
CONFIG_SCSI_FC_ATTRS=m
CONFIG_SCSI_NETLINK=y
CONFIG_SCSI_SAS_ATTRS=m
CONFIG_SCSI_SPI_ATTRS=m
# CONFIG_SENSORS_ADCXX is not set
# CONFIG_SENSORS_LM70 is not set
# CONFIG_SENSORS_MAX1111 is not set
CONFIG_SERIAL_TIMBERDALE=m
CONFIG_SND_HDA_ELD=y
CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0
CONFIG_SND_JACK=y
CONFIG_SND_SPI=y
CONFIG_SPI_BITBANG=m
# CONFIG_SPI_DEBUG is not set
# CONFIG_SPI_GPIO is not set
CONFIG_SPI_MASTER=y
# CONFIG_SPI_SPIDEV is not set
# CONFIG_SPI_TLE62X0 is not set
CONFIG_SPI_XILINX=m
CONFIG_SPI_XILINX_PLTFM=m
CONFIG_SPI=y
# CONFIG_TOUCHSCREEN_ADS7846 is not set
CONFIG_TOUCHSCREEN_TSC2003=m
CONFIG_TOUCHSCREEN_TSC2007=m
CONFIG_TRACEPOINTS=y
# CONFIG_TREE_RCU is not set
# CONFIG_TREE_RCU_TRACE is not set
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_USER_STACKTRACE_SUPPORT=y
CONFIG_VGASTATE=m
CONFIG_VIDEO_TIMBERDALE=m
CONFIG_WIMAX_I2400M=m

View File

@ -1,8 +0,0 @@
CONFIG_LOCALVERSION="-menlow"
CONFIG_INTEL_MENLOW=y
CONFIG_DRM_PSB=y
# LIBERTAS works with Menlow sd8686
CONFIG_LIBERTAS=m
CONFIG_LIBERTAS_SDIO=m

File diff suppressed because it is too large Load Diff

View File

@ -1,52 +0,0 @@
CONFIG_LOCALVERSION="-netbook"
CONFIG_ACER_WMI=y
CONFIG_EEEPC_LAPTOP=m
CONFIG_R8169=y
# CONFIG_R8169_VLAN is not set
CONFIG_ATL1E=y
CONFIG_ATH5K=y
# CONFIG_ATH5K_DEBUG is not set
CONFIG_RT2860=m
CONFIG_RT2860=m
CONFIG_RTL8187SE=m
CONFIG_DRM_I915_KMS=y
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
CONFIG_FONTS=y
CONFIG_FONT_8x8=y
CONFIG_FONT_6x11=y
CONFIG_FONT_7x14=y
# CONFIG_FONT_PEARL_8x8 is not set
# CONFIG_FONT_ACORN_8x8 is not set
# CONFIG_FONT_MINI_4x6 is not set
# CONFIG_FONT_SUN8x16 is not set
# CONFIG_FONT_SUN12x22 is not set
CONFIG_FONT_10x18=y
#
# Enable KVM
#
CONFIG_VIRTUALIZATION=y
CONFIG_KVM=m
CONFIG_KVM_INTEL=m
# CONFIG_KVM_AMD is not set
# CONFIG_KVM_TRACE is not set
# CONFIG_VIRTIO_PCI is not set
# CONFIG_VIRTIO_BALLOON is not set
#
# For VMWARE support
#
CONFIG_FUSION_SPI=y

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,128 +0,0 @@
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index 32e8c5a..8020453 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -24,6 +24,11 @@ oldconfig: $(obj)/conf
silentoldconfig: $(obj)/conf
$< -s $(Kconfig)
+nonint_oldconfig: $(obj)/conf
+ $< -b $(Kconfig)
+loose_nonint_oldconfig: $(obj)/conf
+ $< -B $(Kconfig)
+
# Create new linux.pot file
# Adjust charset to UTF-8 in .po file to accept UTF-8 in Kconfig files
# The symlink is used to repair a deficiency in arch/um
diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c
index fda6313..ed33b66 100644
--- a/scripts/kconfig/conf.c
+++ b/scripts/kconfig/conf.c
@@ -22,6 +22,8 @@
ask_all,
ask_new,
ask_silent,
+ dont_ask,
+ dont_ask_dont_tell,
set_default,
set_yes,
set_mod,
@@ -39,6 +41,8 @@
static char nohelp_text[] = N_("Sorry, no help available for this option yet.\n");
+static int return_value = 0;
+
static const char *get_help(struct menu *menu)
{
if (menu_has_help(menu))
@@ -359,7 +363,10 @@
switch (prop->type) {
case P_MENU:
- if (input_mode == ask_silent && rootEntry != menu) {
+ if ((input_mode == ask_silent ||
+ input_mode == dont_ask ||
+ input_mode == dont_ask_dont_tell) &&
+ rootEntry != menu) {
check_conf(menu);
return;
}
@@ -417,12 +424,21 @@
if (sym && !sym_has_value(sym)) {
if (sym_is_changable(sym) ||
(sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) {
+ if (input_mode == dont_ask ||
+ input_mode == dont_ask_dont_tell) {
+ if (input_mode == dont_ask &&
+ sym->name && !sym_is_choice_value(sym)) {
+ fprintf(stderr,"CONFIG_%s\n",sym->name);
+ ++return_value;
+ }
+ } else {
if (!conf_cnt++)
printf(_("*\n* Restart config...\n*\n"));
rootEntry = menu_get_parent_menu(menu);
conf(rootEntry);
}
}
+ }
for (child = menu->list; child; child = child->next)
check_conf(child);
@@ -438,7 +454,7 @@
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
- while ((opt = getopt(ac, av, "osdD:nmyrh")) != -1) {
+ while ((opt = getopt(ac, av, "osbBdD:nmyrh")) != -1) {
switch (opt) {
case 'o':
input_mode = ask_silent;
@@ -447,6 +463,12 @@
input_mode = ask_silent;
sync_kconfig = 1;
break;
+ case 'b':
+ input_mode = dont_ask;
+ break;
+ case 'B':
+ input_mode = dont_ask_dont_tell;
+ break;
case 'd':
input_mode = set_default;
break;
@@ -510,6 +532,8 @@
case ask_silent:
case ask_all:
case ask_new:
+ case dont_ask:
+ case dont_ask_dont_tell:
conf_read(NULL);
break;
case set_no:
@@ -571,12 +595,16 @@
conf(&rootmenu);
input_mode = ask_silent;
/* fall through */
+ case dont_ask:
+ case dont_ask_dont_tell:
case ask_silent:
/* Update until a loop caused no more changes */
do {
conf_cnt = 0;
check_conf(&rootmenu);
- } while (conf_cnt);
+ } while (conf_cnt &&
+ (input_mode != dont_ask &&
+ input_mode != dont_ask_dont_tell));
break;
}
@@ -598,5 +626,5 @@
exit(1);
}
}
- return 0;
+ return return_value;
}

View File

@ -1,11 +0,0 @@
--- linux-2.6.28/drivers/gpu/drm/i915/i915_drv.c~ 2009-02-20 21:36:06.000000000 -0800
+++ linux-2.6.28/drivers/gpu/drm/i915/i915_drv.c 2009-02-20 21:36:06.000000000 -0800
@@ -35,7 +35,7 @@
#include "drm_pciids.h"
#include <linux/console.h>
-static unsigned int i915_modeset = -1;
+static unsigned int i915_modeset = 1;
module_param_named(modeset, i915_modeset, int, 0400);
unsigned int i915_fbpercrtc = 0;

View File

@ -1,43 +0,0 @@
From dce8113d033975f56630cf6d2a6a908cfb66059d Mon Sep 17 00:00:00 2001
From: Arjan van de Ven <arjan@linux.intel.com>
Date: Sun, 20 Jul 2008 13:12:16 -0700
Subject: [PATCH] fastboot: remove "wait for all devices before mounting root" delay
In the non-initrd case, we wait for all devices to finish their
probing before we try to mount the rootfs.
In practice, this means that we end up waiting 2 extra seconds for
the PS/2 mouse probing even though the root holding device has been
ready since a long time.
The previous two patches in this series made the RAID autodetect code
do it's own "wait for probing to be done" code, and added
"wait and retry" functionality in case the root device isn't actually
available.
These two changes should make it safe to remove the delay itself,
and this patch does this. On my test laptop, this reduces the boot time
by 2 seconds (kernel time goes from 3.9 to 1.9 seconds).
Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
---
--- a/init/do_mounts.c 2009-01-07 18:42:10.000000000 -0800
+++ b/init/do_mounts.c 2009-01-07 18:43:02.000000000 -0800
@@ -370,14 +370,17 @@ void __init prepare_namespace(void)
ssleep(root_delay);
}
+#if 0
/*
* wait for the known devices to complete their probing
*
* Note: this is a potential source of long boot delays.
* For example, it is not atypical to wait 5 seconds here
* for the touchpad of a laptop to initialize.
*/
wait_for_device_probe();
+#endif
+ async_synchronize_full();
md_run_setup();

View File

@ -1,56 +0,0 @@
From 2b5cde2b272f56ec67b56a2af8c067d42eff7328 Mon Sep 17 00:00:00 2001
From: Li Peng <peng.li@intel.com>
Date: Fri, 13 Mar 2009 10:25:07 +0800
Subject: drm/i915: Fix LVDS dither setting
Update bdb_lvds_options structure according to its defination in
2D driver. Then we can parse and set 'lvds_dither' bit correctly
on non-965 chips.
Signed-off-by: Li Peng <peng.li@intel.com>
Signed-off-by: Eric Anholt <eric@anholt.net>
---
drivers/gpu/drm/i915/intel_bios.h | 12 ++++++------
drivers/gpu/drm/i915/intel_lvds.c | 2 +-
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h
index 5ea715a..de621aa 100644
--- a/drivers/gpu/drm/i915/intel_bios.h
+++ b/drivers/gpu/drm/i915/intel_bios.h
@@ -162,13 +162,13 @@ struct bdb_lvds_options {
u8 panel_type;
u8 rsvd1;
/* LVDS capabilities, stored in a dword */
- u8 rsvd2:1;
- u8 lvds_edid:1;
- u8 pixel_dither:1;
- u8 pfit_ratio_auto:1;
- u8 pfit_gfx_mode_enhanced:1;
- u8 pfit_text_mode_enhanced:1;
u8 pfit_mode:2;
+ u8 pfit_text_mode_enhanced:1;
+ u8 pfit_gfx_mode_enhanced:1;
+ u8 pfit_ratio_auto:1;
+ u8 pixel_dither:1;
+ u8 lvds_edid:1;
+ u8 rsvd2:1;
u8 rsvd4;
} __attribute__((packed));
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 0d211af..6619f26 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -265,7 +265,7 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder,
pfit_control = 0;
if (!IS_I965G(dev)) {
- if (dev_priv->panel_wants_dither)
+ if (dev_priv->panel_wants_dither || dev_priv->lvds_dither)
pfit_control |= PANEL_8TO6_DITHER_ENABLE;
}
else
--
1.6.1.3

View File

@ -1,55 +0,0 @@
From ee977685870767221dc763338bb6ed5fd83f65be Mon Sep 17 00:00:00 2001
From: Yong Wang <yong.y.wang@intel.com>
Date: Tue, 6 Jan 2009 15:13:41 +0800
Subject: [PATCH] Revert "drm/i915: GEM on PAE has problems - disable it for now."
This reverts commit ac5c4e76180a74c7f922f6fa71ace0cef45fa433.
---
drivers/gpu/drm/i915/i915_dma.c | 10 +---------
drivers/gpu/drm/i915/i915_drv.h | 2 --
2 files changed, 1 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index afa8a12..553dd4b 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -717,7 +717,7 @@ static int i915_getparam(struct drm_device *dev, void *data,
value = dev->pci_device;
break;
case I915_PARAM_HAS_GEM:
- value = dev_priv->has_gem;
+ value = 1;
break;
default:
DRM_ERROR("Unknown parameter %d\n", param->param);
@@ -830,14 +830,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
"performance may suffer.\n");
}
-#ifdef CONFIG_HIGHMEM64G
- /* don't enable GEM on PAE - needs agp + set_memory_* interface fixes */
- dev_priv->has_gem = 0;
-#else
- /* enable GEM by default */
- dev_priv->has_gem = 1;
-#endif
-
dev->driver->get_vblank_counter = i915_get_vblank_counter;
if (IS_GM45(dev))
dev->driver->get_vblank_counter = gm45_get_vblank_counter;
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index b3cc473..adc972c 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -106,8 +106,6 @@ struct intel_opregion {
typedef struct drm_i915_private {
struct drm_device *dev;
- int has_gem;
-
void __iomem *regs;
drm_local_map_t *sarea;
--
1.5.5.1

View File

@ -1,208 +0,0 @@
From b55de80e49892002a1878013ab9aee1a30970be6 Mon Sep 17 00:00:00 2001
From: Bruce Allan <bruce.w.allan@intel.com>
Date: Sat, 21 Mar 2009 13:25:25 -0700
Subject: [PATCH] e100: add support for 82552 10/100 adapter
This patch enables support for the new Intel 82552 adapter (new PHY paired
with the existing MAC in the ICH7 chipset). No new features are added to
the driver, however there are minor changes due to updated registers and a
few workarounds for hardware errata.
Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/e100.c | 93 +++++++++++++++++++++++++++++++++++++++++++---------
1 files changed, 77 insertions(+), 16 deletions(-)
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index 861d2ee..0504db9 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -167,7 +167,7 @@
#define DRV_NAME "e100"
#define DRV_EXT "-NAPI"
-#define DRV_VERSION "3.5.23-k6"DRV_EXT
+#define DRV_VERSION "3.5.24-k2"DRV_EXT
#define DRV_DESCRIPTION "Intel(R) PRO/100 Network Driver"
#define DRV_COPYRIGHT "Copyright(c) 1999-2006 Intel Corporation"
#define PFX DRV_NAME ": "
@@ -240,6 +240,7 @@ static struct pci_device_id e100_id_table[] = {
INTEL_8255X_ETHERNET_DEVICE(0x1093, 7),
INTEL_8255X_ETHERNET_DEVICE(0x1094, 7),
INTEL_8255X_ETHERNET_DEVICE(0x1095, 7),
+ INTEL_8255X_ETHERNET_DEVICE(0x10fe, 7),
INTEL_8255X_ETHERNET_DEVICE(0x1209, 0),
INTEL_8255X_ETHERNET_DEVICE(0x1229, 0),
INTEL_8255X_ETHERNET_DEVICE(0x2449, 2),
@@ -275,6 +276,7 @@ enum phy {
phy_82562_em = 0x032002A8,
phy_82562_ek = 0x031002A8,
phy_82562_eh = 0x017002A8,
+ phy_82552_v = 0xd061004d,
phy_unknown = 0xFFFFFFFF,
};
@@ -943,6 +945,22 @@ static int mdio_read(struct net_device *netdev, int addr, int reg)
static void mdio_write(struct net_device *netdev, int addr, int reg, int data)
{
+ struct nic *nic = netdev_priv(netdev);
+
+ if ((nic->phy == phy_82552_v) && (reg == MII_BMCR) &&
+ (data & (BMCR_ANRESTART | BMCR_ANENABLE))) {
+ u16 advert = mdio_read(netdev, nic->mii.phy_id, MII_ADVERTISE);
+
+ /*
+ * Workaround Si issue where sometimes the part will not
+ * autoneg to 100Mbps even when advertised.
+ */
+ if (advert & ADVERTISE_100FULL)
+ data |= BMCR_SPEED100 | BMCR_FULLDPLX;
+ else if (advert & ADVERTISE_100HALF)
+ data |= BMCR_SPEED100;
+ }
+
mdio_ctrl(netdev_priv(netdev), addr, mdi_write, reg, data);
}
@@ -1276,16 +1294,12 @@ static int e100_phy_init(struct nic *nic)
if (addr == 32)
return -EAGAIN;
- /* Selected the phy and isolate the rest */
- for (addr = 0; addr < 32; addr++) {
- if (addr != nic->mii.phy_id) {
- mdio_write(netdev, addr, MII_BMCR, BMCR_ISOLATE);
- } else {
- bmcr = mdio_read(netdev, addr, MII_BMCR);
- mdio_write(netdev, addr, MII_BMCR,
- bmcr & ~BMCR_ISOLATE);
- }
- }
+ /* Isolate all the PHY ids */
+ for (addr = 0; addr < 32; addr++)
+ mdio_write(netdev, addr, MII_BMCR, BMCR_ISOLATE);
+ /* Select the discovered PHY */
+ bmcr &= ~BMCR_ISOLATE;
+ mdio_write(netdev, nic->mii.phy_id, MII_BMCR, bmcr);
/* Get phy ID */
id_lo = mdio_read(netdev, nic->mii.phy_id, MII_PHYSID1);
@@ -1303,7 +1317,18 @@ static int e100_phy_init(struct nic *nic)
mdio_write(netdev, nic->mii.phy_id, MII_NSC_CONG, cong);
}
- if ((nic->mac >= mac_82550_D102) || ((nic->flags & ich) &&
+ if (nic->phy == phy_82552_v) {
+ u16 advert = mdio_read(netdev, nic->mii.phy_id, MII_ADVERTISE);
+
+ /* Workaround Si not advertising flow-control during autoneg */
+ advert |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
+ mdio_write(netdev, nic->mii.phy_id, MII_ADVERTISE, advert);
+
+ /* Reset for the above changes to take effect */
+ bmcr = mdio_read(netdev, nic->mii.phy_id, MII_BMCR);
+ bmcr |= BMCR_RESET;
+ mdio_write(netdev, nic->mii.phy_id, MII_BMCR, bmcr);
+ } else if ((nic->mac >= mac_82550_D102) || ((nic->flags & ich) &&
(mdio_read(netdev, nic->mii.phy_id, MII_TPISTATUS) & 0x8000) &&
!(nic->eeprom[eeprom_cnfg_mdix] & eeprom_mdix_enabled))) {
/* enable/disable MDI/MDI-X auto-switching. */
@@ -2134,6 +2159,9 @@ err_clean_rx:
}
#define MII_LED_CONTROL 0x1B
+#define E100_82552_LED_OVERRIDE 0x19
+#define E100_82552_LED_ON 0x000F /* LEDTX and LED_RX both on */
+#define E100_82552_LED_OFF 0x000A /* LEDTX and LED_RX both off */
static void e100_blink_led(unsigned long data)
{
struct nic *nic = (struct nic *)data;
@@ -2143,10 +2171,19 @@ static void e100_blink_led(unsigned long data)
led_on_559 = 0x05,
led_on_557 = 0x07,
};
+ u16 led_reg = MII_LED_CONTROL;
+
+ if (nic->phy == phy_82552_v) {
+ led_reg = E100_82552_LED_OVERRIDE;
- nic->leds = (nic->leds & led_on) ? led_off :
- (nic->mac < mac_82559_D101M) ? led_on_557 : led_on_559;
- mdio_write(nic->netdev, nic->mii.phy_id, MII_LED_CONTROL, nic->leds);
+ nic->leds = (nic->leds == E100_82552_LED_ON) ?
+ E100_82552_LED_OFF : E100_82552_LED_ON;
+ } else {
+ nic->leds = (nic->leds & led_on) ? led_off :
+ (nic->mac < mac_82559_D101M) ? led_on_557 :
+ led_on_559;
+ }
+ mdio_write(nic->netdev, nic->mii.phy_id, led_reg, nic->leds);
mod_timer(&nic->blink_timer, jiffies + HZ / 4);
}
@@ -2375,13 +2412,15 @@ static void e100_diag_test(struct net_device *netdev,
static int e100_phys_id(struct net_device *netdev, u32 data)
{
struct nic *nic = netdev_priv(netdev);
+ u16 led_reg = (nic->phy == phy_82552_v) ? E100_82552_LED_OVERRIDE :
+ MII_LED_CONTROL;
if (!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ))
data = (u32)(MAX_SCHEDULE_TIMEOUT / HZ);
mod_timer(&nic->blink_timer, jiffies);
msleep_interruptible(data * 1000);
del_timer_sync(&nic->blink_timer);
- mdio_write(netdev, nic->mii.phy_id, MII_LED_CONTROL, 0);
+ mdio_write(netdev, nic->mii.phy_id, led_reg, 0);
return 0;
}
@@ -2686,6 +2725,9 @@ static void __devexit e100_remove(struct pci_dev *pdev)
}
}
+#define E100_82552_SMARTSPEED 0x14 /* SmartSpeed Ctrl register */
+#define E100_82552_REV_ANEG 0x0200 /* Reverse auto-negotiation */
+#define E100_82552_ANEG_NOW 0x0400 /* Auto-negotiate now */
static int e100_suspend(struct pci_dev *pdev, pm_message_t state)
{
struct net_device *netdev = pci_get_drvdata(pdev);
@@ -2698,6 +2740,15 @@ static int e100_suspend(struct pci_dev *pdev, pm_message_t state)
pci_save_state(pdev);
if ((nic->flags & wol_magic) | e100_asf(nic)) {
+ /* enable reverse auto-negotiation */
+ if (nic->phy == phy_82552_v) {
+ u16 smartspeed = mdio_read(netdev, nic->mii.phy_id,
+ E100_82552_SMARTSPEED);
+
+ mdio_write(netdev, nic->mii.phy_id,
+ E100_82552_SMARTSPEED, smartspeed |
+ E100_82552_REV_ANEG | E100_82552_ANEG_NOW);
+ }
if (pci_enable_wake(pdev, PCI_D3cold, true))
pci_enable_wake(pdev, PCI_D3hot, true);
} else {
@@ -2721,6 +2772,16 @@ static int e100_resume(struct pci_dev *pdev)
/* ack any pending wake events, disable PME */
pci_enable_wake(pdev, 0, 0);
+ /* disbale reverse auto-negotiation */
+ if (nic->phy == phy_82552_v) {
+ u16 smartspeed = mdio_read(netdev, nic->mii.phy_id,
+ E100_82552_SMARTSPEED);
+
+ mdio_write(netdev, nic->mii.phy_id,
+ E100_82552_SMARTSPEED,
+ smartspeed & ~(E100_82552_REV_ANEG));
+ }
+
netif_device_attach(netdev);
if (netif_running(netdev))
e100_up(nic);
--
1.5.5.1

View File

@ -1,12 +0,0 @@
--- a/kernel/async.c 2009-01-19 18:30:29.000000000 -0800
+++ b/kernel/async.c 2009-01-19 18:31:12.000000000 -0800
@@ -65,7 +65,7 @@ static LIST_HEAD(async_pending);
static LIST_HEAD(async_running);
static DEFINE_SPINLOCK(async_lock);
-static int async_enabled = 0;
+static int async_enabled = 1;
struct async_entry {
struct list_head list;

View File

@ -1,20 +0,0 @@
--- linux-2.6.28/drivers/gpu/drm/i915/intel_lvds.c.org 2009-03-21 19:57:13.000000000 -0700
+++ linux-2.6.28/drivers/gpu/drm/i915/intel_lvds.c 2009-03-21 19:57:25.000000000 -0700
@@ -221,7 +221,7 @@ static void intel_lvds_prepare(struct dr
dev_priv->backlight_duty_cycle = (dev_priv->saveBLC_PWM_CTL &
BACKLIGHT_DUTY_CYCLE_MASK);
- intel_lvds_set_power(dev, false);
+// intel_lvds_set_power(dev, false);
}
static void intel_lvds_commit( struct drm_encoder *encoder)
@@ -233,7 +233,7 @@ static void intel_lvds_commit( struct dr
dev_priv->backlight_duty_cycle =
intel_lvds_get_max_backlight(dev);
- intel_lvds_set_power(dev, true);
+// intel_lvds_set_power(dev, true);
}
static void intel_lvds_mode_set(struct drm_encoder *encoder,

View File

@ -1,161 +0,0 @@
From 24559ecf972ff482222f6fc152f15468d2380e2d Mon Sep 17 00:00:00 2001
From: Li, Shaohua <shaohua.li@intel.com>
Date: Wed, 13 Aug 2008 17:26:01 +0800
Subject: [PATCH] fastboot: remove duplicate unpack_to_rootfs()
we check if initrd is initramfs first and then do real unpack. The
check isn't required, we can directly do unpack. If initrd isn't
initramfs, we can remove garbage. In my laptop, this saves 0.1s boot
time. This penalizes non-initramfs case, but now initramfs is mostly
widely used.
Signed-off-by: Shaohua Li <shaohua.li@intel.com>
Acked-by: Arjan van de Ven <arjan@infradead.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
init/initramfs.c | 71 ++++++++++++++++++++++++++++++++++++++++++-----------
1 files changed, 56 insertions(+), 15 deletions(-)
diff --git a/init/initramfs.c b/init/initramfs.c
index 4f5ba75..6b5c1dc 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -5,6 +5,7 @@
#include <linux/fcntl.h>
#include <linux/delay.h>
#include <linux/string.h>
+#include <linux/dirent.h>
#include <linux/syscalls.h>
#include <linux/utime.h>
@@ -166,8 +167,6 @@ static __initdata char *victim;
static __initdata unsigned count;
static __initdata loff_t this_header, next_header;
-static __initdata int dry_run;
-
static inline void __init eat(unsigned n)
{
victim += n;
@@ -229,10 +228,6 @@ static int __init do_header(void)
parse_header(collected);
next_header = this_header + N_ALIGN(name_len) + body_len;
next_header = (next_header + 3) & ~3;
- if (dry_run) {
- read_into(name_buf, N_ALIGN(name_len), GotName);
- return 0;
- }
state = SkipIt;
if (name_len <= 0 || name_len > PATH_MAX)
return 0;
@@ -303,8 +298,6 @@ static int __init do_name(void)
free_hash();
return 0;
}
- if (dry_run)
- return 0;
clean_path(collected, mode);
if (S_ISREG(mode)) {
int ml = maybe_link();
@@ -475,10 +468,9 @@ static void __init flush_window(void)
outcnt = 0;
}
-static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only)
+static char * __init unpack_to_rootfs(char *buf, unsigned len)
{
int written;
- dry_run = check_only;
header_buf = kmalloc(110, GFP_KERNEL);
symlink_buf = kmalloc(PATH_MAX + N_ALIGN(PATH_MAX) + 1, GFP_KERNEL);
name_buf = kmalloc(N_ALIGN(PATH_MAX), GFP_KERNEL);
@@ -573,10 +565,57 @@ skip:
initrd_end = 0;
}
+#define BUF_SIZE 1024
+static void __init clean_rootfs(void)
+{
+ int fd;
+ void *buf;
+ struct linux_dirent64 *dirp;
+ int count;
+
+ fd = sys_open("/", O_RDONLY, 0);
+ WARN_ON(fd < 0);
+ if (fd < 0)
+ return;
+ buf = kzalloc(BUF_SIZE, GFP_KERNEL);
+ WARN_ON(!buf);
+ if (!buf) {
+ sys_close(fd);
+ return;
+ }
+
+ dirp = buf;
+ count = sys_getdents64(fd, dirp, BUF_SIZE);
+ while (count > 0) {
+ while (count > 0) {
+ struct stat st;
+ int ret;
+
+ ret = sys_newlstat(dirp->d_name, &st);
+ WARN_ON_ONCE(ret);
+ if (!ret) {
+ if (S_ISDIR(st.st_mode))
+ sys_rmdir(dirp->d_name);
+ else
+ sys_unlink(dirp->d_name);
+ }
+
+ count -= dirp->d_reclen;
+ dirp = (void *)dirp + dirp->d_reclen;
+ }
+ dirp = buf;
+ memset(buf, 0, BUF_SIZE);
+ count = sys_getdents64(fd, dirp, BUF_SIZE);
+ }
+
+ sys_close(fd);
+ kfree(buf);
+}
+
static int __init populate_rootfs(void)
{
char *err = unpack_to_rootfs(__initramfs_start,
- __initramfs_end - __initramfs_start, 0);
+ __initramfs_end - __initramfs_start);
if (err)
panic(err);
if (initrd_start) {
@@ -584,13 +623,15 @@ static int __init populate_rootfs(void)
int fd;
printk(KERN_INFO "checking if image is initramfs...");
err = unpack_to_rootfs((char *)initrd_start,
- initrd_end - initrd_start, 1);
+ initrd_end - initrd_start);
if (!err) {
printk(" it is\n");
- unpack_to_rootfs((char *)initrd_start,
- initrd_end - initrd_start, 0);
free_initrd();
return 0;
+ } else {
+ clean_rootfs();
+ unpack_to_rootfs(__initramfs_start,
+ __initramfs_end - __initramfs_start);
}
printk("it isn't (%s); looks like an initrd\n", err);
fd = sys_open("/initrd.image", O_WRONLY|O_CREAT, 0700);
@@ -603,7 +644,7 @@ static int __init populate_rootfs(void)
#else
printk(KERN_INFO "Unpacking initramfs...");
err = unpack_to_rootfs((char *)initrd_start,
- initrd_end - initrd_start, 0);
+ initrd_end - initrd_start);
if (err)
panic(err);
printk(" done\n");
--
1.5.5.1

View File

@ -1,285 +0,0 @@
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index 1c3a8c5..144624a 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -29,6 +29,8 @@
* Jesse Barnes <jesse.barnes@intel.com>
*/
+#include <linux/async.h>
+
#include "drmP.h"
#include "drm_crtc.h"
#include "drm_crtc_helper.h"
@@ -42,6 +44,8 @@ static struct drm_display_mode std_modes[] = {
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
};
+LIST_HEAD(drm_async_list);
+
/**
* drm_helper_probe_connector_modes - get complete set of display modes
* @dev: DRM device
@@ -137,6 +141,26 @@ int drm_helper_probe_connector_modes(struct drm_device *dev, uint32_t maxX,
}
EXPORT_SYMBOL(drm_helper_probe_connector_modes);
+int drm_helper_probe_connector_modes_fast(struct drm_device *dev, uint32_t maxX,
+ uint32_t maxY)
+{
+ struct drm_connector *connector;
+ int count = 0;
+
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+ count += drm_helper_probe_single_connector_modes(connector,
+ maxX, maxY);
+ /*
+ * If we found a 'good' connector, we stop probing futher.
+ */
+ if (count > 0)
+ break;
+ }
+
+ return count;
+}
+EXPORT_SYMBOL(drm_helper_probe_connector_modes_fast);
+
static void drm_helper_add_std_modes(struct drm_device *dev,
struct drm_connector *connector)
{
@@ -882,6 +906,24 @@ bool drm_helper_plugged_event(struct drm_device *dev)
/* FIXME: send hotplug event */
return true;
}
+
+static void async_notify_fb_changed(void *data, async_cookie_t cookie)
+{
+ struct drm_device *dev = data;
+ dev->mode_config.funcs->fb_changed(dev);
+}
+
+static void async_probe_hard(void *data, async_cookie_t cookie)
+{
+ struct drm_device *dev = data;
+ /* Need to wait for async_notify_fb_changed to be done */
+ async_synchronize_cookie_domain(cookie, &drm_async_list);
+ drm_helper_probe_connector_modes(dev,
+ dev->mode_config.max_width,
+ dev->mode_config.max_height);
+}
+
+
/**
* drm_initial_config - setup a sane initial connector configuration
* @dev: DRM device
@@ -902,7 +944,7 @@ bool drm_helper_initial_config(struct drm_device *dev, bool can_grow)
struct drm_connector *connector;
int count = 0;
- count = drm_helper_probe_connector_modes(dev,
+ count = drm_helper_probe_connector_modes_fast(dev,
dev->mode_config.max_width,
dev->mode_config.max_height);
@@ -921,7 +963,9 @@ bool drm_helper_initial_config(struct drm_device *dev, bool can_grow)
drm_setup_crtcs(dev);
/* alert the driver fb layer */
- dev->mode_config.funcs->fb_changed(dev);
+ async_schedule_domain(async_notify_fb_changed, dev, &drm_async_list);
+ /* probe further outputs */
+ async_schedule_domain(async_probe_hard, dev, &drm_async_list);
return 0;
}
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 14c7a23..ef52021 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -48,6 +48,7 @@
#include "drmP.h"
#include "drm_core.h"
+#include <linux/async.h>
static int drm_version(struct drm_device *dev, void *data,
struct drm_file *file_priv);
@@ -345,6 +346,9 @@ void drm_exit(struct drm_driver *driver)
struct drm_device *dev, *tmp;
DRM_DEBUG("\n");
+ /* make sure all async DRM operations are finished */
+ async_synchronize_full_domain(&drm_async_list);
+
list_for_each_entry_safe(dev, tmp, &driver->device_list, driver_item)
drm_cleanup(dev);
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index a839a28..069b189 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -588,20 +588,22 @@ static unsigned char *drm_ddc_read(struct i2c_adapter *adapter)
{
struct i2c_algo_bit_data *algo_data = adapter->algo_data;
unsigned char *edid = NULL;
+ int divider = 5;
int i, j;
algo_data->setscl(algo_data->data, 1);
- for (i = 0; i < 1; i++) {
+ for (i = 0; i < 2; i++) {
/* For some old monitors we need the
* following process to initialize/stop DDC
*/
+
algo_data->setsda(algo_data->data, 1);
- msleep(13);
+ msleep(13 / divider);
algo_data->setscl(algo_data->data, 1);
for (j = 0; j < 5; j++) {
- msleep(10);
+ msleep(10 / divider);
if (algo_data->getscl(algo_data->data))
break;
}
@@ -609,31 +611,33 @@ static unsigned char *drm_ddc_read(struct i2c_adapter *adapter)
continue;
algo_data->setsda(algo_data->data, 0);
- msleep(15);
+ msleep(15 / divider);
algo_data->setscl(algo_data->data, 0);
- msleep(15);
+ msleep(15 / divider);
algo_data->setsda(algo_data->data, 1);
- msleep(15);
+ msleep(15 / divider);
/* Do the real work */
edid = drm_do_probe_ddc_edid(adapter);
algo_data->setsda(algo_data->data, 0);
algo_data->setscl(algo_data->data, 0);
- msleep(15);
+ msleep(15 / divider);
algo_data->setscl(algo_data->data, 1);
for (j = 0; j < 10; j++) {
- msleep(10);
+ msleep(10 / divider);
if (algo_data->getscl(algo_data->data))
break;
}
algo_data->setsda(algo_data->data, 1);
- msleep(15);
+ msleep(15 / divider);
algo_data->setscl(algo_data->data, 0);
algo_data->setsda(algo_data->data, 0);
+
if (edid)
break;
+ divider = 1;
}
/* Release the DDC lines when done or the Apple Cinema HD display
* will switch off
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index a283427..6f2eced 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -319,7 +319,7 @@ void
intel_wait_for_vblank(struct drm_device *dev)
{
/* Wait for 20ms, i.e. one cycle at 50hz. */
- udelay(20000);
+ mdelay(20);
}
static int
@@ -1466,12 +1466,12 @@ static void intel_setup_outputs(struct drm_device *dev)
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_connector *connector;
- intel_crt_init(dev);
-
- /* Set up integrated LVDS */
+ /* Set up integrated LVDS -- will skip if the lid is closed */
if (IS_MOBILE(dev) && !IS_I830(dev))
intel_lvds_init(dev);
+ intel_crt_init(dev);
+
if (IS_I9XX(dev)) {
int found;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 957daef..22a74bd 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -81,6 +81,7 @@ struct intel_output {
int type;
struct intel_i2c_chan *i2c_bus; /* for control functions */
struct intel_i2c_chan *ddc_bus; /* for DDC only stuff */
+ struct edid *edid;
bool load_detect_temp;
bool needs_tv_clock;
void *dev_priv;
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 0d211af..dc4fecc 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -336,6 +336,7 @@ static void intel_lvds_destroy(struct drm_connector *connector)
intel_i2c_destroy(intel_output->ddc_bus);
drm_sysfs_connector_remove(connector);
drm_connector_cleanup(connector);
+ kfree(intel_output->edid);
kfree(connector);
}
@@ -516,5 +517,6 @@ failed:
if (intel_output->ddc_bus)
intel_i2c_destroy(intel_output->ddc_bus);
drm_connector_cleanup(connector);
+ kfree(intel_output->edid);
kfree(connector);
}
diff --git a/drivers/gpu/drm/i915/intel_modes.c b/drivers/gpu/drm/i915/intel_modes.c
index e42019e..8c0d5f6 100644
--- a/drivers/gpu/drm/i915/intel_modes.c
+++ b/drivers/gpu/drm/i915/intel_modes.c
@@ -70,13 +70,21 @@ int intel_ddc_get_modes(struct intel_output *intel_output)
struct edid *edid;
int ret = 0;
+ if (intel_output->edid) {
+ printk(KERN_INFO "Skipping EDID probe due to cached edid\n");
+ return ret;
+ }
+
edid = drm_get_edid(&intel_output->base,
&intel_output->ddc_bus->adapter);
if (edid) {
drm_mode_connector_update_edid_property(&intel_output->base,
edid);
ret = drm_add_edid_modes(&intel_output->base, edid);
- kfree(edid);
+ if (intel_output->type == INTEL_OUTPUT_LVDS)
+ intel_output->edid = edid;
+ else
+ kfree(edid);
}
return ret;
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index e5f4ae9..69ce4f4 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -304,6 +304,7 @@ struct drm_vma_entry {
pid_t pid;
};
+extern struct list_head drm_async_list;
/**
* DMA buffer.
*/

View File

@ -1,40 +0,0 @@
From: Arjan van de Ven <arjan@linux.intel.com>
Date: Mon, 26 Jan 2009 18:58:11 -0800
Subject: [PATCH] ide/net: flip the order of SATA and network init
this patch flips the order in which sata and network drivers are initialized.
SATA probing takes quite a bit of time, and with the asynchronous infrastructure
other drivers that run after it can execute in parallel. Network drivers do tend
to take some real time talking to the hardware, so running these later is
a good thing (the sata probe then runs concurrent)
This saves about 15% of my kernels boot time.
Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
---
drivers/Makefile | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/Makefile b/drivers/Makefile
index c1bf417..2618a61 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -36,13 +36,14 @@
obj-$(CONFIG_FB_INTEL) += video/intelfb/
obj-y += serial/
obj-$(CONFIG_PARPORT) += parport/
-obj-y += base/ block/ misc/ mfd/ net/ media/
+obj-y += base/ block/ misc/ mfd/ media/
obj-$(CONFIG_NUBUS) += nubus/
-obj-$(CONFIG_ATM) += atm/
obj-y += macintosh/
obj-$(CONFIG_IDE) += ide/
obj-$(CONFIG_SCSI) += scsi/
obj-$(CONFIG_ATA) += ata/
+obj-y += net/
+obj-$(CONFIG_ATM) += atm/
obj-$(CONFIG_FUSION) += message/
obj-$(CONFIG_FIREWIRE) += firewire/
obj-y += ieee1394/

View File

@ -1,92 +0,0 @@
From 2c5ccde448ae5f4062802bcd6002f856acbd268f Mon Sep 17 00:00:00 2001
From: Arjan van de Ven <arjan@linux.intel.com>
Date: Tue, 3 Feb 2009 16:26:16 -0800
Subject: [PATCH] input: introduce a tougher i8042.reset
Some bad touchpads don't reset right the first time (MSI Wind U-100 for
example). This patch will retry the reset up to 5 times.
In addition, this patch also adds a module parameter to not treat
reset failures as fatal to the usage of the device. This prevents
a touchpad failure from also disabling the keyboard....
Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
---
Documentation/kernel-parameters.txt | 2 ++
drivers/input/serio/i8042.c | 33 ++++++++++++++++++++++++---------
2 files changed, 26 insertions(+), 9 deletions(-)
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index ac613a6..a43e3bd 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -855,6 +855,8 @@ and is between 256 and 4096 characters. It is defined in the file
[HW] Frequency with which keyboard LEDs should blink
when kernel panics (default is 0.5 sec)
i8042.reset [HW] Reset the controller during init and cleanup
+ i8042.nonfatal [HW] Don't treat i8042.reset failures as fatal for the
+ device initialization.
i8042.unlock [HW] Unlock (ignore) the keylock
i810= [HW,DRM]
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index 170f71e..2473a9a 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -47,6 +47,10 @@ static unsigned int i8042_reset;
module_param_named(reset, i8042_reset, bool, 0);
MODULE_PARM_DESC(reset, "Reset controller during init and cleanup.");
+static unsigned int i8042_nonfatal;
+module_param_named(nonfatal, i8042_nonfatal, bool, 0);
+MODULE_PARM_DESC(reset, "Treat controller test failures as non-fatal.");
+
static unsigned int i8042_direct;
module_param_named(direct, i8042_direct, bool, 0);
MODULE_PARM_DESC(direct, "Put keyboard port into non-translated mode.");
@@ -712,22 +716,33 @@ static int i8042_controller_check(void)
static int i8042_controller_selftest(void)
{
unsigned char param;
+ int i = 0;
if (!i8042_reset)
return 0;
- if (i8042_command(&param, I8042_CMD_CTL_TEST)) {
- printk(KERN_ERR "i8042.c: i8042 controller self test timeout.\n");
- return -ENODEV;
- }
+ /*
+ * We try this 5 times; on some really fragile systems this does not
+ * take the first time...
+ */
+ do {
+
+ if (i8042_command(&param, I8042_CMD_CTL_TEST)) {
+ printk(KERN_ERR "i8042.c: i8042 controller self test timeout.\n");
+ return -ENODEV;
+ }
+
+ if (param == I8042_RET_CTL_TEST)
+ return 0;
- if (param != I8042_RET_CTL_TEST) {
printk(KERN_ERR "i8042.c: i8042 controller selftest failed. (%#x != %#x)\n",
- param, I8042_RET_CTL_TEST);
- return -EIO;
- }
+ param, I8042_RET_CTL_TEST);
+ msleep(50);
+ } while (i++ < 5);
- return 0;
+ if (i8042_nonfatal)
+ return 0;
+ return -EIO;
}
/*
--
1.6.0.6

View File

@ -1,28 +0,0 @@
From 0143f8eb8afcaccba5a78196fb3db4361e0097a7 Mon Sep 17 00:00:00 2001
From: Arjan van de Ven <arjan@linux.intel.com>
Date: Mon, 9 Feb 2009 21:25:32 -0800
Subject: [PATCH] jbd: longer commit interval
... 5 seconds is rather harsh on ssd's..
Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
---
include/linux/jbd.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/include/linux/jbd.h b/include/linux/jbd.h
index 64246dc..d64b7fd 100644
--- a/include/linux/jbd.h
+++ b/include/linux/jbd.h
@@ -46,7 +46,7 @@
/*
* The default maximum commit age, in seconds.
*/
-#define JBD_DEFAULT_MAX_COMMIT_AGE 5
+#define JBD_DEFAULT_MAX_COMMIT_AGE 15
#ifdef CONFIG_JBD_DEBUG
/*
--
1.6.0.6

View File

@ -1,32 +0,0 @@
--- linux-2.6.28/drivers/Makefile~ 2009-03-21 21:23:28.000000000 -0700
+++ linux-2.6.28/drivers/Makefile 2009-03-21 21:23:28.000000000 -0700
@@ -25,15 +25,8 @@
# default.
obj-y += char/
-# gpu/ comes after char for AGP vs DRM startup
-obj-y += gpu/
-
obj-$(CONFIG_CONNECTOR) += connector/
-# i810fb and intelfb depend on char/agp/
-obj-$(CONFIG_FB_I810) += video/i810/
-obj-$(CONFIG_FB_INTEL) += video/intelfb/
-
obj-y += serial/
obj-$(CONFIG_PARPORT) += parport/
obj-y += base/ block/ misc/ mfd/ media/
@@ -43,6 +36,13 @@
obj-$(CONFIG_SCSI) += scsi/
obj-$(CONFIG_ATA) += ata/
obj-y += net/
+
+# gpu/ comes after char for AGP vs DRM startup
+obj-y += gpu/
+# i810fb and intelfb depend on char/agp/
+obj-$(CONFIG_FB_I810) += video/i810/
+obj-$(CONFIG_FB_INTEL) += video/intelfb/
+
obj-$(CONFIG_ATM) += atm/
obj-$(CONFIG_FUSION) += message/
obj-$(CONFIG_FIREWIRE) += firewire/

View File

@ -1,57 +0,0 @@
Patch to get the touchpad on the MSI Wind U-100 working
--- linux-2.6.28/drivers/input/serio/i8042-x86ia64io.h.org 2009-02-01 18:31:29.000000000 -0800
+++ linux-2.6.28/drivers/input/serio/i8042-x86ia64io.h 2009-02-01 18:35:26.000000000 -0800
@@ -378,6 +378,13 @@ static struct dmi_system_id __initdata i
DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
},
},
+ {
+ .ident = "MSI Wind U-100",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_NAME, "U-100"),
+ DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"),
+ },
+ },
{ }
};
#endif
@@ -448,6 +455,25 @@ static struct dmi_system_id __initdata i
{ }
};
+static struct dmi_system_id __initdata i8042_dmi_reset_table[] = {
+ {
+ .ident = "MSI Wind U-100",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_NAME, "U-100"),
+ DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"),
+ },
+ },
+ {
+ .ident = "LG Electronics X110",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_NAME, "X110"),
+ DMI_MATCH(DMI_BOARD_VENDOR, "LG Electronics Inc."),
+ },
+ },
+ { }
+};
+
+
#endif /* CONFIG_X86 */
#ifdef CONFIG_PNP
@@ -564,6 +583,11 @@ static int __init i8042_pnp_init(void)
i8042_nopnp = 1;
#endif
+ if (dmi_check_system(i8042_dmi_reset_table)) {
+ i8042_reset = 1;
+ i8042_nonfatal = 1;
+ }
+
if (i8042_nopnp) {
printk(KERN_INFO "i8042: PNP detection disabled\n");
return 0;

View File

@ -1,83 +0,0 @@
From eaf05431b9ea8676d23106e6373b7d2b8ff2d97d Mon Sep 17 00:00:00 2001
From: Shaohua Li <shaohua.li@intel.com>
Date: Mon, 23 Feb 2009 15:19:16 +0800
Subject: agp/intel: Add support for new intel chipset.
This is a G33-like desktop and mobile chipset.
Signed-off-by: Shaohua Li <shaohua.li@intel.com>
Signed-off-by: Eric Anholt <eric@anholt.net>
---
drivers/char/agp/intel-agp.c | 21 ++++++++++++++++++---
1 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index c771418..0232cfc 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -26,6 +26,10 @@
#define PCI_DEVICE_ID_INTEL_82965GME_IG 0x2A12
#define PCI_DEVICE_ID_INTEL_82945GME_HB 0x27AC
#define PCI_DEVICE_ID_INTEL_82945GME_IG 0x27AE
+#define PCI_DEVICE_ID_INTEL_IGDGM_HB 0xA010
+#define PCI_DEVICE_ID_INTEL_IGDGM_IG 0xA011
+#define PCI_DEVICE_ID_INTEL_IGDG_HB 0xA000
+#define PCI_DEVICE_ID_INTEL_IGDG_IG 0xA001
#define PCI_DEVICE_ID_INTEL_G33_HB 0x29C0
#define PCI_DEVICE_ID_INTEL_G33_IG 0x29C2
#define PCI_DEVICE_ID_INTEL_Q35_HB 0x29B0
@@ -60,7 +64,12 @@
#define IS_G33 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G33_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q35_HB || \
- agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q33_HB)
+ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q33_HB || \
+ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDGM_HB || \
+ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDG_HB)
+
+#define IS_IGD (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDGM_HB || \
+ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDG_HB)
#define IS_G4X (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGD_E_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q45_HB || \
@@ -510,7 +519,7 @@ static void intel_i830_init_gtt_entries(void)
size = 512;
}
size += 4; /* add in BIOS popup space */
- } else if (IS_G33) {
+ } else if (IS_G33 && !IS_IGD) {
/* G33's GTT size defined in gmch_ctrl */
switch (gmch_ctrl & G33_PGETBL_SIZE_MASK) {
case G33_PGETBL_SIZE_1M:
@@ -526,7 +535,7 @@ static void intel_i830_init_gtt_entries(void)
size = 512;
}
size += 4;
- } else if (IS_G4X) {
+ } else if (IS_G4X || IS_IGD) {
/* On 4 series hardware, GTT stolen is separate from graphics
* stolen, ignore it in stolen gtt entries counting. However,
* 4KB of the stolen memory doesn't get mapped to the GTT.
@@ -2159,6 +2168,10 @@ static const struct intel_driver_description {
NULL, &intel_g33_driver },
{ PCI_DEVICE_ID_INTEL_Q33_HB, PCI_DEVICE_ID_INTEL_Q33_IG, 0, "Q33",
NULL, &intel_g33_driver },
+ { PCI_DEVICE_ID_INTEL_IGDGM_HB, PCI_DEVICE_ID_INTEL_IGDGM_IG, 0, "IGD",
+ NULL, &intel_g33_driver },
+ { PCI_DEVICE_ID_INTEL_IGDG_HB, PCI_DEVICE_ID_INTEL_IGDG_IG, 0, "IGD",
+ NULL, &intel_g33_driver },
{ PCI_DEVICE_ID_INTEL_GM45_HB, PCI_DEVICE_ID_INTEL_GM45_IG, 0,
"Mobile Intel® GM45 Express", NULL, &intel_i965_driver },
{ PCI_DEVICE_ID_INTEL_IGD_E_HB, PCI_DEVICE_ID_INTEL_IGD_E_IG, 0,
@@ -2353,6 +2366,8 @@ static struct pci_device_id agp_intel_pci_table[] = {
ID(PCI_DEVICE_ID_INTEL_82945G_HB),
ID(PCI_DEVICE_ID_INTEL_82945GM_HB),
ID(PCI_DEVICE_ID_INTEL_82945GME_HB),
+ ID(PCI_DEVICE_ID_INTEL_IGDGM_HB),
+ ID(PCI_DEVICE_ID_INTEL_IGDG_HB),
ID(PCI_DEVICE_ID_INTEL_82946GZ_HB),
ID(PCI_DEVICE_ID_INTEL_82G35_HB),
ID(PCI_DEVICE_ID_INTEL_82965Q_HB),
--
1.6.1.3

View File

@ -1,336 +0,0 @@
From 8b941bea1d0fe0c5cf0de938cd0bd89ce6640dbb Mon Sep 17 00:00:00 2001
From: Shaohua Li <shaohua.li@intel.com>
Date: Mon, 23 Feb 2009 15:19:19 +0800
Subject: drm/i915: Add support for new G33-like chipset.
This chip is nearly the same, but has new clock settings required.
Signed-off-by: Shaohua Li <shaohua.li@intel.com>
Signed-off-by: Eric Anholt <eric@anholt.net>
---
drivers/gpu/drm/i915/i915_drv.h | 10 +++-
drivers/gpu/drm/i915/i915_reg.h | 4 +
drivers/gpu/drm/i915/intel_display.c | 111 +++++++++++++++++++++++++++++-----
include/drm/drm_pciids.h | 2 +
4 files changed, 109 insertions(+), 18 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 0e27854..36d6bc3 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -787,15 +787,21 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
(dev)->pci_device == 0x2E22 || \
IS_GM45(dev))
+#define IS_IGDG(dev) ((dev)->pci_device == 0xa001)
+#define IS_IGDGM(dev) ((dev)->pci_device == 0xa011)
+#define IS_IGD(dev) (IS_IGDG(dev) || IS_IGDGM(dev))
+
#define IS_G33(dev) ((dev)->pci_device == 0x29C2 || \
(dev)->pci_device == 0x29B2 || \
- (dev)->pci_device == 0x29D2)
+ (dev)->pci_device == 0x29D2 || \
+ (IS_IGD(dev)))
#define IS_I9XX(dev) (IS_I915G(dev) || IS_I915GM(dev) || IS_I945G(dev) || \
IS_I945GM(dev) || IS_I965G(dev) || IS_G33(dev))
#define IS_MOBILE(dev) (IS_I830(dev) || IS_I85X(dev) || IS_I915GM(dev) || \
- IS_I945GM(dev) || IS_I965GM(dev) || IS_GM45(dev))
+ IS_I945GM(dev) || IS_I965GM(dev) || IS_GM45(dev) || \
+ IS_IGD(dev))
#define I915_NEED_GFX_HWS(dev) (IS_G33(dev) || IS_GM45(dev) || IS_G4X(dev))
/* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 9d6539a..f07d315 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -358,6 +358,7 @@
#define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */
#define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */
#define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */
+#define DPLL_FPA01_P1_POST_DIV_MASK_IGD 0x00ff8000 /* IGD */
#define I915_FIFO_UNDERRUN_STATUS (1UL<<31)
#define I915_CRC_ERROR_ENABLE (1UL<<29)
@@ -434,6 +435,7 @@
*/
#define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS 0x003f0000
#define DPLL_FPA01_P1_POST_DIV_SHIFT 16
+#define DPLL_FPA01_P1_POST_DIV_SHIFT_IGD 15
/* i830, required in DVO non-gang */
#define PLL_P2_DIVIDE_BY_4 (1 << 23)
#define PLL_P1_DIVIDE_BY_TWO (1 << 21) /* i830 */
@@ -500,10 +502,12 @@
#define FPB0 0x06048
#define FPB1 0x0604c
#define FP_N_DIV_MASK 0x003f0000
+#define FP_N_IGD_DIV_MASK 0x00ff0000
#define FP_N_DIV_SHIFT 16
#define FP_M1_DIV_MASK 0x00003f00
#define FP_M1_DIV_SHIFT 8
#define FP_M2_DIV_MASK 0x0000003f
+#define FP_M2_IGD_DIV_MASK 0x000000ff
#define FP_M2_DIV_SHIFT 0
#define DPLL_TEST 0x606c
#define DPLLB_TEST_SDVO_DIV_1 (0 << 22)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index a283427..1702564 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -90,18 +90,32 @@ typedef struct {
#define I9XX_DOT_MAX 400000
#define I9XX_VCO_MIN 1400000
#define I9XX_VCO_MAX 2800000
+#define IGD_VCO_MIN 1700000
+#define IGD_VCO_MAX 3500000
#define I9XX_N_MIN 1
#define I9XX_N_MAX 6
+/* IGD's Ncounter is a ring counter */
+#define IGD_N_MIN 3
+#define IGD_N_MAX 6
#define I9XX_M_MIN 70
#define I9XX_M_MAX 120
+#define IGD_M_MIN 2
+#define IGD_M_MAX 256
#define I9XX_M1_MIN 10
#define I9XX_M1_MAX 22
#define I9XX_M2_MIN 5
#define I9XX_M2_MAX 9
+/* IGD M1 is reserved, and must be 0 */
+#define IGD_M1_MIN 0
+#define IGD_M1_MAX 0
+#define IGD_M2_MIN 0
+#define IGD_M2_MAX 254
#define I9XX_P_SDVO_DAC_MIN 5
#define I9XX_P_SDVO_DAC_MAX 80
#define I9XX_P_LVDS_MIN 7
#define I9XX_P_LVDS_MAX 98
+#define IGD_P_LVDS_MIN 7
+#define IGD_P_LVDS_MAX 112
#define I9XX_P1_MIN 1
#define I9XX_P1_MAX 8
#define I9XX_P2_SDVO_DAC_SLOW 10
@@ -115,6 +129,8 @@ typedef struct {
#define INTEL_LIMIT_I8XX_LVDS 1
#define INTEL_LIMIT_I9XX_SDVO_DAC 2
#define INTEL_LIMIT_I9XX_LVDS 3
+#define INTEL_LIMIT_IGD_SDVO_DAC 4
+#define INTEL_LIMIT_IGD_LVDS 5
static const intel_limit_t intel_limits[] = {
{ /* INTEL_LIMIT_I8XX_DVO_DAC */
@@ -168,6 +184,32 @@ static const intel_limit_t intel_limits[] = {
.p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT,
.p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_FAST },
},
+ { /* INTEL_LIMIT_IGD_SDVO */
+ .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX},
+ .vco = { .min = IGD_VCO_MIN, .max = IGD_VCO_MAX },
+ .n = { .min = IGD_N_MIN, .max = IGD_N_MAX },
+ .m = { .min = IGD_M_MIN, .max = IGD_M_MAX },
+ .m1 = { .min = IGD_M1_MIN, .max = IGD_M1_MAX },
+ .m2 = { .min = IGD_M2_MIN, .max = IGD_M2_MAX },
+ .p = { .min = I9XX_P_SDVO_DAC_MIN, .max = I9XX_P_SDVO_DAC_MAX },
+ .p1 = { .min = I9XX_P1_MIN, .max = I9XX_P1_MAX },
+ .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT,
+ .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST },
+ },
+ { /* INTEL_LIMIT_IGD_LVDS */
+ .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX },
+ .vco = { .min = IGD_VCO_MIN, .max = IGD_VCO_MAX },
+ .n = { .min = IGD_N_MIN, .max = IGD_N_MAX },
+ .m = { .min = IGD_M_MIN, .max = IGD_M_MAX },
+ .m1 = { .min = IGD_M1_MIN, .max = IGD_M1_MAX },
+ .m2 = { .min = IGD_M2_MIN, .max = IGD_M2_MAX },
+ .p = { .min = IGD_P_LVDS_MIN, .max = IGD_P_LVDS_MAX },
+ .p1 = { .min = I9XX_P1_MIN, .max = I9XX_P1_MAX },
+ /* IGD only supports single-channel mode. */
+ .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT,
+ .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_SLOW },
+ },
+
};
static const intel_limit_t *intel_limit(struct drm_crtc *crtc)
@@ -175,11 +217,16 @@ static const intel_limit_t *intel_limit(struct drm_crtc *crtc)
struct drm_device *dev = crtc->dev;
const intel_limit_t *limit;
- if (IS_I9XX(dev)) {
+ if (IS_I9XX(dev) && !IS_IGD(dev)) {
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
limit = &intel_limits[INTEL_LIMIT_I9XX_LVDS];
else
limit = &intel_limits[INTEL_LIMIT_I9XX_SDVO_DAC];
+ } else if (IS_IGD(dev)) {
+ if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
+ limit = &intel_limits[INTEL_LIMIT_IGD_LVDS];
+ else
+ limit = &intel_limits[INTEL_LIMIT_IGD_SDVO_DAC];
} else {
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
limit = &intel_limits[INTEL_LIMIT_I8XX_LVDS];
@@ -189,8 +236,21 @@ static const intel_limit_t *intel_limit(struct drm_crtc *crtc)
return limit;
}
-static void intel_clock(int refclk, intel_clock_t *clock)
+/* m1 is reserved as 0 in IGD, n is a ring counter */
+static void igd_clock(int refclk, intel_clock_t *clock)
{
+ clock->m = clock->m2 + 2;
+ clock->p = clock->p1 * clock->p2;
+ clock->vco = refclk * clock->m / clock->n;
+ clock->dot = clock->vco / clock->p;
+}
+
+static void intel_clock(struct drm_device *dev, int refclk, intel_clock_t *clock)
+{
+ if (IS_IGD(dev)) {
+ igd_clock(refclk, clock);
+ return;
+ }
clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2);
clock->p = clock->p1 * clock->p2;
clock->vco = refclk * clock->m / (clock->n + 2);
@@ -226,6 +286,7 @@ bool intel_pipe_has_type (struct drm_crtc *crtc, int type)
static bool intel_PLL_is_valid(struct drm_crtc *crtc, intel_clock_t *clock)
{
const intel_limit_t *limit = intel_limit (crtc);
+ struct drm_device *dev = crtc->dev;
if (clock->p1 < limit->p1.min || limit->p1.max < clock->p1)
INTELPllInvalid ("p1 out of range\n");
@@ -235,7 +296,7 @@ static bool intel_PLL_is_valid(struct drm_crtc *crtc, intel_clock_t *clock)
INTELPllInvalid ("m2 out of range\n");
if (clock->m1 < limit->m1.min || limit->m1.max < clock->m1)
INTELPllInvalid ("m1 out of range\n");
- if (clock->m1 <= clock->m2)
+ if (clock->m1 <= clock->m2 && !IS_IGD(dev))
INTELPllInvalid ("m1 <= m2\n");
if (clock->m < limit->m.min || limit->m.max < clock->m)
INTELPllInvalid ("m out of range\n");
@@ -289,15 +350,17 @@ static bool intel_find_best_PLL(struct drm_crtc *crtc, int target,
memset (best_clock, 0, sizeof (*best_clock));
for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; clock.m1++) {
- for (clock.m2 = limit->m2.min; clock.m2 < clock.m1 &&
- clock.m2 <= limit->m2.max; clock.m2++) {
+ for (clock.m2 = limit->m2.min; clock.m2 <= limit->m2.max; clock.m2++) {
+ /* m1 is always 0 in IGD */
+ if (clock.m2 >= clock.m1 && !IS_IGD(dev))
+ break;
for (clock.n = limit->n.min; clock.n <= limit->n.max;
clock.n++) {
for (clock.p1 = limit->p1.min;
clock.p1 <= limit->p1.max; clock.p1++) {
int this_err;
- intel_clock(refclk, &clock);
+ intel_clock(dev, refclk, &clock);
if (!intel_PLL_is_valid(crtc, &clock))
continue;
@@ -634,7 +697,7 @@ static int intel_get_core_clock_speed(struct drm_device *dev)
return 400000;
else if (IS_I915G(dev))
return 333000;
- else if (IS_I945GM(dev) || IS_845G(dev))
+ else if (IS_I945GM(dev) || IS_845G(dev) || IS_IGDGM(dev))
return 200000;
else if (IS_I915GM(dev)) {
u16 gcfgc = 0;
@@ -782,7 +845,10 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
return -EINVAL;
}
- fp = clock.n << 16 | clock.m1 << 8 | clock.m2;
+ if (IS_IGD(dev))
+ fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2;
+ else
+ fp = clock.n << 16 | clock.m1 << 8 | clock.m2;
dpll = DPLL_VGA_MODE_DIS;
if (IS_I9XX(dev)) {
@@ -799,7 +865,10 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
}
/* compute bitmask from p1 value */
- dpll |= (1 << (clock.p1 - 1)) << 16;
+ if (IS_IGD(dev))
+ dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT_IGD;
+ else
+ dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
switch (clock.p2) {
case 5:
dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5;
@@ -1279,10 +1348,20 @@ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc)
fp = I915_READ((pipe == 0) ? FPA1 : FPB1);
clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT;
- clock.m2 = (fp & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT;
- clock.n = (fp & FP_N_DIV_MASK) >> FP_N_DIV_SHIFT;
+ if (IS_IGD(dev)) {
+ clock.n = ffs((fp & FP_N_IGD_DIV_MASK) >> FP_N_DIV_SHIFT) - 1;
+ clock.m2 = (fp & FP_M2_IGD_DIV_MASK) >> FP_M2_DIV_SHIFT;
+ } else {
+ clock.n = (fp & FP_N_DIV_MASK) >> FP_N_DIV_SHIFT;
+ clock.m2 = (fp & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT;
+ }
+
if (IS_I9XX(dev)) {
- clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK) >>
+ if (IS_IGD(dev))
+ clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_IGD) >>
+ DPLL_FPA01_P1_POST_DIV_SHIFT_IGD);
+ else
+ clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK) >>
DPLL_FPA01_P1_POST_DIV_SHIFT);
switch (dpll & DPLL_MODE_MASK) {
@@ -1301,7 +1380,7 @@ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc)
}
/* XXX: Handle the 100Mhz refclk */
- intel_clock(96000, &clock);
+ intel_clock(dev, 96000, &clock);
} else {
bool is_lvds = (pipe == 1) && (I915_READ(LVDS) & LVDS_PORT_EN);
@@ -1313,9 +1392,9 @@ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc)
if ((dpll & PLL_REF_INPUT_MASK) ==
PLLB_REF_INPUT_SPREADSPECTRUMIN) {
/* XXX: might not be 66MHz */
- intel_clock(66000, &clock);
+ intel_clock(dev, 66000, &clock);
} else
- intel_clock(48000, &clock);
+ intel_clock(dev, 48000, &clock);
} else {
if (dpll & PLL_P1_DIVIDE_BY_TWO)
clock.p1 = 2;
@@ -1328,7 +1407,7 @@ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc)
else
clock.p2 = 2;
- intel_clock(48000, &clock);
+ intel_clock(dev, 48000, &clock);
}
}
diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h
index 5165f24..76c4c82 100644
--- a/include/drm/drm_pciids.h
+++ b/include/drm/drm_pciids.h
@@ -418,4 +418,6 @@
{0x8086, 0x2e02, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \
{0x8086, 0x2e12, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \
{0x8086, 0x2e22, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \
+ {0x8086, 0xa001, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \
+ {0x8086, 0xa011, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \
{0, 0, 0}
--
1.6.1.3

View File

@ -1,21 +0,0 @@
IGD device only has last 1 page used by GTT. this should align to AGP gart code.
Signed-off-by: Shaohua Li <shaohua.li@intel.com>
---
drivers/gpu/drm/i915/i915_dma.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Index: linux/drivers/gpu/drm/i915/i915_dma.c
===================================================================
--- linux.orig/drivers/gpu/drm/i915/i915_dma.c 2009-03-13 15:36:12.000000000 +0800
+++ linux/drivers/gpu/drm/i915/i915_dma.c 2009-03-13 15:37:26.000000000 +0800
@@ -880,7 +880,7 @@ static int i915_probe_agp(struct drm_dev
* Some of the preallocated space is taken by the GTT
* and popup. GTT is 1K per MB of aperture size, and popup is 4K.
*/
- if (IS_G4X(dev))
+ if (IS_G4X(dev) || IS_IGD(dev))
overhead = 4096;
else
overhead = (*aperture_size / 1024) + 4096;

View File

@ -1,38 +0,0 @@
In IGD, DPCUNIT_CLOCK_GATE_DISABLE bit should be set, otherwise i2c
access will be wrong.
Signed-off-by: Shaohua Li <shaohua.li@intel.com>
---
drivers/gpu/drm/i915/i915_reg.h | 1 +
drivers/gpu/drm/i915/intel_display.c | 5 +++++
2 files changed, 6 insertions(+)
Index: linux/drivers/gpu/drm/i915/i915_reg.h
===================================================================
--- linux.orig/drivers/gpu/drm/i915/i915_reg.h 2009-03-16 14:18:27.000000000 +0800
+++ linux/drivers/gpu/drm/i915/i915_reg.h 2009-03-16 14:28:09.000000000 +0800
@@ -523,6 +523,7 @@
#define DPLLA_INPUT_BUFFER_ENABLE (1 << 0)
#define D_STATE 0x6104
#define CG_2D_DIS 0x6200
+#define DPCUNIT_CLOCK_GATE_DISABLE (1 << 24)
#define CG_3D_DIS 0x6204
/*
Index: linux/drivers/gpu/drm/i915/intel_display.c
===================================================================
--- linux.orig/drivers/gpu/drm/i915/intel_display.c 2009-03-16 14:16:11.000000000 +0800
+++ linux/drivers/gpu/drm/i915/intel_display.c 2009-03-16 14:27:46.000000000 +0800
@@ -1545,6 +1545,11 @@ static void intel_setup_outputs(struct d
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_connector *connector;
+ /* When using bit bashing for I2C, this bit needs to be set to 1 */
+ if (IS_IGD(dev))
+ I915_WRITE(CG_2D_DIS,
+ I915_READ(CG_2D_DIS) | DPCUNIT_CLOCK_GATE_DISABLE);
+
intel_crt_init(dev);
/* Set up integrated LVDS */

View File

@ -1,28 +0,0 @@
diff --git a/drivers/gpu/drm/psb/psb_fb.c b/drivers/gpu/drm/psb/psb_fb.c
index 67934c0..8fc5221 100644
--- a/drivers/gpu/drm/psb/psb_fb.c
+++ b/drivers/gpu/drm/psb/psb_fb.c
@@ -896,8 +896,10 @@ static int psbfb_kms_off(struct drm_device *dev, int suspend)
list_for_each_entry(fb, &dev->mode_config.fb_list, head) {
struct fb_info *info = fb->fbdev;
- if (suspend)
+ if (suspend) {
fb_set_suspend(info, 1);
+ psbfb_blank(FB_BLANK_POWERDOWN, info);
+ }
}
mutex_unlock(&dev->mode_config.mutex);
@@ -928,8 +930,10 @@ static int psbfb_kms_on(struct drm_device *dev, int resume)
list_for_each_entry(fb, &dev->mode_config.fb_list, head) {
struct fb_info *info = fb->fbdev;
- if (resume)
+ if (resume) {
fb_set_suspend(info, 0);
+ psbfb_blank(FB_BLANK_UNBLANK, info);
+ }
}
mutex_unlock(&dev->mode_config.mutex);

File diff suppressed because it is too large Load Diff

View File

@ -1,61 +0,0 @@
From 0384d086e31092628596af98b1e33fad586cef0a Mon Sep 17 00:00:00 2001
From: Arjan van de Ven <arjan@linux.intel.com>
Date: Sun, 20 Jul 2008 13:01:28 -0700
Subject: [PATCH] fastboot: retry mounting the root fs if we can't find init
currently we wait until all device init is done before trying to mount
the root fs, and to consequently execute init.
In preparation for relaxing the first delay, this patch adds a retry
attempt in case /sbin/init is not found. Before retrying, the code
will wait for all device init to complete.
While this patch by itself doesn't gain boot time yet (it needs follow on
patches), the alternative already is to panic()...
Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
---
--- a/init/main.c 2009-01-07 18:29:11.000000000 -0800
+++ b/init/main.c 2009-01-07 18:32:08.000000000 -0800
@@ -837,6 +837,7 @@ static void run_init_process(char *init_
*/
static noinline int init_post(void)
{
+ int retry_count = 1;
/* need to finish all async __init code before freeing the memory */
async_synchronize_full();
free_initmem();
@@ -859,6 +860,8 @@ static noinline int init_post(void)
ramdisk_execute_command);
}
+retry:
+
/*
* We try each of these until one succeeds.
*
@@ -871,6 +874,23 @@ static noinline int init_post(void)
"defaults...\n", execute_command);
}
run_init_process("/sbin/init");
+
+ if (retry_count > 0) {
+ retry_count--;
+ /*
+ * We haven't found init yet... potentially because the device
+ * is still being probed. We need to
+ * - flush keventd and friends
+ * - wait for the known devices to complete their probing
+ * - try to mount the root fs again
+ */
+ flush_scheduled_work();
+ while (driver_probe_done() != 0)
+ msleep(100);
+ prepare_namespace();
+ goto retry;
+ }
+
run_init_process("/etc/init");
run_init_process("/bin/init");
run_init_process("/bin/sh");

View File

@ -1,17 +0,0 @@
From: Arjan van de Ven <arjan@linux.intel.com>
Date: Fri, 23 Jan 2009
Small fix changing error msg to info msg in acer wmi driver
---
diff -durp a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c
--- a/drivers/platform/x86/acer-wmi.c 2009-01-23 13:58:36.000000000 -0800
+++ b/drivers/platform/x86/acer-wmi.c 2009-01-23 14:00:12.000000000 -0800
@@ -1290,7 +1290,7 @@ static int __init acer_wmi_init(void)
AMW0_find_mailled();
if (!interface) {
- printk(ACER_ERR "No or unsupported WMI interface, unable to "
+ printk(ACER_INFO "No or unsupported WMI interface, unable to "
"load\n");
return -ENODEV;
}

View File

@ -1,66 +0,0 @@
From be9df3282d24a7326bba2eea986c79d822f0e998 Mon Sep 17 00:00:00 2001
From: Arjan van de Ven <arjan@linux.intel.com>
Date: Sun, 21 Sep 2008 11:58:27 -0700
Subject: [PATCH] superreadahead patch
---
fs/ext3/ioctl.c | 3 +++
fs/ext3/super.c | 1 +
include/linux/ext3_fs.h | 1 +
include/linux/fs.h | 2 ++
4 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/fs/ext3/ioctl.c b/fs/ext3/ioctl.c
index b7394d0..c2e7f23 100644
--- a/fs/ext3/ioctl.c
+++ b/fs/ext3/ioctl.c
@@ -290,6 +290,9 @@ group_add_out:
mnt_drop_write(filp->f_path.mnt);
return err;
}
+ case EXT3_IOC_INODE_JIFFIES: {
+ return inode->created_when;
+ }
default:
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index f6c94f2..268dd1d 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -461,6 +461,7 @@ static struct inode *ext3_alloc_inode(struct super_block *sb)
#endif
ei->i_block_alloc_info = NULL;
ei->vfs_inode.i_version = 1;
+ ei->vfs_inode.created_when = jiffies;
return &ei->vfs_inode;
}
diff --git a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h
index d14f029..fff5510 100644
--- a/include/linux/ext3_fs.h
+++ b/include/linux/ext3_fs.h
@@ -225,6 +225,7 @@ struct ext3_new_group_data {
#endif
#define EXT3_IOC_GETRSVSZ _IOR('f', 5, long)
#define EXT3_IOC_SETRSVSZ _IOW('f', 6, long)
+#define EXT3_IOC_INODE_JIFFIES _IOR('f', 19, long)
/*
* ioctl commands in 32 bit emulation
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 4a853ef..c346136 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -685,6 +685,8 @@ struct inode {
void *i_security;
#endif
void *i_private; /* fs or device private pointer */
+
+ unsigned long created_when; /* jiffies of creation time */
};
/*
--
1.5.5.1

View File

@ -1,130 +0,0 @@
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index f8f86de..5d4cea2 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -676,6 +676,9 @@ static int psmouse_extensions(struct psmouse *psmouse,
if (touchkit_ps2_detect(psmouse, set_properties) == 0)
return PSMOUSE_TOUCHKIT_PS2;
+
+ if (elftouch_ps2_detect(psmouse, set_properties) == 0)
+ return PSMOUSE_ELFTOUCH_PS2;
}
/*
@@ -786,6 +789,12 @@ static const struct psmouse_protocol psmouse_protocols[] = {
.alias = "trackpoint",
.detect = trackpoint_detect,
},
+ {
+ .type = PSMOUSE_ELFTOUCH_PS2,
+ .name = "elftouchPS2",
+ .alias = "elftouch",
+ .detect = elftouch_ps2_detect,
+ },
#endif
#ifdef CONFIG_MOUSE_PS2_TOUCHKIT
{
diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
index 54ed267..8d1ba79 100644
--- a/drivers/input/mouse/psmouse.h
+++ b/drivers/input/mouse/psmouse.h
@@ -89,6 +89,7 @@ enum psmouse_type {
PSMOUSE_TRACKPOINT,
PSMOUSE_TOUCHKIT_PS2,
PSMOUSE_CORTRON,
+ PSMOUSE_ELFTOUCH_PS2,
PSMOUSE_HGPK,
PSMOUSE_ELANTECH,
PSMOUSE_AUTO /* This one should always be last */
diff --git a/drivers/input/mouse/touchkit_ps2.c b/drivers/input/mouse/touchkit_ps2.c
index 3fadb2a..e9c27f1 100644
--- a/drivers/input/mouse/touchkit_ps2.c
+++ b/drivers/input/mouse/touchkit_ps2.c
@@ -51,6 +51,11 @@
#define TOUCHKIT_GET_X(packet) (((packet)[1] << 7) | (packet)[2])
#define TOUCHKIT_GET_Y(packet) (((packet)[3] << 7) | (packet)[4])
+#define ELFTOUCH_MAX_XC 0x0fff
+#define ELFTOUCH_MAX_YC 0x0fff
+#define ELFTOUCH_GET_X(packet) (((packet)[3] << 7) | (packet)[4])
+#define ELFTOUCH_GET_Y(packet) (((packet)[1] << 7) | (packet)[2])
+
static psmouse_ret_t touchkit_ps2_process_byte(struct psmouse *psmouse)
{
unsigned char *packet = psmouse->packet;
@@ -59,9 +64,15 @@ static psmouse_ret_t touchkit_ps2_process_byte(struct psmouse *psmouse)
if (psmouse->pktcnt != 5)
return PSMOUSE_GOOD_DATA;
- input_report_abs(dev, ABS_X, TOUCHKIT_GET_X(packet));
- input_report_abs(dev, ABS_Y, TOUCHKIT_GET_Y(packet));
+ if(psmouse->type==PSMOUSE_ELFTOUCH_PS2) {
+ input_report_abs(dev, ABS_X, ELFTOUCH_GET_X(packet));
+ input_report_abs(dev, ABS_Y, ELFTOUCH_GET_Y(packet));
+ } else {
+ input_report_abs(dev, ABS_X, TOUCHKIT_GET_X(packet));
+ input_report_abs(dev, ABS_Y, TOUCHKIT_GET_Y(packet));
+ }
input_report_key(dev, BTN_TOUCH, TOUCHKIT_GET_TOUCHED(packet));
+
input_sync(dev);
return PSMOUSE_FULL_PACKET;
@@ -98,3 +109,33 @@ int touchkit_ps2_detect(struct psmouse *psmouse, int set_properties)
return 0;
}
+
+int elftouch_ps2_detect(struct psmouse *psmouse, int set_properties)
+{
+ struct input_dev *dev = psmouse->dev;
+ unsigned char param[16];
+ int command, res;
+
+ param[0]=0x0f4;
+ command = TOUCHKIT_SEND_PARMS(1, 0, TOUCHKIT_CMD);
+ res=ps2_command(&psmouse->ps2dev, param, command);
+ if(res) { return -ENODEV; }
+
+ param[0]=0x0b0;
+ command = TOUCHKIT_SEND_PARMS(1, 1, TOUCHKIT_CMD);
+ res=ps2_command(&psmouse->ps2dev, param, command);
+ if(res) { return -ENODEV; }
+
+ if (set_properties) {
+ dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+ set_bit(BTN_TOUCH, dev->keybit);
+ input_set_abs_params(dev, ABS_X, 0, ELFTOUCH_MAX_XC, 0, 0);
+ input_set_abs_params(dev, ABS_Y, 0, ELFTOUCH_MAX_YC, 0, 0);
+
+ psmouse->vendor = "ElfTouch";
+ psmouse->name = "Touchscreen";
+ psmouse->protocol_handler = touchkit_ps2_process_byte;
+ psmouse->pktsize = 5;
+ }
+ return 0;
+}
diff --git a/drivers/input/mouse/touchkit_ps2.h b/drivers/input/mouse/touchkit_ps2.h
index 8a0dd35..f32ef4c 100644
--- a/drivers/input/mouse/touchkit_ps2.h
+++ b/drivers/input/mouse/touchkit_ps2.h
@@ -14,12 +14,18 @@
#ifdef CONFIG_MOUSE_PS2_TOUCHKIT
int touchkit_ps2_detect(struct psmouse *psmouse, int set_properties);
+int elftouch_ps2_detect(struct psmouse *psmouse, int set_properties);
#else
static inline int touchkit_ps2_detect(struct psmouse *psmouse,
int set_properties)
{
return -ENOSYS;
}
+static inline int elftouch_ps2_detect(struct psmouse *psmouse,
+ int set_properties)
+{
+ return -ENOSYS;
+}
#endif /* CONFIG_MOUSE_PS2_TOUCHKIT */
#endif

View File

@ -1,69 +0,0 @@
Gitweb: http://git.kernel.org/linus/d6de2c80e9d758d2e36c21699117db6178c0f517
Commit: d6de2c80e9d758d2e36c21699117db6178c0f517
Parent: 7933a3cfba017330ebb25f9820cb25ec9cdd67cc
Author: Linus Torvalds <torvalds@linux-foundation.org>
AuthorDate: Fri Apr 10 12:17:41 2009 -0700
Committer: Linus Torvalds <torvalds@linux-foundation.org>
CommitDate: Sat Apr 11 12:44:49 2009 -0700
async: Fix module loading async-work regression
Several drivers use asynchronous work to do device discovery, and we
synchronize with them in the compiled-in case before we actually try to
mount root filesystems etc.
However, when compiled as modules, that synchronization is missing - the
module loading completes, but the driver hasn't actually finished
probing for devices, and that means that any user mode that expects to
use the devices after the 'insmod' is now potentially broken.
We already saw one case of a similar issue in the ACPI battery code,
where the kernel itself expected the module to be all done, and unmapped
the init memory - but the async device discovery was still running.
That got hacked around by just removing the "__init" (see commit
5d38258ec026921a7b266f4047ebeaa75db358e5 "ACPI battery: fix async boot
oops"), but the real fix is to just make the module loading wait for all
async work to be completed.
It will slow down module loading, but since common devices should be
built in anyway, and since the bug is really annoying and hard to handle
from user space (and caused several S3 resume regressions), the simple
fix to wait is the right one.
This fixes at least
http://bugzilla.kernel.org/show_bug.cgi?id=13063
but probably a few other bugzilla entries too (12936, for example), and
is confirmed to fix Rafael's storage driver breakage after resume bug
report (no bugzilla entry).
We should also be able to now revert that ACPI battery fix.
Reported-and-tested-by: Rafael J. Wysocki <rjw@suse.com>
Tested-by: Heinz Diehl <htd@fancy-poultry.org>
Acked-by: Arjan van de Ven <arjan@linux.intel.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
---
kernel/module.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/kernel/module.c b/kernel/module.c
index 05f014e..e797812 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -2388,6 +2388,9 @@ SYSCALL_DEFINE3(init_module, void __user *, umod,
blocking_notifier_call_chain(&module_notify_list,
MODULE_STATE_LIVE, mod);
+ /* We need to finish all async code before the module init sequence is done */
+ async_synchronize_full();
+
mutex_lock(&module_mutex);
/* Drop initial reference. */
module_put(mod);
--
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html

View File

@ -1,139 +0,0 @@
From: Rafael J. Wysocki <rjw@suse.com>
Organization: SUSE
To: Arjan van de Ven <arjan@linux.intel.com>
CC: Linus Torvalds <torvalds@linux-foundation.org>
OK, updated patch follows, with a changelog.
I've added this check to user.c too, because that code can be called
independently of the one in disk.c . Also, if resume is user space-driven,
it's a good idea to wait for all of the device probes to complete before
continuing.
Thanks,
Rafael
---
From: Rafael J. Wysocki <rjw@sisk.pl>
Subject: PM/Hibernate: Wait for SCSI devices scan to complete during resume
There is a race between resume from hibernation and the asynchronous
scanning of SCSI devices and to prevent it from happening we need to
call scsi_complete_async_scans() during resume from hibernation.
In addition, if the resume from hibernation is userland-driven, it's
better to wait for all device probes in the kernel to complete before
attempting to open the resume device.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
---
drivers/scsi/scsi_priv.h | 3 ---
drivers/scsi/scsi_wait_scan.c | 2 +-
include/scsi/scsi_scan.h | 11 +++++++++++
kernel/power/disk.c | 8 ++++++++
kernel/power/user.c | 9 +++++++++
5 files changed, 29 insertions(+), 4 deletions(-)
Index: linux-2.6/include/scsi/scsi_scan.h
===================================================================
--- /dev/null
+++ linux-2.6/include/scsi/scsi_scan.h
@@ -0,0 +1,11 @@
+#ifndef _SCSI_SCSI_SCAN_H
+#define _SCSI_SCSI_SCAN_H
+
+#ifdef CONFIG_SCSI
+/* drivers/scsi/scsi_scan.c */
+extern int scsi_complete_async_scans(void);
+#else
+static inline int scsi_complete_async_scans(void) { return 0; }
+#endif
+
+#endif /* _SCSI_SCSI_SCAN_H */
Index: linux-2.6/drivers/scsi/scsi_priv.h
===================================================================
--- linux-2.6.orig/drivers/scsi/scsi_priv.h
+++ linux-2.6/drivers/scsi/scsi_priv.h
@@ -38,9 +38,6 @@ static inline void scsi_log_completion(s
{ };
#endif
-/* scsi_scan.c */
-int scsi_complete_async_scans(void);
-
/* scsi_devinfo.c */
extern int scsi_get_device_flags(struct scsi_device *sdev,
const unsigned char *vendor,
Index: linux-2.6/drivers/scsi/scsi_wait_scan.c
===================================================================
--- linux-2.6.orig/drivers/scsi/scsi_wait_scan.c
+++ linux-2.6/drivers/scsi/scsi_wait_scan.c
@@ -11,7 +11,7 @@
*/
#include <linux/module.h>
-#include "scsi_priv.h"
+#include <scsi/scsi_scan.h>
static int __init wait_scan_init(void)
{
Index: linux-2.6/kernel/power/disk.c
===================================================================
--- linux-2.6.orig/kernel/power/disk.c
+++ linux-2.6/kernel/power/disk.c
@@ -22,5 +22,6 @@
#include <linux/console.h>
#include <linux/cpu.h>
#include <linux/freezer.h>
+#include <scsi/scsi_scan.h>
#include "power.h"
@@ -645,6 +646,13 @@ static int software_resume(void)
return 0;
/*
+ * We can't depend on SCSI devices being available after loading one of
+ * their modules if scsi_complete_async_scans() is not called and the
+ * resume device usually is a SCSI one.
+ */
+ scsi_complete_async_scans();
+
+ /*
* name_to_dev_t() below takes a sysfs buffer mutex when sysfs
* is configured into the kernel. Since the regular hibernate
* trigger path is via sysfs which takes a buffer mutex before
Index: linux-2.6/kernel/power/user.c
===================================================================
--- linux-2.6.orig/kernel/power/user.c
+++ linux-2.6/kernel/power/user.c
@@ -24,6 +24,7 @@
#include <linux/cpu.h>
#include <linux/freezer.h>
#include <linux/smp_lock.h>
+#include <scsi/scsi_scan.h>
#include <asm/uaccess.h>
@@ -92,6 +93,7 @@ static int snapshot_open(struct inode *i
filp->private_data = data;
memset(&data->handle, 0, sizeof(struct snapshot_handle));
if ((filp->f_flags & O_ACCMODE) == O_RDONLY) {
+ /* Hibernating. The image device should be accessible. */
data->swap = swsusp_resume_device ?
swap_type_of(swsusp_resume_device, 0, NULL) : -1;
data->mode = O_RDONLY;
@@ -99,6 +101,13 @@ static int snapshot_open(struct inode *i
if (error)
pm_notifier_call_chain(PM_POST_HIBERNATION);
} else {
+ /*
+ * Resuming. We may need to wait for the image device to
+ * appear.
+ */
+ wait_for_device_probe();
+ scsi_complete_async_scans();
+
data->swap = -1;
data->mode = O_WRONLY;
error = pm_notifier_call_chain(PM_RESTORE_PREPARE);

View File

@ -1,38 +0,0 @@
diff --git a/drivers/staging/rt2860/rt_linux.c b/drivers/staging/rt2860/rt_linux.c
index 80176b2..fc682be 100644
--- a/drivers/staging/rt2860/rt_linux.c
+++ b/drivers/staging/rt2860/rt_linux.c
@@ -27,7 +27,7 @@
#include "rt_config.h"
-ULONG RTDebugLevel = RT_DEBUG_ERROR;
+ULONG RTDebugLevel = RT_DEBUG_OFF;
BUILD_TIMER_FUNCTION(MlmePeriodicExec);
BUILD_TIMER_FUNCTION(AsicRxAntEvalTimeout);
diff --git a/drivers/staging/rt2860/rt_linux.h b/drivers/staging/rt2860/rt_linux.h
index 25b53ac..56ac9ac 100644
--- a/drivers/staging/rt2860/rt_linux.h
+++ b/drivers/staging/rt2860/rt_linux.h
@@ -375,18 +375,9 @@ extern ULONG RTDebugLevel;
#define DBGPRINT(Level, Fmt) DBGPRINT_RAW(Level, Fmt)
+#define DBGPRINT_ERR(Fmt)
-#define DBGPRINT_ERR(Fmt) \
-{ \
- printk("ERROR!!! "); \
- printk Fmt; \
-}
-
-#define DBGPRINT_S(Status, Fmt) \
-{ \
- printk Fmt; \
-}
-
+#define DBGPRINT_S(Status, Fmt)
#else
#define DBGPRINT(Level, Fmt)

File diff suppressed because it is too large Load Diff

View File

@ -1,142 +0,0 @@
From e412ebbb8cea2aaf32f689ffc630b57cfe13bde5 Mon Sep 17 00:00:00 2001
From: Alan Olsen <alanx.r.olsen@intel.com>
Date: Tue, 21 Jul 2009 13:14:25 -0700
Subject: [PATCH] linux-2.6-build-nonintconfig.patch
Signed-off-by: Alan Olsen <alanx.r.olsen@intel.com>
---
scripts/kconfig/Makefile | 5 +++++
scripts/kconfig/conf.c | 36 ++++++++++++++++++++++++++++++++----
2 files changed, 37 insertions(+), 4 deletions(-)
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index 5ddf8be..a4365db 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -28,6 +28,11 @@ oldconfig: $(obj)/conf
silentoldconfig: $(obj)/conf
$< -s $(Kconfig)
+nonint_oldconfig: $(obj)/conf
+ $< -b $(Kconfig)
+loose_nonint_oldconfig: $(obj)/conf
+ $< -B $(Kconfig)
+
# Create new linux.pot file
# Adjust charset to UTF-8 in .po file to accept UTF-8 in Kconfig files
# The symlink is used to repair a deficiency in arch/um
diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c
index 3baaaec..2a81742 100644
--- a/scripts/kconfig/conf.c
+++ b/scripts/kconfig/conf.c
@@ -23,6 +23,8 @@ enum {
ask_all,
ask_new,
ask_silent,
+ dont_ask,
+ dont_ask_dont_tell,
set_default,
set_yes,
set_mod,
@@ -40,6 +42,8 @@ static struct menu *rootEntry;
static char nohelp_text[] = N_("Sorry, no help available for this option yet.\n");
+static int return_value = 0;
+
static const char *get_help(struct menu *menu)
{
if (menu_has_help(menu))
@@ -360,7 +364,10 @@ static void conf(struct menu *menu)
switch (prop->type) {
case P_MENU:
- if (input_mode == ask_silent && rootEntry != menu) {
+ if ((input_mode == ask_silent ||
+ input_mode == dont_ask ||
+ input_mode == dont_ask_dont_tell) &&
+ rootEntry != menu) {
check_conf(menu);
return;
}
@@ -418,12 +425,21 @@ static void check_conf(struct menu *menu)
if (sym && !sym_has_value(sym)) {
if (sym_is_changable(sym) ||
(sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) {
+ if (input_mode == dont_ask ||
+ input_mode == dont_ask_dont_tell) {
+ if (input_mode == dont_ask &&
+ sym->name && !sym_is_choice_value(sym)) {
+ fprintf(stderr,"CONFIG_%s\n",sym->name);
+ ++return_value;
+ }
+ } else {
if (!conf_cnt++)
printf(_("*\n* Restart config...\n*\n"));
rootEntry = menu_get_parent_menu(menu);
conf(rootEntry);
}
}
+ }
for (child = menu->list; child; child = child->next)
check_conf(child);
@@ -439,7 +455,7 @@ int main(int ac, char **av)
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
- while ((opt = getopt(ac, av, "osdD:nmyrh")) != -1) {
+ while ((opt = getopt(ac, av, "osbBdD:nmyrh")) != -1) {
switch (opt) {
case 'o':
input_mode = ask_silent;
@@ -448,6 +464,12 @@ int main(int ac, char **av)
input_mode = ask_silent;
sync_kconfig = 1;
break;
+ case 'b':
+ input_mode = dont_ask;
+ break;
+ case 'B':
+ input_mode = dont_ask_dont_tell;
+ break;
case 'd':
input_mode = set_default;
break;
@@ -525,6 +547,8 @@ int main(int ac, char **av)
case ask_silent:
case ask_all:
case ask_new:
+ case dont_ask:
+ case dont_ask_dont_tell:
conf_read(NULL);
break;
case set_no:
@@ -586,12 +610,16 @@ int main(int ac, char **av)
conf(&rootmenu);
input_mode = ask_silent;
/* fall through */
+ case dont_ask:
+ case dont_ask_dont_tell:
case ask_silent:
/* Update until a loop caused no more changes */
do {
conf_cnt = 0;
check_conf(&rootmenu);
- } while (conf_cnt);
+ } while (conf_cnt &&
+ (input_mode != dont_ask &&
+ input_mode != dont_ask_dont_tell));
break;
}
@@ -613,5 +641,5 @@ int main(int ac, char **av)
exit(1);
}
}
- return 0;
+ return return_value;
}
--
1.6.0.6

View File

@ -1,61 +0,0 @@
commit 0f592e33934bf6108e33e34f00b425f98ee833ef
Author: Matthew Garrett <mjg@redhat.com>
Date: Wed Jul 8 19:04:23 2009 +0100
usb: Allow drivers to enable USB autosuspend on a per-device basis
USB autosuspend is currently only enabled by default for hubs. On other
hardware the decision is made by userspace. This is unnecessary in cases
where we know that the hardware supports autosuspend, so this patch adds
a function to allow drivers to enable it at probe time.
Signed-off-by: Matthew Garrett <mjg@redhat.com>
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 69e5773..6e81caa 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -1560,6 +1560,21 @@ void usb_autopm_put_interface_async(struct usb_interface *intf)
EXPORT_SYMBOL_GPL(usb_autopm_put_interface_async);
/**
+ * usb_device_autosuspend_enable - enable autosuspend on a device
+ * @udev: the usb_device to be autosuspended
+ *
+ * This routine should be called by an interface driver when it knows that
+ * the device in question supports USB autosuspend.
+ *
+ */
+void usb_device_autosuspend_enable(struct usb_device *udev)
+{
+ udev->autosuspend_disabled = 0;
+ udev->autoresume_disabled = 0;
+}
+EXPORT_SYMBOL_GPL(usb_device_autosuspend_enable);
+
+/**
* usb_autopm_get_interface - increment a USB interface's PM-usage counter
* @intf: the usb_interface whose counter should be incremented
*
diff --git a/include/linux/usb.h b/include/linux/usb.h
index b1e3c2f..61bddbe 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -543,6 +543,7 @@ extern struct usb_device *usb_find_device(u16 vendor_id, u16 product_id);
/* USB autosuspend and autoresume */
#ifdef CONFIG_USB_SUSPEND
+extern void usb_device_autosuspend_enable(struct usb_device *udev);
extern int usb_autopm_set_interface(struct usb_interface *intf);
extern int usb_autopm_get_interface(struct usb_interface *intf);
extern void usb_autopm_put_interface(struct usb_interface *intf);
@@ -568,6 +569,9 @@ static inline void usb_mark_last_busy(struct usb_device *udev)
#else
+static inline void usb_device_autosuspend_enable(struct usb_device *udev)
+{ }
+
static inline int usb_autopm_set_interface(struct usb_interface *intf)
{ return 0; }

View File

@ -1,19 +0,0 @@
commit 9d4c919bcfa794c054cc33155c7e3c53ac2c5684
Author: Matthew Garrett <mjg@redhat.com>
Date: Sun Jul 19 02:24:49 2009 +0100
Enable autosuspend on UVC by default
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index 89927b7..8de516b 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -1647,6 +1647,8 @@ static int uvc_probe(struct usb_interface *intf,
"supported.\n", ret);
}
+ usb_device_autosuspend_enable(udev);
+
uvc_trace(UVC_TRACE_PROBE, "UVC device initialized.\n");
return 0;

View File

@ -1,47 +0,0 @@
From dce8113d033975f56630cf6d2a6a908cfb66059d Mon Sep 17 00:00:00 2001
From: Arjan van de Ven <arjan@linux.intel.com>
Date: Sun, 20 Jul 2008 13:12:16 -0700
Subject: [PATCH] fastboot: remove "wait for all devices before mounting root" delay
In the non-initrd case, we wait for all devices to finish their
probing before we try to mount the rootfs.
In practice, this means that we end up waiting 2 extra seconds for
the PS/2 mouse probing even though the root holding device has been
ready since a long time.
The previous two patches in this series made the RAID autodetect code
do it's own "wait for probing to be done" code, and added
"wait and retry" functionality in case the root device isn't actually
available.
These two changes should make it safe to remove the delay itself,
and this patch does this. On my test laptop, this reduces the boot time
by 2 seconds (kernel time goes from 3.9 to 1.9 seconds).
Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
---
---
init/do_mounts.c | 3 +++
1 file changed, 3 insertions(+)
Index: linux-2.6.29/init/do_mounts.c
===================================================================
--- linux-2.6.29.orig/init/do_mounts.c
+++ linux-2.6.29/init/do_mounts.c
@@ -370,6 +370,7 @@ void __init prepare_namespace(void)
ssleep(root_delay);
}
+#if 0
/*
* wait for the known devices to complete their probing
*
@@ -378,6 +379,8 @@ void __init prepare_namespace(void)
* for the touchpad of a laptop to initialize.
*/
wait_for_device_probe();
+#endif
+ async_synchronize_full();
md_run_setup();

View File

@ -1,25 +0,0 @@
From 0143f8eb8afcaccba5a78196fb3db4361e0097a7 Mon Sep 17 00:00:00 2001
From: Arjan van de Ven <arjan@linux.intel.com>
Date: Mon, 9 Feb 2009 21:25:32 -0800
Subject: [PATCH] jbd: longer commit interval
... 5 seconds is rather harsh on ssd's..
Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
---
include/linux/jbd.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Index: linux-2.6.29/include/linux/jbd.h
===================================================================
--- linux-2.6.29.orig/include/linux/jbd.h
+++ linux-2.6.29/include/linux/jbd.h
@@ -46,7 +46,7 @@
/*
* The default maximum commit age, in seconds.
*/
-#define JBD_DEFAULT_MAX_COMMIT_AGE 5
+#define JBD_DEFAULT_MAX_COMMIT_AGE 15
#ifdef CONFIG_JBD_DEBUG
/*

View File

@ -1,38 +0,0 @@
---
drivers/Makefile | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
Index: linux-2.6.29/drivers/Makefile
===================================================================
--- linux-2.6.29.orig/drivers/Makefile
+++ linux-2.6.29/drivers/Makefile
@@ -25,15 +25,8 @@ obj-$(CONFIG_REGULATOR) += regulator/
# default.
obj-y += char/
-# gpu/ comes after char for AGP vs DRM startup
-obj-y += gpu/
-
obj-$(CONFIG_CONNECTOR) += connector/
-# i810fb and intelfb depend on char/agp/
-obj-$(CONFIG_FB_I810) += video/i810/
-obj-$(CONFIG_FB_INTEL) += video/intelfb/
-
obj-y += serial/
obj-$(CONFIG_PARPORT) += parport/
obj-y += base/ block/ misc/ mfd/ media/
@@ -43,6 +36,13 @@ obj-$(CONFIG_IDE) += ide/
obj-$(CONFIG_SCSI) += scsi/
obj-$(CONFIG_ATA) += ata/
obj-y += net/
+
+# gpu/ comes after char for AGP vs DRM startup
+obj-y += gpu/
+# i810fb and intelfb depend on char/agp/
+obj-$(CONFIG_FB_I810) += video/i810/
+obj-$(CONFIG_FB_INTEL) += video/intelfb/
+
obj-$(CONFIG_ATM) += atm/
obj-$(CONFIG_FUSION) += message/
obj-$(CONFIG_FIREWIRE) += firewire/

View File

@ -1,33 +0,0 @@
--- vanilla-2.6.31-rc4/drivers/gpu/drm/i915/intel_lvds.c~ 2009-07-31 11:23:05.000000000 -0700
+++ vanilla-2.6.31-rc4/drivers/gpu/drm/i915/intel_lvds.c 2009-07-31 11:23:05.000000000 -0700
@@ -111,19 +111,12 @@ static void intel_lvds_set_power(struct
if (on) {
I915_WRITE(ctl_reg, I915_READ(ctl_reg) |
POWER_TARGET_ON);
- do {
- pp_status = I915_READ(status_reg);
- } while ((pp_status & PP_ON) == 0);
-
intel_lvds_set_backlight(dev, dev_priv->backlight_duty_cycle);
} else {
intel_lvds_set_backlight(dev, 0);
I915_WRITE(ctl_reg, I915_READ(ctl_reg) &
~POWER_TARGET_ON);
- do {
- pp_status = I915_READ(status_reg);
- } while (pp_status & PP_ON);
}
}
--- linux-2.6.31/drivers/gpu/drm/i915/intel_lvds.c~ 2009-10-11 10:13:38.000000000 -0700
+++ linux-2.6.31/drivers/gpu/drm/i915/intel_lvds.c 2009-10-11 10:13:38.000000000 -0700
@@ -98,7 +98,7 @@
static void intel_lvds_set_power(struct drm_device *dev, bool on)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- u32 pp_status, ctl_reg, status_reg;
+ u32 ctl_reg, status_reg;
if (IS_IGDNG(dev)) {
ctl_reg = PCH_PP_CONTROL;

View File

@ -1,58 +0,0 @@
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 004541c..b218780 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -81,6 +81,7 @@ struct intel_output {
int type;
struct i2c_adapter *i2c_bus;
struct i2c_adapter *ddc_bus;
+ struct edid *edid;
bool load_detect_temp;
bool needs_tv_clock;
void *dev_priv;
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 9ab38ef..9fba800 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -657,6 +657,7 @@ static void intel_lvds_destroy(struct drm_connector *connector)
intel_i2c_destroy(intel_output->ddc_bus);
drm_sysfs_connector_remove(connector);
drm_connector_cleanup(connector);
+ kfree(intel_output->edid);
kfree(connector);
}
@@ -1017,5 +1018,6 @@ failed:
if (intel_output->ddc_bus)
intel_i2c_destroy(intel_output->ddc_bus);
drm_connector_cleanup(connector);
+ kfree(intel_output->edid);
kfree(intel_output);
}
diff --git a/drivers/gpu/drm/i915/intel_modes.c b/drivers/gpu/drm/i915/intel_modes.c
index 67e2f46..5ac537f 100644
--- a/drivers/gpu/drm/i915/intel_modes.c
+++ b/drivers/gpu/drm/i915/intel_modes.c
@@ -74,6 +74,10 @@ int intel_ddc_get_modes(struct intel_output *intel_output)
int ret = 0;
intel_i2c_quirk_set(intel_output->base.dev, true);
+ if (intel_output->edid && intel_output->type == INTEL_OUTPUT_LVDS) {
+ printk(KERN_INFO "Skipping EDID probe due to cached edid\n");
+ return ret;
+ }
edid = drm_get_edid(&intel_output->base, intel_output->ddc_bus);
intel_i2c_quirk_set(intel_output->base.dev, false);
if (edid) {
@@ -81,7 +85,10 @@ int intel_ddc_get_modes(struct intel_output *intel_output)
edid);
ret = drm_add_edid_modes(&intel_output->base, edid);
intel_output->base.display_info.raw_edid = NULL;
- kfree(edid);
+ if (intel_output->type == INTEL_OUTPUT_LVDS)
+ intel_output->edid = edid;
+ else
+ kfree(edid);
}
return ret;

View File

@ -1,118 +0,0 @@
Index: b/drivers/gpu/drm/drm_crtc_helper.c
===================================================================
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -29,6 +29,8 @@
* Jesse Barnes <jesse.barnes@intel.com>
*/
+#include <linux/async.h>
+
#include "drmP.h"
#include "drm_crtc.h"
#include "drm_crtc_helper.h"
@@ -62,6 +64,8 @@ static void drm_mode_validate_flag(struc
return;
}
+LIST_HEAD(drm_async_list);
+
/**
* drm_helper_probe_connector_modes - get complete set of display modes
* @dev: DRM device
@@ -916,6 +920,7 @@ bool drm_helper_plugged_event(struct drm
/* FIXME: send hotplug event */
return true;
}
+
/**
* drm_initial_config - setup a sane initial connector configuration
* @dev: DRM device
@@ -953,13 +958,26 @@ bool drm_helper_initial_config(struct dr
drm_setup_crtcs(dev);
- /* alert the driver fb layer */
dev->mode_config.funcs->fb_changed(dev);
-
return 0;
}
EXPORT_SYMBOL(drm_helper_initial_config);
+static void drm_helper_initial_config_helper(void *ptr, async_cookie_t cookie)
+{
+ struct drm_device *dev = ptr;
+ drm_helper_initial_config(dev);
+}
+
+void drm_helper_initial_config_async(struct drm_device *dev)
+{
+ async_schedule_domain(drm_helper_initial_config_helper,
+ dev, &drm_async_list);
+}
+EXPORT_SYMBOL(drm_helper_initial_config_async);
+
+
+
static int drm_helper_choose_encoder_dpms(struct drm_encoder *encoder)
{
int dpms = DRM_MODE_DPMS_OFF;
Index: b/drivers/gpu/drm/drm_drv.c
===================================================================
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -49,6 +49,7 @@
#include <linux/debugfs.h>
#include "drmP.h"
#include "drm_core.h"
+#include <linux/async.h>
static int drm_version(struct drm_device *dev, void *data,
@@ -290,6 +291,9 @@ void drm_exit(struct drm_driver *driver)
struct drm_device *dev, *tmp;
DRM_DEBUG("\n");
+ /* make sure all async DRM operations are finished */
+ async_synchronize_full_domain(&drm_async_list);
+
if (driver->driver_features & DRIVER_MODESET) {
pci_unregister_driver(&driver->pci_driver);
} else {
Index: b/include/drm/drmP.h
===================================================================
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -328,6 +328,7 @@ struct drm_vma_entry {
pid_t pid;
};
+extern struct list_head drm_async_list;
/**
* DMA buffer.
*/
Index: b/include/drm/drm_crtc_helper.h
===================================================================
--- a/include/drm/drm_crtc_helper.h
+++ b/include/drm/drm_crtc_helper.h
@@ -92,6 +92,7 @@ extern int drm_helper_probe_single_conne
extern void drm_helper_disable_unused_functions(struct drm_device *dev);
extern int drm_helper_hotplug_stage_two(struct drm_device *dev);
extern bool drm_helper_initial_config(struct drm_device *dev);
+extern void drm_helper_initial_config_async(struct drm_device *dev);
extern int drm_crtc_helper_set_config(struct drm_mode_set *set);
extern bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
struct drm_display_mode *mode,
Index: b/drivers/gpu/drm/i915/i915_dma.c
===================================================================
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1045,7 +1045,7 @@ static int i915_load_modeset_init(struct
intel_modeset_init(dev);
- drm_helper_initial_config(dev);
+ drm_helper_initial_config_async(dev);
return 0;

View File

@ -1,22 +0,0 @@
From: Arjan van de Ven <arjan@linux.intel.com>
Date: Fri, 23 Jan 2009
Small fix changing error msg to info msg in acer wmi driver
---
---
drivers/platform/x86/acer-wmi.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Index: linux-2.6.29/drivers/platform/x86/acer-wmi.c
===================================================================
--- linux-2.6.29.orig/drivers/platform/x86/acer-wmi.c
+++ linux-2.6.29/drivers/platform/x86/acer-wmi.c
@@ -1290,7 +1290,7 @@ static int __init acer_wmi_init(void)
AMW0_find_mailled();
if (!interface) {
- printk(ACER_ERR "No or unsupported WMI interface, unable to "
+ printk(ACER_INFO "No or unsupported WMI interface, unable to "
"load\n");
return -ENODEV;
}

View File

@ -1,66 +0,0 @@
From 4d690855d6bdc15b753ac3c21bf507ad94d46aac Mon Sep 17 00:00:00 2001
From: Arjan van de Ven <arjan@linux.intel.com>
Date: Sun, 21 Sep 2008 11:58:27 -0700
Subject: [PATCH] superreadahead patch
---
fs/ext3/ioctl.c | 3 +++
fs/ext3/super.c | 1 +
include/linux/ext3_fs.h | 1 +
include/linux/fs.h | 2 ++
4 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/fs/ext3/ioctl.c b/fs/ext3/ioctl.c
index 8897481..08f4854 100644
--- a/fs/ext3/ioctl.c
+++ b/fs/ext3/ioctl.c
@@ -276,6 +276,9 @@ group_add_out:
mnt_drop_write(filp->f_path.mnt);
return err;
}
+ case EXT3_IOC_INODE_JIFFIES: {
+ return inode->created_when;
+ }
default:
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 524b349..e6e8514 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -466,6 +466,7 @@ static struct inode *ext3_alloc_inode(struct super_block *sb)
return NULL;
ei->i_block_alloc_info = NULL;
ei->vfs_inode.i_version = 1;
+ ei->vfs_inode.created_when = jiffies;
return &ei->vfs_inode;
}
diff --git a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h
index 634a5e5..84d5394 100644
--- a/include/linux/ext3_fs.h
+++ b/include/linux/ext3_fs.h
@@ -250,6 +250,7 @@ struct ext3_new_group_data {
#endif
#define EXT3_IOC_GETRSVSZ _IOR('f', 5, long)
#define EXT3_IOC_SETRSVSZ _IOW('f', 6, long)
+#define EXT3_IOC_INODE_JIFFIES _IOR('f', 19, long)
/*
* ioctl commands in 32 bit emulation
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 0872372..078e3fd 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -781,6 +781,8 @@ struct inode {
struct posix_acl *i_default_acl;
#endif
void *i_private; /* fs or device private pointer */
+
+ unsigned long created_when; /* jiffies of creation time */
};
/*
--
1.6.0.6

View File

@ -1,146 +0,0 @@
From 3281da09528ca94f1b1fd39cae388f5b5423aa46 Mon Sep 17 00:00:00 2001
From: Alan Olsen <alanx.r.olsen@intel.com>
Date: Tue, 21 Jul 2009 13:26:58 -0700
Subject: [PATCH] linux-2.6.29-touchkit.patch
Signed-off-by: Alan Olsen <alanx.r.olsen@intel.com>
---
drivers/input/mouse/psmouse-base.c | 9 +++++++
drivers/input/mouse/psmouse.h | 1 +
drivers/input/mouse/touchkit_ps2.c | 45 ++++++++++++++++++++++++++++++++++-
drivers/input/mouse/touchkit_ps2.h | 6 ++++
4 files changed, 59 insertions(+), 2 deletions(-)
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index b407b35..4c6b184 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -678,6 +678,9 @@ static int psmouse_extensions(struct psmouse *psmouse,
if (touchkit_ps2_detect(psmouse, set_properties) == 0)
return PSMOUSE_TOUCHKIT_PS2;
+
+ if (elftouch_ps2_detect(psmouse, set_properties) == 0)
+ return PSMOUSE_ELFTOUCH_PS2;
}
/*
@@ -788,6 +791,12 @@ static const struct psmouse_protocol psmouse_protocols[] = {
.alias = "trackpoint",
.detect = trackpoint_detect,
},
+ {
+ .type = PSMOUSE_ELFTOUCH_PS2,
+ .name = "elftouchPS2",
+ .alias = "elftouch",
+ .detect = elftouch_ps2_detect,
+ },
#endif
#ifdef CONFIG_MOUSE_PS2_TOUCHKIT
{
diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
index 54ed267..8d1ba79 100644
--- a/drivers/input/mouse/psmouse.h
+++ b/drivers/input/mouse/psmouse.h
@@ -89,6 +89,7 @@ enum psmouse_type {
PSMOUSE_TRACKPOINT,
PSMOUSE_TOUCHKIT_PS2,
PSMOUSE_CORTRON,
+ PSMOUSE_ELFTOUCH_PS2,
PSMOUSE_HGPK,
PSMOUSE_ELANTECH,
PSMOUSE_AUTO /* This one should always be last */
diff --git a/drivers/input/mouse/touchkit_ps2.c b/drivers/input/mouse/touchkit_ps2.c
index 3fadb2a..e9c27f1 100644
--- a/drivers/input/mouse/touchkit_ps2.c
+++ b/drivers/input/mouse/touchkit_ps2.c
@@ -51,6 +51,11 @@
#define TOUCHKIT_GET_X(packet) (((packet)[1] << 7) | (packet)[2])
#define TOUCHKIT_GET_Y(packet) (((packet)[3] << 7) | (packet)[4])
+#define ELFTOUCH_MAX_XC 0x0fff
+#define ELFTOUCH_MAX_YC 0x0fff
+#define ELFTOUCH_GET_X(packet) (((packet)[3] << 7) | (packet)[4])
+#define ELFTOUCH_GET_Y(packet) (((packet)[1] << 7) | (packet)[2])
+
static psmouse_ret_t touchkit_ps2_process_byte(struct psmouse *psmouse)
{
unsigned char *packet = psmouse->packet;
@@ -59,9 +64,15 @@ static psmouse_ret_t touchkit_ps2_process_byte(struct psmouse *psmouse)
if (psmouse->pktcnt != 5)
return PSMOUSE_GOOD_DATA;
- input_report_abs(dev, ABS_X, TOUCHKIT_GET_X(packet));
- input_report_abs(dev, ABS_Y, TOUCHKIT_GET_Y(packet));
+ if(psmouse->type==PSMOUSE_ELFTOUCH_PS2) {
+ input_report_abs(dev, ABS_X, ELFTOUCH_GET_X(packet));
+ input_report_abs(dev, ABS_Y, ELFTOUCH_GET_Y(packet));
+ } else {
+ input_report_abs(dev, ABS_X, TOUCHKIT_GET_X(packet));
+ input_report_abs(dev, ABS_Y, TOUCHKIT_GET_Y(packet));
+ }
input_report_key(dev, BTN_TOUCH, TOUCHKIT_GET_TOUCHED(packet));
+
input_sync(dev);
return PSMOUSE_FULL_PACKET;
@@ -98,3 +109,33 @@ int touchkit_ps2_detect(struct psmouse *psmouse, int set_properties)
return 0;
}
+
+int elftouch_ps2_detect(struct psmouse *psmouse, int set_properties)
+{
+ struct input_dev *dev = psmouse->dev;
+ unsigned char param[16];
+ int command, res;
+
+ param[0]=0x0f4;
+ command = TOUCHKIT_SEND_PARMS(1, 0, TOUCHKIT_CMD);
+ res=ps2_command(&psmouse->ps2dev, param, command);
+ if(res) { return -ENODEV; }
+
+ param[0]=0x0b0;
+ command = TOUCHKIT_SEND_PARMS(1, 1, TOUCHKIT_CMD);
+ res=ps2_command(&psmouse->ps2dev, param, command);
+ if(res) { return -ENODEV; }
+
+ if (set_properties) {
+ dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+ set_bit(BTN_TOUCH, dev->keybit);
+ input_set_abs_params(dev, ABS_X, 0, ELFTOUCH_MAX_XC, 0, 0);
+ input_set_abs_params(dev, ABS_Y, 0, ELFTOUCH_MAX_YC, 0, 0);
+
+ psmouse->vendor = "ElfTouch";
+ psmouse->name = "Touchscreen";
+ psmouse->protocol_handler = touchkit_ps2_process_byte;
+ psmouse->pktsize = 5;
+ }
+ return 0;
+}
diff --git a/drivers/input/mouse/touchkit_ps2.h b/drivers/input/mouse/touchkit_ps2.h
index 8a0dd35..f32ef4c 100644
--- a/drivers/input/mouse/touchkit_ps2.h
+++ b/drivers/input/mouse/touchkit_ps2.h
@@ -14,12 +14,18 @@
#ifdef CONFIG_MOUSE_PS2_TOUCHKIT
int touchkit_ps2_detect(struct psmouse *psmouse, int set_properties);
+int elftouch_ps2_detect(struct psmouse *psmouse, int set_properties);
#else
static inline int touchkit_ps2_detect(struct psmouse *psmouse,
int set_properties)
{
return -ENOSYS;
}
+static inline int elftouch_ps2_detect(struct psmouse *psmouse,
+ int set_properties)
+{
+ return -ENOSYS;
+}
#endif /* CONFIG_MOUSE_PS2_TOUCHKIT */
#endif
--
1.6.0.6

View File

@ -1,32 +0,0 @@
From a5a267593c15ac987f78cfc21cae0c8ef723f81e Mon Sep 17 00:00:00 2001
From: Alan Olsen <alan.r.olsen@intel.com>
Date: Mon, 21 Sep 2009 13:58:49 -0700
Subject: [PATCH] linux-2.6.30-non-root-X.patch
Signed-off-by: Alan Olsen <alan.r.olsen@intel.com>
---
drivers/gpu/drm/drm_drv.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 4678f8f..b7f3a41 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -64,12 +64,12 @@ static struct drm_ioctl_desc drm_ioctls[] = {
DRM_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_getmap, 0),
DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT, drm_getclient, 0),
DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS, drm_getstats, 0),
- DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER),
DRM_IOCTL_DEF(DRM_IOCTL_SET_UNIQUE, drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
DRM_IOCTL_DEF(DRM_IOCTL_BLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
DRM_IOCTL_DEF(DRM_IOCTL_UNBLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF(DRM_IOCTL_AUTH_MAGIC, drm_authmagic, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_AUTH_MAGIC, drm_authmagic, DRM_AUTH|DRM_MASTER),
DRM_IOCTL_DEF(DRM_IOCTL_ADD_MAP, drm_addmap_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
DRM_IOCTL_DEF(DRM_IOCTL_RM_MAP, drm_rmmap_ioctl, DRM_AUTH),
--
1.6.0.6

View File

@ -1,44 +0,0 @@
From 9de5f61c79361bf6e9394d2f77a2b436d53deee5 Mon Sep 17 00:00:00 2001
From: Yong Wang <yong.y.wang@intel.com>
Date: Tue, 30 Jun 2009 14:17:19 +0800
Subject: [PATCH] Revert "net: num_dma_maps is not used"
This reverts commit eae3f29cc73f83cc3f1891d3ad40021b5172c630.
The IVI driver is a user of num_dma_maps.
Signed-off-by: Yong Wang <yong.y.wang@intel.com>
---
include/linux/skbuff.h | 3 +++
net/core/skb_dma_map.c | 1 +
2 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index b47b3f0..468bc21 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -198,6 +198,9 @@ struct skb_shared_info {
unsigned short gso_type;
__be32 ip6_frag_id;
union skb_shared_tx tx_flags;
+#ifdef CONFIG_HAS_DMA
+ unsigned int num_dma_maps;
+#endif
struct sk_buff *frag_list;
struct skb_shared_hwtstamps hwtstamps;
skb_frag_t frags[MAX_SKB_FRAGS];
diff --git a/net/core/skb_dma_map.c b/net/core/skb_dma_map.c
index 79687df..07d4ac5 100644
--- a/net/core/skb_dma_map.c
+++ b/net/core/skb_dma_map.c
@@ -30,6 +30,7 @@ int skb_dma_map(struct device *dev, struct sk_buff *skb,
goto unwind;
sp->dma_maps[i] = map;
}
+ sp->num_dma_maps = i + 1;
return 0;
--
1.6.0.6

View File

@ -1,465 +0,0 @@
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index e70c57e..8e36fc8 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -35,7 +36,7 @@
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
-#define VERSION "0.5"
+#define VERSION "0.6"
static int ignore_dga;
static int ignore_csr;
@@ -145,6 +146,7 @@ static struct usb_device_id blacklist_table[] = {
#define BTUSB_INTR_RUNNING 0
#define BTUSB_BULK_RUNNING 1
#define BTUSB_ISOC_RUNNING 2
+#define BTUSB_SUSPENDING 3
struct btusb_data {
struct hci_dev *hdev;
@@ -157,11 +159,15 @@ struct btusb_data {
unsigned long flags;
struct work_struct work;
+ struct work_struct waker;
struct usb_anchor tx_anchor;
struct usb_anchor intr_anchor;
struct usb_anchor bulk_anchor;
struct usb_anchor isoc_anchor;
+ struct usb_anchor deferred;
+ int tx_in_flight;
+ spinlock_t txlock;
struct usb_endpoint_descriptor *intr_ep;
struct usb_endpoint_descriptor *bulk_tx_ep;
@@ -174,8 +180,26 @@ struct btusb_data {
unsigned int sco_num;
int isoc_altsetting;
int suspend_count;
+ int did_iso_resume:1;
};
+static int inc_tx(struct btusb_data *data)
+{
+ unsigned long flags;
+ int rv;
+
+ spin_lock_irqsave(&data->txlock, flags);
+ rv = test_bit(BTUSB_SUSPENDING, &data->flags);
+ BT_DBG("BTUSB_SUSPENDING bit = %d for intf %p in %s",
+ rv, data->intf, __func__);
+ if (!rv)
+ data->tx_in_flight++;
+ spin_unlock_irqrestore(&data->txlock, flags);
+
+ return rv;
+}
+
+
static void btusb_intr_complete(struct urb *urb)
{
struct hci_dev *hdev = urb->context;
@@ -202,6 +226,7 @@ static void btusb_intr_complete(struct urb *urb)
if (!test_bit(BTUSB_INTR_RUNNING, &data->flags))
return;
+ usb_mark_last_busy(data->udev);
usb_anchor_urb(urb, &data->intr_anchor);
err = usb_submit_urb(urb, GFP_ATOMIC);
@@ -327,6 +352,7 @@ static int btusb_submit_bulk_urb(struct hci_dev *hdev, gfp_t mem_flags)
urb->transfer_flags |= URB_FREE_BUFFER;
+ usb_mark_last_busy(data->udev);
usb_anchor_urb(urb, &data->bulk_anchor);
err = usb_submit_urb(urb, mem_flags);
@@ -465,6 +491,33 @@ static void btusb_tx_complete(struct urb *urb)
{
struct sk_buff *skb = urb->context;
struct hci_dev *hdev = (struct hci_dev *) skb->dev;
+ struct btusb_data *data = hdev->driver_data;
+
+ BT_DBG("%s urb %p status %d count %d", hdev->name,
+ urb, urb->status, urb->actual_length);
+
+ if (!test_bit(HCI_RUNNING, &hdev->flags))
+ goto done;
+
+ if (!urb->status)
+ hdev->stat.byte_tx += urb->transfer_buffer_length;
+ else
+ hdev->stat.err_tx++;
+
+done:
+ spin_lock(&data->txlock);
+ data->tx_in_flight--;
+ spin_unlock(&data->txlock);
+
+ kfree(urb->setup_packet);
+
+ kfree_skb(skb);
+}
+
+static void btusb_isoc_tx_complete(struct urb *urb)
+{
+ struct sk_buff *skb = urb->context;
+ struct hci_dev *hdev = (struct hci_dev *) skb->dev;
BT_DBG("%s urb %p status %d count %d", hdev->name,
urb, urb->status, urb->actual_length);
@@ -490,11 +543,16 @@ static int btusb_open(struct hci_dev *hdev)
BT_DBG("%s", hdev->name);
+ err = usb_autopm_get_interface(data->intf);
+ if (err < 0)
+ return err;
+ data->intf->needs_remote_wakeup = 1;
+
if (test_and_set_bit(HCI_RUNNING, &hdev->flags))
- return 0;
+ goto out;
if (test_and_set_bit(BTUSB_INTR_RUNNING, &data->flags))
- return 0;
+ goto out;
err = btusb_submit_intr_urb(hdev, GFP_KERNEL);
if (err < 0)
@@ -502,6 +560,7 @@ static int btusb_open(struct hci_dev *hdev)
err = btusb_submit_bulk_urb(hdev, GFP_KERNEL);
if (err < 0) {
+ BT_DBG("kill urbs %s", __func__);
usb_kill_anchored_urbs(&data->intr_anchor);
goto failed;
}
@@ -509,17 +568,28 @@ static int btusb_open(struct hci_dev *hdev)
set_bit(BTUSB_BULK_RUNNING, &data->flags);
btusb_submit_bulk_urb(hdev, GFP_KERNEL);
+out:
+ usb_autopm_put_interface(data->intf);
return 0;
failed:
clear_bit(BTUSB_INTR_RUNNING, &data->flags);
clear_bit(HCI_RUNNING, &hdev->flags);
+ usb_autopm_put_interface(data->intf);
return err;
}
+static void btusb_stop_traffic(struct btusb_data *data)
+{
+ usb_kill_anchored_urbs(&data->intr_anchor);
+ usb_kill_anchored_urbs(&data->bulk_anchor);
+ usb_kill_anchored_urbs(&data->isoc_anchor);
+}
+
static int btusb_close(struct hci_dev *hdev)
{
struct btusb_data *data = hdev->driver_data;
+ int err;
BT_DBG("%s", hdev->name);
@@ -529,13 +599,16 @@ static int btusb_close(struct hci_dev *hdev)
cancel_work_sync(&data->work);
clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
- usb_kill_anchored_urbs(&data->isoc_anchor);
-
clear_bit(BTUSB_BULK_RUNNING, &data->flags);
- usb_kill_anchored_urbs(&data->bulk_anchor);
-
clear_bit(BTUSB_INTR_RUNNING, &data->flags);
- usb_kill_anchored_urbs(&data->intr_anchor);
+
+ BT_DBG("kill urbs %s", __func__);
+ btusb_stop_traffic(data);
+ err = usb_autopm_get_interface(data->intf);
+ if (!err) {
+ data->intf->needs_remote_wakeup = 0;
+ usb_autopm_put_interface(data->intf);
+ }
return 0;
}
@@ -546,6 +619,7 @@ static int btusb_flush(struct hci_dev *hdev)
BT_DBG("%s", hdev->name);
+ BT_DBG("kill urbs %s", __func__);
usb_kill_anchored_urbs(&data->tx_anchor);
return 0;
@@ -622,7 +696,7 @@ static int btusb_send_frame(struct sk_buff *skb)
urb->dev = data->udev;
urb->pipe = pipe;
urb->context = skb;
- urb->complete = btusb_tx_complete;
+ urb->complete = btusb_isoc_tx_complete;
urb->interval = data->isoc_tx_ep->bInterval;
urb->transfer_flags = URB_ISO_ASAP;
@@ -633,12 +707,23 @@ static int btusb_send_frame(struct sk_buff *skb)
le16_to_cpu(data->isoc_tx_ep->wMaxPacketSize));
hdev->stat.sco_tx++;
- break;
+ goto skip_waking;
default:
return -EILSEQ;
}
+ err = inc_tx(data);
+ if (err) {
+
+ usb_anchor_urb(urb, &data->deferred);
+ schedule_work(&data->waker);
+ err = 0;
+ goto out;
+ } else {
+
+ }
+skip_waking:
usb_anchor_urb(urb, &data->tx_anchor);
err = usb_submit_urb(urb, GFP_ATOMIC);
@@ -646,10 +731,13 @@ static int btusb_send_frame(struct sk_buff *skb)
BT_ERR("%s urb %p submission failed", hdev->name, urb);
kfree(urb->setup_packet);
usb_unanchor_urb(urb);
+ } else {
+ usb_mark_last_busy(data->udev);
}
usb_free_urb(urb);
+out:
return err;
}
@@ -721,10 +809,23 @@ static void btusb_work(struct work_struct *work)
{
struct btusb_data *data = container_of(work, struct btusb_data, work);
struct hci_dev *hdev = data->hdev;
+ int err;
if (hdev->conn_hash.sco_num > 0) {
+ if (!data->did_iso_resume) {
+ err = usb_autopm_get_interface(data->isoc);
+ if (!err) {
+ data->did_iso_resume = 1;
+ } else {
+ clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
+ BT_DBG("kill urbs %s", __func__);
+ usb_kill_anchored_urbs(&data->isoc_anchor);
+ return;
+ }
+ }
if (data->isoc_altsetting != 2) {
clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
+ BT_DBG("kill urbs %s", __func__);
usb_kill_anchored_urbs(&data->isoc_anchor);
if (__set_isoc_interface(hdev, 2) < 0)
@@ -739,12 +840,28 @@ static void btusb_work(struct work_struct *work)
}
} else {
clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
+ BT_DBG("kill urbs %s", __func__);
usb_kill_anchored_urbs(&data->isoc_anchor);
__set_isoc_interface(hdev, 0);
+ if (data->did_iso_resume) {
+ data->did_iso_resume = 0;
+ usb_autopm_put_interface(data->isoc);
+ }
}
}
+static void btusb_waker(struct work_struct *work)
+{
+ struct btusb_data *data = container_of(work, struct btusb_data, waker);
+ int err;
+
+
+ err = usb_autopm_get_interface(data->intf);
+ if (!err)
+ usb_autopm_put_interface(data->intf);
+}
+
static int btusb_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
@@ -814,11 +931,14 @@ static int btusb_probe(struct usb_interface *intf,
spin_lock_init(&data->lock);
INIT_WORK(&data->work, btusb_work);
+ INIT_WORK(&data->waker, btusb_waker);
+ spin_lock_init(&data->txlock);
init_usb_anchor(&data->tx_anchor);
init_usb_anchor(&data->intr_anchor);
init_usb_anchor(&data->bulk_anchor);
init_usb_anchor(&data->isoc_anchor);
+ init_usb_anchor(&data->deferred);
hdev = hci_alloc_dev();
if (!hdev) {
@@ -949,39 +1069,78 @@ static int btusb_suspend(struct usb_interface *intf, pm_message_t message)
BT_DBG("intf %p", intf);
- if (data->suspend_count++)
+ if (data->suspend_count++) {
+ BT_DBG("data->suspend_count = %d for intf %p, returning from %s",
+ data->suspend_count, intf, __func__);
return 0;
+ }
+ BT_DBG("data->suspend_count = %d for intf %p, continuing %s",
+ data->suspend_count, intf, __func__);
+
+ spin_lock_irq(&data->txlock);
+ if (!(interface_to_usbdev(intf)->auto_pm && data->tx_in_flight)) {
+ BT_DBG("Setting BTUSB_SUSPENDING bit in %s for intf %p",
+ __func__, intf);
+ set_bit(BTUSB_SUSPENDING, &data->flags);
+ spin_unlock_irq(&data->txlock);
+ } else {
+ spin_unlock_irq(&data->txlock);
+ BT_DBG("%d URBs in flight", data->tx_in_flight);
+ data->suspend_count--;
+ return -EBUSY;
+ }
cancel_work_sync(&data->work);
+ BT_DBG("kill urbs %s", __func__);
+ btusb_stop_traffic(data);
usb_kill_anchored_urbs(&data->tx_anchor);
- usb_kill_anchored_urbs(&data->isoc_anchor);
- usb_kill_anchored_urbs(&data->bulk_anchor);
- usb_kill_anchored_urbs(&data->intr_anchor);
-
return 0;
}
+static void play_deferred(struct btusb_data *data)
+{
+ struct urb *urb;
+ int err;
+
+ while ((urb = usb_get_from_anchor(&data->deferred))) {
+ err = usb_submit_urb(urb, GFP_ATOMIC);
+ if (err < 0)
+ break;
+ else
+ data->tx_in_flight++;
+
+ }
+ usb_scuttle_anchored_urbs(&data->deferred);
+}
+
static int btusb_resume(struct usb_interface *intf)
{
struct btusb_data *data = usb_get_intfdata(intf);
struct hci_dev *hdev = data->hdev;
- int err;
+ int err = 0;
BT_DBG("intf %p", intf);
- if (--data->suspend_count)
+ if (--data->suspend_count) {
+ BT_DBG("data->suspend_count = %d for intf %p, returning from %s",
+ data->suspend_count, intf, __func__);
return 0;
+ }
- if (!test_bit(HCI_RUNNING, &hdev->flags))
- return 0;
+ if (!test_bit(HCI_RUNNING, &hdev->flags)) {
+ BT_DBG("HCI not running, returning from %s", __func__);
+ goto no_io_needed;
+ }
if (test_bit(BTUSB_INTR_RUNNING, &data->flags)) {
err = btusb_submit_intr_urb(hdev, GFP_NOIO);
if (err < 0) {
clear_bit(BTUSB_INTR_RUNNING, &data->flags);
- return err;
+ BT_DBG("Error (%d) submitting interrupt URB, returning from %s",
+ err, __func__);
+ goto err_out;
}
}
@@ -989,9 +1148,12 @@ static int btusb_resume(struct usb_interface *intf)
err = btusb_submit_bulk_urb(hdev, GFP_NOIO);
if (err < 0) {
clear_bit(BTUSB_BULK_RUNNING, &data->flags);
- return err;
- } else
+ BT_DBG("Error (%d) submitting bulk URB, returning from %s",
+ err, __func__);
+ goto err_out;
+ } else {
btusb_submit_bulk_urb(hdev, GFP_NOIO);
+ }
}
if (test_bit(BTUSB_ISOC_RUNNING, &data->flags)) {
@@ -1001,7 +1163,24 @@ static int btusb_resume(struct usb_interface *intf)
btusb_submit_isoc_urb(hdev, GFP_NOIO);
}
+ spin_lock_irq(&data->txlock);
+ play_deferred(data);
+ BT_DBG("Clearing BTUSB_SUSPENDING bit in %s for intf %p", __func__, intf);
+ clear_bit(BTUSB_SUSPENDING, &data->flags);
+ spin_unlock_irq(&data->txlock);
+ schedule_work(&data->work);
+
return 0;
+
+err_out:
+ usb_scuttle_anchored_urbs(&data->deferred);
+no_io_needed:
+ spin_lock_irq(&data->txlock);
+ BT_DBG("Clearing BTUSB_SUSPENDING bit in %s for intf %p", __func__, intf);
+ clear_bit(BTUSB_SUSPENDING, &data->flags);
+ spin_unlock_irq(&data->txlock);
+
+ return err;
}
static struct usb_driver btusb_driver = {
@@ -1011,6 +1190,7 @@ static struct usb_driver btusb_driver = {
.suspend = btusb_suspend,
.resume = btusb_resume,
.id_table = btusb_table,
+ .supports_autosuspend = 1,
};
static int __init btusb_init(void)
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index e70c57e..ac94f91 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -908,6 +967,7 @@ static int btusb_probe(struct usb_interface *intf,
}
usb_set_intfdata(intf, data);
+ usb_device_autosuspend_enable(data->udev);
return 0;
}

View File

@ -1,26 +0,0 @@
From 70ae749d15e012ab4a33aa2abe7a4d97a4dcebdb Mon Sep 17 00:00:00 2001
From: Li Peng <peng.li@intel.com>
Date: Thu, 20 Aug 2009 13:54:04 +0800
Subject: Add G33 series in VGA hotplug support category
Test on the IGD chip, which is a G33-like graphic device.
---
drivers/gpu/drm/i915/i915_drv.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 7537f57..940ee4c 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -892,7 +892,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define SUPPORTS_INTEGRATED_HDMI(dev) (IS_G4X(dev) || IS_IGDNG(dev))
#define SUPPORTS_INTEGRATED_DP(dev) (IS_G4X(dev) || IS_IGDNG(dev))
#define SUPPORTS_EDP(dev) (IS_IGDNG_M(dev))
-#define I915_HAS_HOTPLUG(dev) (IS_I945G(dev) || IS_I945GM(dev) || IS_I965G(dev))
+#define I915_HAS_HOTPLUG(dev) (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev) || IS_I965G(dev))
/* dsparb controlled by hw only */
#define DSPARB_HWCONTROL(dev) (IS_G4X(dev) || IS_IGDNG(dev))
--
1.6.1.3

View File

@ -1,43 +0,0 @@
diff --git a/drivers/gpu/drm/i915/i915_opregion.c b/drivers/gpu/drm/i915/i915_opregion.c
index e4b4e88..2d51935 100644
--- a/drivers/gpu/drm/i915/i915_opregion.c
+++ b/drivers/gpu/drm/i915/i915_opregion.c
@@ -148,6 +148,7 @@ static u32 asle_set_backlight(struct drm_device *dev, u32 bclp)
struct drm_i915_private *dev_priv = dev->dev_private;
struct opregion_asle *asle = dev_priv->opregion.asle;
u32 blc_pwm_ctl, blc_pwm_ctl2;
+ u32 max_backlight, level, shift;
if (!(bclp & ASLE_BCLP_VALID))
return ASLE_BACKLIGHT_FAIL;
@@ -157,14 +158,25 @@ static u32 asle_set_backlight(struct drm_device *dev, u32 bclp)
return ASLE_BACKLIGHT_FAIL;
blc_pwm_ctl = I915_READ(BLC_PWM_CTL);
- blc_pwm_ctl &= ~BACKLIGHT_DUTY_CYCLE_MASK;
blc_pwm_ctl2 = I915_READ(BLC_PWM_CTL2);
- if (blc_pwm_ctl2 & BLM_COMBINATION_MODE)
+ if (IS_I965G(dev) && (blc_pwm_ctl2 & BLM_COMBINATION_MODE))
pci_write_config_dword(dev->pdev, PCI_LBPC, bclp);
- else
- I915_WRITE(BLC_PWM_CTL, blc_pwm_ctl | ((bclp * 0x101)-1));
-
+ else {
+ if (IS_IGD(dev)) {
+ blc_pwm_ctl &= ~(BACKLIGHT_DUTY_CYCLE_MASK - 1);
+ max_backlight = (blc_pwm_ctl & BACKLIGHT_MODULATION_FREQ_MASK) >>
+ BACKLIGHT_MODULATION_FREQ_SHIFT;
+ shift = BACKLIGHT_DUTY_CYCLE_SHIFT + 1;
+ } else {
+ blc_pwm_ctl &= ~BACKLIGHT_DUTY_CYCLE_MASK;
+ max_backlight = ((blc_pwm_ctl & BACKLIGHT_MODULATION_FREQ_MASK) >>
+ BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
+ shift = BACKLIGHT_DUTY_CYCLE_SHIFT;
+ }
+ level = (bclp * max_backlight) / 255;
+ I915_WRITE(BLC_PWM_CTL, blc_pwm_ctl | (level << shift));
+ }
asle->cblv = (bclp*0x64)/0xff | ASLE_CBLV_VALID;
return 0;

View File

@ -1,26 +0,0 @@
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index f85aaf2..2e5841e 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -412,6 +412,9 @@ int drm_vblank_get(struct drm_device *dev, int crtc)
dev->vblank_enabled[crtc] = 1;
drm_update_vblank_count(dev, crtc);
}
+ } else if (atomic_read(&dev->vblank_refcount[crtc]) > 1) {
+ atomic_dec(&dev->vblank_refcount[crtc]);
+ ret = -EINVAL;
}
spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 748ed50..9cb07a5 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1549,6 +1549,7 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode)
/* Wait for vblank for the disable to take effect. */
intel_wait_for_vblank(dev);
+ dev->vblank_enabled[pipe] = 0;
temp = I915_READ(dpll_reg);
if ((temp & DPLL_VCO_ENABLE) != 0) {

View File

@ -1,307 +0,0 @@
From 4e8354884daa2ee3e491bae69a81f85a2d1ca8ba Mon Sep 17 00:00:00 2001
From: Fei Jiang <fei.jiang@intel.com>
Date: Mon, 3 Aug 2009 11:31:53 -0400
Subject: [PATCH] change for general drm code to implement kms-flip feature
Signed-off-by: Fei Jiang <fei.jiang@intel.com>
---
drivers/gpu/drm/drm_crtc.c | 128 ++++++++++++++++++++++++++++++++++++++++++++
drivers/gpu/drm/drm_drv.c | 1 +
drivers/gpu/drm/drm_irq.c | 30 ++++++++++
include/drm/drm.h | 1 +
include/drm/drmP.h | 9 +++
include/drm/drm_crtc.h | 12 ++++
include/drm/drm_mode.h | 16 ++++++
7 files changed, 197 insertions(+), 0 deletions(-)
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 8fab789..3ada446
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -2452,3 +2452,131 @@ out:
mutex_unlock(&dev->mode_config.mutex);
return ret;
}
+
+/**
+ * drm_mode_page_flip_ioctl - page flip ioctl
+ * @dev: DRM device
+ * @data: ioctl args
+ * @file_priv: file private data
+ *
+ * The page flip ioctl replaces the current front buffer with a new
+ * one, using the CRTC's set_base function, which should just update
+ * the front buffer base pointer. It's up to set_base to make
+ * sure the update doesn't result in tearing (on some hardware the
+ * base register is double buffered, so this is easy).
+ *
+ * Note that this covers just the simple case of flipping the front
+ * buffer immediately. Interval handling and interlaced modes have to
+ * be handled by userspace, or with new ioctls.
+ */
+int drm_mode_page_flip_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+#if 0
+ struct drm_pending_flip *pending;
+#endif
+
+ struct drm_mode_page_flip *flip_data = data;
+ struct drm_mode_object *drm_obj, *fb_obj;
+ struct drm_crtc *crtc;
+ int ret = 0;
+
+ if (!(drm_core_check_feature(dev, DRIVER_MODESET)))
+ return -ENODEV;
+
+ /*
+ * Reject unknown flags so future userspace knows what we (don't)
+ * support
+ */
+ if (flip_data->flags & (~DRM_MODE_PAGE_FLIP_FLAGS_MASK)) {
+ DRM_DEBUG("bad page flip flags\n");
+ return -EINVAL;
+ }
+#if 0
+ pending = kzalloc(sizeof *pending, GFP_KERNEL);
+ if (pending == NULL)
+ return -ENOMEM;
+#endif
+ mutex_lock(&dev->struct_mutex);
+
+ fb_obj = drm_mode_object_find(dev, flip_data->fb_id,
+ DRM_MODE_OBJECT_FB);
+ if (!fb_obj) {
+ DRM_DEBUG("unknown fb %d\n", flip_data->fb_id);
+ ret = -ENOENT;
+ goto out_unlock;
+ }
+
+ drm_obj = drm_mode_object_find(dev, flip_data->crtc_id,
+ DRM_MODE_OBJECT_CRTC);
+ if (!drm_obj) {
+ DRM_DEBUG("unknown crtc %d\n", flip_data->crtc_id);
+ ret = -ENOENT;
+ goto out_unlock;
+ }
+ crtc = obj_to_crtc(drm_obj);
+ if (!crtc->enabled) {
+ DRM_DEBUG("crtc %d not enabled\n", flip_data->crtc_id);
+ ret = -EINVAL;
+ goto out_unlock;
+ }
+
+#if 0
+ if (crtc->fb->funcs->unpin == NULL) {
+ DRM_DEBUG("fb for crtc %d does not support delayed unpin\n",
+ flip_data->crtc_id);
+ ret = -ENODEV;
+ goto out_unlock;
+ }
+
+ pending->crtc = crtc;
+ pending->old_fb = crtc->fb;
+ pending->pipe = crtc->pipe;
+ pending->event.base.type = DRM_EVENT_MODE_PAGE_FLIP;
+ pending->event.base.length = sizeof pending->event;
+ pending->event.user_data = flip_data->user_data;
+ pending->pending_event.event = &pending->event.base;
+ pending->pending_event.file_priv = file_priv;
+ pending->pending_event.destroy =
+ (void (*) (struct drm_pending_event *)) kfree;
+
+ /* Get vblank ref for completion handling */
+ ret = drm_vblank_get(dev, crtc->pipe);
+ if (ret) {
+ DRM_DEBUG("failed to take vblank ref\n");
+ goto out_unlock;
+ }
+
+ pending->frame = drm_vblank_count(dev, crtc->pipe);
+ list_add_tail(&pending->link, &dev->flip_list);
+#endif
+
+ /*
+ * The set_base call will change the domain on the new fb,
+ * which will force the rendering to finish and block the
+ * ioctl. We need to do this last part from a work queue, to
+ * avoid blocking userspace here.
+ */
+ crtc->fb = obj_to_fb(fb_obj);
+retry_set:
+ ret = (*crtc->funcs->set_base)(crtc, 0, 0, NULL);
+ if (ret == -ERESTARTSYS)
+ goto retry_set;
+
+ if (ret) {
+ DRM_ERROR("set_base failed: %d\n", ret);
+ goto out_unlock;
+ }
+
+ mutex_unlock(&dev->struct_mutex);
+
+ return 0;
+
+out_unlock:
+ mutex_unlock(&dev->struct_mutex);
+#if 0
+ kfree(pending);
+#endif
+ return ret;
+}
+
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 1ce7977..761c2ec
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -145,6 +145,7 @@ static struct drm_ioctl_desc drm_ioctls[] = {
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_MASTER|DRM_CONTROL_ALLOW),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_MASTER|DRM_CONTROL_ALLOW),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_MASTER|DRM_CONTROL_ALLOW),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_PAGE_FLIP, drm_mode_page_flip_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW),
};
#define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls )
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index b4a3dbc..d5104df
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -71,6 +71,28 @@ int drm_irq_by_busid(struct drm_device *dev, void *data,
return 0;
}
+#if 0
+static void drm_flip_work_func(struct work_struct *work)
+{
+ struct drm_device *dev =
+ container_of(work, struct drm_device, flip_work);
+#if 0
+ struct drm_pending_flip *f, *t;
+#endif
+ u32 frame;
+
+ mutex_lock(&dev->struct_mutex);
+
+ list_for_each_entry_safe(f, t, &dev->flip_list, link) {
+ frame = drm_vblank_count(dev, f->pipe);
+ if (vblank_after(frame, f->frame))
+ drm_finish_pending_flip(dev, f, frame);
+ }
+
+ mutex_unlock(&dev->struct_mutex);
+}
+#endif
+
static void vblank_disable_fn(unsigned long arg)
{
struct drm_device *dev = (struct drm_device *)arg;
@@ -161,6 +183,11 @@ int drm_vblank_init(struct drm_device *dev, int num_crtcs)
atomic_set(&dev->vblank_refcount[i], 0);
}
+#if 0
+ INIT_LIST_HEAD(&dev->flip_list);
+ INIT_WORK(&dev->flip_work, drm_flip_work_func);
+#endif
+
dev->vblank_disable_allowed = 0;
return 0;
@@ -626,5 +653,8 @@ void drm_handle_vblank(struct drm_device *dev, int crtc)
{
atomic_inc(&dev->_vblank_count[crtc]);
DRM_WAKEUP(&dev->vbl_queue[crtc]);
+#if 0
+ schedule_work(&dev->flip_work);
+#endif
}
EXPORT_SYMBOL(drm_handle_vblank);
diff --git a/include/drm/drm.h b/include/drm/drm.h
index 7cb50bd..78bd91b
--- a/include/drm/drm.h
+++ b/include/drm/drm.h
@@ -686,6 +686,7 @@ struct drm_gem_open {
#define DRM_IOCTL_MODE_GETFB DRM_IOWR(0xAD, struct drm_mode_fb_cmd)
#define DRM_IOCTL_MODE_ADDFB DRM_IOWR(0xAE, struct drm_mode_fb_cmd)
#define DRM_IOCTL_MODE_RMFB DRM_IOWR(0xAF, unsigned int)
+#define DRM_IOCTL_MODE_PAGE_FLIP DRM_IOW( 0xB0, struct drm_mode_page_flip)
/**
* Device specific ioctls should only be in their respective headers
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index c5122bf..36f9e6a
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -976,6 +976,15 @@ struct drm_device {
cycles_t ctx_start;
cycles_t lck_start;
+ struct work_struct flip_work;
+
+#if 0
+ /**
+ * List of objects waiting on flip completion
+ */
+ struct list_head flip_list;
+#endif
+
struct fasync_struct *buf_async;/**< Processes waiting for SIGIO */
wait_queue_head_t buf_readers; /**< Processes waiting to read */
wait_queue_head_t buf_writers; /**< Processes waiting to ctx switch */
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 7300fb8..742c870
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -331,6 +331,16 @@ struct drm_crtc_funcs {
void (*destroy)(struct drm_crtc *crtc);
int (*set_config)(struct drm_mode_set *set);
+
+ /*
+ * Move the crtc on the current fb to the given position.
+ * This function is optional. If old_fb is provided, the
+ * function will wait for vblank and unpin it. If old_fb is
+ * NULL, nothing is unpinned and the caller must call
+ * mode_unpin_fb to release the old framebuffer.
+ */
+ int (*set_base)(struct drm_crtc *crtc, int x, int y,
+ struct drm_framebuffer *old_fb);
};
/**
@@ -736,4 +746,6 @@ extern int drm_mode_gamma_get_ioctl(struct drm_device *dev,
extern int drm_mode_gamma_set_ioctl(struct drm_device *dev,
void *data, struct drm_file *file_priv);
extern bool drm_detect_hdmi_monitor(struct edid *edid);
+extern int drm_mode_page_flip_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
#endif /* __DRM_CRTC_H__ */
diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h
index ae304cc..464b779
--- a/include/drm/drm_mode.h
+++ b/include/drm/drm_mode.h
@@ -265,4 +265,20 @@ struct drm_mode_crtc_lut {
__u64 blue;
};
+#define DRM_MODE_PAGE_FLIP_WAIT (1<<0) /* block on previous page flip */
+#define DRM_MODE_PAGE_FLIP_FLAGS_MASK (DRM_MODE_PAGE_FLIP_WAIT)
+
+struct drm_mode_page_flip {
+ /** Handle of new front buffer */
+ __u32 fb_id;
+ __u32 crtc_id;
+
+ /* 64 bit cookie returned to userspace in the page flip event. */
+ __u64 user_data;
+ /**
+ * page flip flags (wait on flip only for now)
+ */
+ __u32 flags;
+};
+
#endif
--
1.5.3.4

View File

@ -1,140 +0,0 @@
From 5deab387f5b9ec79a6bf7edc52b0653c2a6d44b5 Mon Sep 17 00:00:00 2001
From: Alan Olsen <alan.r.olsen@intel.com>
Date: Fri, 11 Sep 2009 15:57:46 -0700
Subject: [PATCH] linux-2.6.31-drm-mem-info.patch
Signed-off-by: Alan Olsen <alan.r.olsen@intel.com>
---
drivers/gpu/drm/Makefile | 4 +++
drivers/gpu/drm/drm_info.c | 58 ++++++++++++++++++++++++++++++++++++++++++++
drivers/gpu/drm/drm_proc.c | 2 +
include/drm/drmP.h | 2 +
4 files changed, 66 insertions(+), 0 deletions(-)
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index fe23f29..d76f167 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -4,6 +4,10 @@
ccflags-y := -Iinclude/drm
+ifeq ($(CONFIG_DRM_PSB),y)
+ ccflags-y += -Idrivers/gpu/drm/psb
+endif
+
drm-y := drm_auth.o drm_bufs.o drm_cache.o \
drm_context.o drm_dma.o drm_drawable.o \
drm_drv.o drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \
diff --git a/drivers/gpu/drm/drm_info.c b/drivers/gpu/drm/drm_info.c
index f0f6c6b..0ecc778 100644
--- a/drivers/gpu/drm/drm_info.c
+++ b/drivers/gpu/drm/drm_info.c
@@ -36,6 +36,10 @@
#include <linux/seq_file.h>
#include "drmP.h"
+#ifdef CONFIG_DRM_PSB
+#include "psb/psb_drv.h"
+#endif
+
/**
* Called when "/proc/dri/.../name" is read.
*
@@ -211,6 +215,33 @@ int drm_vblank_info(struct seq_file *m, void *data)
return 0;
}
+int drm_gem_object_mem_info(int id, void *ptr, void *data)
+{
+ struct drm_gem_object *obj = ptr;
+ struct seq_file *m = data;
+
+ seq_printf(m, "object 0x%p name %2d memory %8zd\n",
+ obj, obj->name, obj->size);
+
+ return 0;
+}
+
+int drm_gem_clients_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;
+ struct drm_file *priv;
+
+ mutex_lock(&dev->struct_mutex);
+ list_for_each_entry(priv, &dev->filelist, lhead) {
+ seq_printf(m, "pid %5d \n", priv->pid);
+ idr_for_each(&priv->object_idr, &drm_gem_object_mem_info, m);
+ seq_printf(m, "\n");
+ }
+ mutex_unlock(&dev->struct_mutex);
+ return 0;
+}
+
/**
* Called when "/proc/dri/.../clients" is read.
*
@@ -273,6 +304,33 @@ int drm_gem_object_info(struct seq_file *m, void* data)
return 0;
}
+#ifdef CONFIG_DRM_PSB
+int drm_ttm_mem_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;
+
+ if (!strncmp("psb", dev->devname, 3)) {
+ struct ttm_bo_device *bdev = &psb_priv(dev)->bdev;
+ struct ttm_mem_global *glob = bdev->mem_glob;
+
+ spin_lock(&glob->lock);
+ seq_printf(m, "used memory %llu \n", glob->used_memory);
+ seq_printf(m, "used total memory %llu \n", glob->used_total_memory);
+ spin_unlock(&glob->lock);
+ } else {
+ seq_printf(m, "This is not a PSB device, no ttm mem info available\n");
+ }
+ return 0;
+}
+#else
+int drm_ttm_mem_info(struct seq_file *m, void* data)
+{
+ seq_printf(m, "ttm is not used\n");
+ return 0;
+}
+#endif
+
#if DRM_DEBUG_CODE
int drm_vma_info(struct seq_file *m, void *data)
diff --git a/drivers/gpu/drm/drm_proc.c b/drivers/gpu/drm/drm_proc.c
index bbd4b3d..26e64ec 100644
--- a/drivers/gpu/drm/drm_proc.c
+++ b/drivers/gpu/drm/drm_proc.c
@@ -55,6 +55,8 @@ static struct drm_info_list drm_proc_list[] = {
{"bufs", drm_bufs_info, 0},
{"gem_names", drm_gem_name_info, DRIVER_GEM},
{"gem_objects", drm_gem_object_info, DRIVER_GEM},
+ {"gem_clients", drm_gem_clients_info, DRIVER_GEM},
+ {"ttm_meminfo", drm_ttm_mem_info, 0},
#if DRM_DEBUG_CODE
{"vma", drm_vma_info, 0},
#endif
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index dbd40f1..5575b9a 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -1355,6 +1355,8 @@ extern int drm_vblank_info(struct seq_file *m, void *data);
extern int drm_clients_info(struct seq_file *m, void* data);
extern int drm_gem_name_info(struct seq_file *m, void *data);
extern int drm_gem_object_info(struct seq_file *m, void* data);
+extern int drm_gem_clients_info(struct seq_file *m, void *data);
+extern int drm_ttm_mem_info(struct seq_file *m, void* data);
#if DRM_DEBUG_CODE
extern int drm_vma_info(struct seq_file *m, void *data);
--
1.6.0.6

File diff suppressed because it is too large Load Diff

View File

@ -1,206 +0,0 @@
From: Greg Kroah-Hartman <gregkh@suse.de>
Subject: Samsung backlight driver
This driver implements backlight controls for Samsung laptops that currently do not have ACPI support for this control.
It has been tested on the N130 laptop and properly works there.
Info for the NC10 was provided by Soeren Sonnenburg <bugreports@nn7.de> Info for the NP-Q45 from Jie Huchet <jeremie@lamah.info>
Many thanks to Dmitry Torokhov <dmitry.torokhov@gmail.com> for cleanups and other suggestions on how to make the driver simpler.
Cc: Soeren Sonnenburg <bugreports@nn7.de>
Cc: Jie Huchet <jeremie@lamah.info>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/platform/x86/Kconfig | 12 ++
drivers/platform/x86/Makefile | 1
drivers/platform/x86/samsung-backlight.c | 157
+++++++++++++++++++++++++++++++ 3 files changed, 170 insertions(+)
diff -purN vanilla-2.6.31-rc6/drivers/platform/x86/Kconfig linux-2.6.31-rc6/drivers/platform/x86/Kconfig
--- vanilla-2.6.31-rc6/drivers/platform/x86/Kconfig 2009-08-17 20:55:37.000000000 +0000
+++ linux-2.6.31-rc6/drivers/platform/x86/Kconfig 2009-08-17 20:58:25.000000000 +0000
@@ -425,4 +425,16 @@ config ACPI_TOSHIBA
If you have a legacy free Toshiba laptop (such as the Libretto L1
series), say Y.
+
+config SAMSUNG_BACKLIGHT
+ tristate "Samsung Backlight driver"
+ depends on BACKLIGHT_CLASS_DEVICE
+ depends on DMI
+ ---help---
+ This driver adds support to control the backlight on a number of
+ Samsung laptops, like the N130.
+
+ It will only be loaded on laptops that properly need it, so it is
+ safe to say Y here.
+
endif # X86_PLATFORM_DEVICES
diff -purN vanilla-2.6.31-rc6/drivers/platform/x86/Makefile linux-2.6.31-rc6/drivers/platform/x86/Makefile
--- vanilla-2.6.31-rc6/drivers/platform/x86/Makefile 2009-08-17 20:55:37.000000000 +0000
+++ linux-2.6.31-rc6/drivers/platform/x86/Makefile 2009-08-17 20:58:44.000000000 +0000
@@ -20,3 +20,4 @@ obj-$(CONFIG_INTEL_MENLOW) += intel_menl
obj-$(CONFIG_ACPI_WMI) += wmi.o
obj-$(CONFIG_ACPI_ASUS) += asus_acpi.o
obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o
+obj-$(CONFIG_SAMSUNG_BACKLIGHT) += samsung-backlight.o
diff -purN vanilla-2.6.31-rc6/drivers/platform/x86/samsung-backlight.c linux-2.6.31-rc6/drivers/platform/x86/samsung-backlight.c
--- vanilla-2.6.31-rc6/drivers/platform/x86/samsung-backlight.c 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.31-rc6/drivers/platform/x86/samsung-backlight.c 2009-08-17 21:00:10.000000000 +0000
@@ -0,0 +1,151 @@
+/*
+ * Samsung N130 and NC10 Laptop Backlight driver
+ *
+ * Copyright (C) 2009 Greg Kroah-Hartman (gregkh@suse.de)
+ * Copyright (C) 2009 Novell 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 <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/backlight.h>
+#include <linux/fb.h>
+#include <linux/dmi.h>
+
+#define MAX_BRIGHT 0xff
+#define OFFSET 0xf4
+
+static int offset = OFFSET;
+module_param(offset, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(offset, "The offset into the PCI device for the brightness control");
+static struct pci_dev *pci_device;
+static struct backlight_device *backlight_device;
+
+static u8 read_brightness(void)
+{
+ u8 brightness;
+
+ pci_read_config_byte(pci_device, offset, &brightness);
+ return brightness;
+}
+
+static void set_brightness(u8 brightness) {
+ pci_write_config_byte(pci_device, offset, brightness); }
+
+static int get_brightness(struct backlight_device *bd) {
+ return bd->props.brightness;
+}
+
+static int update_status(struct backlight_device *bd) {
+ set_brightness(bd->props.brightness);
+ return 0;
+}
+
+static struct backlight_ops backlight_ops = {
+ .get_brightness = get_brightness,
+ .update_status = update_status,
+};
+
+static int __init dmi_check_cb(const struct dmi_system_id *id) {
+ printk(KERN_INFO KBUILD_MODNAME ": found laptop model '%s'\n",
+ id->ident);
+ return 0;
+}
+
+static struct dmi_system_id __initdata samsung_dmi_table[] = {
+ {
+ .ident = "N120",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "N120"),
+ DMI_MATCH(DMI_BOARD_NAME, "N120"),
+ },
+ .callback = dmi_check_cb,
+ },
+ {
+ .ident = "N130",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "N130"),
+ DMI_MATCH(DMI_BOARD_NAME, "N130"),
+ },
+ .callback = dmi_check_cb,
+ },
+ {
+ .ident = "NC10",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "NC10"),
+ DMI_MATCH(DMI_BOARD_NAME, "NC10"),
+ },
+ .callback = dmi_check_cb,
+ },
+ {
+ .ident = "NP-Q45",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "SQ45S70S"),
+ DMI_MATCH(DMI_BOARD_NAME, "SQ45S70S"),
+ },
+ .callback = dmi_check_cb,
+ },
+ { },
+};
+
+static int __init samsung_init(void)
+{
+ if (!dmi_check_system(samsung_dmi_table))
+ return -ENODEV;
+
+ /*
+ * The Samsung N120, N130, and NC10 use pci device id 0x27ae, while the
+ * NP-Q45 uses 0x2a02. Odds are we might need to add more to the
+ * list over time...
+ */
+ pci_device = pci_get_device(PCI_VENDOR_ID_INTEL, 0x27ae, NULL);
+ if (!pci_device) {
+ pci_device = pci_get_device(PCI_VENDOR_ID_INTEL, 0x2a02, NULL);
+ if (!pci_device)
+ return -ENODEV;
+ }
+
+ /* create a backlight device to talk to this one */
+ backlight_device = backlight_device_register("samsung",
+ &pci_device->dev,
+ NULL, &backlight_ops);
+ if (IS_ERR(backlight_device)) {
+ pci_dev_put(pci_device);
+ return PTR_ERR(backlight_device);
+ }
+
+ backlight_device->props.max_brightness = MAX_BRIGHT;
+ backlight_device->props.brightness = read_brightness();
+ backlight_device->props.power = FB_BLANK_UNBLANK;
+ backlight_update_status(backlight_device);
+
+ return 0;
+}
+
+static void __exit samsung_exit(void)
+{
+ backlight_device_unregister(backlight_device);
+
+ /* we are done with the PCI device, put it back */
+ pci_dev_put(pci_device);
+}
+
+module_init(samsung_init);
+module_exit(samsung_exit);
+
+MODULE_AUTHOR("Greg Kroah-Hartman <gregkh@suse.de>");
+MODULE_DESCRIPTION("Samsung Backlight driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("dmi:*:svnSAMSUNGELECTRONICSCO.,LTD.:pnN120:*:rnN120:*");
+MODULE_ALIAS("dmi:*:svnSAMSUNGELECTRONICSCO.,LTD.:pnN130:*:rnN130:*");
+MODULE_ALIAS("dmi:*:svnSAMSUNGELECTRONICSCO.,LTD.:pnNC10:*:rnNC10:*");
+MODULE_ALIAS("dmi:*:svnSAMSUNGELECTRONICSCO.,LTD.:pnSQ45S70S:*:rnSQ45S70S:*");

View File

@ -1,14 +0,0 @@
KERN_ERR is not appropriate for a printk level of a successful operation
--- linux-2.6.30/drivers/hid/hid-wacom.c~ 2009-09-04 10:37:20.000000000 -0700
+++ linux-2.6.30/drivers/hid/hid-wacom.c 2009-09-04 10:37:20.000000000 -0700
@@ -244,7 +244,7 @@
ret = hid_register_driver(&wacom_driver);
if (ret)
printk(KERN_ERR "can't register wacom driver\n");
- printk(KERN_ERR "wacom driver registered\n");
+ printk(KERN_INFO "wacom driver registered\n");
return ret;
}

View File

@ -1,173 +0,0 @@
From edeae90d635501a632efa0c7fe0667aa2cbe29be Mon Sep 17 00:00:00 2001
From: Arjan van de Ven <arjan@linux.intel.com>
Date: Mon, 28 Sep 2009 15:14:04 +0200
Subject: [PATCH] acpi: Provide a set of tables to check the BIOS tables for correctness
Today, the BIOS provides us with latency information for each C state.
Unfortunately this information is sometimes put into the BIOS by
apprentice BIOS programmers in a hurry, and as a result, it occasionally
contains utter garbage.
This patch adds a table based verification; if the CPU is known in the table,
the values the BIOS provides to us are corrected for the apprentice-factor
so that the CPUIDLE code can rely on the latency and break-even values
to be reasonably sane.
Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
---
drivers/acpi/Makefile | 2 +-
drivers/acpi/processor_idle.c | 3 +
drivers/acpi/processor_mwait_table.c | 110 ++++++++++++++++++++++++++++++++++
include/acpi/processor.h | 3 +
4 files changed, 117 insertions(+), 1 deletions(-)
create mode 100644 drivers/acpi/processor_mwait_table.c
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 82cd49d..ab56b28 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -60,5 +60,5 @@ obj-$(CONFIG_ACPI_POWER_METER) += power_meter.o
# processor has its own "processor." module_param namespace
processor-y := processor_core.o processor_throttling.o
-processor-y += processor_idle.o processor_thermal.o
+processor-y += processor_idle.o processor_thermal.o processor_mwait_table.o
processor-$(CONFIG_CPU_FREQ) += processor_perflib.o
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index cc61a62..db444a0 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -1088,6 +1088,9 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr)
state->target_residency = cx->latency * latency_factor;
state->power_usage = cx->power;
+ if (cx->entry_method == ACPI_CSTATE_FFH)
+ acpi_verify_mwait_data(state, cx);
+
state->flags = 0;
switch (cx->type) {
case ACPI_STATE_C1:
diff --git a/drivers/acpi/processor_mwait_table.c b/drivers/acpi/processor_mwait_table.c
new file mode 100644
index 0000000..f29c28c
--- /dev/null
+++ b/drivers/acpi/processor_mwait_table.c
@@ -0,0 +1,102 @@
+/*
+ * processor_mwait_table.c: BIOS table verification/correction
+ *
+ * (C) Copyright 2009 Intel Corporation
+ * Authors:
+ * Arjan van de Ven <arjan@linux.intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2
+ * of the License.
+ */
+
+#include <asm/processor.h>
+#include <linux/acpi.h>
+#include <acpi/processor.h>
+#include <linux/cpuidle.h>
+
+
+#define ATLEAST 1
+#define ATMOST 2
+#define EXACTLY 3
+
+#define MAX_ENTRIES 12
+
+struct mwait_entry {
+ unsigned int mwait_value;
+ unsigned long exit_latency;
+ unsigned long break_even_point;
+ int compare_method;
+};
+
+struct cpu_entry {
+ int vendor;
+ int family;
+ int model;
+
+ struct mwait_entry entries[MAX_ENTRIES];
+};
+
+static struct cpu_entry mwait_entries[] =
+{
+ /* Intel "Atom" CPUs */
+ {.vendor = X86_VENDOR_INTEL, .family = 6, . model = 28,
+ .entries = {
+ {0x00, 1, 1, ATLEAST},
+ {0x10, 2, 20, ATLEAST},
+ {0x30, 57, 300, ATLEAST},
+ {0x50, 64, 4000, ATLEAST},
+ }
+ },
+
+
+};
+
+
+static unsigned long
+compare_and_set(unsigned long original, unsigned long new, int compare)
+{
+ if (compare == EXACTLY)
+ return new;
+ if (compare == ATLEAST && new > original)
+ return new;
+ if (compare == ATMOST && new < original)
+ return new;
+ return original;
+}
+
+
+void acpi_verify_mwait_data(struct cpuidle_state *state,
+ struct acpi_processor_cx *cx)
+{
+#if defined(__i386__) || defined(__x86_64__)
+ int i;
+
+ struct cpuinfo_x86 *cpudata = &boot_cpu_data;
+
+
+ for (i = 0; i < ARRAY_SIZE(mwait_entries); i++) {
+ int j;
+ if (mwait_entries[i].vendor != cpudata->x86_vendor)
+ continue;
+ if (mwait_entries[i].family != cpudata->x86)
+ continue;
+ if (mwait_entries[i].model != cpudata->x86_model)
+ continue;
+ for (j = 0; j < ARRAY_SIZE(mwait_entries[i].entries); j++) {
+ if (!mwait_entries[i].entries[j].compare_method)
+ continue;
+ if (mwait_entries[i].entries[j].mwait_value != cx->address)
+ continue;
+ state->exit_latency = compare_and_set(state->exit_latency,
+ mwait_entries[i].entries[j].exit_latency,
+ mwait_entries[i].entries[j].compare_method);
+ state->target_residency = compare_and_set(state->target_residency,
+ mwait_entries[i].entries[j].break_even_point,
+ mwait_entries[i].entries[j].compare_method);
+ break;
+ }
+ }
+#endif
+}
diff --git a/include/acpi/processor.h b/include/acpi/processor.h
index 740ac3a..175e4d1 100644
--- a/include/acpi/processor.h
+++ b/include/acpi/processor.h
@@ -352,5 +352,8 @@ static inline void acpi_thermal_cpufreq_exit(void)
return;
}
#endif
+extern void acpi_verify_mwait_data(struct cpuidle_state *state,
+ struct acpi_processor_cx *cx);
+
#endif
--
1.6.2.5

View File

@ -1,407 +0,0 @@
From f890417fc5dc4450e1dab69d7a870d6e706825a5 Mon Sep 17 00:00:00 2001
From: Arjan van de Ven <arjan@linux.intel.com>
Date: Sun, 20 Sep 2009 08:45:07 +0200
Subject: [PATCH] cpuidle: Fix the menu governor to boost IO performance
Fix the menu idle governor which balances power savings, energy efficiency
and performance impact.
The reason for a reworked governor is that there have been serious
performance issues reported with the existing code on Nehalem server
systems.
To show this I'm sure Andrew wants to see benchmark results:
(benchmark is "fio", "no cstates" is using "idle=poll")
no cstates current linux new algorithm
1 disk 107 Mb/s 85 Mb/s 105 Mb/s
2 disks 215 Mb/s 123 Mb/s 209 Mb/s
12 disks 590 Mb/s 320 Mb/s 585 Mb/s
In various power benchmark measurements, no degredation was found by our
measurement&diagnostics team. Obviously a small percentage more power
was used in the "fio" benchmark, due to the much higher performance.
While it would be a novel idea to describe the new algorithm in this
commit message, I cheaped out and described it in comments in the code
instead.
[changes in v2: spelling fixes from akpm, review feedback,
folded menu-tng into menu.c
changes in v3: use this_rq() as per akpm suggestion]
Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
Cc: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
Cc: Len Brown <lenb@kernel.org>
Acked-by: Ingo Molnar <mingo@elte.hu>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Yanmin Zhang <yanmin_zhang@linux.intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
drivers/cpuidle/governors/menu.c | 251 ++++++++++++++++++++++++++++++++------
include/linux/sched.h | 4 +
kernel/sched.c | 13 ++
3 files changed, 229 insertions(+), 39 deletions(-)
diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c
index f1df59f..9f3d775 100644
--- a/drivers/cpuidle/governors/menu.c
+++ b/drivers/cpuidle/governors/menu.c
@@ -2,8 +2,12 @@
* menu.c - the menu idle governor
*
* Copyright (C) 2006-2007 Adam Belay <abelay@novell.com>
+ * Copyright (C) 2009 Intel Corporation
+ * Author:
+ * Arjan van de Ven <arjan@linux.intel.com>
*
- * This code is licenced under the GPL.
+ * This code is licenced under the GPL version 2 as described
+ * in the COPYING file that acompanies the Linux Kernel.
*/
#include <linux/kernel.h>
@@ -13,20 +17,153 @@
#include <linux/ktime.h>
#include <linux/hrtimer.h>
#include <linux/tick.h>
+#include <linux/sched.h>
-#define BREAK_FUZZ 4 /* 4 us */
-#define PRED_HISTORY_PCT 50
+#define BUCKETS 12
+#define RESOLUTION 1024
+#define DECAY 4
+#define MAX_INTERESTING 50000
+
+/*
+ * Concepts and ideas behind the menu governor
+ *
+ * For the menu governor, there are 3 decision factors for picking a C
+ * state:
+ * 1) Energy break even point
+ * 2) Performance impact
+ * 3) Latency tolerance (from pmqos infrastructure)
+ * These these three factors are treated independently.
+ *
+ * Energy break even point
+ * -----------------------
+ * C state entry and exit have an energy cost, and a certain amount of time in
+ * the C state is required to actually break even on this cost. CPUIDLE
+ * provides us this duration in the "target_residency" field. So all that we
+ * need is a good prediction of how long we'll be idle. Like the traditional
+ * menu governor, we start with the actual known "next timer event" time.
+ *
+ * Since there are other source of wakeups (interrupts for example) than
+ * the next timer event, this estimation is rather optimistic. To get a
+ * more realistic estimate, a correction factor is applied to the estimate,
+ * that is based on historic behavior. For example, if in the past the actual
+ * duration always was 50% of the next timer tick, the correction factor will
+ * be 0.5.
+ *
+ * menu uses a running average for this correction factor, however it uses a
+ * set of factors, not just a single factor. This stems from the realization
+ * that the ratio is dependent on the order of magnitude of the expected
+ * duration; if we expect 500 milliseconds of idle time the likelihood of
+ * getting an interrupt very early is much higher than if we expect 50 micro
+ * seconds of idle time. A second independent factor that has big impact on
+ * the actual factor is if there is (disk) IO outstanding or not.
+ * (as a special twist, we consider every sleep longer than 50 milliseconds
+ * as perfect; there are no power gains for sleeping longer than this)
+ *
+ * For these two reasons we keep an array of 12 independent factors, that gets
+ * indexed based on the magnitude of the expected duration as well as the
+ * "is IO outstanding" property.
+ *
+ * Limiting Performance Impact
+ * ---------------------------
+ * C states, especially those with large exit latencies, can have a real
+ * noticable impact on workloads, which is not acceptable for most sysadmins,
+ * and in addition, less performance has a power price of its own.
+ *
+ * As a general rule of thumb, menu assumes that the following heuristic
+ * holds:
+ * The busier the system, the less impact of C states is acceptable
+ *
+ * This rule-of-thumb is implemented using a performance-multiplier:
+ * If the exit latency times the performance multiplier is longer than
+ * the predicted duration, the C state is not considered a candidate
+ * for selection due to a too high performance impact. So the higher
+ * this multiplier is, the longer we need to be idle to pick a deep C
+ * state, and thus the less likely a busy CPU will hit such a deep
+ * C state.
+ *
+ * Two factors are used in determing this multiplier:
+ * a value of 10 is added for each point of "per cpu load average" we have.
+ * a value of 5 points is added for each process that is waiting for
+ * IO on this CPU.
+ * (these values are experimentally determined)
+ *
+ * The load average factor gives a longer term (few seconds) input to the
+ * decision, while the iowait value gives a cpu local instantanious input.
+ * The iowait factor may look low, but realize that this is also already
+ * represented in the system load average.
+ *
+ */
struct menu_device {
int last_state_idx;
unsigned int expected_us;
- unsigned int predicted_us;
- unsigned int current_predicted_us;
- unsigned int last_measured_us;
- unsigned int elapsed_us;
+ u64 predicted_us;
+ unsigned int measured_us;
+ unsigned int exit_us;
+ unsigned int bucket;
+ u64 correction_factor[BUCKETS];
};
+
+#define LOAD_INT(x) ((x) >> FSHIFT)
+#define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100)
+
+static int get_loadavg(void)
+{
+ unsigned long this = this_cpu_load();
+
+
+ return LOAD_INT(this) * 10 + LOAD_FRAC(this) / 10;
+}
+
+static inline int which_bucket(unsigned int duration)
+{
+ int bucket = 0;
+
+ /*
+ * We keep two groups of stats; one with no
+ * IO pending, one without.
+ * This allows us to calculate
+ * E(duration)|iowait
+ */
+ if (nr_iowait_cpu())
+ bucket = BUCKETS/2;
+
+ if (duration < 10)
+ return bucket;
+ if (duration < 100)
+ return bucket + 1;
+ if (duration < 1000)
+ return bucket + 2;
+ if (duration < 10000)
+ return bucket + 3;
+ if (duration < 100000)
+ return bucket + 4;
+ return bucket + 5;
+}
+
+/*
+ * Return a multiplier for the exit latency that is intended
+ * to take performance requirements into account.
+ * The more performance critical we estimate the system
+ * to be, the higher this multiplier, and thus the higher
+ * the barrier to go to an expensive C state.
+ */
+static inline int performance_multiplier(void)
+{
+ int mult = 1;
+
+ /* for higher loadavg, we are more reluctant */
+
+ mult += 2 * get_loadavg();
+
+ /* for IO wait tasks (per cpu!) we add 5x each */
+ mult += 10 * nr_iowait_cpu();
+
+ return mult;
+}
+
static DEFINE_PER_CPU(struct menu_device, menu_devices);
/**
@@ -38,37 +175,59 @@ static int menu_select(struct cpuidle_device *dev)
struct menu_device *data = &__get_cpu_var(menu_devices);
int latency_req = pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY);
int i;
+ int multiplier;
+
+ data->last_state_idx = 0;
+ data->exit_us = 0;
/* Special case when user has set very strict latency requirement */
- if (unlikely(latency_req == 0)) {
- data->last_state_idx = 0;
+ if (unlikely(latency_req == 0))
return 0;
- }
- /* determine the expected residency time */
+ /* determine the expected residency time, round up */
data->expected_us =
- (u32) ktime_to_ns(tick_nohz_get_sleep_length()) / 1000;
+ DIV_ROUND_UP((u32)ktime_to_ns(tick_nohz_get_sleep_length()), 1000);
+
+
+ data->bucket = which_bucket(data->expected_us);
+
+ multiplier = performance_multiplier();
+
+ /*
+ * if the correction factor is 0 (eg first time init or cpu hotplug
+ * etc), we actually want to start out with a unity factor.
+ */
+ if (data->correction_factor[data->bucket] == 0)
+ 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);
+
+ /*
+ * We want to default to C1 (hlt), not to busy polling
+ * unless the timer is happening really really soon.
+ */
+ if (data->expected_us > 5)
+ data->last_state_idx = CPUIDLE_DRIVER_STATE_START;
- /* Recalculate predicted_us based on prediction_history_pct */
- data->predicted_us *= PRED_HISTORY_PCT;
- data->predicted_us += (100 - PRED_HISTORY_PCT) *
- data->current_predicted_us;
- data->predicted_us /= 100;
/* find the deepest idle state that satisfies our constraints */
- for (i = CPUIDLE_DRIVER_STATE_START + 1; i < dev->state_count; i++) {
+ for (i = CPUIDLE_DRIVER_STATE_START; i < dev->state_count; i++) {
struct cpuidle_state *s = &dev->states[i];
- if (s->target_residency > data->expected_us)
- break;
if (s->target_residency > data->predicted_us)
break;
if (s->exit_latency > latency_req)
break;
+ if (s->exit_latency * multiplier > data->predicted_us)
+ break;
+ data->exit_us = s->exit_latency;
+ data->last_state_idx = i;
}
- data->last_state_idx = i - 1;
- return i - 1;
+ return data->last_state_idx;
}
/**
@@ -85,35 +244,49 @@ static void menu_reflect(struct cpuidle_device *dev)
unsigned int last_idle_us = cpuidle_get_last_residency(dev);
struct cpuidle_state *target = &dev->states[last_idx];
unsigned int measured_us;
+ u64 new_factor;
/*
* Ugh, this idle state doesn't support residency measurements, so we
* are basically lost in the dark. As a compromise, assume we slept
- * for one full standard timer tick. However, be aware that this
- * could potentially result in a suboptimal state transition.
+ * for the whole expected time.
*/
if (unlikely(!(target->flags & CPUIDLE_FLAG_TIME_VALID)))
- last_idle_us = USEC_PER_SEC / HZ;
+ last_idle_us = data->expected_us;
+
+
+ measured_us = last_idle_us;
/*
- * measured_us and elapsed_us are the cumulative idle time, since the
- * last time we were woken out of idle by an interrupt.
+ * We correct for the exit latency; we are assuming here that the
+ * exit latency happens after the event that we're interested in.
*/
- if (data->elapsed_us <= data->elapsed_us + last_idle_us)
- measured_us = data->elapsed_us + last_idle_us;
+ if (measured_us > data->exit_us)
+ measured_us -= data->exit_us;
+
+
+ /* update our correction ratio */
+
+ new_factor = data->correction_factor[data->bucket]
+ * (DECAY - 1) / DECAY;
+
+ if (data->expected_us > 0 && data->measured_us < MAX_INTERESTING)
+ new_factor += RESOLUTION * measured_us / data->expected_us;
else
- measured_us = -1;
+ /*
+ * we were idle so long that we count it as a perfect
+ * prediction
+ */
+ new_factor += RESOLUTION;
- /* Predict time until next break event */
- data->current_predicted_us = max(measured_us, data->last_measured_us);
+ /*
+ * We don't want 0 as factor; we always want at least
+ * a tiny bit of estimated time.
+ */
+ if (new_factor == 0)
+ new_factor = 1;
- if (last_idle_us + BREAK_FUZZ <
- data->expected_us - target->exit_latency) {
- data->last_measured_us = measured_us;
- data->elapsed_us = 0;
- } else {
- data->elapsed_us = measured_us;
- }
+ data->correction_factor[data->bucket] = new_factor;
}
/**
diff --git a/include/linux/sched.h b/include/linux/sched.h
index cdc1298..d559406 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -140,6 +140,10 @@ extern int nr_processes(void);
extern unsigned long nr_running(void);
extern unsigned long nr_uninterruptible(void);
extern unsigned long nr_iowait(void);
+extern unsigned long nr_iowait_cpu(void);
+extern unsigned long this_cpu_load(void);
+
+
extern void calc_global_load(void);
extern u64 cpu_nr_migrations(int cpu);
diff --git a/kernel/sched.c b/kernel/sched.c
index 4dbe8e7..541b370 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -2910,6 +2910,19 @@ unsigned long nr_iowait(void)
return sum;
}
+unsigned long nr_iowait_cpu(void)
+{
+ struct rq *this = this_rq();
+ return atomic_read(&this->nr_iowait);
+}
+
+unsigned long this_cpu_load(void)
+{
+ struct rq *this = this_rq();
+ return this->cpu_load[0];
+}
+
+
/* Variables and functions for calc_load */
static atomic_long_t calc_load_tasks;
static unsigned long calc_load_update;
--
1.6.0.6

View File

@ -1,86 +0,0 @@
commit ee5aa7b8b98774f408d20a2f61f97a89ac66c29b
Author: Joe Peterson <joe@skyrush.com>
Date: Wed Sep 9 15:03:13 2009 -0600
n_tty: honor opost flag for echoes
Fixes the following bug:
http://bugs.linuxbase.org/show_bug.cgi?id=2692
Causes processing of echoed characters (output from the echo buffer) to
honor the O_OPOST flag, which is consistent with the old behavior.
Note that this and the next patch ("n_tty: move echoctl check and
clean up logic") were verified together by the bug reporters, and
the test now passes.
Signed-off-by: Joe Peterson <joe@skyrush.com>
Cc: Linux Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c
index 4e28b35..e6eeeb2 100644
--- a/drivers/char/n_tty.c
+++ b/drivers/char/n_tty.c
@@ -272,7 +272,8 @@ static inline int is_continuation(unsigned char c, struct tty_struct *tty)
*
* This is a helper function that handles one output character
* (including special characters like TAB, CR, LF, etc.),
- * putting the results in the tty driver's write buffer.
+ * doing OPOST processing and putting the results in the
+ * tty driver's write buffer.
*
* Note that Linux currently ignores TABDLY, CRDLY, VTDLY, FFDLY
* and NLDLY. They simply aren't relevant in the world today.
@@ -350,8 +351,9 @@ static int do_output_char(unsigned char c, struct tty_struct *tty, int space)
* @c: character (or partial unicode symbol)
* @tty: terminal device
*
- * Perform OPOST processing. Returns -1 when the output device is
- * full and the character must be retried.
+ * Output one character with OPOST processing.
+ * Returns -1 when the output device is full and the character
+ * must be retried.
*
* Locking: output_lock to protect column state and space left
* (also, this is called from n_tty_write under the
@@ -377,8 +379,11 @@ static int process_output(unsigned char c, struct tty_struct *tty)
/**
* process_output_block - block post processor
* @tty: terminal device
- * @inbuf: user buffer
- * @nr: number of bytes
+ * @buf: character buffer
+ * @nr: number of bytes to output
+ *
+ * Output a block of characters with OPOST processing.
+ * Returns the number of characters output.
*
* This path is used to speed up block console writes, among other
* things when processing blocks of output data. It handles only
@@ -605,12 +610,18 @@ static void process_echoes(struct tty_struct *tty)
if (no_space_left)
break;
} else {
- int retval;
-
- retval = do_output_char(c, tty, space);
- if (retval < 0)
- break;
- space -= retval;
+ if (O_OPOST(tty) &&
+ !(test_bit(TTY_HW_COOK_OUT, &tty->flags))) {
+ int retval = do_output_char(c, tty, space);
+ if (retval < 0)
+ break;
+ space -= retval;
+ } else {
+ if (!space)
+ break;
+ tty_put_char(tty, c);
+ space -= 1;
+ }
cp += 1;
nr -= 1;
}

View File

@ -1,91 +0,0 @@
commit 62b263585bb5005d44a764c90d80f9c4bb8188c1
Author: Joe Peterson <joe@skyrush.com>
Date: Wed Sep 9 15:03:47 2009 -0600
n_tty: move echoctl check and clean up logic
Check L_ECHOCTL before insertting a character in the echo buffer
(rather than as the buffer is processed), to be more consistent with
when all other L_ flags are checked. Also cleaned up the related logic.
Note that this and the previous patch ("n_tty: honor opost flag for echoes")
were verified together by the reporters of the bug that patch addresses
(http://bugs.linuxbase.org/show_bug.cgi?id=2692), and the test now passes.
Signed-off-by: Joe Peterson <joe@skyrush.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c
index e6eeeb2..2e50f4d 100644
--- a/drivers/char/n_tty.c
+++ b/drivers/char/n_tty.c
@@ -576,33 +576,23 @@ static void process_echoes(struct tty_struct *tty)
break;
default:
- if (iscntrl(op)) {
- if (L_ECHOCTL(tty)) {
- /*
- * Ensure there is enough space
- * for the whole ctrl pair.
- */
- if (space < 2) {
- no_space_left = 1;
- break;
- }
- tty_put_char(tty, '^');
- tty_put_char(tty, op ^ 0100);
- tty->column += 2;
- space -= 2;
- } else {
- if (!space) {
- no_space_left = 1;
- break;
- }
- tty_put_char(tty, op);
- space--;
- }
- }
/*
- * If above falls through, this was an
- * undefined op.
+ * If the op is not a special byte code,
+ * it is a ctrl char tagged to be echoed
+ * as "^X" (where X is the letter
+ * representing the control char).
+ * Note that we must ensure there is
+ * enough space for the whole ctrl pair.
+ *
*/
+ if (space < 2) {
+ no_space_left = 1;
+ break;
+ }
+ tty_put_char(tty, '^');
+ tty_put_char(tty, op ^ 0100);
+ tty->column += 2;
+ space -= 2;
cp += 2;
nr -= 2;
}
@@ -809,8 +799,8 @@ static void echo_char_raw(unsigned char c, struct tty_struct *tty)
* Echo user input back onto the screen. This must be called only when
* L_ECHO(tty) is true. Called from the driver receive_buf path.
*
- * This variant tags control characters to be possibly echoed as
- * as "^X" (where X is the letter representing the control char).
+ * This variant tags control characters to be echoed as "^X"
+ * (where X is the letter representing the control char).
*
* Locking: echo_lock to protect the echo buffer
*/
@@ -823,7 +813,7 @@ static void echo_char(unsigned char c, struct tty_struct *tty)
add_echo_byte(ECHO_OP_START, tty);
add_echo_byte(ECHO_OP_START, tty);
} else {
- if (iscntrl(c) && c != '\t')
+ if (L_ECHOCTL(tty) && iscntrl(c) && c != '\t')
add_echo_byte(ECHO_OP_START, tty);
add_echo_byte(c, tty);
}

View File

@ -1,64 +0,0 @@
From 33725d4939f457b12d7bc1bcbcc0dfb8b2f5bd48 Mon Sep 17 00:00:00 2001
From: Arjan van de Ven <arjan@linux.intel.com>
Date: Thu, 24 Sep 2009 13:24:16 +0200
Subject: [PATCH] x86, timers: check for pending timers after (device) interrupts
Now that range timers and deferred timers are common, I found a
problem with these using the "perf timechart" tool.
It turns out that on x86, these two 'opportunistic' timers only
get checked when another "real" timer happens.
These opportunistic timers have the objective to save power by
hitchhiking on other wakeups, as to avoid CPU wakeups by themselves
as much as possible.
The change in this patch runs this check not only at timer interrupts,
but at all (device) interrupts. The effect is that
1) the deferred timers/range timers get delayed less
2) the range timers cause less wakeups by themselves because
the percentage of hitchhiking on existing wakeup events goes up.
I've verified the working of the patch using "perf timechart",
the original exposed bug is gone with this patch.
Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
---
arch/x86/kernel/irq.c | 2 ++
arch/x86/kernel/smp.c | 1 +
2 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index 74656d1..3912061 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -244,6 +244,7 @@ unsigned int __irq_entry do_IRQ(struct pt_regs *regs)
__func__, smp_processor_id(), vector, irq);
}
+ run_local_timers();
irq_exit();
set_irq_regs(old_regs);
@@ -268,6 +269,7 @@ void smp_generic_interrupt(struct pt_regs *regs)
if (generic_interrupt_extension)
generic_interrupt_extension();
+ run_local_timers();
irq_exit();
set_irq_regs(old_regs);
diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c
index ec1de97..d915d95 100644
--- a/arch/x86/kernel/smp.c
+++ b/arch/x86/kernel/smp.c
@@ -198,6 +198,7 @@ void smp_reschedule_interrupt(struct pt_regs *regs)
{
ack_APIC_irq();
inc_irq_stat(irq_resched_count);
+ run_local_timers();
/*
* KVM uses this interrupt to force a cpu out of guest mode
*/
--
1.6.0.6

View File

@ -1,275 +0,0 @@
From 524a1da3c45683cec77480acc6cab1d33ae8d5cb Mon Sep 17 00:00:00 2001
From: Arjan van de Ven <arjan@linux.intel.com>
Date: Sat, 26 Sep 2009 12:36:21 +0200
Subject: [PATCH] x86: Use __builtin_object_size to validate the buffer size for copy_from_user
gcc (4.x) supports the __builtin_object_size() builtin, which reports the
size of an object that a pointer point to, when known at compile time.
If the buffer size is not known at compile time, a constant -1 is returned.
This patch uses this feature to add a sanity check to copy_from_user();
if the target buffer is known to be smaller than the copy size, the copy
is aborted and a WARNing is emitted in memory debug mode.
These extra checks compile away when the object size is not known,
or if both the buffer size and the copy length are constants.
Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
Reviewed-by: Ingo Molnar <mingo@elte.hu>
---
arch/x86/include/asm/uaccess_32.h | 19 ++++++++++++++++++-
arch/x86/include/asm/uaccess_64.h | 19 ++++++++++++++++++-
arch/x86/kernel/x8664_ksyms_64.c | 2 +-
arch/x86/lib/copy_user_64.S | 4 ++--
arch/x86/lib/usercopy_32.c | 4 ++--
include/linux/compiler-gcc4.h | 2 ++
include/linux/compiler.h | 4 ++++
7 files changed, 47 insertions(+), 7 deletions(-)
diff --git a/arch/x86/include/asm/uaccess_32.h b/arch/x86/include/asm/uaccess_32.h
index 632fb44..582d6ae 100644
--- a/arch/x86/include/asm/uaccess_32.h
+++ b/arch/x86/include/asm/uaccess_32.h
@@ -187,9 +187,26 @@ __copy_from_user_inatomic_nocache(void *to, const void __user *from,
unsigned long __must_check copy_to_user(void __user *to,
const void *from, unsigned long n);
-unsigned long __must_check copy_from_user(void *to,
+unsigned long __must_check _copy_from_user(void *to,
const void __user *from,
unsigned long n);
+
+static inline unsigned long __must_check copy_from_user(void *to,
+ const void __user *from,
+ 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);
+#ifdef CONFIG_DEBUG_VM
+ else
+ WARN(1, "Buffer overflow detected!\n");
+#endif
+ return ret;
+}
+
long __must_check strncpy_from_user(char *dst, const char __user *src,
long count);
long __must_check __strncpy_from_user(char *dst,
diff --git a/arch/x86/include/asm/uaccess_64.h b/arch/x86/include/asm/uaccess_64.h
index db24b21..ce6fec7 100644
--- a/arch/x86/include/asm/uaccess_64.h
+++ b/arch/x86/include/asm/uaccess_64.h
@@ -21,10 +21,27 @@ copy_user_generic(void *to, const void *from, unsigned len);
__must_check unsigned long
copy_to_user(void __user *to, const void *from, unsigned len);
__must_check unsigned long
-copy_from_user(void *to, const void __user *from, unsigned len);
+_copy_from_user(void *to, const void __user *from, unsigned len);
__must_check unsigned long
copy_in_user(void __user *to, const void __user *from, unsigned len);
+static inline unsigned long __must_check copy_from_user(void *to,
+ const void __user *from,
+ 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);
+#ifdef CONFIG_DEBUG_VM
+ else
+ WARN(1, "Buffer overflow detected!\n");
+#endif
+ return ret;
+}
+
+
static __always_inline __must_check
int __copy_from_user(void *dst, const void __user *src, unsigned size)
{
diff --git a/arch/x86/kernel/x8664_ksyms_64.c b/arch/x86/kernel/x8664_ksyms_64.c
index 3909e3b..a0cdd8c 100644
--- a/arch/x86/kernel/x8664_ksyms_64.c
+++ b/arch/x86/kernel/x8664_ksyms_64.c
@@ -30,7 +30,7 @@ EXPORT_SYMBOL(__put_user_8);
EXPORT_SYMBOL(copy_user_generic);
EXPORT_SYMBOL(__copy_user_nocache);
-EXPORT_SYMBOL(copy_from_user);
+EXPORT_SYMBOL(_copy_from_user);
EXPORT_SYMBOL(copy_to_user);
EXPORT_SYMBOL(__copy_from_user_inatomic);
diff --git a/arch/x86/lib/copy_user_64.S b/arch/x86/lib/copy_user_64.S
index 6ba0f7b..4be3c41 100644
--- a/arch/x86/lib/copy_user_64.S
+++ b/arch/x86/lib/copy_user_64.S
@@ -78,7 +78,7 @@ ENTRY(copy_to_user)
ENDPROC(copy_to_user)
/* Standard copy_from_user with segment limit checking */
-ENTRY(copy_from_user)
+ENTRY(_copy_from_user)
CFI_STARTPROC
GET_THREAD_INFO(%rax)
movq %rsi,%rcx
@@ -88,7 +88,7 @@ ENTRY(copy_from_user)
jae bad_from_user
ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string
CFI_ENDPROC
-ENDPROC(copy_from_user)
+ENDPROC(_copy_from_user)
ENTRY(copy_user_generic)
CFI_STARTPROC
diff --git a/arch/x86/lib/usercopy_32.c b/arch/x86/lib/usercopy_32.c
index 1f118d4..8498684 100644
--- a/arch/x86/lib/usercopy_32.c
+++ b/arch/x86/lib/usercopy_32.c
@@ -874,7 +874,7 @@ EXPORT_SYMBOL(copy_to_user);
* data to the requested size using zero bytes.
*/
unsigned long
-copy_from_user(void *to, const void __user *from, unsigned long n)
+_copy_from_user(void *to, const void __user *from, unsigned long n)
{
if (access_ok(VERIFY_READ, from, n))
n = __copy_from_user(to, from, n);
@@ -882,4 +882,4 @@ copy_from_user(void *to, const void __user *from, unsigned long n)
memset(to, 0, n);
return n;
}
-EXPORT_SYMBOL(copy_from_user);
+EXPORT_SYMBOL(_copy_from_user);
diff --git a/include/linux/compiler-gcc4.h b/include/linux/compiler-gcc4.h
index 450fa59..a3aef5d 100644
--- a/include/linux/compiler-gcc4.h
+++ b/include/linux/compiler-gcc4.h
@@ -37,3 +37,5 @@
#define __cold __attribute__((__cold__))
#endif
+
+#define __compiletime_object_size(obj) __builtin_object_size(obj, 0)
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 9d4c4b0..9c42853 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -185,6 +185,10 @@ extern void __chk_io_ptr(const volatile void __iomem *);
# define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
#endif
+/* Compile time object size, -1 for unknown */
+#ifndef __compiletime_object_size
+# define __compiletime_object_size(obj) -1
+#endif
/*
* Prevent the compiler from merging or refetching accesses. The compiler
* is also forbidden from reordering successive instances of ACCESS_ONCE(),
--
1.6.0.6
From 350cf3cd513e6759ae6852946532a47249f25600 Mon Sep 17 00:00:00 2001
From: Arjan van de Ven <arjan@linux.intel.com>
Date: Wed, 30 Sep 2009 12:57:46 +0200
Subject: [PATCH] x86: Turn the copy_from_user check into an (optional) compile time warning
A previous patch added the buffer size check to copy_from_user().
One of the things learned from analyzing the result of the previous patch
is that in general, gcc is really good at proving that the code contains
sufficient security checks to not need to do a runtime check. But that
for those cases where gcc could not prove this, there was a relatively
high percentage of real security issues.
This patch turns the case of "gcc cannot prove" into a compile time
warning, as long as a sufficiently new gcc is in use.
The objective is that these warnings will trigger developers checking
new cases out before a security hole enters a linux kernel release.
Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
---
arch/x86/include/asm/uaccess_32.h | 12 +++++++++---
arch/x86/lib/usercopy_32.c | 6 ++++++
include/linux/compiler-gcc4.h | 3 +++
include/linux/compiler.h | 4 ++++
4 files changed, 22 insertions(+), 3 deletions(-)
diff --git a/arch/x86/include/asm/uaccess_32.h b/arch/x86/include/asm/uaccess_32.h
index 582d6ae..7826639 100644
--- a/arch/x86/include/asm/uaccess_32.h
+++ b/arch/x86/include/asm/uaccess_32.h
@@ -191,6 +191,13 @@ unsigned long __must_check _copy_from_user(void *to,
const void __user *from,
unsigned long n);
+
+extern void copy_from_user_overflow(void)
+#ifdef CONFIG_DEBUG_STACKOVERFLOW
+ __compiletime_warning("copy_from_user buffer size is not provably correct")
+#endif
+;
+
static inline unsigned long __must_check copy_from_user(void *to,
const void __user *from,
unsigned long n)
@@ -200,10 +207,9 @@ static inline unsigned long __must_check copy_from_user(void *to,
if (likely(sz == -1 || sz >= n))
ret = _copy_from_user(to, from, n);
-#ifdef CONFIG_DEBUG_VM
else
- WARN(1, "Buffer overflow detected!\n");
-#endif
+ copy_from_user_overflow();
+
return ret;
}
diff --git a/arch/x86/lib/usercopy_32.c b/arch/x86/lib/usercopy_32.c
index 8498684..e218d5d 100644
--- a/arch/x86/lib/usercopy_32.c
+++ b/arch/x86/lib/usercopy_32.c
@@ -883,3 +883,9 @@ _copy_from_user(void *to, const void __user *from, unsigned long n)
return n;
}
EXPORT_SYMBOL(_copy_from_user);
+
+void copy_from_user_overflow(void)
+{
+ WARN(1, "Buffer overflow detected!\n");
+}
+EXPORT_SYMBOL(copy_from_user_overflow);
diff --git a/include/linux/compiler-gcc4.h b/include/linux/compiler-gcc4.h
index a3aef5d..f1709c1 100644
--- a/include/linux/compiler-gcc4.h
+++ b/include/linux/compiler-gcc4.h
@@ -39,3 +39,6 @@
#endif
#define __compiletime_object_size(obj) __builtin_object_size(obj, 0)
+#if __GNUC_MINOR__ >= 4
+#define __compiletime_warning(message) __attribute__((warning(message)))
+#endif
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 9c42853..241dfd8 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -189,6 +189,10 @@ extern void __chk_io_ptr(const volatile void __iomem *);
#ifndef __compiletime_object_size
# define __compiletime_object_size(obj) -1
#endif
+#ifndef __compiletime_warning
+# define __compiletime_warning(message)
+#endif
+
/*
* Prevent the compiler from merging or refetching accesses. The compiler
* is also forbidden from reordering successive instances of ACCESS_ONCE(),
--
1.6.2.5

View File

@ -1,95 +0,0 @@
From 42cb68d81a218b0fd7c053356d379a93270b40ea Mon Sep 17 00:00:00 2001
From: Yong Wang <yong.y.wang@intel.com>
Date: Fri, 30 Oct 2009 10:33:20 +0800
Subject: [PATCH] x86: Do not unregister PIT clocksource on PIT oneshot setup/shutdown
Backported from upstream commit 8cab02dc3c58a12235c6d463ce684dded9696848
and this fixes bug #7377 "system can not resume from S3". Further information
can be found at http://bugzilla.kernel.org/show_bug.cgi?id=14222.
Signed-off-by: Yong Wang <yong.y.wang@intel.com>
---
arch/x86/kernel/i8253.c | 36 ++----------------------------------
1 files changed, 2 insertions(+), 34 deletions(-)
diff --git a/arch/x86/kernel/i8253.c b/arch/x86/kernel/i8253.c
index da890f0..23c1679 100644
--- a/arch/x86/kernel/i8253.c
+++ b/arch/x86/kernel/i8253.c
@@ -19,14 +19,6 @@
DEFINE_SPINLOCK(i8253_lock);
EXPORT_SYMBOL(i8253_lock);
-#ifdef CONFIG_X86_32
-static void pit_disable_clocksource(void);
-static void pit_enable_clocksource(void);
-#else
-static inline void pit_disable_clocksource(void) { }
-static inline void pit_enable_clocksource(void) { }
-#endif
-
/*
* HPET replaces the PIT, when enabled. So we need to know, which of
* the two timers is used
@@ -59,17 +51,15 @@ static void init_pit_timer(enum clock_event_mode mode,
outb_pit(0, PIT_CH0);
outb_pit(0, PIT_CH0);
}
- pit_disable_clocksource();
break;
case CLOCK_EVT_MODE_ONESHOT:
/* One shot setup */
- pit_disable_clocksource();
outb_pit(0x38, PIT_MODE);
break;
case CLOCK_EVT_MODE_RESUME:
- pit_enable_clocksource();
+ /* Nothing to do here */
break;
}
spin_unlock(&i8253_lock);
@@ -202,27 +192,8 @@ static struct clocksource pit_cs = {
.shift = 20,
};
-int pit_cs_registered;
-static void pit_disable_clocksource(void)
-{
- if (pit_cs_registered) {
- clocksource_unregister(&pit_cs);
- pit_cs_registered = 0;
- }
-}
-
-static void pit_enable_clocksource(void)
-{
- if (!pit_cs_registered && !clocksource_register(&pit_cs)) {
- pit_cs_registered = 1;
- }
-}
-
-
-
static int __init init_pit_clocksource(void)
{
- int ret;
/*
* Several reasons not to register PIT as a clocksource:
*
@@ -236,10 +207,7 @@ static int __init init_pit_clocksource(void)
pit_cs.mult = clocksource_hz2mult(CLOCK_TICK_RATE, pit_cs.shift);
- ret = clocksource_register(&pit_cs);
- if (!ret)
- pit_cs_registered = 1;
- return ret;
+ return clocksource_register(&pit_cs);
}
arch_initcall(init_pit_clocksource);
--
1.5.5.1

View File

@ -1,46 +0,0 @@
require linux-moblin.inc
PR = "r12"
DEFAULT_PREFERENCE = "-1"
DEFAULT_PREFERENCE_netbook = "1"
DEFAULT_PREFERENCE_menlow = "1"
SRC_URI = "${KERNELORG_MIRROR}/pub/linux/kernel/v2.6/linux-2.6.29.1.tar.bz2 \
file://linux-2.6-build-nonintconfig.patch;patch=1 \
file://linux-2.6.29-retry-root-mount.patch;patch=1 \
file://linux-2.6.29-dont-wait-for-mouse.patch;patch=1 \
file://linux-2.6.29-fast-initrd.patch;patch=1 \
file://linux-2.6.29-sreadahead.patch;patch=1 \
file://linux-2.6.29-enable-async-by-default.patch;patch=1 \
file://linux-2.6.29-drm-revert.patch;patch=1 \
file://linux-2.6.19-modesetting-by-default.patch;patch=1 \
file://linux-2.6.29-fast-kms.patch;patch=1 \
file://linux-2.6.29-even-faster-kms.patch;patch=1 \
file://linux-2.6.29-silence-acer-message.patch;patch=1 \
file://linux-2.6.29-input-introduce-a-tougher-i8042.reset.patch;patch=1 \
file://linux-2.6.29-msiwind.patch;patch=1 \
file://linux-2.6.29-flip-ide-net.patch;patch=1 \
file://linux-2.6.29-kms-after-sata.patch;patch=1 \
file://linux-2.6.29-jbd-longer-commit-interval.patch;patch=1 \
file://linux-2.6.29-touchkit.patch;patch=1 \
file://linux-2.6.30-fix-async.patch;patch=1 \
file://linux-2.6.30-fix-suspend.patch;patch=1 \
file://0001-drm-Split-out-the-mm-declarations-in-a-separate-hea.patch;patch=1 \
file://0002-drm-Add-a-tracker-for-global-objects.patch;patch=1 \
file://0003-drm-Export-hash-table-functionality.patch;patch=1 \
file://0007-drm-Add-unlocked-IOCTL-functionality-from-the-drm-r.patch;patch=1 \
file://linux-2.6.29-psb-driver.patch;patch=1 \
file://linux-2.6.29-psb-S0i1_and_S0i3_OSPM_support.patch;patch=1 \
file://linux-2.6.29-e100-add-support-for-82552-10-100-adapter.patch;patch=1 \
file://linux-2.6.29-pnv-agp.patch;patch=1 \
file://linux-2.6.29-pnv-drm.patch;patch=1 \
file://linux-2.6.29-pnv-fix-gtt-size.patch;patch=1 \
file://linux-2.6.29-pnv-fix-i2c.patch;patch=1 \
file://linux-2.6.29-drm-i915-Fix-LVDS-dither-setting.patch;patch=1 \
file://linux-2.6.29-timberdale.patch;patch=1 \
# file://i915_split.patch;patch=1 \
file://defconfig-menlow \
file://defconfig-netbook"
S = "${WORKDIR}/linux-2.6.29.1"

View File

@ -1,47 +0,0 @@
require linux-moblin.inc
PR = "r0"
DEFAULT_PREFERENCE = "-1"
DEFAULT_PREFERENCE_netbook = "1"
#DEFAULT_PREFERENCE_menlow = "1"
SRC_URI = "${KERNELORG_MIRROR}/pub/linux/kernel/v2.6/linux-2.6.31.5.tar.bz2 \
file://linux-2.6-build-nonintconfig.patch;patch=1 \
file://linux-2.6.32-cpuidle.patch;patch=1 \
file://linux-2.6.32-n_tty-honor-opost-flag-for-echoes.patch;patch=1 \
file://linux-2.6.32-n_tty-move-echoctl-check-and-clean-up-logic.patch;patch=1 \
file://linux-2.6.33-pit-fix.patch;patch=1 \
file://linux-2.6.29-dont-wait-for-mouse.patch;patch=1 \
file://linux-2.6.29-sreadahead.patch;patch=1 \
file://linux-2.6.29-kms-edid-cache.patch;patch=1 \
file://linux-2.6.29-kms-run-async.patch;patch=1 \
file://linux-2.6.29-kms-dont-blank-display.patch;patch=1 \
file://linux-2.6.29-kms-after-sata.patch;patch=1 \
file://linux-2.6.30-non-root-X.patch;patch=1 \
file://linux-2.6.31-drm-kms-flip.patch;patch=1 \
file://linux-2.6.31-drm-mem-info.patch;patch=1 \
file://linux-2.6.31-drm-i915-fix.patch;patch=1 \
file://linux-2.6.31-drm-i915-opregion.patch;patch=1 \
file://linux-2.6.31-drm-i915-vblank-fix.patch;patch=1 \
file://linux-2.6.29-silence-acer-message.patch;patch=1 \
file://linux-2.6.31-silence-wacom.patch;patch=1 \
file://linux-2.6.29-jbd-longer-commit-interval.patch;patch=1 \
file://linux-2.6.29-touchkit.patch;patch=1 \
file://linux-2.6.31-1-2-timberdale.patch;patch=1 \
file://linux-2.6.31-2-2-timberdale.patch;patch=1 \
file://linux-2.6-driver-level-usb-autosuspend.patch;patch=1 \
file://linux-2.6.31-bluetooth-suspend.patch;patch=1 \
file://linux-2.6-usb-uvc-autosuspend.patch;patch=1 \
file://linux-2.6.31-samsung.patch;patch=1 \
file://MRST-GFX-driver-consolidated.patch;patch=1 \
file://linux-2.6.31-iegd.patch;patch=1 \
file://linux-2.6.32-acpi-cstate-fixup.patch;patch=1 \
file://linux-2.6.32-timer-fix.patch;patch=1 \
file://linux-2.6.33-copy-checks.patch;patch=1 \
file://close_debug_info_of_rt2860.patch;patch=1 \
# file://i915_split.patch.patch;patch=1 \
# file://defconfig-menlow \
file://defconfig-netbook"
S = "${WORKDIR}/linux-2.6.31.5"