aboutsummaryrefslogtreecommitdiffstats
diff options
-rw-r--r--driver/sysfs-crash-debugging.patch2
-rw-r--r--driver/sysfs-small-header-file-cleanup-for-sysfs-n.patch68
-rw-r--r--f1.patch217
-rw-r--r--f2.patch110
-rw-r--r--firmware-move-firmware_class-from-documentation-to-samples.patch711
-rw-r--r--series12
-rw-r--r--usb/usb-ftdi_sio-note-missing-locking.patch39
-rw-r--r--usb/usb-io_ti-lock-mcr-and-msr-shadows-properly.patch58
-rw-r--r--usb/usb-iuu_phoenix-lock-priv-tiostatus-properly.patch59
-rw-r--r--usb/usb-kobil_sct-get-rid-of-unneeded-priv-line_state.patch68
-rw-r--r--usb/usb-serial-note-mos7480-and-option-don-t-lock-modem-status.patch36
-rw-r--r--usb/usb-ti_usb_3410_5052-extend-locking-to-msr-and-shadow-mcr.patch76
-rw-r--r--usb/usb-usb-serial-prepare-for-bkl-push-down.patch70
13 files changed, 1524 insertions, 2 deletions
diff --git a/driver/sysfs-crash-debugging.patch b/driver/sysfs-crash-debugging.patch
index 8de6be22c3cacb..587b42c8b343c1 100644
--- a/driver/sysfs-crash-debugging.patch
+++ b/driver/sysfs-crash-debugging.patch
@@ -109,7 +109,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
extern int __must_check sysfs_init(void);
-@@ -218,6 +219,10 @@ static inline int __must_check sysfs_ini
+@@ -213,6 +214,10 @@ static inline int __must_check sysfs_ini
return 0;
}
diff --git a/driver/sysfs-small-header-file-cleanup-for-sysfs-n.patch b/driver/sysfs-small-header-file-cleanup-for-sysfs-n.patch
new file mode 100644
index 00000000000000..743eafe2940468
--- /dev/null
+++ b/driver/sysfs-small-header-file-cleanup-for-sysfs-n.patch
@@ -0,0 +1,68 @@
+From rientjes@google.com Wed Feb 20 14:32:30 2008
+From: David Rientjes <rientjes@google.com>
+Date: Tue, 19 Feb 2008 17:39:02 -0800 (PST)
+Subject: sysfs: small header file cleanup for SYSFS=n
+To: Andrew Morton <akpm@linux-foundation.org>
+Cc: Randy Dunlap <randy.dunlap@oracle.com>, linux-kernel@vger.kernel.org
+Message-ID: <alpine.DEB.1.00.0802191738070.20797@chino.kir.corp.google.com>
+
+
+Convert sysfs_remove_bin_file() to have a return type of 'void' for
+!CONFIG_SYSFS configurations. Also removes unnecessary colons from empty
+void functions.
+
+Signed-off-by: David Rientjes <rientjes@google.com>
+Reviewed-by: Randy Dunlap <randy.dunlap@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/linux/sysfs.h | 9 ++-------
+ 1 file changed, 2 insertions(+), 7 deletions(-)
+
+--- a/include/linux/sysfs.h
++++ b/include/linux/sysfs.h
+@@ -131,7 +131,6 @@ static inline int sysfs_create_dir(struc
+
+ static inline void sysfs_remove_dir(struct kobject *kobj)
+ {
+- ;
+ }
+
+ static inline int sysfs_rename_dir(struct kobject *kobj, const char *new_name)
+@@ -160,7 +159,6 @@ static inline int sysfs_chmod_file(struc
+ static inline void sysfs_remove_file(struct kobject *kobj,
+ const struct attribute *attr)
+ {
+- ;
+ }
+
+ static inline int sysfs_create_bin_file(struct kobject *kobj,
+@@ -169,10 +167,9 @@ static inline int sysfs_create_bin_file(
+ return 0;
+ }
+
+-static inline int sysfs_remove_bin_file(struct kobject *kobj,
+- struct bin_attribute *attr)
++static inline void sysfs_remove_bin_file(struct kobject *kobj,
++ struct bin_attribute *attr)
+ {
+- return 0;
+ }
+
+ static inline int sysfs_create_link(struct kobject *kobj,
+@@ -183,7 +180,6 @@ static inline int sysfs_create_link(stru
+
+ static inline void sysfs_remove_link(struct kobject *kobj, const char *name)
+ {
+- ;
+ }
+
+ static inline int sysfs_create_group(struct kobject *kobj,
+@@ -195,7 +191,6 @@ static inline int sysfs_create_group(str
+ static inline void sysfs_remove_group(struct kobject *kobj,
+ const struct attribute_group *grp)
+ {
+- ;
+ }
+
+ static inline int sysfs_add_file_to_group(struct kobject *kobj,
diff --git a/f1.patch b/f1.patch
new file mode 100644
index 00000000000000..232bfb8e5a9af8
--- /dev/null
+++ b/f1.patch
@@ -0,0 +1,217 @@
+---
+ samples/firmware_class/firmware_sample_driver.c | 45 ++++++++--------
+ samples/firmware_class/firmware_sample_firmware_class.c | 33 +++++------
+ 2 files changed, 40 insertions(+), 38 deletions(-)
+
+--- a/samples/firmware_class/firmware_sample_driver.c
++++ b/samples/firmware_class/firmware_sample_driver.c
+@@ -12,8 +12,7 @@
+ #include <linux/init.h>
+ #include <linux/device.h>
+ #include <linux/string.h>
+-
+-#include "linux/firmware.h"
++#include <linux/firmware.h>
+
+ static struct device ghost_device = {
+ .bus_id = "ghost0",
+@@ -31,11 +30,14 @@ static void sample_firmware_load(char *f
+ static void sample_probe_default(void)
+ {
+ /* uses the default method to get the firmware */
+- const struct firmware *fw_entry;
+- printk(KERN_INFO "firmware_sample_driver: a ghost device got inserted :)\n");
++ const struct firmware *fw_entry;
++ int retval;
++
++ printk(KERN_INFO "firmware_sample_driver: "
++ "a ghost device got inserted :)\n");
+
+- if(request_firmware(&fw_entry, "sample_driver_fw", &ghost_device)!=0)
+- {
++ retval = request_firmware(&fw_entry, "sample_driver_fw", &ghost_device);
++ if (retval) {
+ printk(KERN_ERR
+ "firmware_sample_driver: Firmware not available\n");
+ return;
+@@ -47,17 +49,20 @@ static void sample_probe_default(void)
+
+ /* finish setting up the device */
+ }
++
+ static void sample_probe_specific(void)
+ {
++ int retval;
+ /* Uses some specific hotplug support to get the firmware from
+ * userspace directly into the hardware, or via some sysfs file */
+
+ /* NOTE: This currently doesn't work */
+
+- printk(KERN_INFO "firmware_sample_driver: a ghost device got inserted :)\n");
++ printk(KERN_INFO "firmware_sample_driver: "
++ "a ghost device got inserted :)\n");
+
+- if(request_firmware(NULL, "sample_driver_fw", &ghost_device)!=0)
+- {
++ retval = request_firmware(NULL, "sample_driver_fw", &ghost_device);
++ if (retval) {
+ printk(KERN_ERR
+ "firmware_sample_driver: Firmware load failed\n");
+ return;
+@@ -70,7 +75,7 @@ static void sample_probe_specific(void)
+ }
+ static void sample_probe_async_cont(const struct firmware *fw, void *context)
+ {
+- if(!fw){
++ if (!fw) {
+ printk(KERN_ERR
+ "firmware_sample_driver: firmware load failed\n");
+ return;
+@@ -80,19 +85,18 @@ static void sample_probe_async_cont(cons
+ (char *)context);
+ sample_firmware_load(fw->data, fw->size);
+ }
++
+ static void sample_probe_async(void)
+ {
+ /* Let's say that I can't sleep */
+ int error;
+- error = request_firmware_nowait (THIS_MODULE, FW_ACTION_NOHOTPLUG,
+- "sample_driver_fw", &ghost_device,
+- "my device pointer",
+- sample_probe_async_cont);
+- if(error){
+- printk(KERN_ERR
+- "firmware_sample_driver:"
++ error = request_firmware_nowait(THIS_MODULE, FW_ACTION_NOHOTPLUG,
++ "sample_driver_fw", &ghost_device,
++ "my device pointer",
++ sample_probe_async_cont);
++ if (error)
++ printk(KERN_ERR "firmware_sample_driver:"
+ " request_firmware_nowait failed\n");
+- }
+ }
+
+ static int sample_init(void)
+@@ -105,11 +109,12 @@ static int sample_init(void)
+ sample_probe_async();
+ return 0;
+ }
++
+ static void __exit sample_exit(void)
+ {
+ }
+
+-module_init (sample_init);
+-module_exit (sample_exit);
++module_init(sample_init);
++module_exit(sample_exit);
+
+ MODULE_LICENSE("GPL");
+--- a/samples/firmware_class/firmware_sample_firmware_class.c
++++ b/samples/firmware_class/firmware_sample_firmware_class.c
+@@ -25,30 +25,27 @@ MODULE_LICENSE("GPL");
+
+ static inline struct class_device *to_class_dev(struct kobject *obj)
+ {
+- return container_of(obj,struct class_device,kobj);
++ return container_of(obj, struct class_device, kobj);
+ }
++
+ static inline
+ struct class_device_attribute *to_class_dev_attr(struct attribute *_attr)
+ {
+- return container_of(_attr,struct class_device_attribute,attr);
++ return container_of(_attr, struct class_device_attribute, attr);
+ }
+
+-int sysfs_create_bin_file(struct kobject * kobj, struct bin_attribute * attr);
+-int sysfs_remove_bin_file(struct kobject * kobj, struct bin_attribute * attr);
+-
+ struct firmware_priv {
+ char fw_id[FIRMWARE_NAME_MAX];
+ s32 loading:2;
+ u32 abort:1;
+ };
+
+-extern struct class firmware_class;
+-
+ static ssize_t firmware_loading_show(struct class_device *class_dev, char *buf)
+ {
+ struct firmware_priv *fw_priv = class_get_devdata(class_dev);
+ return sprintf(buf, "%d\n", fw_priv->loading);
+ }
++
+ static ssize_t firmware_loading_store(struct class_device *class_dev,
+ const char *buf, size_t count)
+ {
+@@ -57,7 +54,7 @@ static ssize_t firmware_loading_store(st
+
+ fw_priv->loading = simple_strtol(buf, NULL, 10);
+
+- switch(fw_priv->loading){
++ switch (fw_priv->loading) {
+ case -1:
+ /* abort load an panic */
+ break;
+@@ -65,7 +62,7 @@ static ssize_t firmware_loading_store(st
+ /* setup load */
+ break;
+ case 0:
+- if(prev_loading==1){
++ if (prev_loading == 1) {
+ /* finish load and get the device back to working
+ * state */
+ }
+@@ -130,24 +127,24 @@ static int fw_setup_class_device(struct
+ class_dev->class = &firmware_class,
+ class_set_devdata(class_dev, fw_priv);
+ retval = class_device_register(class_dev);
+- if (retval){
++ if (retval) {
+ printk(KERN_ERR "%s: class_device_register failed\n",
+- __FUNCTION__);
++ __func__);
+ goto error_free_fw_priv;
+ }
+
+ retval = sysfs_create_bin_file(&class_dev->kobj, &firmware_attr_data);
+- if (retval){
++ if (retval) {
+ printk(KERN_ERR "%s: sysfs_create_bin_file failed\n",
+- __FUNCTION__);
++ __func__);
+ goto error_unreg_class_dev;
+ }
+
+ retval = class_device_create_file(class_dev,
+ &class_device_attr_loading);
+- if (retval){
++ if (retval) {
+ printk(KERN_ERR "%s: class_device_create_file failed\n",
+- __FUNCTION__);
++ __func__);
+ goto error_remove_data;
+ }
+
+@@ -183,16 +180,16 @@ static int __init firmware_sample_init(v
+
+ device_initialize(&my_device);
+ class_dev = kmalloc(sizeof(struct class_device), GFP_KERNEL);
+- if(!class_dev)
++ if (!class_dev)
+ return -ENOMEM;
+
+ error = fw_setup_class_device(class_dev, "my_firmware_image",
+ &my_device);
+- if(error){
++ if (error) {
+ kfree(class_dev);
+ return error;
+ }
+- return 0;
++ return 0;
+
+ }
+ static void __exit firmware_sample_exit(void)
diff --git a/f2.patch b/f2.patch
new file mode 100644
index 00000000000000..47c6b064b81e40
--- /dev/null
+++ b/f2.patch
@@ -0,0 +1,110 @@
+---
+ samples/firmware_class/firmware_sample_firmware_class.c | 44 ++++++----------
+ 1 file changed, 18 insertions(+), 26 deletions(-)
+
+--- a/samples/firmware_class/firmware_sample_firmware_class.c
++++ b/samples/firmware_class/firmware_sample_firmware_class.c
+@@ -23,16 +23,8 @@ MODULE_AUTHOR("Manuel Estrada Sainz");
+ MODULE_DESCRIPTION("Hackish sample for using firmware class directly");
+ MODULE_LICENSE("GPL");
+
+-static inline struct class_device *to_class_dev(struct kobject *obj)
+-{
+- return container_of(obj, struct class_device, kobj);
+-}
+-
+-static inline
+-struct class_device_attribute *to_class_dev_attr(struct attribute *_attr)
+-{
+- return container_of(_attr, struct class_device_attribute, attr);
+-}
++#define to_dev(obj) container_of(obj, struct device, kobj)
++#define to_class_dev_attr(_attr) container_of(_attr, struct class_device_attribute, attr)
+
+ struct firmware_priv {
+ char fw_id[FIRMWARE_NAME_MAX];
+@@ -40,16 +32,18 @@ struct firmware_priv {
+ u32 abort:1;
+ };
+
+-static ssize_t firmware_loading_show(struct class_device *class_dev, char *buf)
++static ssize_t firmware_loading_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
+ {
+- struct firmware_priv *fw_priv = class_get_devdata(class_dev);
++ struct firmware_priv *fw_priv = dev_get_drvdata(dev);
+ return sprintf(buf, "%d\n", fw_priv->loading);
+ }
+
+-static ssize_t firmware_loading_store(struct class_device *class_dev,
++static ssize_t firmware_loading_store(struct device *dev,
++ struct device_attribute *attr,
+ const char *buf, size_t count)
+ {
+- struct firmware_priv *fw_priv = class_get_devdata(class_dev);
++ struct firmware_priv *fw_priv = dev_get_drvdata(dev);
+ int prev_loading = fw_priv->loading;
+
+ fw_priv->loading = simple_strtol(buf, NULL, 10);
+@@ -71,15 +65,15 @@ static ssize_t firmware_loading_store(st
+
+ return count;
+ }
+-static CLASS_DEVICE_ATTR(loading, 0644,
+- firmware_loading_show, firmware_loading_store);
++static DEVICE_ATTR(loading, 0644,
++ firmware_loading_show, firmware_loading_store);
+
+ static ssize_t firmware_data_read(struct kobject *kobj,
+ struct bin_attribute *bin_attr,
+ char *buffer, loff_t offset, size_t count)
+ {
+- struct class_device *class_dev = to_class_dev(kobj);
+- struct firmware_priv *fw_priv = class_get_devdata(class_dev);
++ struct device *dev = to_dev(kobj);
++ struct firmware_priv *fw_priv = dev_get_drvdata(dev);
+
+ /* read from the devices firmware memory */
+
+@@ -89,8 +83,8 @@ static ssize_t firmware_data_write(struc
+ struct bin_attribute *bin_attr,
+ char *buffer, loff_t offset, size_t count)
+ {
+- struct class_device *class_dev = to_class_dev(kobj);
+- struct firmware_priv *fw_priv = class_get_devdata(class_dev);
++ struct device *dev = to_dev(kobj);
++ struct firmware_priv *fw_priv = dev_get_drvdata(dev);
+
+ /* write to the devices firmware memory */
+
+@@ -102,9 +96,8 @@ static struct bin_attribute firmware_att
+ .read = firmware_data_read,
+ .write = firmware_data_write,
+ };
+-static int fw_setup_class_device(struct class_device *class_dev,
+- const char *fw_name,
+- struct device *device)
++static int fw_setup_device(struct device *dev, const char *fw_name,
++ struct device *parent)
+ {
+ int retval;
+ struct firmware_priv *fw_priv;
+@@ -115,7 +108,7 @@ static int fw_setup_class_device(struct
+ goto out;
+ }
+
+- memset(class_dev, 0, sizeof(*class_dev));
++ memset(dev, 0, sizeof(*dev));
+
+ strncpy(fw_priv->fw_id, fw_name, FIRMWARE_NAME_MAX);
+ fw_priv->fw_id[FIRMWARE_NAME_MAX-1] = '\0';
+@@ -183,8 +176,7 @@ static int __init firmware_sample_init(v
+ if (!class_dev)
+ return -ENOMEM;
+
+- error = fw_setup_class_device(class_dev, "my_firmware_image",
+- &my_device);
++ error = fw_setup_device(class_dev, "my_firmware_image", &my_device);
+ if (error) {
+ kfree(class_dev);
+ return error;
diff --git a/firmware-move-firmware_class-from-documentation-to-samples.patch b/firmware-move-firmware_class-from-documentation-to-samples.patch
new file mode 100644
index 00000000000000..83a087640bf9d0
--- /dev/null
+++ b/firmware-move-firmware_class-from-documentation-to-samples.patch
@@ -0,0 +1,711 @@
+From randy.dunlap@oracle.com Wed Feb 20 14:33:28 2008
+From: Randy Dunlap <randy.dunlap@oracle.com>
+Date: Wed, 20 Feb 2008 13:20:50 -0800
+Subject: firmware: move firmware_class from Documentation/ to samples/
+To: Greg KH <greg@kroah.com>
+Cc: lkml <linux-kernel@vger.kernel.org>, akpm <akpm@linux-foundation.org>
+Message-ID: <20080220132050.8f1dac05.randy.dunlap@oracle.com>
+
+
+From: Randy Dunlap <randy.dunlap@oracle.com>
+
+Move the firmware_class sample drivers to samples/ so that they are
+buildable and can be maintained. Add Kconfig entry for firmware_class.
+
+Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
+Acked-by: Marcel Holtmann <marcel@holtmann.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ Documentation/firmware_class/firmware_sample_driver.c | 115 -----
+ Documentation/firmware_class/firmware_sample_firmware_class.c | 207 ----------
+ samples/Kconfig | 8
+ samples/Makefile | 2
+ samples/firmware_class/Makefile | 1
+ samples/firmware_class/firmware_sample_driver.c | 115 +++++
+ samples/firmware_class/firmware_sample_firmware_class.c | 207 ++++++++++
+ 7 files changed, 332 insertions(+), 323 deletions(-)
+
+--- a/Documentation/firmware_class/firmware_sample_driver.c
++++ /dev/null
+@@ -1,115 +0,0 @@
+-/*
+- * firmware_sample_driver.c -
+- *
+- * Copyright (c) 2003 Manuel Estrada Sainz
+- *
+- * Sample code on how to use request_firmware() from drivers.
+- *
+- */
+-
+-#include <linux/module.h>
+-#include <linux/kernel.h>
+-#include <linux/init.h>
+-#include <linux/device.h>
+-#include <linux/string.h>
+-
+-#include "linux/firmware.h"
+-
+-static struct device ghost_device = {
+- .bus_id = "ghost0",
+-};
+-
+-
+-static void sample_firmware_load(char *firmware, int size)
+-{
+- u8 buf[size+1];
+- memcpy(buf, firmware, size);
+- buf[size] = '\0';
+- printk(KERN_INFO "firmware_sample_driver: firmware: %s\n", buf);
+-}
+-
+-static void sample_probe_default(void)
+-{
+- /* uses the default method to get the firmware */
+- const struct firmware *fw_entry;
+- printk(KERN_INFO "firmware_sample_driver: a ghost device got inserted :)\n");
+-
+- if(request_firmware(&fw_entry, "sample_driver_fw", &ghost_device)!=0)
+- {
+- printk(KERN_ERR
+- "firmware_sample_driver: Firmware not available\n");
+- return;
+- }
+-
+- sample_firmware_load(fw_entry->data, fw_entry->size);
+-
+- release_firmware(fw_entry);
+-
+- /* finish setting up the device */
+-}
+-static void sample_probe_specific(void)
+-{
+- /* Uses some specific hotplug support to get the firmware from
+- * userspace directly into the hardware, or via some sysfs file */
+-
+- /* NOTE: This currently doesn't work */
+-
+- printk(KERN_INFO "firmware_sample_driver: a ghost device got inserted :)\n");
+-
+- if(request_firmware(NULL, "sample_driver_fw", &ghost_device)!=0)
+- {
+- printk(KERN_ERR
+- "firmware_sample_driver: Firmware load failed\n");
+- return;
+- }
+-
+- /* request_firmware blocks until userspace finished, so at
+- * this point the firmware should be already in the device */
+-
+- /* finish setting up the device */
+-}
+-static void sample_probe_async_cont(const struct firmware *fw, void *context)
+-{
+- if(!fw){
+- printk(KERN_ERR
+- "firmware_sample_driver: firmware load failed\n");
+- return;
+- }
+-
+- printk(KERN_INFO "firmware_sample_driver: device pointer \"%s\"\n",
+- (char *)context);
+- sample_firmware_load(fw->data, fw->size);
+-}
+-static void sample_probe_async(void)
+-{
+- /* Let's say that I can't sleep */
+- int error;
+- error = request_firmware_nowait (THIS_MODULE, FW_ACTION_NOHOTPLUG,
+- "sample_driver_fw", &ghost_device,
+- "my device pointer",
+- sample_probe_async_cont);
+- if(error){
+- printk(KERN_ERR
+- "firmware_sample_driver:"
+- " request_firmware_nowait failed\n");
+- }
+-}
+-
+-static int sample_init(void)
+-{
+- device_initialize(&ghost_device);
+- /* since there is no real hardware insertion I just call the
+- * sample probe functions here */
+- sample_probe_specific();
+- sample_probe_default();
+- sample_probe_async();
+- return 0;
+-}
+-static void __exit sample_exit(void)
+-{
+-}
+-
+-module_init (sample_init);
+-module_exit (sample_exit);
+-
+-MODULE_LICENSE("GPL");
+--- a/Documentation/firmware_class/firmware_sample_firmware_class.c
++++ /dev/null
+@@ -1,207 +0,0 @@
+-/*
+- * firmware_sample_firmware_class.c -
+- *
+- * Copyright (c) 2003 Manuel Estrada Sainz
+- *
+- * NOTE: This is just a probe of concept, if you think that your driver would
+- * be well served by this mechanism please contact me first.
+- *
+- * DON'T USE THIS CODE AS IS
+- *
+- */
+-
+-#include <linux/device.h>
+-#include <linux/module.h>
+-#include <linux/init.h>
+-#include <linux/timer.h>
+-#include <linux/slab.h>
+-#include <linux/string.h>
+-#include <linux/firmware.h>
+-
+-
+-MODULE_AUTHOR("Manuel Estrada Sainz");
+-MODULE_DESCRIPTION("Hackish sample for using firmware class directly");
+-MODULE_LICENSE("GPL");
+-
+-static inline struct class_device *to_class_dev(struct kobject *obj)
+-{
+- return container_of(obj,struct class_device,kobj);
+-}
+-static inline
+-struct class_device_attribute *to_class_dev_attr(struct attribute *_attr)
+-{
+- return container_of(_attr,struct class_device_attribute,attr);
+-}
+-
+-int sysfs_create_bin_file(struct kobject * kobj, struct bin_attribute * attr);
+-int sysfs_remove_bin_file(struct kobject * kobj, struct bin_attribute * attr);
+-
+-struct firmware_priv {
+- char fw_id[FIRMWARE_NAME_MAX];
+- s32 loading:2;
+- u32 abort:1;
+-};
+-
+-extern struct class firmware_class;
+-
+-static ssize_t firmware_loading_show(struct class_device *class_dev, char *buf)
+-{
+- struct firmware_priv *fw_priv = class_get_devdata(class_dev);
+- return sprintf(buf, "%d\n", fw_priv->loading);
+-}
+-static ssize_t firmware_loading_store(struct class_device *class_dev,
+- const char *buf, size_t count)
+-{
+- struct firmware_priv *fw_priv = class_get_devdata(class_dev);
+- int prev_loading = fw_priv->loading;
+-
+- fw_priv->loading = simple_strtol(buf, NULL, 10);
+-
+- switch(fw_priv->loading){
+- case -1:
+- /* abort load an panic */
+- break;
+- case 1:
+- /* setup load */
+- break;
+- case 0:
+- if(prev_loading==1){
+- /* finish load and get the device back to working
+- * state */
+- }
+- break;
+- }
+-
+- return count;
+-}
+-static CLASS_DEVICE_ATTR(loading, 0644,
+- firmware_loading_show, firmware_loading_store);
+-
+-static ssize_t firmware_data_read(struct kobject *kobj,
+- struct bin_attribute *bin_attr,
+- char *buffer, loff_t offset, size_t count)
+-{
+- struct class_device *class_dev = to_class_dev(kobj);
+- struct firmware_priv *fw_priv = class_get_devdata(class_dev);
+-
+- /* read from the devices firmware memory */
+-
+- return count;
+-}
+-static ssize_t firmware_data_write(struct kobject *kobj,
+- struct bin_attribute *bin_attr,
+- char *buffer, loff_t offset, size_t count)
+-{
+- struct class_device *class_dev = to_class_dev(kobj);
+- struct firmware_priv *fw_priv = class_get_devdata(class_dev);
+-
+- /* write to the devices firmware memory */
+-
+- return count;
+-}
+-static struct bin_attribute firmware_attr_data = {
+- .attr = {.name = "data", .mode = 0644},
+- .size = 0,
+- .read = firmware_data_read,
+- .write = firmware_data_write,
+-};
+-static int fw_setup_class_device(struct class_device *class_dev,
+- const char *fw_name,
+- struct device *device)
+-{
+- int retval;
+- struct firmware_priv *fw_priv;
+-
+- fw_priv = kzalloc(sizeof(struct firmware_priv), GFP_KERNEL);
+- if (!fw_priv) {
+- retval = -ENOMEM;
+- goto out;
+- }
+-
+- memset(class_dev, 0, sizeof(*class_dev));
+-
+- strncpy(fw_priv->fw_id, fw_name, FIRMWARE_NAME_MAX);
+- fw_priv->fw_id[FIRMWARE_NAME_MAX-1] = '\0';
+-
+- strncpy(class_dev->class_id, device->bus_id, BUS_ID_SIZE);
+- class_dev->class_id[BUS_ID_SIZE-1] = '\0';
+- class_dev->dev = device;
+-
+- class_dev->class = &firmware_class,
+- class_set_devdata(class_dev, fw_priv);
+- retval = class_device_register(class_dev);
+- if (retval){
+- printk(KERN_ERR "%s: class_device_register failed\n",
+- __FUNCTION__);
+- goto error_free_fw_priv;
+- }
+-
+- retval = sysfs_create_bin_file(&class_dev->kobj, &firmware_attr_data);
+- if (retval){
+- printk(KERN_ERR "%s: sysfs_create_bin_file failed\n",
+- __FUNCTION__);
+- goto error_unreg_class_dev;
+- }
+-
+- retval = class_device_create_file(class_dev,
+- &class_device_attr_loading);
+- if (retval){
+- printk(KERN_ERR "%s: class_device_create_file failed\n",
+- __FUNCTION__);
+- goto error_remove_data;
+- }
+-
+- goto out;
+-
+-error_remove_data:
+- sysfs_remove_bin_file(&class_dev->kobj, &firmware_attr_data);
+-error_unreg_class_dev:
+- class_device_unregister(class_dev);
+-error_free_fw_priv:
+- kfree(fw_priv);
+-out:
+- return retval;
+-}
+-static void fw_remove_class_device(struct class_device *class_dev)
+-{
+- struct firmware_priv *fw_priv = class_get_devdata(class_dev);
+-
+- class_device_remove_file(class_dev, &class_device_attr_loading);
+- sysfs_remove_bin_file(&class_dev->kobj, &firmware_attr_data);
+- class_device_unregister(class_dev);
+-}
+-
+-static struct class_device *class_dev;
+-
+-static struct device my_device = {
+- .bus_id = "my_dev0",
+-};
+-
+-static int __init firmware_sample_init(void)
+-{
+- int error;
+-
+- device_initialize(&my_device);
+- class_dev = kmalloc(sizeof(struct class_device), GFP_KERNEL);
+- if(!class_dev)
+- return -ENOMEM;
+-
+- error = fw_setup_class_device(class_dev, "my_firmware_image",
+- &my_device);
+- if(error){
+- kfree(class_dev);
+- return error;
+- }
+- return 0;
+-
+-}
+-static void __exit firmware_sample_exit(void)
+-{
+- struct firmware_priv *fw_priv = class_get_devdata(class_dev);
+- fw_remove_class_device(class_dev);
+- kfree(fw_priv);
+- kfree(class_dev);
+-}
+-module_init(firmware_sample_init);
+-module_exit(firmware_sample_exit);
+-
+--- a/samples/Kconfig
++++ b/samples/Kconfig
+@@ -22,5 +22,13 @@ config SAMPLE_KOBJECT
+
+ If in doubt, say "N" here.
+
++config SAMPLE_FIRMWARE_CLASS
++ tristate "Build firmware_class examples -- loadable modules only"
++ depends on FW_LOADER && m
++ help
++ This build firmware_class example modules.
++
++ If in doubt, say "N" here.
++
+ endif # SAMPLES
+
+--- a/samples/Makefile
++++ b/samples/Makefile
+@@ -1,3 +1,3 @@
+ # Makefile for Linux samples code
+
+-obj-$(CONFIG_SAMPLES) += markers/ kobject/
++obj-$(CONFIG_SAMPLES) += markers/ kobject/ firmware_class/
+--- /dev/null
++++ b/samples/firmware_class/Makefile
+@@ -0,0 +1 @@
++obj-$(CONFIG_SAMPLE_FIRMWARE_CLASS) += firmware_sample_driver.o firmware_sample_firmware_class.o
+--- /dev/null
++++ b/samples/firmware_class/firmware_sample_driver.c
+@@ -0,0 +1,115 @@
++/*
++ * firmware_sample_driver.c -
++ *
++ * Copyright (c) 2003 Manuel Estrada Sainz
++ *
++ * Sample code on how to use request_firmware() from drivers.
++ *
++ */
++
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/device.h>
++#include <linux/string.h>
++
++#include "linux/firmware.h"
++
++static struct device ghost_device = {
++ .bus_id = "ghost0",
++};
++
++
++static void sample_firmware_load(char *firmware, int size)
++{
++ u8 buf[size+1];
++ memcpy(buf, firmware, size);
++ buf[size] = '\0';
++ printk(KERN_INFO "firmware_sample_driver: firmware: %s\n", buf);
++}
++
++static void sample_probe_default(void)
++{
++ /* uses the default method to get the firmware */
++ const struct firmware *fw_entry;
++ printk(KERN_INFO "firmware_sample_driver: a ghost device got inserted :)\n");
++
++ if(request_firmware(&fw_entry, "sample_driver_fw", &ghost_device)!=0)
++ {
++ printk(KERN_ERR
++ "firmware_sample_driver: Firmware not available\n");
++ return;
++ }
++
++ sample_firmware_load(fw_entry->data, fw_entry->size);
++
++ release_firmware(fw_entry);
++
++ /* finish setting up the device */
++}
++static void sample_probe_specific(void)
++{
++ /* Uses some specific hotplug support to get the firmware from
++ * userspace directly into the hardware, or via some sysfs file */
++
++ /* NOTE: This currently doesn't work */
++
++ printk(KERN_INFO "firmware_sample_driver: a ghost device got inserted :)\n");
++
++ if(request_firmware(NULL, "sample_driver_fw", &ghost_device)!=0)
++ {
++ printk(KERN_ERR
++ "firmware_sample_driver: Firmware load failed\n");
++ return;
++ }
++
++ /* request_firmware blocks until userspace finished, so at
++ * this point the firmware should be already in the device */
++
++ /* finish setting up the device */
++}
++static void sample_probe_async_cont(const struct firmware *fw, void *context)
++{
++ if(!fw){
++ printk(KERN_ERR
++ "firmware_sample_driver: firmware load failed\n");
++ return;
++ }
++
++ printk(KERN_INFO "firmware_sample_driver: device pointer \"%s\"\n",
++ (char *)context);
++ sample_firmware_load(fw->data, fw->size);
++}
++static void sample_probe_async(void)
++{
++ /* Let's say that I can't sleep */
++ int error;
++ error = request_firmware_nowait (THIS_MODULE, FW_ACTION_NOHOTPLUG,
++ "sample_driver_fw", &ghost_device,
++ "my device pointer",
++ sample_probe_async_cont);
++ if(error){
++ printk(KERN_ERR
++ "firmware_sample_driver:"
++ " request_firmware_nowait failed\n");
++ }
++}
++
++static int sample_init(void)
++{
++ device_initialize(&ghost_device);
++ /* since there is no real hardware insertion I just call the
++ * sample probe functions here */
++ sample_probe_specific();
++ sample_probe_default();
++ sample_probe_async();
++ return 0;
++}
++static void __exit sample_exit(void)
++{
++}
++
++module_init (sample_init);
++module_exit (sample_exit);
++
++MODULE_LICENSE("GPL");
+--- /dev/null
++++ b/samples/firmware_class/firmware_sample_firmware_class.c
+@@ -0,0 +1,207 @@
++/*
++ * firmware_sample_firmware_class.c -
++ *
++ * Copyright (c) 2003 Manuel Estrada Sainz
++ *
++ * NOTE: This is just a probe of concept, if you think that your driver would
++ * be well served by this mechanism please contact me first.
++ *
++ * DON'T USE THIS CODE AS IS
++ *
++ */
++
++#include <linux/device.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/timer.h>
++#include <linux/slab.h>
++#include <linux/string.h>
++#include <linux/firmware.h>
++
++
++MODULE_AUTHOR("Manuel Estrada Sainz");
++MODULE_DESCRIPTION("Hackish sample for using firmware class directly");
++MODULE_LICENSE("GPL");
++
++static inline struct class_device *to_class_dev(struct kobject *obj)
++{
++ return container_of(obj,struct class_device,kobj);
++}
++static inline
++struct class_device_attribute *to_class_dev_attr(struct attribute *_attr)
++{
++ return container_of(_attr,struct class_device_attribute,attr);
++}
++
++int sysfs_create_bin_file(struct kobject * kobj, struct bin_attribute * attr);
++int sysfs_remove_bin_file(struct kobject * kobj, struct bin_attribute * attr);
++
++struct firmware_priv {
++ char fw_id[FIRMWARE_NAME_MAX];
++ s32 loading:2;
++ u32 abort:1;
++};
++
++extern struct class firmware_class;
++
++static ssize_t firmware_loading_show(struct class_device *class_dev, char *buf)
++{
++ struct firmware_priv *fw_priv = class_get_devdata(class_dev);
++ return sprintf(buf, "%d\n", fw_priv->loading);
++}
++static ssize_t firmware_loading_store(struct class_device *class_dev,
++ const char *buf, size_t count)
++{
++ struct firmware_priv *fw_priv = class_get_devdata(class_dev);
++ int prev_loading = fw_priv->loading;
++
++ fw_priv->loading = simple_strtol(buf, NULL, 10);
++
++ switch(fw_priv->loading){
++ case -1:
++ /* abort load an panic */
++ break;
++ case 1:
++ /* setup load */
++ break;
++ case 0:
++ if(prev_loading==1){
++ /* finish load and get the device back to working
++ * state */
++ }
++ break;
++ }
++
++ return count;
++}
++static CLASS_DEVICE_ATTR(loading, 0644,
++ firmware_loading_show, firmware_loading_store);
++
++static ssize_t firmware_data_read(struct kobject *kobj,
++ struct bin_attribute *bin_attr,
++ char *buffer, loff_t offset, size_t count)
++{
++ struct class_device *class_dev = to_class_dev(kobj);
++ struct firmware_priv *fw_priv = class_get_devdata(class_dev);
++
++ /* read from the devices firmware memory */
++
++ return count;
++}
++static ssize_t firmware_data_write(struct kobject *kobj,
++ struct bin_attribute *bin_attr,
++ char *buffer, loff_t offset, size_t count)
++{
++ struct class_device *class_dev = to_class_dev(kobj);
++ struct firmware_priv *fw_priv = class_get_devdata(class_dev);
++
++ /* write to the devices firmware memory */
++
++ return count;
++}
++static struct bin_attribute firmware_attr_data = {
++ .attr = {.name = "data", .mode = 0644},
++ .size = 0,
++ .read = firmware_data_read,
++ .write = firmware_data_write,
++};
++static int fw_setup_class_device(struct class_device *class_dev,
++ const char *fw_name,
++ struct device *device)
++{
++ int retval;
++ struct firmware_priv *fw_priv;
++
++ fw_priv = kzalloc(sizeof(struct firmware_priv), GFP_KERNEL);
++ if (!fw_priv) {
++ retval = -ENOMEM;
++ goto out;
++ }
++
++ memset(class_dev, 0, sizeof(*class_dev));
++
++ strncpy(fw_priv->fw_id, fw_name, FIRMWARE_NAME_MAX);
++ fw_priv->fw_id[FIRMWARE_NAME_MAX-1] = '\0';
++
++ strncpy(class_dev->class_id, device->bus_id, BUS_ID_SIZE);
++ class_dev->class_id[BUS_ID_SIZE-1] = '\0';
++ class_dev->dev = device;
++
++ class_dev->class = &firmware_class,
++ class_set_devdata(class_dev, fw_priv);
++ retval = class_device_register(class_dev);
++ if (retval){
++ printk(KERN_ERR "%s: class_device_register failed\n",
++ __FUNCTION__);
++ goto error_free_fw_priv;
++ }
++
++ retval = sysfs_create_bin_file(&class_dev->kobj, &firmware_attr_data);
++ if (retval){
++ printk(KERN_ERR "%s: sysfs_create_bin_file failed\n",
++ __FUNCTION__);
++ goto error_unreg_class_dev;
++ }
++
++ retval = class_device_create_file(class_dev,
++ &class_device_attr_loading);
++ if (retval){
++ printk(KERN_ERR "%s: class_device_create_file failed\n",
++ __FUNCTION__);
++ goto error_remove_data;
++ }
++
++ goto out;
++
++error_remove_data:
++ sysfs_remove_bin_file(&class_dev->kobj, &firmware_attr_data);
++error_unreg_class_dev:
++ class_device_unregister(class_dev);
++error_free_fw_priv:
++ kfree(fw_priv);
++out:
++ return retval;
++}
++static void fw_remove_class_device(struct class_device *class_dev)
++{
++ struct firmware_priv *fw_priv = class_get_devdata(class_dev);
++
++ class_device_remove_file(class_dev, &class_device_attr_loading);
++ sysfs_remove_bin_file(&class_dev->kobj, &firmware_attr_data);
++ class_device_unregister(class_dev);
++}
++
++static struct class_device *class_dev;
++
++static struct device my_device = {
++ .bus_id = "my_dev0",
++};
++
++static int __init firmware_sample_init(void)
++{
++ int error;
++
++ device_initialize(&my_device);
++ class_dev = kmalloc(sizeof(struct class_device), GFP_KERNEL);
++ if(!class_dev)
++ return -ENOMEM;
++
++ error = fw_setup_class_device(class_dev, "my_firmware_image",
++ &my_device);
++ if(error){
++ kfree(class_dev);
++ return error;
++ }
++ return 0;
++
++}
++static void __exit firmware_sample_exit(void)
++{
++ struct firmware_priv *fw_priv = class_get_devdata(class_dev);
++ fw_remove_class_device(class_dev);
++ kfree(fw_priv);
++ kfree(class_dev);
++}
++
++module_init(firmware_sample_init);
++module_exit(firmware_sample_exit);
diff --git a/series b/series
index 4414f67c742cb9..7ed6d3b77b202b 100644
--- a/series
+++ b/series
@@ -29,6 +29,7 @@ driver/driver-core-memory-semaphore-to-mutex.patch
driver/driver-core-register_memory-unregister_memory-clean-ups-and-bugfix.patch
driver/driver-core-pm-make-suspend_device-static.patch
driver/driver-core-numactl-interleave-all-doesn-t-works-on-memoryless-node.patch
+driver/sysfs-small-header-file-cleanup-for-sysfs-n.patch
driver/net-convert-the-phy_device-file-to-use-bus_find_device_by_name.patch
@@ -120,7 +121,13 @@ usb/usb-misc-auerswald-cp_mutex-to-mutex.diff
usb/usb-misc-auerswald-ccp_readmutex-to-mutex.diff
usb/usb-misc-auerswald-ccp_mutex-to-mutex.diff
usb/usb-minor-ehci-xitd-simplifications.patch
-
+usb/usb-usb-serial-prepare-for-bkl-push-down.patch
+usb/usb-ftdi_sio-note-missing-locking.patch
+usb/usb-serial-note-mos7480-and-option-don-t-lock-modem-status.patch
+usb/usb-iuu_phoenix-lock-priv-tiostatus-properly.patch
+usb/usb-kobil_sct-get-rid-of-unneeded-priv-line_state.patch
+usb/usb-ti_usb_3410_5052-extend-locking-to-msr-and-shadow-mcr.patch
+usb/usb-io_ti-lock-mcr-and-msr-shadows-properly.patch
usb/usb-add-usb-serial-spcp8x5-driver.patch
@@ -141,3 +148,6 @@ driver/video-add-the-go7007-driver.patch
#pending/class-move-driver-core-specific-parts-to-a-private-structure.patch
+firmware-move-firmware_class-from-documentation-to-samples.patch
+f1.patch
+f2.patch
diff --git a/usb/usb-ftdi_sio-note-missing-locking.patch b/usb/usb-ftdi_sio-note-missing-locking.patch
new file mode 100644
index 00000000000000..82486930c8cbd7
--- /dev/null
+++ b/usb/usb-ftdi_sio-note-missing-locking.patch
@@ -0,0 +1,39 @@
+From alan@lxorguk.ukuu.org.uk Wed Feb 20 14:27:26 2008
+From: Alan Cox <alan@lxorguk.ukuu.org.uk>
+Date: Wed, 20 Feb 2008 20:49:53 +0000
+Subject: USB: ftdi_sio: Note missing locking
+To: akpm@osdl.org, greg@kroah.com, linux-usb@vger.kerne.org
+Message-ID: <20080220204953.38030773@core>
+
+
+The ftdi_sio driver has no internal locking on the dtr/rts state. Flag
+that up for someone to fix.
+
+Signed-off-by: Alan Cox <alan@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/serial/ftdi_sio.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/serial/ftdi_sio.c
++++ b/drivers/usb/serial/ftdi_sio.c
+@@ -524,9 +524,8 @@ static int update_mctrl(struct usb_seria
+ }
+
+ buf = kmalloc(1, GFP_NOIO);
+- if (!buf) {
++ if (!buf)
+ return -ENOMEM;
+- }
+
+ clear &= ~set; /* 'set' takes precedence over 'clear' */
+ urb_value = 0;
+@@ -559,6 +558,7 @@ static int update_mctrl(struct usb_seria
+ (clear & TIOCM_DTR) ? "LOW" : "unchanged",
+ (set & TIOCM_RTS) ? "HIGH" :
+ (clear & TIOCM_RTS) ? "LOW" : "unchanged");
++ /* FIXME: locking on last_dtr_rts */
+ priv->last_dtr_rts = (priv->last_dtr_rts & ~clear) | set;
+ }
+ return rv;
diff --git a/usb/usb-io_ti-lock-mcr-and-msr-shadows-properly.patch b/usb/usb-io_ti-lock-mcr-and-msr-shadows-properly.patch
new file mode 100644
index 00000000000000..8920f53dc17704
--- /dev/null
+++ b/usb/usb-io_ti-lock-mcr-and-msr-shadows-properly.patch
@@ -0,0 +1,58 @@
+From alan@lxorguk.ukuu.org.uk Wed Feb 20 14:31:16 2008
+From: Alan Cox <alan@lxorguk.ukuu.org.uk>
+Date: Wed, 20 Feb 2008 21:38:32 +0000
+Subject: USB: io_ti: lock mcr and msr shadows properly
+To: akpm@osdl.org, greg@kroah.com, linux-usb@vger.kernel.org
+Message-ID: <20080220213832.35e946b4@core>
+
+
+Signed-off-by: Alan Cox <alan@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/serial/io_ti.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/drivers/usb/serial/io_ti.c
++++ b/drivers/usb/serial/io_ti.c
+@@ -2560,9 +2560,11 @@ static int edge_tiocmset (struct usb_ser
+ {
+ struct edgeport_port *edge_port = usb_get_serial_port_data(port);
+ unsigned int mcr;
++ unsigned long flags;
+
+ dbg("%s - port %d", __FUNCTION__, port->number);
+
++ spin_lock_irqsave(&edge_port->ep_lock, flags);
+ mcr = edge_port->shadow_mcr;
+ if (set & TIOCM_RTS)
+ mcr |= MCR_RTS;
+@@ -2579,6 +2581,7 @@ static int edge_tiocmset (struct usb_ser
+ mcr &= ~MCR_LOOPBACK;
+
+ edge_port->shadow_mcr = mcr;
++ spin_unlock_irqrestore(&edge_port->ep_lock, flags);
+
+ TIRestoreMCR (edge_port, mcr);
+
+@@ -2591,9 +2594,12 @@ static int edge_tiocmget(struct usb_seri
+ unsigned int result = 0;
+ unsigned int msr;
+ unsigned int mcr;
++ unsigned long flags;
+
+ dbg("%s - port %d", __FUNCTION__, port->number);
+
++ spin_lock_irqsave(&edge_port->ep_lock, flags);
++
+ msr = edge_port->shadow_msr;
+ mcr = edge_port->shadow_mcr;
+ result = ((mcr & MCR_DTR) ? TIOCM_DTR: 0) /* 0x002 */
+@@ -2605,6 +2611,7 @@ static int edge_tiocmget(struct usb_seri
+
+
+ dbg("%s -- %x", __FUNCTION__, result);
++ spin_unlock_irqrestore(&edge_port->ep_lock, flags);
+
+ return result;
+ }
diff --git a/usb/usb-iuu_phoenix-lock-priv-tiostatus-properly.patch b/usb/usb-iuu_phoenix-lock-priv-tiostatus-properly.patch
new file mode 100644
index 00000000000000..5aea65ec09fb90
--- /dev/null
+++ b/usb/usb-iuu_phoenix-lock-priv-tiostatus-properly.patch
@@ -0,0 +1,59 @@
+From alan@lxorguk.ukuu.org.uk Wed Feb 20 14:28:55 2008
+From: Alan Cox <alan@lxorguk.ukuu.org.uk>
+Date: Wed, 20 Feb 2008 21:39:25 +0000
+Subject: USB: iuu_phoenix: lock priv->tiostatus properly
+To: akpm@osdl.org, greg@kroah.com, linux-usb@vger.kernel.org
+Message-ID: <20080220213925.002facbd@core>
+
+
+Signed-off-by: Alan Cox <alan@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/serial/iuu_phoenix.c | 18 +++++++++++++-----
+ 1 file changed, 13 insertions(+), 5 deletions(-)
+
+--- a/drivers/usb/serial/iuu_phoenix.c
++++ b/drivers/usb/serial/iuu_phoenix.c
+@@ -148,20 +148,21 @@ static int iuu_tiocmset(struct usb_seria
+ unsigned int set, unsigned int clear)
+ {
+ struct iuu_private *priv = usb_get_serial_port_data(port);
+- struct tty_struct *tty;
+- tty = port->tty;
++ unsigned long flags;
+
++ /* FIXME: locking on tiomstatus */
+ dbg("%s (%d) msg : SET = 0x%04x, CLEAR = 0x%04x ", __FUNCTION__,
+ port->number, set, clear);
++
++ spin_lock_irqsave(&priv->lock, flags);
+ if (set & TIOCM_RTS)
+ priv->tiostatus = TIOCM_RTS;
+
+ if (!(set & TIOCM_RTS) && priv->tiostatus == TIOCM_RTS) {
+ dbg("%s TIOCMSET RESET called !!!", __FUNCTION__);
+ priv->reset = 1;
+- return 0;
+ }
+-
++ spin_unlock_irqrestore(&priv->lock, flags);
+ return 0;
+ }
+
+@@ -173,7 +174,14 @@ static int iuu_tiocmset(struct usb_seria
+ static int iuu_tiocmget(struct usb_serial_port *port, struct file *file)
+ {
+ struct iuu_private *priv = usb_get_serial_port_data(port);
+- return priv->tiostatus;
++ unsigned long flags;
++ int rc;
++
++ spin_lock_irqsave(&priv->lock, flags);
++ rc = priv->tiostatus;
++ spin_unlock_irqrestore(&priv->lock, flags);
++
++ return rc;
+ }
+
+ static void iuu_rxcmd(struct urb *urb)
diff --git a/usb/usb-kobil_sct-get-rid-of-unneeded-priv-line_state.patch b/usb/usb-kobil_sct-get-rid-of-unneeded-priv-line_state.patch
new file mode 100644
index 00000000000000..39011bdcb56614
--- /dev/null
+++ b/usb/usb-kobil_sct-get-rid-of-unneeded-priv-line_state.patch
@@ -0,0 +1,68 @@
+From alan@lxorguk.ukuu.org.uk Wed Feb 20 14:29:25 2008
+From: Alan Cox <alan@lxorguk.ukuu.org.uk>
+Date: Wed, 20 Feb 2008 21:40:34 +0000
+Subject: USB: kobil_sct: Get rid of unneeded priv->line_state
+To: akpm@osdl.org, greg@kroah.com, linux-usb@vger.kernel.org
+Message-ID: <20080220214034.4072e840@core>
+
+
+Signed-off-by: Alan Cox <alan@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/serial/kobil_sct.c | 15 +++++----------
+ 1 file changed, 5 insertions(+), 10 deletions(-)
+
+--- a/drivers/usb/serial/kobil_sct.c
++++ b/drivers/usb/serial/kobil_sct.c
+@@ -139,7 +139,6 @@ struct kobil_private {
+ int filled; // index of the last char in buf
+ int cur_pos; // index of the next char to send in buf
+ __u16 device_type;
+- int line_state;
+ };
+
+
+@@ -161,7 +160,6 @@ static int kobil_startup (struct usb_ser
+ priv->filled = 0;
+ priv->cur_pos = 0;
+ priv->device_type = le16_to_cpu(serial->dev->descriptor.idProduct);
+- priv->line_state = 0;
+
+ switch (priv->device_type){
+ case KOBIL_ADAPTER_B_PRODUCT_ID:
+@@ -226,7 +224,6 @@ static int kobil_open (struct usb_serial
+
+ dbg("%s - port %d", __FUNCTION__, port->number);
+ priv = usb_get_serial_port_data(port);
+- priv->line_state = 0;
+
+ // someone sets the dev to 0 if the close method has been called
+ port->interrupt_in_urb->dev = port->serial->dev;
+@@ -524,14 +521,11 @@ static int kobil_tiocmget(struct usb_ser
+ dbg("%s - port %d Send get_status_line_state URB returns: %i. Statusline: %02x",
+ __FUNCTION__, port->number, result, transfer_buffer[0]);
+
+- if ((transfer_buffer[0] & SUSBCR_GSL_DSR) != 0) {
+- priv->line_state |= TIOCM_DSR;
+- } else {
+- priv->line_state &= ~TIOCM_DSR;
+- }
+-
++ result = 0;
++ if ((transfer_buffer[0] & SUSBCR_GSL_DSR) != 0)
++ result = TIOCM_DSR;
+ kfree(transfer_buffer);
+- return priv->line_state;
++ return result;
+ }
+
+ static int kobil_tiocmset(struct usb_serial_port *port, struct file *file,
+@@ -544,6 +538,7 @@ static int kobil_tiocmset(struct usb_se
+ unsigned char *transfer_buffer;
+ int transfer_buffer_length = 8;
+
++ /* FIXME: locking ? */
+ priv = usb_get_serial_port_data(port);
+ if ((priv->device_type == KOBIL_USBTWIN_PRODUCT_ID) || (priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID)) {
+ // This device doesn't support ioctl calls
diff --git a/usb/usb-serial-note-mos7480-and-option-don-t-lock-modem-status.patch b/usb/usb-serial-note-mos7480-and-option-don-t-lock-modem-status.patch
new file mode 100644
index 00000000000000..64fa1048e51028
--- /dev/null
+++ b/usb/usb-serial-note-mos7480-and-option-don-t-lock-modem-status.patch
@@ -0,0 +1,36 @@
+From alan@lxorguk.ukuu.org.uk Wed Feb 20 14:28:30 2008
+From: Alan Cox <alan@lxorguk.ukuu.org.uk>
+Date: Wed, 20 Feb 2008 20:51:45 +0000
+Subject: USB: serial: Note mos7480 and option don't lock modem status
+To: akpm@osdl.org, greg@kroah.com, linux-usb@vger.kernel.org
+Message-ID: <20080220205145.2e0a61f9@core>
+
+
+Signed-off-by: Alan Cox <alan@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/serial/mos7840.c | 1 +
+ drivers/usb/serial/option.c | 1 +
+ 2 files changed, 2 insertions(+)
+
+--- a/drivers/usb/serial/mos7840.c
++++ b/drivers/usb/serial/mos7840.c
+@@ -1709,6 +1709,7 @@ static int mos7840_tiocmset(struct usb_s
+ if (mos7840_port == NULL)
+ return -ENODEV;
+
++ /* FIXME: What locks the port registers ? */
+ mcr = mos7840_port->shadowMCR;
+ if (clear & TIOCM_RTS)
+ mcr &= ~MCR_RTS;
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -353,6 +353,7 @@ static int option_tiocmset(struct usb_se
+
+ portdata = usb_get_serial_port_data(port);
+
++ /* FIXME: what locks portdata fields ? */
+ if (set & TIOCM_RTS)
+ portdata->rts_state = 1;
+ if (set & TIOCM_DTR)
diff --git a/usb/usb-ti_usb_3410_5052-extend-locking-to-msr-and-shadow-mcr.patch b/usb/usb-ti_usb_3410_5052-extend-locking-to-msr-and-shadow-mcr.patch
new file mode 100644
index 00000000000000..4e96eaf38e01b9
--- /dev/null
+++ b/usb/usb-ti_usb_3410_5052-extend-locking-to-msr-and-shadow-mcr.patch
@@ -0,0 +1,76 @@
+From alan@lxorguk.ukuu.org.uk Wed Feb 20 14:29:55 2008
+From: Alan Cox <alan@lxorguk.ukuu.org.uk>
+Date: Wed, 20 Feb 2008 21:41:40 +0000
+Subject: USB: ti_usb_3410_5052: Extend locking to msr and shadow mcr
+To: akpm@osdl.org, greg@kroah.com, linux-usb@vger.kernel.org
+Message-ID: <20080220214140.0c7ab8eb@core>
+
+
+Signed-off-by: Alan Cox <alan@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/serial/ti_usb_3410_5052.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/drivers/usb/serial/ti_usb_3410_5052.c
++++ b/drivers/usb/serial/ti_usb_3410_5052.c
+@@ -1022,14 +1022,17 @@ static int ti_tiocmget(struct usb_serial
+ unsigned int result;
+ unsigned int msr;
+ unsigned int mcr;
++ unsigned long flags;
+
+ dbg("%s - port %d", __FUNCTION__, port->number);
+
+ if (tport == NULL)
+ return -ENODEV;
+
++ spin_lock_irqsave(&tport->tp_lock, flags);
+ msr = tport->tp_msr;
+ mcr = tport->tp_shadow_mcr;
++ spin_unlock_irqrestore(&tport->tp_lock, flags);
+
+ result = ((mcr & TI_MCR_DTR) ? TIOCM_DTR : 0)
+ | ((mcr & TI_MCR_RTS) ? TIOCM_RTS : 0)
+@@ -1050,12 +1053,14 @@ static int ti_tiocmset(struct usb_serial
+ {
+ struct ti_port *tport = usb_get_serial_port_data(port);
+ unsigned int mcr;
++ unsigned long flags;
+
+ dbg("%s - port %d", __FUNCTION__, port->number);
+
+ if (tport == NULL)
+ return -ENODEV;
+
++ spin_lock_irqsave(&tport->tp_lock, flags);
+ mcr = tport->tp_shadow_mcr;
+
+ if (set & TIOCM_RTS)
+@@ -1071,6 +1076,7 @@ static int ti_tiocmset(struct usb_serial
+ mcr &= ~TI_MCR_DTR;
+ if (clear & TIOCM_LOOP)
+ mcr &= ~TI_MCR_LOOP;
++ spin_unlock_irqrestore(&tport->tp_lock, flags);
+
+ return ti_set_mcr(tport, mcr);
+ }
+@@ -1358,14 +1364,17 @@ static void ti_send(struct ti_port *tpor
+
+ static int ti_set_mcr(struct ti_port *tport, unsigned int mcr)
+ {
++ unsigned long flags;
+ int status;
+
+ status = ti_write_byte(tport->tp_tdev,
+ tport->tp_uart_base_addr + TI_UART_OFFSET_MCR,
+ TI_MCR_RTS | TI_MCR_DTR | TI_MCR_LOOP, mcr);
+
++ spin_lock_irqsave(&tport->tp_lock, flags);
+ if (!status)
+ tport->tp_shadow_mcr = mcr;
++ spin_unlock_irqrestore(&tport->tp_lock, flags);
+
+ return status;
+ }
diff --git a/usb/usb-usb-serial-prepare-for-bkl-push-down.patch b/usb/usb-usb-serial-prepare-for-bkl-push-down.patch
new file mode 100644
index 00000000000000..85304e2880de88
--- /dev/null
+++ b/usb/usb-usb-serial-prepare-for-bkl-push-down.patch
@@ -0,0 +1,70 @@
+From alan@lxorguk.ukuu.org.uk Wed Feb 20 14:27:12 2008
+From: Alan Cox <alan@lxorguk.ukuu.org.uk>
+Date: Wed, 20 Feb 2008 20:47:56 +0000
+Subject: USB: usb-serial: Prepare for BKL push down
+To: akpm@osdl.org, linux-kernel@vger.kernel.org, greg@kroah.com
+Message-ID: <20080220204756.1aa67aee@core>
+
+
+Take the lock in usb-serial instead. As it relies on the BKL internally
+we can't push it any deeper yet.
+
+Signed-off-by: Alan Cox <alan@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/serial/usb-serial.c | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/serial/usb-serial.c
++++ b/drivers/usb/serial/usb-serial.c
+@@ -401,11 +401,13 @@ static int serial_ioctl (struct tty_stru
+ struct usb_serial_port *port = tty->driver_data;
+ int retval = -ENODEV;
+
++ lock_kernel();
+ if (!port)
+ goto exit;
+
+ dbg("%s - port %d, cmd 0x%.4x", __FUNCTION__, port->number, cmd);
+
++ /* Caution - port->open_count is BKL protected */
+ if (!port->open_count) {
+ dbg ("%s - port not open", __FUNCTION__);
+ goto exit;
+@@ -416,8 +418,8 @@ static int serial_ioctl (struct tty_stru
+ retval = port->serial->type->ioctl(port, file, cmd, arg);
+ else
+ retval = -ENOIOCTLCMD;
+-
+ exit:
++ unlock_kernel();
+ return retval;
+ }
+
+@@ -446,19 +448,24 @@ static void serial_break (struct tty_str
+ {
+ struct usb_serial_port *port = tty->driver_data;
+
+- if (!port)
++ lock_kernel();
++ if (!port) {
++ unlock_kernel();
+ return;
++ }
+
+ dbg("%s - port %d", __FUNCTION__, port->number);
+
+ if (!port->open_count) {
+ dbg("%s - port not open", __FUNCTION__);
++ unlock_kernel();
+ return;
+ }
+
+ /* pass on to the driver specific version of this function if it is available */
+ if (port->serial->type->break_ctl)
+ port->serial->type->break_ctl(port, break_state);
++ unlock_kernel();
+ }
+
+ static int serial_read_proc (char *page, char **start, off_t off, int count, int *eof, void *data)