aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorAndrey Konovalov <andrey.konovalov@linaro.org>2012-07-16 20:16:53 +0400
committerAndrey Konovalov <andrey.konovalov@linaro.org>2012-07-16 20:16:53 +0400
commit5c7650b0c8efaa68ffb797c6da402b68d4418db8 (patch)
tree905aa9b075a26cee573f7904d2c2a5260aea28f1 /drivers
parentce9a20884a7270eb503f908ac8f3a065b822a6f1 (diff)
parentaa887ff761b432d16559dac6205cc7f3d0c35d1e (diff)
Automatically merging tracking-ubuntu-sauce into merge-linux-linaro-core-tracking
Conflicting files:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/battery.c39
-rw-r--r--drivers/acpi/video.c10
-rw-r--r--drivers/base/Kconfig9
-rw-r--r--drivers/base/power/main.c26
-rw-r--r--drivers/block/nbd.c2
-rw-r--r--drivers/block/xen-blkfront.c120
-rw-r--r--drivers/bluetooth/btusb.c3
-rw-r--r--drivers/cdrom/cdrom.c2
-rw-r--r--drivers/cpufreq/cpufreq.c22
-rw-r--r--drivers/firewire/ohci.c2
-rw-r--r--drivers/gpu/drm/drm_fops.c8
-rw-r--r--drivers/gpu/drm/drm_pci.c4
-rw-r--r--drivers/gpu/drm/drm_platform.c4
-rw-r--r--drivers/gpu/drm/drm_stub.c2
-rw-r--r--drivers/input/keyboard/Kconfig11
-rw-r--r--drivers/input/keyboard/Makefile1
-rw-r--r--drivers/input/keyboard/highbank_keys.c141
-rw-r--r--drivers/input/mouse/synaptics.c4
-rw-r--r--drivers/input/mouse/synaptics.h1
-rw-r--r--drivers/md/dm.c1
-rw-r--r--drivers/mmc/core/host.c1
-rw-r--r--drivers/mmc/host/omap_hsmmc.c2
-rw-r--r--drivers/net/ethernet/calxeda/xgmac.c5
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/mmc_core.c2
-rw-r--r--drivers/net/wireless/hostap/hostap_hw.c2
-rw-r--r--drivers/parport/Kconfig2
-rw-r--r--drivers/pci/pcie/aspm.c3
-rw-r--r--drivers/platform/x86/dell-wmi.c2
-rw-r--r--drivers/platform/x86/sony-laptop.c23
-rw-r--r--drivers/pnp/isapnp/core.c12
-rw-r--r--drivers/staging/Makefile2
-rw-r--r--drivers/tty/vt/vt.c43
-rw-r--r--drivers/tty/vt/vt_ioctl.c10
-rw-r--r--drivers/usb/core/hub.c34
-rw-r--r--drivers/usb/core/sysfs.c6
-rw-r--r--drivers/usb/storage/unusual_devs.h7
-rw-r--r--drivers/video/Kconfig4
-rw-r--r--drivers/video/vesafb.c82
38 files changed, 563 insertions, 91 deletions
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 7dd3f9fb9f3f..f22741069adb 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -976,6 +976,18 @@ static int battery_notify(struct notifier_block *nb,
return 0;
}
+static LIST_HEAD(acpi_battery_domain);
+
+static void acpi_battery_update_async(struct acpi_device *device, async_cookie_t cookie)
+{
+ struct acpi_battery *battery = acpi_driver_data(device);
+
+ acpi_battery_update(battery);
+ printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n",
+ ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device),
+ device->status.battery_present ? "present" : "absent");
+}
+
static int acpi_battery_add(struct acpi_device *device)
{
int result = 0;
@@ -995,13 +1007,16 @@ static int acpi_battery_add(struct acpi_device *device)
if (ACPI_SUCCESS(acpi_get_handle(battery->device->handle,
"_BIX", &handle)))
set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags);
- result = acpi_battery_update(battery);
- if (result)
- goto fail;
+
+ /* Mark the battery for update at first access. */
+ battery->update_time = 0;
#ifdef CONFIG_ACPI_PROCFS_POWER
result = acpi_battery_add_fs(device);
#endif
- if (result) {
+ if (!result) {
+ async_schedule_domain(acpi_battery_update_async, device, &acpi_battery_domain);
+
+ } else {
#ifdef CONFIG_ACPI_PROCFS_POWER
acpi_battery_remove_fs(device);
#endif
@@ -1031,6 +1046,10 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
if (!device || !acpi_driver_data(device))
return -EINVAL;
+
+ /* Ensure all async updates are complete before freeing the battery. */
+ async_synchronize_full_domain(&acpi_battery_domain);
+
battery = acpi_driver_data(device);
unregister_pm_notifier(&battery->pm_nb);
#ifdef CONFIG_ACPI_PROCFS_POWER
@@ -1068,27 +1087,21 @@ static struct acpi_driver acpi_battery_driver = {
},
};
-static void __init acpi_battery_init_async(void *unused, async_cookie_t cookie)
+static int __init acpi_battery_init(void)
{
if (acpi_disabled)
return;
#ifdef CONFIG_ACPI_PROCFS_POWER
acpi_battery_dir = acpi_lock_battery_dir();
if (!acpi_battery_dir)
- return;
+ return -1;
#endif
if (acpi_bus_register_driver(&acpi_battery_driver) < 0) {
#ifdef CONFIG_ACPI_PROCFS_POWER
acpi_unlock_battery_dir(acpi_battery_dir);
#endif
- return;
+ return -1;
}
- return;
-}
-
-static int __init acpi_battery_init(void)
-{
- async_schedule(acpi_battery_init_async, NULL);
return 0;
}
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 1e0a9e17c31d..dad347d0d4bb 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -73,6 +73,14 @@ static bool brightness_switch_enabled = 1;
module_param(brightness_switch_enabled, bool, 0644);
/*
+ * The Default is to let the OS handle brightness autoswitching due to
+ * AC/battery status changes. On some laptops (MSI Wind) this doesn't
+ * work so we need a workaround.
+ */
+static int brightness_autoswitch_via_bios = 0;
+module_param(brightness_autoswitch_via_bios, bool, 0644);
+
+/*
* By default, we don't allow duplicate ACPI video bus devices
* under the same VGA controller
*/
@@ -1425,7 +1433,7 @@ static int acpi_video_bus_put_devices(struct acpi_video_bus *video)
static int acpi_video_bus_start_devices(struct acpi_video_bus *video)
{
- return acpi_video_bus_DOS(video, 0, 0);
+ return acpi_video_bus_DOS(video, 0, !brightness_autoswitch_via_bios);
}
static int acpi_video_bus_stop_devices(struct acpi_video_bus *video)
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index d70e795edab5..3677ef9ff925 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -306,4 +306,13 @@ config SW_SYNC_USER
Provides a user space API to the sw sync object.
*WARNING* improper use of this can result in deadlocking kernel
drivers from userspace.
+
+config SR_REPORT_TIME_LIMIT
+ int "Default low threshold"
+ depends on PM
+ default 100
+ help
+ Print suspend/resume information for driver/device for time greater
+ then default msec, ie 100 msec.
+
endmenu
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 8b1ab105f6f8..952aa4645faa 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -359,6 +359,24 @@ static void pm_dev_err(struct device *dev, pm_message_t state, char *info,
dev_name(dev), pm_verb(state.event), info, error);
}
+static void device_show_time(struct device *dev, ktime_t starttime, pm_message_t state, char *info)
+{
+ ktime_t calltime;
+ s64 usecs64;
+ int usecs;
+
+ calltime = ktime_get();
+ usecs64 = ktime_to_ns(ktime_sub(calltime, starttime));
+ do_div(usecs64, NSEC_PER_USEC);
+ usecs = usecs64;
+ if (usecs == 0)
+ usecs = 1;
+ if ((usecs / USEC_PER_MSEC) > CONFIG_SR_REPORT_TIME_LIMIT)
+ pr_info("PM: %s%s%s of drv:%s dev:%s complete after %ld.%03ld msecs\n", info ?: "", info ? " " : "", pm_verb(state.event),
+ dev_driver_string(dev), dev_name(dev), usecs / USEC_PER_MSEC,
+ usecs % USEC_PER_MSEC);
+}
+
static void dpm_show_time(ktime_t starttime, pm_message_t state, char *info)
{
ktime_t calltime;
@@ -411,6 +429,7 @@ static int device_resume_noirq(struct device *dev, pm_message_t state)
pm_callback_t callback = NULL;
char *info = NULL;
int error = 0;
+ ktime_t starttime = ktime_get();
TRACE_DEVICE(dev);
TRACE_RESUME(0);
@@ -418,6 +437,7 @@ static int device_resume_noirq(struct device *dev, pm_message_t state)
if (dev->pm_domain) {
info = "noirq power domain ";
callback = pm_noirq_op(&dev->pm_domain->ops, state);
+ device_show_time(dev, starttime, state, "early");
} else if (dev->type && dev->type->pm) {
info = "noirq type ";
callback = pm_noirq_op(dev->type->pm, state);
@@ -572,6 +592,7 @@ static int device_resume(struct device *dev, pm_message_t state, bool async)
char *info = NULL;
int error = 0;
bool put = false;
+ ktime_t starttime = ktime_get();
TRACE_DEVICE(dev);
TRACE_RESUME(0);
@@ -632,6 +653,7 @@ static int device_resume(struct device *dev, pm_message_t state, bool async)
callback = pm_op(dev->driver->pm, state);
}
+ device_show_time(dev, starttime, state, NULL);
End:
error = dpm_run_callback(callback, dev, state, info);
dev->power.is_suspended = false;
@@ -863,6 +885,7 @@ static int device_suspend_noirq(struct device *dev, pm_message_t state)
{
pm_callback_t callback = NULL;
char *info = NULL;
+ ktime_t starttime = ktime_get();
if (dev->pm_domain) {
info = "noirq power domain ";
@@ -876,6 +899,7 @@ static int device_suspend_noirq(struct device *dev, pm_message_t state)
} else if (dev->bus && dev->bus->pm) {
info = "noirq bus ";
callback = pm_noirq_op(dev->bus->pm, state);
+ device_show_time(dev, starttime, state, "late");
}
if (!callback && dev->driver && dev->driver->pm) {
@@ -1060,6 +1084,7 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
int error = 0;
struct timer_list timer;
struct dpm_drv_wd_data data;
+ ktime_t starttime = ktime_get();
dpm_wait_for_children(dev, async);
@@ -1129,6 +1154,7 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
error = dpm_run_callback(callback, dev, state, info);
+ device_show_time(dev, starttime, state, NULL);
End:
if (!error) {
dev->power.is_suspended = true;
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index 061427a75d37..bb8b53da1db7 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -57,7 +57,7 @@ static unsigned int debugflags;
static unsigned int nbds_max = 16;
static struct nbd_device *nbd_dev;
-static int max_part;
+static int max_part = 15;
/*
* Use just one lock (or at most 1 per NIC). Two arguments for this:
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index e4fb3374dcd2..43860d31ec4b 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -73,7 +73,8 @@ struct blk_shadow {
static DEFINE_MUTEX(blkfront_mutex);
static const struct block_device_operations xlvbd_block_fops;
-#define BLK_RING_SIZE __CONST_RING_SIZE(blkif, PAGE_SIZE)
+#define BLK_MAX_RING_AREA_SIZE (BLKIF_MAX_NUM_RING_PAGES * PAGE_SIZE)
+#define BLK_MAX_RING_SIZE __CONST_RING_SIZE(blkif, BLK_MAX_RING_AREA_SIZE)
/*
* We have one of these per vbd, whether ide, scsi or 'other'. They
@@ -89,14 +90,15 @@ struct blkfront_info
int vdevice;
blkif_vdev_t handle;
enum blkif_state connected;
- int ring_ref;
+ int num_ring_pages;
+ int ring_ref[BLKIF_MAX_NUM_RING_PAGES];
struct blkif_front_ring ring;
struct scatterlist sg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
unsigned int evtchn, irq;
struct request_queue *rq;
struct work_struct work;
struct gnttab_free_callback callback;
- struct blk_shadow shadow[BLK_RING_SIZE];
+ struct blk_shadow shadow[BLK_MAX_RING_SIZE];
unsigned long shadow_free;
unsigned int feature_flush;
unsigned int flush_op;
@@ -135,7 +137,8 @@ static DEFINE_SPINLOCK(minor_lock);
static int get_id_from_freelist(struct blkfront_info *info)
{
unsigned long free = info->shadow_free;
- BUG_ON(free >= BLK_RING_SIZE);
+ int ring_size = __RING_SIZE((struct blkif_sring *)0, info->num_ring_pages * PAGE_SIZE);
+ BUG_ON(free >= ring_size);
info->shadow_free = info->shadow[free].req.u.rw.id;
info->shadow[free].req.u.rw.id = 0x0fffffee; /* debug */
return free;
@@ -707,6 +710,8 @@ static void blkif_restart_queue(struct work_struct *work)
static void blkif_free(struct blkfront_info *info, int suspend)
{
+ int i;
+
/* Prevent new requests being issued until we fix things up. */
spin_lock_irq(&info->io_lock);
info->connected = suspend ?
@@ -722,10 +727,17 @@ static void blkif_free(struct blkfront_info *info, int suspend)
flush_work_sync(&info->work);
/* Free resources associated with old device channel. */
- if (info->ring_ref != GRANT_INVALID_REF) {
- gnttab_end_foreign_access(info->ring_ref, 0,
- (unsigned long)info->ring.sring);
- info->ring_ref = GRANT_INVALID_REF;
+ for (i = 0; i < info->num_ring_pages; i++) {
+ /* Free resources associated with old device channel. */
+ if (info->ring_ref[i] != GRANT_INVALID_REF) {
+ gnttab_end_foreign_access(info->ring_ref[i], 0, 0L);
+ info->ring_ref[i] = GRANT_INVALID_REF;
+ }
+ }
+ if (info->ring.sring) {
+ int ring_area_size = info->num_ring_pages * PAGE_SIZE;
+ free_pages((unsigned long)info->ring.sring,
+ get_order(ring_area_size));
info->ring.sring = NULL;
}
if (info->irq)
@@ -862,27 +874,32 @@ static int setup_blkring(struct xenbus_device *dev,
struct blkfront_info *info)
{
struct blkif_sring *sring;
- int err;
+ int i, order, err;
+ int ring_area_size = info->num_ring_pages * PAGE_SIZE;
- info->ring_ref = GRANT_INVALID_REF;
+ for (i = 0; i < info->num_ring_pages; i++) {
+ info->ring_ref[i] = GRANT_INVALID_REF;
+ }
- sring = (struct blkif_sring *)__get_free_page(GFP_NOIO | __GFP_HIGH);
+ order = get_order(ring_area_size);
+ sring = (struct blkif_sring *)__get_free_pages(GFP_KERNEL, order);
if (!sring) {
xenbus_dev_fatal(dev, -ENOMEM, "allocating shared ring");
return -ENOMEM;
}
SHARED_RING_INIT(sring);
- FRONT_RING_INIT(&info->ring, sring, PAGE_SIZE);
-
- sg_init_table(info->sg, BLKIF_MAX_SEGMENTS_PER_REQUEST);
-
- err = xenbus_grant_ring(dev, virt_to_mfn(info->ring.sring));
- if (err < 0) {
- free_page((unsigned long)sring);
- info->ring.sring = NULL;
- goto fail;
+ FRONT_RING_INIT(&info->ring, sring, ring_area_size);
+
+ for (i = 0; i < info->num_ring_pages; i++) {
+ unsigned long addr = (unsigned long)info->ring.sring + i * PAGE_SIZE;
+ err = xenbus_grant_ring(dev, virt_to_mfn(addr));
+ if (err < 0) {
+ free_pages((unsigned long)sring, order);
+ info->ring.sring = NULL;
+ goto fail;
+ }
+ info->ring_ref[i] = err;
}
- info->ring_ref = err;
err = xenbus_alloc_evtchn(dev, &info->evtchn);
if (err)
@@ -911,7 +928,13 @@ static int talk_to_blkback(struct xenbus_device *dev,
{
const char *message = NULL;
struct xenbus_transaction xbt;
- int err;
+ int err, i;
+
+ BUILD_BUG_ON(BLKIF_MAX_NUM_RING_PAGES != 1 &&
+ BLKIF_MAX_NUM_RING_PAGES != 2 &&
+ BLKIF_MAX_NUM_RING_PAGES != 4 &&
+ BLKIF_MAX_NUM_RING_PAGES != 8 &&
+ BLKIF_MAX_NUM_RING_PAGES != 16);
/* Create shared ring, alloc event channel. */
err = setup_blkring(dev, info);
@@ -925,11 +948,30 @@ again:
goto destroy_blkring;
}
- err = xenbus_printf(xbt, dev->nodename,
- "ring-ref", "%u", info->ring_ref);
- if (err) {
- message = "writing ring-ref";
- goto abort_transaction;
+ if (info->num_ring_pages == 1) {
+ err = xenbus_printf(xbt, dev->nodename,
+ "ring-ref", "%u", info->ring_ref[0]);
+ if (err) {
+ message = "writing ring-ref";
+ goto abort_transaction;
+ }
+ } else {
+ err = xenbus_printf(xbt, dev->nodename, "num-ring-pages", "%u",
+ info->num_ring_pages);
+ if (err) {
+ message = "writing num-ring-pages";
+ goto abort_transaction;
+ }
+ for (i = 0; i < info->num_ring_pages; i++) {
+ char buf[16];
+ snprintf(buf, sizeof(buf), "ring-ref%d", i);
+ err = xenbus_printf(xbt, dev->nodename, buf, "%u",
+ info->ring_ref[i]);
+ if (err) {
+ message = "writing ring-refs";
+ goto abort_transaction;
+ }
+ }
}
err = xenbus_printf(xbt, dev->nodename,
"event-channel", "%u", info->evtchn);
@@ -977,6 +1019,7 @@ static int blkfront_probe(struct xenbus_device *dev,
{
int err, vdevice, i;
struct blkfront_info *info;
+ int ring_size, max_ring_pages;
/* FIXME: Use dynamic device id if this is not set. */
err = xenbus_scanf(XBT_NIL, dev->nodename,
@@ -990,6 +1033,10 @@ static int blkfront_probe(struct xenbus_device *dev,
return err;
}
}
+ err = xenbus_scanf(XBT_NIL, dev->otherend,
+ "max-ring-pages", "%u", &max_ring_pages);
+ if (err != 1)
+ max_ring_pages = 1;
if (xen_hvm_domain()) {
char *type;
@@ -1033,9 +1080,13 @@ static int blkfront_probe(struct xenbus_device *dev,
info->connected = BLKIF_STATE_DISCONNECTED;
INIT_WORK(&info->work, blkif_restart_queue);
- for (i = 0; i < BLK_RING_SIZE; i++)
+ info->num_ring_pages = min(max_ring_pages, BLKIF_MAX_NUM_RING_PAGES);
+
+ ring_size = __RING_SIZE((struct blkif_sring *)0,
+ info->num_ring_pages * PAGE_SIZE);
+ for (i = 0; i < ring_size; i++)
info->shadow[i].req.u.rw.id = i+1;
- info->shadow[BLK_RING_SIZE-1].req.u.rw.id = 0x0fffffff;
+ info->shadow[ring_size-1].req.u.rw.id = 0x0fffffff;
/* Front end dir is a number, which is used as the id. */
info->handle = simple_strtoul(strrchr(dev->nodename, '/')+1, NULL, 0);
@@ -1048,6 +1099,9 @@ static int blkfront_probe(struct xenbus_device *dev,
return err;
}
+ printk(KERN_INFO "blkfront %s num-ring-pages %d nr_ents %d.\n",
+ dev->nodename, info->num_ring_pages, ring_size);
+
return 0;
}
@@ -1058,6 +1112,7 @@ static int blkif_recover(struct blkfront_info *info)
struct blkif_request *req;
struct blk_shadow *copy;
int j;
+ int ring_size = __RING_SIZE((struct blkif_sring *)0, info->num_ring_pages * PAGE_SIZE);
/* Stage 1: Make a safe copy of the shadow state. */
copy = kmalloc(sizeof(info->shadow),
@@ -1068,13 +1123,13 @@ static int blkif_recover(struct blkfront_info *info)
/* Stage 2: Set up free list. */
memset(&info->shadow, 0, sizeof(info->shadow));
- for (i = 0; i < BLK_RING_SIZE; i++)
+ for (i = 0; i < ring_size; i++)
info->shadow[i].req.u.rw.id = i+1;
info->shadow_free = info->ring.req_prod_pvt;
- info->shadow[BLK_RING_SIZE-1].req.u.rw.id = 0x0fffffff;
+ info->shadow[ring_size-1].req.u.rw.id = 0x0fffffff;
/* Stage 3: Find pending requests and requeue them. */
- for (i = 0; i < BLK_RING_SIZE; i++) {
+ for (i = 0; i < ring_size; i++) {
/* Not in use? */
if (!copy[i].request)
continue;
@@ -1545,3 +1600,4 @@ MODULE_LICENSE("GPL");
MODULE_ALIAS_BLOCKDEV_MAJOR(XENVBD_MAJOR);
MODULE_ALIAS("xen:vbd");
MODULE_ALIAS("xenblk");
+
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 83ebb241bfcc..3f68112a36ea 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -102,10 +102,13 @@ static struct usb_device_id btusb_table[] = {
/* Broadcom BCM20702A0 */
{ USB_DEVICE(0x0489, 0xe042) },
+ { USB_DEVICE(0x0a5c, 0x21e1) },
{ USB_DEVICE(0x0a5c, 0x21e3) },
{ USB_DEVICE(0x0a5c, 0x21e6) },
{ USB_DEVICE(0x0a5c, 0x21e8) },
{ USB_DEVICE(0x0a5c, 0x21f3) },
+ { USB_DEVICE(0x0a5c, 0x21e6) },
+ { USB_DEVICE(0x0a5c, 0x21f3) },
{ USB_DEVICE(0x413c, 0x8197) },
/* Foxconn - Hon Hai */
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
index d620b4495745..72cf3159c67c 100644
--- a/drivers/cdrom/cdrom.c
+++ b/drivers/cdrom/cdrom.c
@@ -289,7 +289,7 @@ static bool debug;
/* default compatibility mode */
static bool autoclose=1;
static bool autoeject;
-static bool lockdoor = 1;
+static bool lockdoor = 0;
/* will we ever get to use this... sigh. */
static bool check_media_type;
/* automatically restart mrw format */
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 7f2f149ae40f..222966f34432 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -1817,6 +1817,20 @@ static struct notifier_block __refdata cpufreq_cpu_notifier = {
* REGISTER / UNREGISTER CPUFREQ DRIVER *
*********************************************************************/
+static char cpufreq_driver_name[CPUFREQ_NAME_LEN];
+
+static int __init cpufreq_driver_setup(char *str)
+{
+ strlcpy(cpufreq_driver_name, str, CPUFREQ_NAME_LEN);
+ return 1;
+}
+
+/*
+ * Set this name to only allow one specific cpu freq driver, e.g.,
+ * cpufreq_driver=powernow-k8
+ */
+__setup("cpufreq_driver=", cpufreq_driver_setup);
+
/**
* cpufreq_register_driver - register a CPU Frequency driver
* @driver_data: A struct cpufreq_driver containing the values#
@@ -1839,7 +1853,13 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
((!driver_data->setpolicy) && (!driver_data->target)))
return -EINVAL;
- pr_debug("trying to register driver %s\n", driver_data->name);
+ pr_debug("trying to register driver %s, cpufreq_driver=%s\n",
+ driver_data->name, cpufreq_driver_name);
+
+ if (cpufreq_driver_name[0])
+ if (!driver_data->name ||
+ strcmp(cpufreq_driver_name, driver_data->name))
+ return -EINVAL;
if (driver_data->setpolicy)
driver_data->flags |= CPUFREQ_CONST_LOOPS;
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index c1af05e834b6..6ac61488082e 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -320,6 +320,8 @@ static const struct {
{PCI_VENDOR_ID_VIA, PCI_ANY_ID, PCI_ANY_ID,
QUIRK_CYCLE_TIMER | QUIRK_NO_MSI},
+ {PCI_VENDOR_ID_O2, PCI_ANY_ID, PCI_ANY_ID,
+ QUIRK_NO_MSI},
};
/* This overrides anything that was found in ohci_quirks[]. */
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index 123de28f94ef..9c14f633772c 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -129,7 +129,8 @@ int drm_open(struct inode *inode, struct file *filp)
minor = idr_find(&drm_minors_idr, minor_id);
if (!minor)
return -ENODEV;
-
+ if (IS_ERR(minor))
+ return PTR_ERR(minor);
if (!(dev = minor->dev))
return -ENODEV;
@@ -180,7 +181,10 @@ int drm_stub_open(struct inode *inode, struct file *filp)
minor = idr_find(&drm_minors_idr, minor_id);
if (!minor)
goto out;
-
+ if (IS_ERR(minor)) {
+ err = PTR_ERR(minor);
+ goto out;
+ }
if (!(dev = minor->dev))
goto out;
diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c
index 13f3d936472f..b3216724122a 100644
--- a/drivers/gpu/drm/drm_pci.c
+++ b/drivers/gpu/drm/drm_pci.c
@@ -367,6 +367,10 @@ int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
list_add_tail(&dev->driver_item, &driver->device_list);
+ if (drm_core_check_feature(dev, DRIVER_MODESET))
+ idr_replace(&drm_minors_idr, dev->control, dev->control->index);
+ idr_replace(&drm_minors_idr, dev->primary, dev->primary->index);
+
DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n",
driver->name, driver->major, driver->minor, driver->patchlevel,
driver->date, pci_name(pdev), dev->primary->index);
diff --git a/drivers/gpu/drm/drm_platform.c b/drivers/gpu/drm/drm_platform.c
index 82431dcae37b..d749389a15a0 100644
--- a/drivers/gpu/drm/drm_platform.c
+++ b/drivers/gpu/drm/drm_platform.c
@@ -90,6 +90,10 @@ int drm_get_platform_dev(struct platform_device *platdev,
list_add_tail(&dev->driver_item, &driver->device_list);
+ if (drm_core_check_feature(dev, DRIVER_MODESET))
+ idr_replace(&drm_minors_idr, dev->control, dev->control->index);
+ idr_replace(&drm_minors_idr, dev->primary, dev->primary->index);
+
mutex_unlock(&drm_global_mutex);
DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c
index 21bcd4a555d8..0251c38ac267 100644
--- a/drivers/gpu/drm/drm_stub.c
+++ b/drivers/gpu/drm/drm_stub.c
@@ -356,7 +356,7 @@ int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int type)
new_minor->index = minor_id;
INIT_LIST_HEAD(&new_minor->master_list);
- idr_replace(&drm_minors_idr, new_minor, minor_id);
+ idr_replace(&drm_minors_idr, ERR_PTR(-EAGAIN), minor_id);
if (type == DRM_MINOR_LEGACY) {
ret = drm_proc_init(new_minor, minor_id, drm_proc_root);
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index c0e11ecc646f..c99bf9065f75 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -204,6 +204,17 @@ config KEYBOARD_GPIO_POLLED
To compile this driver as a module, choose M here: the
module will be called gpio_keys_polled.
+config KEYBOARD_HIGHBANK
+ tristate "Calxeda Highbank Virtual Keys"
+ depends on ARCH_HIGHBANK
+ default y
+ help
+ This driver implements support for virtual power keys on Calxeda
+ Highbank systems.
+
+ To compile this driver as a module, choose M here: the
+ module will be called highbank_keys.
+
config KEYBOARD_TCA6416
tristate "TCA6416/TCA6408A Keypad Support"
depends on I2C
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index b03b02456a82..5dc046906f3f 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_KEYBOARD_DAVINCI) += davinci_keyscan.o
obj-$(CONFIG_KEYBOARD_EP93XX) += ep93xx_keypad.o
obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o
obj-$(CONFIG_KEYBOARD_GPIO_POLLED) += gpio_keys_polled.o
+obj-$(CONFIG_KEYBOARD_HIGHBANK) += highbank_keys.o
obj-$(CONFIG_KEYBOARD_TCA6416) += tca6416-keypad.o
obj-$(CONFIG_KEYBOARD_TCA8418) += tca8418_keypad.o
obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o
diff --git a/drivers/input/keyboard/highbank_keys.c b/drivers/input/keyboard/highbank_keys.c
new file mode 100644
index 000000000000..a84ecf371755
--- /dev/null
+++ b/drivers/input/keyboard/highbank_keys.c
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2011 Calxeda, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+
+#include <mach/pl320-ipc.h>
+
+struct hb_keys_drvdata {
+ struct input_dev *input;
+ struct notifier_block nb;
+};
+
+int hb_keys_notifier(struct notifier_block *nb, unsigned long event, void *data)
+{
+ struct hb_keys_drvdata *ddata = container_of(nb, struct hb_keys_drvdata, nb);
+ struct input_dev *input = ddata->input;
+ u32 *d = data;
+ u32 key = d[0];
+
+ if (event != 0x1000 /*HB_IPC_KEY*/)
+ return 0;
+
+ input_event(input, EV_KEY, key, 1);
+ input_event(input, EV_KEY, key, 0);
+ input_sync(input);
+ return 0;
+}
+
+static int hb_keys_open(struct input_dev *input)
+{
+ struct hb_keys_drvdata *ddata = input_get_drvdata(input);
+ return pl320_ipc_register_notifier(&ddata->nb);
+}
+
+static void hb_keys_close(struct input_dev *input)
+{
+ struct hb_keys_drvdata *ddata = input_get_drvdata(input);
+ pl320_ipc_unregister_notifier(&ddata->nb);
+}
+
+static int __devinit hb_keys_probe(struct platform_device *pdev)
+{
+ struct hb_keys_drvdata *ddata;
+ struct device *dev = &pdev->dev;
+ struct input_dev *input;
+ int error;
+
+ ddata = kzalloc(sizeof(*ddata), GFP_KERNEL);
+ if (!ddata)
+ return -ENOMEM;
+
+ input = input_allocate_device();
+ if (!input) {
+ dev_err(dev, "failed to allocate state\n");
+ error = -ENOMEM;
+ goto fail1;
+ }
+
+ platform_set_drvdata(pdev, ddata);
+ input_set_drvdata(input, ddata);
+
+ ddata->input = input;
+ ddata->nb.notifier_call = hb_keys_notifier;
+
+ input->name = pdev->name;
+ input->phys = "highbank/input0";
+ input->dev.parent = &pdev->dev;
+ input->open = hb_keys_open;
+ input->close = hb_keys_close;
+
+ input->id.bustype = BUS_HOST;
+ input->id.vendor = 0x0001;
+ input->id.product = 0x0001;
+ input->id.version = 0x0100;
+
+ input_set_capability(input, EV_KEY, KEY_POWER);
+ input_set_capability(input, EV_KEY, KEY_SLEEP);
+
+ error = input_register_device(input);
+ if (error) {
+ dev_err(dev, "Unable to register input device, error: %d\n",
+ error);
+ goto fail2;
+ }
+
+ return 0;
+
+ fail2:
+ input_free_device(input);
+ fail1:
+ kfree(ddata);
+ return error;
+}
+
+static int __devexit hb_keys_remove(struct platform_device *pdev)
+{
+ struct hb_keys_drvdata *ddata = platform_get_drvdata(pdev);
+ input_unregister_device(ddata->input);
+ kfree(ddata);
+ return 0;
+}
+
+static struct of_device_id hb_keys_of_match[] = {
+ { .compatible = "calxeda,hb-keys", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, hb_keys_of_match);
+
+static struct platform_driver hb_keys_driver = {
+ .probe = hb_keys_probe,
+ .remove = __devexit_p(hb_keys_remove),
+ .driver = {
+ .name = "hb-keys",
+ .of_match_table = hb_keys_of_match,
+ }
+};
+
+module_platform_driver(hb_keys_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Calxeda, Inc.");
+MODULE_DESCRIPTION("Keys driver for Calxeda Highbank");
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index c703d53be3a0..c6d986963992 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -1223,7 +1223,9 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv)
/* Clickpads report only left button */
__clear_bit(BTN_RIGHT, dev->keybit);
__clear_bit(BTN_MIDDLE, dev->keybit);
- }
+ } else if (SYN_CAP_CLICKPAD2BTN(priv->ext_cap_0c) ||
+ SYN_CAP_CLICKPAD2BTN2(priv->ext_cap_0c))
+ __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit);
}
static ssize_t synaptics_show_disable_gesture(struct psmouse *psmouse,
diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h
index fd26ccca13d7..816d7bd07d85 100644
--- a/drivers/input/mouse/synaptics.h
+++ b/drivers/input/mouse/synaptics.h
@@ -80,6 +80,7 @@
*/
#define SYN_CAP_CLICKPAD(ex0c) ((ex0c) & 0x100000) /* 1-button ClickPad */
#define SYN_CAP_CLICKPAD2BTN(ex0c) ((ex0c) & 0x000100) /* 2-button ClickPad */
+#define SYN_CAP_CLICKPAD2BTN2(ex0c) ((ex0c) & 0x200000) /* 2-button ClickPad */
#define SYN_CAP_MAX_DIMENSIONS(ex0c) ((ex0c) & 0x020000)
#define SYN_CAP_MIN_DIMENSIONS(ex0c) ((ex0c) & 0x002000)
#define SYN_CAP_ADV_GESTURE(ex0c) ((ex0c) & 0x080000)
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index e24143cc2040..ea1f089b128e 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -2653,6 +2653,7 @@ struct gendisk *dm_disk(struct mapped_device *md)
{
return md->disk;
}
+EXPORT_SYMBOL_GPL(dm_disk);
struct kobject *dm_kobject(struct mapped_device *md)
{
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index dd7b1203e867..8de85186482f 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -436,3 +436,4 @@ void mmc_free_host(struct mmc_host *host)
}
EXPORT_SYMBOL(mmc_free_host);
+
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 55a017a5da86..cc9b0c627310 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -1850,7 +1850,7 @@ static int __devinit omap_hsmmc_probe(struct platform_device *pdev)
host->slot_id = 0;
host->mapbase = res->start + pdata->reg_offset;
host->base = ioremap(host->mapbase, SZ_4K);
- host->power_mode = MMC_POWER_OFF;
+ host->power_mode = -1;
host->next_data.cookie = 1;
platform_set_drvdata(pdev, host);
diff --git a/drivers/net/ethernet/calxeda/xgmac.c b/drivers/net/ethernet/calxeda/xgmac.c
index 11f667f6131a..8fc5fd0fb76c 100644
--- a/drivers/net/ethernet/calxeda/xgmac.c
+++ b/drivers/net/ethernet/calxeda/xgmac.c
@@ -210,7 +210,7 @@
#define DMA_INTR_ENA_TIE 0x00000001 /* Transmit Interrupt */
#define DMA_INTR_NORMAL (DMA_INTR_ENA_NIE | DMA_INTR_ENA_RIE | \
- DMA_INTR_ENA_TUE)
+ DMA_INTR_ENA_TUE | DMA_INTR_ENA_TIE)
#define DMA_INTR_ABNORMAL (DMA_INTR_ENA_AIE | DMA_INTR_ENA_FBE | \
DMA_INTR_ENA_RWE | DMA_INTR_ENA_RSE | \
@@ -933,6 +933,7 @@ static void xgmac_tx_err(struct xgmac_priv *priv)
desc_init_tx_desc(priv->dma_tx, DMA_TX_RING_SZ);
priv->tx_tail = 0;
priv->tx_head = 0;
+ writel(priv->dma_tx_phy, priv->base + XGMAC_DMA_TX_BASE_ADDR);
writel(reg | DMA_CONTROL_ST, priv->base + XGMAC_DMA_CONTROL);
writel(DMA_STATUS_TU | DMA_STATUS_TPS | DMA_STATUS_NIS | DMA_STATUS_AIS,
@@ -972,7 +973,7 @@ static int xgmac_hw_init(struct net_device *dev)
writel(DMA_INTR_DEFAULT_MASK, ioaddr + XGMAC_DMA_INTR_ENA);
/* XGMAC requires AXI bus init. This is a 'magic number' for now */
- writel(0x000100E, ioaddr + XGMAC_DMA_AXI_BUS);
+ writel(0x0077000E, ioaddr + XGMAC_DMA_AXI_BUS);
ctrl |= XGMAC_CONTROL_DDIC | XGMAC_CONTROL_JE | XGMAC_CONTROL_ACS |
XGMAC_CONTROL_CAR;
diff --git a/drivers/net/ethernet/stmicro/stmmac/mmc_core.c b/drivers/net/ethernet/stmicro/stmmac/mmc_core.c
index c07cfe989f6e..2de44aee73cb 100644
--- a/drivers/net/ethernet/stmicro/stmmac/mmc_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/mmc_core.c
@@ -23,7 +23,9 @@
*******************************************************************************/
#include <linux/kernel.h>
+#include <stdarg.h>
#include <linux/io.h>
+#include <linux/printk.h>
#include "mmc.h"
/* MAC Management Counters register offset */
diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c
index 50f87b60b0bd..16e2fee4d246 100644
--- a/drivers/net/wireless/hostap/hostap_hw.c
+++ b/drivers/net/wireless/hostap/hostap_hw.c
@@ -68,7 +68,7 @@ static char essid[33] = "test";
module_param_string(essid, essid, sizeof(essid), 0444);
MODULE_PARM_DESC(essid, "Host AP's ESSID");
-static int iw_mode[MAX_PARM_DEVICES] = { IW_MODE_MASTER, DEF_INTS };
+static int iw_mode[MAX_PARM_DEVICES] = { IW_MODE_INFRA, DEF_INTS };
module_param_array(iw_mode, int, NULL, 0444);
MODULE_PARM_DESC(iw_mode, "Initial operation mode");
diff --git a/drivers/parport/Kconfig b/drivers/parport/Kconfig
index d92185a5523b..9654a9e83200 100644
--- a/drivers/parport/Kconfig
+++ b/drivers/parport/Kconfig
@@ -36,7 +36,7 @@ if PARPORT
config PARPORT_PC
tristate "PC-style hardware"
depends on (!SPARC64 || PCI) && !SPARC32 && !M32R && !FRV && \
- (!M68K || ISA) && !MN10300 && !AVR32 && !BLACKFIN
+ (!M68K || ISA) && !MN10300 && !AVR32 && !BLACKFIN && !ARCH_OMAP
---help---
You should say Y here if you have a PC-style parallel port. All
IBM PC compatible computers and some Alphas have PC-style
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index b500840a143b..474f22f304e4 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -798,6 +798,9 @@ void pcie_clear_aspm(struct pci_bus *bus)
{
struct pci_dev *child;
+ if (aspm_force)
+ return;
+
/*
* Clear any ASPM setup that the firmware has carried out on this bus
*/
diff --git a/drivers/platform/x86/dell-wmi.c b/drivers/platform/x86/dell-wmi.c
index fa9a2171cc13..3ab412c18d23 100644
--- a/drivers/platform/x86/dell-wmi.c
+++ b/drivers/platform/x86/dell-wmi.c
@@ -165,7 +165,7 @@ static void dell_wmi_notify(u32 value, void *context)
u16 *buffer_entry = (u16 *)obj->buffer.pointer;
if (dell_new_hk_type && (buffer_entry[1] != 0x10)) {
- pr_info("Received unknown WMI event (0x%x)\n",
+ pr_debug("Received unknown WMI event (0x%x)\n",
buffer_entry[1]);
kfree(obj);
return;
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c
index 210d4ae547c2..9e9a55ec5e9c 100644
--- a/drivers/platform/x86/sony-laptop.c
+++ b/drivers/platform/x86/sony-laptop.c
@@ -2760,6 +2760,10 @@ struct sonypi_eventtypes {
struct sonypi_event *events;
};
+struct sony_pic_quirk_entry {
+ u8 set_wwan_power;
+};
+
struct sony_pic_dev {
struct acpi_device *acpi_dev;
struct sony_pic_irq *cur_irq;
@@ -2770,6 +2774,7 @@ struct sony_pic_dev {
struct sonypi_eventtypes *event_types;
int (*handle_irq)(const u8, const u8);
int model;
+ struct sony_pic_quirk_entry *quirks;
u16 evport_offset;
u8 camera_power;
u8 bluetooth_power;
@@ -4204,6 +4209,12 @@ static int sony_pic_add(struct acpi_device *device)
if (result)
goto err_remove_pf;
+ if (spic_dev.quirks && spic_dev.quirks->set_wwan_power) {
+ /*
+ * Power isn't enabled by default.
+ */
+ __sony_pic_set_wwanpower(1);
+ }
return 0;
err_remove_pf:
@@ -4274,6 +4285,16 @@ static struct acpi_driver sony_pic_driver = {
},
};
+static struct sony_pic_quirk_entry sony_pic_vaio_vgn = {
+ .set_wwan_power = 1,
+};
+
+static int dmi_matched(const struct dmi_system_id *dmi)
+{
+ spic_dev.quirks = dmi->driver_data;
+ return 0;
+}
+
static struct dmi_system_id __initdata sonypi_dmi_table[] = {
{
.ident = "Sony Vaio",
@@ -4288,6 +4309,8 @@ static struct dmi_system_id __initdata sonypi_dmi_table[] = {
DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
DMI_MATCH(DMI_PRODUCT_NAME, "VGN-"),
},
+ .callback = dmi_matched,
+ .driver_data = &sony_pic_vaio_vgn,
},
{ }
};
diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c
index 918d5f044865..972fde662338 100644
--- a/drivers/pnp/isapnp/core.c
+++ b/drivers/pnp/isapnp/core.c
@@ -41,6 +41,7 @@
#include <linux/init.h>
#include <linux/isapnp.h>
#include <linux/mutex.h>
+#include <linux/async.h>
#include <asm/io.h>
#include "../base.h"
@@ -1001,7 +1002,7 @@ struct pnp_protocol isapnp_protocol = {
.disable = isapnp_disable_resources,
};
-static int __init isapnp_init(void)
+static int __init real_isapnp_init(void)
{
int cards;
struct pnp_card *card;
@@ -1095,6 +1096,15 @@ static int __init isapnp_init(void)
return 0;
}
+static void __init async_isapnp_init(void *unused, async_cookie_t cookie)
+{
+ (void)real_isapnp_init();
+}
+
+static int __init isapnp_init(void)
+{
+ async_schedule(async_isapnp_init, NULL);
+}
device_initcall(isapnp_init);
/* format is: noisapnp */
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index a987b3ad380b..3b32dd97dae0 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -27,7 +27,7 @@ obj-$(CONFIG_LINE6_USB) += line6/
obj-$(CONFIG_USB_SERIAL_QUATECH2) += serqt_usb2/
obj-$(CONFIG_OCTEON_ETHERNET) += octeon/
obj-$(CONFIG_VT6655) += vt6655/
-obj-$(CONFIG_VT6656) += vt6656/
+#obj-$(CONFIG_VT6656) += vt6656/
obj-$(CONFIG_VME_BUS) += vme/
obj-$(CONFIG_IPACK_BUS) += ipack/
obj-$(CONFIG_DX_SEP) += sep/
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 84cbf298c094..509037447161 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -102,6 +102,7 @@
#include <linux/uaccess.h>
#include <linux/kdb.h>
#include <linux/ctype.h>
+#include <linux/screen_info.h>
#define MAX_NR_CON_DRIVER 16
@@ -144,7 +145,7 @@ static const struct consw *con_driver_map[MAX_NR_CONSOLES];
static int con_open(struct tty_struct *, struct file *);
static void vc_init(struct vc_data *vc, unsigned int rows,
- unsigned int cols, int do_clear);
+ unsigned int cols, int do_clear, int mode);
static void gotoxy(struct vc_data *vc, int new_x, int new_y);
static void save_cur(struct vc_data *vc);
static void reset_terminal(struct vc_data *vc, int do_clear);
@@ -165,6 +166,9 @@ module_param(global_cursor_default, int, S_IRUGO | S_IWUSR);
static int cur_default = CUR_DEFAULT;
module_param(cur_default, int, S_IRUGO | S_IWUSR);
+int vt_handoff = 0;
+module_param_named(handoff, vt_handoff, int, S_IRUGO | S_IWUSR);
+
/*
* ignore_poke: don't unblank the screen when things are typed. This is
* mainly for the privacy of braille terminal users.
@@ -694,6 +698,13 @@ void redraw_screen(struct vc_data *vc, int is_switch)
}
if (tty0dev)
sysfs_notify(&tty0dev->kobj, NULL, "active");
+ /*
+ * If we are switching away from a transparent VT the contents
+ * will be lost, convert it into a blank text console then
+ * it will be repainted blank if we ever switch back.
+ */
+ if (old_vc->vc_mode == KD_TRANSPARENT)
+ old_vc->vc_mode = KD_TEXT;
} else {
hide_cursor(vc);
redraw = 1;
@@ -807,7 +818,7 @@ int vc_allocate(unsigned int currcons) /* return 0 on success */
if (global_cursor_default == -1)
global_cursor_default = 1;
- vc_init(vc, vc->vc_rows, vc->vc_cols, 1);
+ vc_init(vc, vc->vc_rows, vc->vc_cols, 1, KD_TEXT);
vcs_make_sysfs(currcons);
atomic_notifier_call_chain(&vt_notifier_list, VT_ALLOCATE, &param);
}
@@ -2848,7 +2859,7 @@ module_param_named(italic, default_italic_color, int, S_IRUGO | S_IWUSR);
module_param_named(underline, default_underline_color, int, S_IRUGO | S_IWUSR);
static void vc_init(struct vc_data *vc, unsigned int rows,
- unsigned int cols, int do_clear)
+ unsigned int cols, int do_clear, int mode)
{
int j, k ;
@@ -2859,7 +2870,7 @@ static void vc_init(struct vc_data *vc, unsigned int rows,
set_origin(vc);
vc->vc_pos = vc->vc_origin;
- reset_vc(vc);
+ reset_vc(vc, mode);
for (j=k=0; j<16; j++) {
vc->vc_palette[k++] = default_red[j] ;
vc->vc_palette[k++] = default_grn[j] ;
@@ -2885,6 +2896,13 @@ static int __init con_init(void)
struct vc_data *vc;
unsigned int currcons = 0, i;
+ if (screen_info.flags & VIDEO_FLAGS_HANDOFF) {
+ if (vt_handoff == 0)
+ vt_handoff = 8;
+ printk(KERN_INFO "vt handoff: grub requested handoff (vt#%d)\n",
+ vt_handoff);
+ }
+
console_lock();
if (conswitchp)
@@ -2916,16 +2934,31 @@ static int __init con_init(void)
mod_timer(&console_timer, jiffies + (blankinterval * HZ));
}
+ if (vt_handoff > 0 && vt_handoff <= MAX_NR_CONSOLES) {
+ currcons = vt_handoff - 1;
+ vc_cons[currcons].d = vc = kzalloc(sizeof(struct vc_data), GFP_NOWAIT);
+ INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK);
+ visual_init(vc, currcons, 1);
+ vc->vc_screenbuf = kzalloc(vc->vc_screenbuf_size, GFP_NOWAIT);
+ vc_init(vc, vc->vc_rows, vc->vc_cols, 0, KD_TRANSPARENT);
+ }
for (currcons = 0; currcons < MIN_NR_CONSOLES; currcons++) {
+ if (currcons == vt_handoff - 1)
+ continue;
vc_cons[currcons].d = vc = kzalloc(sizeof(struct vc_data), GFP_NOWAIT);
INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK);
tty_port_init(&vc->port);
visual_init(vc, currcons, 1);
vc->vc_screenbuf = kzalloc(vc->vc_screenbuf_size, GFP_NOWAIT);
vc_init(vc, vc->vc_rows, vc->vc_cols,
- currcons || !vc->vc_sw->con_save_screen);
+ currcons || !vc->vc_sw->con_save_screen, KD_TEXT);
}
currcons = fg_console = 0;
+ if (vt_handoff > 0) {
+ printk(KERN_INFO "vt handoff: transparent VT on vt#%d\n",
+ vt_handoff);
+ currcons = fg_console = vt_handoff - 1;
+ }
master_display_fg = vc = vc_cons[currcons].d;
set_origin(vc);
save_screen(vc);
diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c
index 64618547be11..ff5496af5faa 100644
--- a/drivers/tty/vt/vt_ioctl.c
+++ b/drivers/tty/vt/vt_ioctl.c
@@ -996,9 +996,9 @@ out:
return ret;
}
-void reset_vc(struct vc_data *vc)
+void reset_vc(struct vc_data *vc, int mode)
{
- vc->vc_mode = KD_TEXT;
+ vc->vc_mode = mode;
vt_reset_unicode(vc->vc_num);
vc->vt_mode.mode = VT_AUTO;
vc->vt_mode.waitv = 0;
@@ -1030,7 +1030,7 @@ void vc_SAK(struct work_struct *work)
*/
if (tty)
__do_SAK(tty);
- reset_vc(vc);
+ reset_vc(vc, KD_TEXT);
}
console_unlock();
}
@@ -1287,7 +1287,7 @@ static void complete_change_console(struct vc_data *vc)
* this outside of VT_PROCESS but there is no single process
* to account for and tracking tty count may be undesirable.
*/
- reset_vc(vc);
+ reset_vc(vc, KD_TEXT);
if (old_vc_mode != vc->vc_mode) {
if (vc->vc_mode == KD_TEXT)
@@ -1359,7 +1359,7 @@ void change_console(struct vc_data *new_vc)
* this outside of VT_PROCESS but there is no single process
* to account for and tracking tty count may be undesirable.
*/
- reset_vc(vc);
+ reset_vc(vc, KD_TEXT);
/*
* Fall through to normal (VT_AUTO) handling of the switch...
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 8fb484984c86..9062963fb5b2 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -24,6 +24,7 @@
#include <linux/kthread.h>
#include <linux/mutex.h>
#include <linux/freezer.h>
+#include <linux/rcupdate.h>
#include <asm/uaccess.h>
#include <asm/byteorder.h>
@@ -2218,6 +2219,10 @@ fail:
*/
int usb_deauthorize_device(struct usb_device *usb_dev)
{
+ char *product = NULL;
+ char *manufacturer = NULL;
+ char *serial = NULL;
+
usb_lock_device(usb_dev);
if (usb_dev->authorized == 0)
goto out_unauthorized;
@@ -2225,11 +2230,12 @@ int usb_deauthorize_device(struct usb_device *usb_dev)
usb_dev->authorized = 0;
usb_set_configuration(usb_dev, -1);
- kfree(usb_dev->product);
+ product = usb_dev->product;
+ manufacturer = usb_dev->manufacturer;
+ serial = usb_dev->serial;
+
usb_dev->product = kstrdup("n/a (unauthorized)", GFP_KERNEL);
- kfree(usb_dev->manufacturer);
usb_dev->manufacturer = kstrdup("n/a (unauthorized)", GFP_KERNEL);
- kfree(usb_dev->serial);
usb_dev->serial = kstrdup("n/a (unauthorized)", GFP_KERNEL);
usb_destroy_configuration(usb_dev);
@@ -2237,6 +2243,12 @@ int usb_deauthorize_device(struct usb_device *usb_dev)
out_unauthorized:
usb_unlock_device(usb_dev);
+ if (product || manufacturer || serial) {
+ synchronize_rcu();
+ kfree(product);
+ kfree(manufacturer);
+ kfree(serial);
+ }
return 0;
}
@@ -2244,6 +2256,9 @@ out_unauthorized:
int usb_authorize_device(struct usb_device *usb_dev)
{
int result = 0, c;
+ char *product = NULL;
+ char *manufacturer = NULL;
+ char *serial = NULL;
usb_lock_device(usb_dev);
if (usb_dev->authorized == 1)
@@ -2262,11 +2277,12 @@ int usb_authorize_device(struct usb_device *usb_dev)
goto error_device_descriptor;
}
- kfree(usb_dev->product);
+ product = usb_dev->product;
+ manufacturer = usb_dev->manufacturer;
+ serial = usb_dev->serial;
+
usb_dev->product = NULL;
- kfree(usb_dev->manufacturer);
usb_dev->manufacturer = NULL;
- kfree(usb_dev->serial);
usb_dev->serial = NULL;
usb_dev->authorized = 1;
@@ -2294,6 +2310,12 @@ error_device_descriptor:
error_autoresume:
out_authorized:
usb_unlock_device(usb_dev); // complements locktree
+ if (product || manufacturer || serial) {
+ synchronize_rcu();
+ kfree(product);
+ kfree(manufacturer);
+ kfree(serial);
+ }
return result;
}
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
index 9a56e3adf476..45801b5678fc 100644
--- a/drivers/usb/core/sysfs.c
+++ b/drivers/usb/core/sysfs.c
@@ -85,9 +85,9 @@ static ssize_t show_##name(struct device *dev, \
int retval; \
\
udev = to_usb_device(dev); \
- usb_lock_device(udev); \
- retval = sprintf(buf, "%s\n", udev->name); \
- usb_unlock_device(udev); \
+ rcu_read_lock(); \
+ retval = sprintf(buf, "%s\n", rcu_dereference(udev->name)); \
+ rcu_read_unlock(); \
return retval; \
} \
static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL);
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index 1719886bb9be..d1630aeae363 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -1163,6 +1163,13 @@ UNUSUAL_DEV( 0x0af0, 0x6971, 0x0000, 0x9999,
USB_SC_DEVICE, USB_PR_DEVICE, option_ms_init,
0),
+/* Reported by Timo Aaltonen <tjaalton@ubuntu.com> */
+UNUSUAL_DEV( 0x0af0, 0x7011, 0x0000, 0x9999,
+ "Option",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, option_ms_init,
+ 0 ),
+
/* Reported by F. Aben <f.aben@option.com>
* This device (wrongly) has a vendor-specific device descriptor.
* The entry is needed so usb-storage can bind to it's mass-storage
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index b6ea1b569100..b786a00023ab 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -755,8 +755,8 @@ config FB_UVESA
If unsure, say N.
config FB_VESA
- bool "VESA VGA graphics support"
- depends on (FB = y) && X86
+ tristate "VESA VGA graphics support"
+ depends on FB && X86
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c
index 501b3406c6d5..eb78a5986c26 100644
--- a/drivers/video/vesafb.c
+++ b/drivers/video/vesafb.c
@@ -27,6 +27,12 @@
#define dac_reg (0x3c8)
#define dac_val (0x3c9)
+struct vesafb_info
+{
+ u32 pseudo_palette[256];
+ int mtrr_hdl;
+};
+
/* --------------------------------------------------------------------- */
static struct fb_var_screeninfo vesafb_defined __initdata = {
@@ -40,22 +46,43 @@ static struct fb_var_screeninfo vesafb_defined __initdata = {
.vmode = FB_VMODE_NONINTERLACED,
};
-static struct fb_fix_screeninfo vesafb_fix __initdata = {
+static struct fb_fix_screeninfo vesafb_fix = {
.id = "VESA VGA",
.type = FB_TYPE_PACKED_PIXELS,
.accel = FB_ACCEL_NONE,
};
+#ifndef MODULE
static int inverse __read_mostly;
-static int mtrr __read_mostly; /* disable mtrr */
+#endif
+static int mtrr __read_mostly = 3; /* disable mtrr */
static int vram_remap __initdata; /* Set amount of memory to be used */
static int vram_total __initdata; /* Set total amount of memory */
static int pmi_setpal __read_mostly = 1; /* pmi for palette changes ??? */
+static int redraw __read_mostly;
static int ypan __read_mostly; /* 0..nothing, 1..ypan, 2..ywrap */
+static int ywrap __read_mostly;
static void (*pmi_start)(void) __read_mostly;
static void (*pmi_pal) (void) __read_mostly;
static int depth __read_mostly;
static int vga_compat __read_mostly;
+
+module_param(redraw, bool, 0);
+module_param(ypan, bool, 0);
+module_param(ywrap, bool, 0);
+module_param_named(vgapal, pmi_setpal, invbool, 0);
+MODULE_PARM_DESC(vgapal, "Use VGA for setting palette (default)");
+module_param_named(pmipal, pmi_setpal, bool, 0);
+MODULE_PARM_DESC(pmipal, "Use PMI for setting palette");
+module_param(mtrr, uint, 0);
+MODULE_PARM_DESC(mtrr, "Enable MTRR support (default)");
+module_param_named(nomtrr, mtrr, invbool, 0);
+MODULE_PARM_DESC(nomtrr, "Disable MTRR support");
+module_param(vram_remap, int, 0);
+MODULE_PARM_DESC(vram_remap, "Set total amount of memory to be used");
+module_param(vram_total, int, 0);
+MODULE_PARM_DESC(vram_total, "Total amount of memory");
+
/* --------------------------------------------------------------------- */
static int vesafb_pan_display(struct fb_var_screeninfo *var,
@@ -192,6 +219,7 @@ static struct fb_ops vesafb_ops = {
.fb_imageblit = cfb_imageblit,
};
+#ifndef MODULE
static int __init vesafb_setup(char *options)
{
char *this_opt;
@@ -225,10 +253,12 @@ static int __init vesafb_setup(char *options)
}
return 0;
}
+#endif
static int __init vesafb_probe(struct platform_device *dev)
{
struct fb_info *info;
+ struct vesafb_info *vfb_info;
int i, err;
unsigned int size_vmode;
unsigned int size_remap;
@@ -287,13 +317,14 @@ static int __init vesafb_probe(struct platform_device *dev)
spaces our resource handlers simply don't know about */
}
- info = framebuffer_alloc(sizeof(u32) * 256, &dev->dev);
+ info = framebuffer_alloc(sizeof(struct vesafb_info), &dev->dev);
if (!info) {
release_mem_region(vesafb_fix.smem_start, size_total);
return -ENOMEM;
}
- info->pseudo_palette = info->par;
- info->par = NULL;
+ vfb_info = (struct vesafb_info *) info->par;
+ vfb_info->mtrr_hdl = -1;
+ info->pseudo_palette = vfb_info->pseudo_palette;
/* set vesafb aperture size for generic probing */
info->apertures = alloc_apertures(1);
@@ -423,17 +454,15 @@ static int __init vesafb_probe(struct platform_device *dev)
}
if (type) {
- int rc;
-
/* Find the largest power-of-two */
temp_size = roundup_pow_of_two(temp_size);
/* Try and find a power of two to add */
do {
- rc = mtrr_add(vesafb_fix.smem_start, temp_size,
+ vfb_info->mtrr_hdl = mtrr_add(vesafb_fix.smem_start, temp_size,
type, 1);
temp_size >>= 1;
- } while (temp_size >= PAGE_SIZE && rc == -EINVAL);
+ } while (temp_size >= PAGE_SIZE && vfb_info->mtrr_hdl == -EINVAL);
}
}
#endif
@@ -495,7 +524,27 @@ err:
return err;
}
+static int __exit vesafb_remove(struct platform_device *device)
+{
+ struct fb_info *info = dev_get_drvdata(&device->dev);
+
+ unregister_framebuffer(info);
+#ifdef CONFIG_MTRR
+ {
+ struct vesafb_info *vfb_info = (struct vesafb_info *) info->par;
+ if (vfb_info->mtrr_hdl >= 0)
+ mtrr_del(vfb_info->mtrr_hdl, 0, 0);
+ }
+#endif
+ iounmap(info->screen_base);
+ framebuffer_release(info);
+ release_mem_region(vesafb_fix.smem_start, vesafb_fix.smem_len);
+
+ return 0;
+}
+
static struct platform_driver vesafb_driver = {
+ .remove = vesafb_remove,
.driver = {
.name = "vesafb",
},
@@ -506,11 +555,18 @@ static struct platform_device *vesafb_device;
static int __init vesafb_init(void)
{
int ret;
+#ifndef MODULE
char *option = NULL;
/* ignore error return of fb_get_options */
fb_get_options("vesafb", &option);
vesafb_setup(option);
+#else
+ if (redraw)
+ ypan = 0;
+ if (ywrap)
+ ypan = 2;
+#endif
vesafb_device = platform_device_alloc("vesafb", 0);
if (!vesafb_device)
@@ -530,6 +586,14 @@ static int __init vesafb_init(void)
return ret;
}
+
+static void __exit vesafb_exit(void)
+{
+ platform_device_unregister(vesafb_device);
+ platform_driver_unregister(&vesafb_driver);
+}
+
module_init(vesafb_init);
+module_exit(vesafb_exit);
MODULE_LICENSE("GPL");