aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2009-10-26 10:48:18 +0900
committerPaul Mundt <lethal@linux-sh.org>2009-10-26 10:48:18 +0900
commit6253195b671b98a4e5da5d39c2df9f8f257bcea1 (patch)
tree3b7ca1d8ef5d9c50a77abf1d1cf5b2b5aa243284 /drivers
parent15893fb565921507da80e500d85bb2575989bb57 (diff)
parent60339fad5c68c9c533cd14e67194ff8f727c41d9 (diff)
Merge branch 'sh/stable-updates'
Conflicts: arch/sh/kernel/dwarf.c
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ata/ahci.c3
-rw-r--r--drivers/ata/libata-core.c12
-rw-r--r--drivers/ata/libata-eh.c6
-rw-r--r--drivers/ata/pata_atiixp.c2
-rw-r--r--drivers/ata/pata_sc1200.c3
-rw-r--r--drivers/ata/pata_via.c2
-rw-r--r--drivers/ata/sata_mv.c29
-rw-r--r--drivers/ata/sata_nv.c18
-rw-r--r--drivers/block/virtio_blk.c39
-rw-r--r--drivers/char/hw_random/virtio-rng.c3
-rw-r--r--drivers/char/virtio_console.c1
-rw-r--r--drivers/crypto/padlock-sha.c14
-rw-r--r--drivers/edac/amd64_edac.c8
-rw-r--r--drivers/ide/atiixp.c2
-rw-r--r--drivers/input/input.c65
-rw-r--r--drivers/input/keyboard/atkbd.c96
-rw-r--r--drivers/input/misc/hp_sdc_rtc.c2
-rw-r--r--drivers/input/mouse/logips2pp.c2
-rw-r--r--drivers/input/mouse/synaptics.c10
-rw-r--r--drivers/input/serio/i8042-x86ia64io.h13
-rw-r--r--drivers/md/dm-exception-store.c38
-rw-r--r--drivers/md/dm-exception-store.h8
-rw-r--r--drivers/md/dm-log-userspace-base.c2
-rw-r--r--drivers/md/dm-snap-persistent.c16
-rw-r--r--drivers/md/dm-snap.c25
-rw-r--r--drivers/md/dm.c11
-rw-r--r--drivers/mmc/host/at91_mci.c1
-rw-r--r--drivers/net/benet/be_cmds.c33
-rw-r--r--drivers/net/benet/be_cmds.h5
-rw-r--r--drivers/net/benet/be_main.c27
-rw-r--r--drivers/net/ethoc.c21
-rw-r--r--drivers/net/fec.c2
-rw-r--r--drivers/net/ks8851.c42
-rw-r--r--drivers/net/ks8851.h1
-rw-r--r--drivers/net/niu.c2
-rw-r--r--drivers/net/virtio_net.c3
-rw-r--r--drivers/net/vmxnet3/vmxnet3_drv.c27
-rw-r--r--drivers/net/vmxnet3/vmxnet3_int.h2
-rw-r--r--drivers/pci/quirks.c6
-rw-r--r--drivers/virtio/virtio_balloon.c3
40 files changed, 376 insertions, 229 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index b1a257746a1..a06f5d6375a 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -575,7 +575,7 @@ static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_VDEVICE(ATI, 0x4395), board_ahci_sb700 }, /* ATI SB700/800 */
/* AMD */
- { PCI_VDEVICE(AMD, 0x7800), board_ahci }, /* AMD SB900 */
+ { PCI_VDEVICE(AMD, 0x7800), board_ahci }, /* AMD Hudson-2 */
/* AMD is using RAID class only for ahci controllers */
{ PCI_VENDOR_ID_AMD, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
PCI_CLASS_STORAGE_RAID << 8, 0xffffff, board_ahci },
@@ -605,6 +605,7 @@ static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_VDEVICE(NVIDIA, 0x0559), board_ahci_yesncq }, /* MCP67 */
{ PCI_VDEVICE(NVIDIA, 0x055a), board_ahci_yesncq }, /* MCP67 */
{ PCI_VDEVICE(NVIDIA, 0x055b), board_ahci_yesncq }, /* MCP67 */
+ { PCI_VDEVICE(NVIDIA, 0x0580), board_ahci_yesncq }, /* Linux ID */
{ PCI_VDEVICE(NVIDIA, 0x07f0), board_ahci_yesncq }, /* MCP73 */
{ PCI_VDEVICE(NVIDIA, 0x07f1), board_ahci_yesncq }, /* MCP73 */
{ PCI_VDEVICE(NVIDIA, 0x07f2), board_ahci_yesncq }, /* MCP73 */
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index b525a098134..d7f0f1b1ae3 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -5028,12 +5028,14 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
qc->flags |= ATA_QCFLAG_FAILED;
if (unlikely(qc->flags & ATA_QCFLAG_FAILED)) {
- if (!ata_tag_internal(qc->tag)) {
- /* always fill result TF for failed qc */
- fill_result_tf(qc);
+ /* always fill result TF for failed qc */
+ fill_result_tf(qc);
+
+ if (!ata_tag_internal(qc->tag))
ata_qc_schedule_eh(qc);
- return;
- }
+ else
+ __ata_qc_complete(qc);
+ return;
}
WARN_ON_ONCE(ap->pflags & ATA_PFLAG_FROZEN);
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 0a97822da21..bba2ae5df1c 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -2981,12 +2981,14 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link,
* device detection messages backwards.
*/
ata_for_each_dev(dev, link, ALL) {
- if (!(new_mask & (1 << dev->devno)) ||
- dev->class == ATA_DEV_PMP)
+ if (!(new_mask & (1 << dev->devno)))
continue;
dev->class = ehc->classes[dev->devno];
+ if (dev->class == ATA_DEV_PMP)
+ continue;
+
ehc->i.flags |= ATA_EHI_PRINTINFO;
rc = ata_dev_configure(dev);
ehc->i.flags &= ~ATA_EHI_PRINTINFO;
diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c
index aa4b3f6ae77..ae4454d4e95 100644
--- a/drivers/ata/pata_atiixp.c
+++ b/drivers/ata/pata_atiixp.c
@@ -246,7 +246,7 @@ static const struct pci_device_id atiixp[] = {
{ PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP400_IDE), },
{ PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP600_IDE), },
{ PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP700_IDE), },
- { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_SB900_IDE), },
+ { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_HUDSON2_IDE), },
{ },
};
diff --git a/drivers/ata/pata_sc1200.c b/drivers/ata/pata_sc1200.c
index f49814d6fd2..3bbed8322ec 100644
--- a/drivers/ata/pata_sc1200.c
+++ b/drivers/ata/pata_sc1200.c
@@ -235,8 +235,7 @@ static int sc1200_init_one(struct pci_dev *dev, const struct pci_device_id *id)
.udma_mask = ATA_UDMA2,
.port_ops = &sc1200_port_ops
};
- /* Can't enable port 2 yet, see top comments */
- const struct ata_port_info *ppi[] = { &info, };
+ const struct ata_port_info *ppi[] = { &info, NULL };
return ata_pci_sff_init_one(dev, ppi, &sc1200_sht, NULL);
}
diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c
index 45657cacec4..88984b803d6 100644
--- a/drivers/ata/pata_via.c
+++ b/drivers/ata/pata_via.c
@@ -111,7 +111,7 @@ static const struct via_isa_bridge {
{ "vt8251", PCI_DEVICE_ID_VIA_8251, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
{ "cx700", PCI_DEVICE_ID_VIA_CX700, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_SATA_PATA },
{ "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_NO_ENABLES },
- { "vt6415", PCI_DEVICE_ID_VIA_6415, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_NO_ENABLES },
+ { "vt6415", PCI_DEVICE_ID_VIA_6415, 0x00, 0xff, VIA_UDMA_133 | VIA_BAD_AST | VIA_NO_ENABLES },
{ "vt8237a", PCI_DEVICE_ID_VIA_8237A, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
{ "vt8237", PCI_DEVICE_ID_VIA_8237, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
{ "vt8235", PCI_DEVICE_ID_VIA_8235, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 17f9ff9067a..6f5093b7c8c 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -1382,6 +1382,25 @@ static int mv_qc_defer(struct ata_queued_cmd *qc)
*/
if (pp->pp_flags & MV_PP_FLAG_DELAYED_EH)
return ATA_DEFER_PORT;
+
+ /* PIO commands need exclusive link: no other commands [DMA or PIO]
+ * can run concurrently.
+ * set excl_link when we want to send a PIO command in DMA mode
+ * or a non-NCQ command in NCQ mode.
+ * When we receive a command from that link, and there are no
+ * outstanding commands, mark a flag to clear excl_link and let
+ * the command go through.
+ */
+ if (unlikely(ap->excl_link)) {
+ if (link == ap->excl_link) {
+ if (ap->nr_active_links)
+ return ATA_DEFER_PORT;
+ qc->flags |= ATA_QCFLAG_CLEAR_EXCL;
+ return 0;
+ } else
+ return ATA_DEFER_PORT;
+ }
+
/*
* If the port is completely idle, then allow the new qc.
*/
@@ -1395,8 +1414,14 @@ static int mv_qc_defer(struct ata_queued_cmd *qc)
* doesn't allow it.
*/
if ((pp->pp_flags & MV_PP_FLAG_EDMA_EN) &&
- (pp->pp_flags & MV_PP_FLAG_NCQ_EN) && ata_is_ncq(qc->tf.protocol))
- return 0;
+ (pp->pp_flags & MV_PP_FLAG_NCQ_EN)) {
+ if (ata_is_ncq(qc->tf.protocol))
+ return 0;
+ else {
+ ap->excl_link = link;
+ return ATA_DEFER_PORT;
+ }
+ }
return ATA_DEFER_PORT;
}
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index 86a40582999..1eb4e020eb5 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -1594,9 +1594,21 @@ static int nv_hardreset(struct ata_link *link, unsigned int *class,
!ata_dev_enabled(link->device))
sata_link_hardreset(link, sata_deb_timing_hotplug, deadline,
NULL, NULL);
- else if (!(ehc->i.flags & ATA_EHI_QUIET))
- ata_link_printk(link, KERN_INFO,
- "nv: skipping hardreset on occupied port\n");
+ else {
+ const unsigned long *timing = sata_ehc_deb_timing(ehc);
+ int rc;
+
+ if (!(ehc->i.flags & ATA_EHI_QUIET))
+ ata_link_printk(link, KERN_INFO, "nv: skipping "
+ "hardreset on occupied port\n");
+
+ /* make sure the link is online */
+ rc = sata_link_resume(link, timing, deadline);
+ /* whine about phy resume failure but proceed */
+ if (rc && rc != -EOPNOTSUPP)
+ ata_link_printk(link, KERN_WARNING, "failed to resume "
+ "link (errno=%d)\n", rc);
+ }
/* device signature acquisition is unreliable */
return -EAGAIN;
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index 43f19389647..51042f0ba7e 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -3,7 +3,6 @@
#include <linux/blkdev.h>
#include <linux/hdreg.h>
#include <linux/virtio.h>
-#include <linux/virtio_ids.h>
#include <linux/virtio_blk.h>
#include <linux/scatterlist.h>
@@ -183,34 +182,6 @@ static void do_virtblk_request(struct request_queue *q)
vblk->vq->vq_ops->kick(vblk->vq);
}
-/* return ATA identify data
- */
-static int virtblk_identify(struct gendisk *disk, void *argp)
-{
- struct virtio_blk *vblk = disk->private_data;
- void *opaque;
- int err = -ENOMEM;
-
- opaque = kmalloc(VIRTIO_BLK_ID_BYTES, GFP_KERNEL);
- if (!opaque)
- goto out;
-
- err = virtio_config_buf(vblk->vdev, VIRTIO_BLK_F_IDENTIFY,
- offsetof(struct virtio_blk_config, identify), opaque,
- VIRTIO_BLK_ID_BYTES);
-
- if (err)
- goto out_kfree;
-
- if (copy_to_user(argp, opaque, VIRTIO_BLK_ID_BYTES))
- err = -EFAULT;
-
-out_kfree:
- kfree(opaque);
-out:
- return err;
-}
-
static void virtblk_prepare_flush(struct request_queue *q, struct request *req)
{
req->cmd_type = REQ_TYPE_LINUX_BLOCK;
@@ -222,10 +193,6 @@ static int virtblk_ioctl(struct block_device *bdev, fmode_t mode,
{
struct gendisk *disk = bdev->bd_disk;
struct virtio_blk *vblk = disk->private_data;
- void __user *argp = (void __user *)data;
-
- if (cmd == HDIO_GET_IDENTITY)
- return virtblk_identify(disk, argp);
/*
* Only allow the generic SCSI ioctls if the host can support it.
@@ -233,7 +200,8 @@ static int virtblk_ioctl(struct block_device *bdev, fmode_t mode,
if (!virtio_has_feature(vblk->vdev, VIRTIO_BLK_F_SCSI))
return -ENOTTY;
- return scsi_cmd_ioctl(disk->queue, disk, mode, cmd, argp);
+ return scsi_cmd_ioctl(disk->queue, disk, mode, cmd,
+ (void __user *)data);
}
/* We provide getgeo only to please some old bootloader/partitioning tools */
@@ -332,7 +300,6 @@ static int __devinit virtblk_probe(struct virtio_device *vdev)
}
vblk->disk->queue->queuedata = vblk;
- queue_flag_set_unlocked(QUEUE_FLAG_VIRT, vblk->disk->queue);
if (index < 26) {
sprintf(vblk->disk->disk_name, "vd%c", 'a' + index % 26);
@@ -445,7 +412,7 @@ static struct virtio_device_id id_table[] = {
static unsigned int features[] = {
VIRTIO_BLK_F_BARRIER, VIRTIO_BLK_F_SEG_MAX, VIRTIO_BLK_F_SIZE_MAX,
VIRTIO_BLK_F_GEOMETRY, VIRTIO_BLK_F_RO, VIRTIO_BLK_F_BLK_SIZE,
- VIRTIO_BLK_F_SCSI, VIRTIO_BLK_F_IDENTIFY, VIRTIO_BLK_F_FLUSH
+ VIRTIO_BLK_F_SCSI, VIRTIO_BLK_F_FLUSH
};
/*
diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c
index 962968f05b9..915157fcff9 100644
--- a/drivers/char/hw_random/virtio-rng.c
+++ b/drivers/char/hw_random/virtio-rng.c
@@ -21,7 +21,6 @@
#include <linux/scatterlist.h>
#include <linux/spinlock.h>
#include <linux/virtio.h>
-#include <linux/virtio_ids.h>
#include <linux/virtio_rng.h>
/* The host will fill any buffer we give it with sweet, sweet randomness. We
@@ -117,7 +116,7 @@ static int virtrng_probe(struct virtio_device *vdev)
return 0;
}
-static void virtrng_remove(struct virtio_device *vdev)
+static void __devexit virtrng_remove(struct virtio_device *vdev)
{
vdev->config->reset(vdev);
hwrng_unregister(&virtio_hwrng);
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index 0d328b59568..a035ae39a35 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -31,7 +31,6 @@
#include <linux/err.h>
#include <linux/init.h>
#include <linux/virtio.h>
-#include <linux/virtio_ids.h>
#include <linux/virtio_console.h>
#include "hvc_console.h"
diff --git a/drivers/crypto/padlock-sha.c b/drivers/crypto/padlock-sha.c
index 76cb6b345e7..0af80577dc7 100644
--- a/drivers/crypto/padlock-sha.c
+++ b/drivers/crypto/padlock-sha.c
@@ -24,6 +24,12 @@
#include <asm/i387.h>
#include "padlock.h"
+#ifdef CONFIG_64BIT
+#define STACK_ALIGN 16
+#else
+#define STACK_ALIGN 4
+#endif
+
struct padlock_sha_desc {
struct shash_desc fallback;
};
@@ -64,7 +70,9 @@ static int padlock_sha1_finup(struct shash_desc *desc, const u8 *in,
/* We can't store directly to *out as it may be unaligned. */
/* BTW Don't reduce the buffer size below 128 Bytes!
* PadLock microcode needs it that big. */
- char result[128] __attribute__ ((aligned(PADLOCK_ALIGNMENT)));
+ char buf[128 + PADLOCK_ALIGNMENT - STACK_ALIGN] __attribute__
+ ((aligned(STACK_ALIGN)));
+ char *result = PTR_ALIGN(&buf[0], PADLOCK_ALIGNMENT);
struct padlock_sha_desc *dctx = shash_desc_ctx(desc);
struct sha1_state state;
unsigned int space;
@@ -128,7 +136,9 @@ static int padlock_sha256_finup(struct shash_desc *desc, const u8 *in,
/* We can't store directly to *out as it may be unaligned. */
/* BTW Don't reduce the buffer size below 128 Bytes!
* PadLock microcode needs it that big. */
- char result[128] __attribute__ ((aligned(PADLOCK_ALIGNMENT)));
+ char buf[128 + PADLOCK_ALIGNMENT - STACK_ALIGN] __attribute__
+ ((aligned(STACK_ALIGN)));
+ char *result = PTR_ALIGN(&buf[0], PADLOCK_ALIGNMENT);
struct padlock_sha_desc *dctx = shash_desc_ctx(desc);
struct sha256_state state;
unsigned int space;
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index 4f4ac82382f..d4560d9d5a8 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -1122,7 +1122,7 @@ static void k8_read_dram_base_limit(struct amd64_pvt *pvt, int dram)
debugf0("Reading K8_DRAM_BASE_LOW failed\n");
/* Extract parts into separate data entries */
- pvt->dram_base[dram] = ((u64) low & 0xFFFF0000) << 24;
+ pvt->dram_base[dram] = ((u64) low & 0xFFFF0000) << 8;
pvt->dram_IntlvEn[dram] = (low >> 8) & 0x7;
pvt->dram_rw_en[dram] = (low & 0x3);
@@ -1135,7 +1135,7 @@ static void k8_read_dram_base_limit(struct amd64_pvt *pvt, int dram)
* Extract parts into separate data entries. Limit is the HIGHEST memory
* location of the region, so lower 24 bits need to be all ones
*/
- pvt->dram_limit[dram] = (((u64) low & 0xFFFF0000) << 24) | 0x00FFFFFF;
+ pvt->dram_limit[dram] = (((u64) low & 0xFFFF0000) << 8) | 0x00FFFFFF;
pvt->dram_IntlvSel[dram] = (low >> 8) & 0x7;
pvt->dram_DstNode[dram] = (low & 0x7);
}
@@ -1369,7 +1369,7 @@ static void f10_read_dram_base_limit(struct amd64_pvt *pvt, int dram)
pvt->dram_IntlvEn[dram] = (low_base >> 8) & 0x7;
pvt->dram_base[dram] = (((u64)high_base & 0x000000FF) << 40) |
- (((u64)low_base & 0xFFFF0000) << 24);
+ (((u64)low_base & 0xFFFF0000) << 8);
low_offset = K8_DRAM_LIMIT_LOW + (dram << 3);
high_offset = F10_DRAM_LIMIT_HIGH + (dram << 3);
@@ -1391,7 +1391,7 @@ static void f10_read_dram_base_limit(struct amd64_pvt *pvt, int dram)
* memory location of the region, so low 24 bits need to be all ones.
*/
pvt->dram_limit[dram] = (((u64)high_limit & 0x000000FF) << 40) |
- (((u64) low_limit & 0xFFFF0000) << 24) |
+ (((u64) low_limit & 0xFFFF0000) << 8) |
0x00FFFFFF;
}
diff --git a/drivers/ide/atiixp.c b/drivers/ide/atiixp.c
index 6396c3ad325..837322b10a4 100644
--- a/drivers/ide/atiixp.c
+++ b/drivers/ide/atiixp.c
@@ -177,7 +177,7 @@ static const struct pci_device_id atiixp_pci_tbl[] = {
{ PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP400_IDE), 0 },
{ PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP600_IDE), 1 },
{ PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP700_IDE), 0 },
- { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_SB900_IDE), 0 },
+ { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_HUDSON2_IDE), 0 },
{ 0, },
};
MODULE_DEVICE_TABLE(pci, atiixp_pci_tbl);
diff --git a/drivers/input/input.c b/drivers/input/input.c
index c6f88ebb40c..cc763c96fad 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -782,10 +782,29 @@ static unsigned int input_proc_devices_poll(struct file *file, poll_table *wait)
return 0;
}
+union input_seq_state {
+ struct {
+ unsigned short pos;
+ bool mutex_acquired;
+ };
+ void *p;
+};
+
static void *input_devices_seq_start(struct seq_file *seq, loff_t *pos)
{
- if (mutex_lock_interruptible(&input_mutex))
- return NULL;
+ union input_seq_state *state = (union input_seq_state *)&seq->private;
+ int error;
+
+ /* We need to fit into seq->private pointer */
+ BUILD_BUG_ON(sizeof(union input_seq_state) != sizeof(seq->private));
+
+ error = mutex_lock_interruptible(&input_mutex);
+ if (error) {
+ state->mutex_acquired = false;
+ return ERR_PTR(error);
+ }
+
+ state->mutex_acquired = true;
return seq_list_start(&input_dev_list, *pos);
}
@@ -795,9 +814,12 @@ static void *input_devices_seq_next(struct seq_file *seq, void *v, loff_t *pos)
return seq_list_next(v, &input_dev_list, pos);
}
-static void input_devices_seq_stop(struct seq_file *seq, void *v)
+static void input_seq_stop(struct seq_file *seq, void *v)
{
- mutex_unlock(&input_mutex);
+ union input_seq_state *state = (union input_seq_state *)&seq->private;
+
+ if (state->mutex_acquired)
+ mutex_unlock(&input_mutex);
}
static void input_seq_print_bitmap(struct seq_file *seq, const char *name,
@@ -861,7 +883,7 @@ static int input_devices_seq_show(struct seq_file *seq, void *v)
static const struct seq_operations input_devices_seq_ops = {
.start = input_devices_seq_start,
.next = input_devices_seq_next,
- .stop = input_devices_seq_stop,
+ .stop = input_seq_stop,
.show = input_devices_seq_show,
};
@@ -881,40 +903,49 @@ static const struct file_operations input_devices_fileops = {
static void *input_handlers_seq_start(struct seq_file *seq, loff_t *pos)
{
- if (mutex_lock_interruptible(&input_mutex))
- return NULL;
+ union input_seq_state *state = (union input_seq_state *)&seq->private;
+ int error;
+
+ /* We need to fit into seq->private pointer */
+ BUILD_BUG_ON(sizeof(union input_seq_state) != sizeof(seq->private));
+
+ error = mutex_lock_interruptible(&input_mutex);
+ if (error) {
+ state->mutex_acquired = false;
+ return ERR_PTR(error);
+ }
+
+ state->mutex_acquired = true;
+ state->pos = *pos;
- seq->private = (void *)(unsigned long)*pos;
return seq_list_start(&input_handler_list, *pos);
}
static void *input_handlers_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
- seq->private = (void *)(unsigned long)(*pos + 1);
- return seq_list_next(v, &input_handler_list, pos);
-}
+ union input_seq_state *state = (union input_seq_state *)&seq->private;
-static void input_handlers_seq_stop(struct seq_file *seq, void *v)
-{
- mutex_unlock(&input_mutex);
+ state->pos = *pos + 1;
+ return seq_list_next(v, &input_handler_list, pos);
}
static int input_handlers_seq_show(struct seq_file *seq, void *v)
{
struct input_handler *handler = container_of(v, struct input_handler, node);
+ union input_seq_state *state = (union input_seq_state *)&seq->private;
- seq_printf(seq, "N: Number=%ld Name=%s",
- (unsigned long)seq->private, handler->name);
+ seq_printf(seq, "N: Number=%u Name=%s", state->pos, handler->name);
if (handler->fops)
seq_printf(seq, " Minor=%d", handler->minor);
seq_putc(seq, '\n');
return 0;
}
+
static const struct seq_operations input_handlers_seq_ops = {
.start = input_handlers_seq_start,
.next = input_handlers_seq_next,
- .stop = input_handlers_seq_stop,
+ .stop = input_seq_stop,
.show = input_handlers_seq_show,
};
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index 4709e15af60..a6512372c7a 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -574,11 +574,22 @@ static void atkbd_event_work(struct work_struct *work)
mutex_lock(&atkbd->event_mutex);
- if (test_and_clear_bit(ATKBD_LED_EVENT_BIT, &atkbd->event_mask))
- atkbd_set_leds(atkbd);
+ if (!atkbd->enabled) {
+ /*
+ * Serio ports are resumed asynchronously so while driver core
+ * thinks that device is already fully operational in reality
+ * it may not be ready yet. In this case we need to keep
+ * rescheduling till reconnect completes.
+ */
+ schedule_delayed_work(&atkbd->event_work,
+ msecs_to_jiffies(100));
+ } else {
+ if (test_and_clear_bit(ATKBD_LED_EVENT_BIT, &atkbd->event_mask))
+ atkbd_set_leds(atkbd);
- if (test_and_clear_bit(ATKBD_REP_EVENT_BIT, &atkbd->event_mask))
- atkbd_set_repeat_rate(atkbd);
+ if (test_and_clear_bit(ATKBD_REP_EVENT_BIT, &atkbd->event_mask))
+ atkbd_set_repeat_rate(atkbd);
+ }
mutex_unlock(&atkbd->event_mutex);
}
@@ -770,6 +781,30 @@ static int atkbd_select_set(struct atkbd *atkbd, int target_set, int allow_extra
return 3;
}
+static int atkbd_reset_state(struct atkbd *atkbd)
+{
+ struct ps2dev *ps2dev = &atkbd->ps2dev;
+ unsigned char param[1];
+
+/*
+ * Set the LEDs to a predefined state (all off).
+ */
+
+ param[0] = 0;
+ if (ps2_command(ps2dev, param, ATKBD_CMD_SETLEDS))
+ return -1;
+
+/*
+ * Set autorepeat to fastest possible.
+ */
+
+ param[0] = 0;
+ if (ps2_command(ps2dev, param, ATKBD_CMD_SETREP))
+ return -1;
+
+ return 0;
+}
+
static int atkbd_activate(struct atkbd *atkbd)
{
struct ps2dev *ps2dev = &atkbd->ps2dev;
@@ -852,29 +887,6 @@ static unsigned int atkbd_hp_forced_release_keys[] = {
};
/*
- * Inventec system with broken key release on volume keys
- */
-static unsigned int atkbd_inventec_forced_release_keys[] = {
- 0xae, 0xb0, -1U
-};
-
-/*
- * Perform fixup for HP Pavilion ZV6100 laptop that doesn't generate release
- * for its volume buttons
- */
-static unsigned int atkbd_hp_zv6100_forced_release_keys[] = {
- 0xae, 0xb0, -1U
-};
-
-/*
- * Perform fixup for HP (Compaq) Presario R4000 R4100 R4200 that don't generate
- * release for their volume buttons
- */
-static unsigned int atkbd_hp_r4000_forced_release_keys[] = {
- 0xae, 0xb0, -1U
-};
-
-/*
* Samsung NC10,NC20 with Fn+F? key release not working
*/
static unsigned int atkbd_samsung_forced_release_keys[] = {
@@ -882,14 +894,6 @@ static unsigned int atkbd_samsung_forced_release_keys[] = {
};
/*
- * The volume up and volume down special keys on a Fujitsu Amilo PA 1510 laptop
- * do not generate release events so we have to do it ourselves.
- */
-static unsigned int atkbd_amilo_pa1510_forced_release_keys[] = {
- 0xb0, 0xae, -1U
-};
-
-/*
* Amilo Pi 3525 key release for Fn+Volume keys not working
*/
static unsigned int atkbd_amilo_pi3525_forced_release_keys[] = {
@@ -911,6 +915,14 @@ static unsigned int atkdb_soltech_ta12_forced_release_keys[] = {
};
/*
+ * Many notebooks don't send key release event for volume up/down
+ * keys, with key list below common among them
+ */
+static unsigned int atkbd_volume_forced_release_keys[] = {
+ 0xae, 0xb0, -1U
+};
+
+/*
* atkbd_set_keycode_table() initializes keyboard's keycode table
* according to the selected scancode set
*/
@@ -1087,6 +1099,7 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
}
atkbd->set = atkbd_select_set(atkbd, atkbd_set, atkbd_extra);
+ atkbd_reset_state(atkbd);
atkbd_activate(atkbd);
} else {
@@ -1267,6 +1280,7 @@ static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t coun
atkbd->dev = new_dev;
atkbd->set = atkbd_select_set(atkbd, atkbd->set, value);
+ atkbd_reset_state(atkbd);
atkbd_activate(atkbd);
atkbd_set_keycode_table(atkbd);
atkbd_set_device_attrs(atkbd);
@@ -1548,7 +1562,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion ZV6100"),
},
.callback = atkbd_setup_forced_release,
- .driver_data = atkbd_hp_zv6100_forced_release_keys,
+ .driver_data = atkbd_volume_forced_release_keys,
},
{
.ident = "HP Presario R4000",
@@ -1557,7 +1571,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4000"),
},
.callback = atkbd_setup_forced_release,
- .driver_data = atkbd_hp_r4000_forced_release_keys,
+ .driver_data = atkbd_volume_forced_release_keys,
},
{
.ident = "HP Presario R4100",
@@ -1566,7 +1580,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4100"),
},
.callback = atkbd_setup_forced_release,
- .driver_data = atkbd_hp_r4000_forced_release_keys,
+ .driver_data = atkbd_volume_forced_release_keys,
},
{
.ident = "HP Presario R4200",
@@ -1575,7 +1589,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4200"),
},
.callback = atkbd_setup_forced_release,
- .driver_data = atkbd_hp_r4000_forced_release_keys,
+ .driver_data = atkbd_volume_forced_release_keys,
},
{
.ident = "Inventec Symphony",
@@ -1584,7 +1598,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
DMI_MATCH(DMI_PRODUCT_NAME, "SYMPHONY 6.0/7.0"),
},
.callback = atkbd_setup_forced_release,
- .driver_data = atkbd_inventec_for